Opossum 简介
Opossum 是 Node.js 生态中最流行的断路器库(当前版本 v8.1.3),由 Node.js Foundation 的 nodeshift 团队维护,采用 Apache-2.0 开源协议。它的名字来源于北美负鼠(opossum),遇到危险时会"装死" -- 这正是断路器打开时的行为:快速失败,不再尝试。
GitHub 仓库:nodeshift/opossum
安装
pnpm add opossum
bash
基本使用
创建断路器实例
import CircuitBreaker from 'opossum';
// 定义需要被保护的异步函数
const fetchUserData = async (userId: string) => {
const response = await fetch(`http://user-service/api/users/${userId}`);
if (!response.ok) {
throw new Error(`用户服务返回错误: ${response.status}`);
}
return response.json();
};
// 创建断路器
const breaker = new CircuitBreaker(fetchUserData, {
timeout: 3000, // 3 秒超时
errorThresholdPercentage: 50, // 错误率 50% 时熔断
resetTimeout: 30000, // 30 秒后尝试恢复
volumeThreshold: 10, // 至少 10 次请求后才开始统计
rollingCountTimeout: 10000, // 10 秒的统计窗口
});
typescript
使用断路器
// 调用被保护的函数
const result = await breaker.fire('user-123')
.then(data => console.log('成功:', data))
.catch(error => console.error('失败:', error.message));
typescript
在 NestJS 中集成 Opossum
创建断路器服务
// src/shared/circuit-breaker.service.ts
import { Injectable, Logger } from '@nestjs/common';
import CircuitBreaker from 'opossum';
interface BreakerOptions {
timeout?: number;
errorThresholdPercentage?: number;
resetTimeout?: number;
}
@Injectable()
export class CircuitBreakerService {
private readonly logger = new Logger(CircuitBreakerService.name);
private breakers = new Map<string, CircuitBreaker>();
// 创建或获取断路器实例
getBreaker<T extends (...args: any[]) => Promise<any>>(
name: string,
fn: T,
options?: BreakerOptions,
): CircuitBreaker {
if (this.breakers.has(name)) {
return this.breakers.get(name)!;
}
const breaker = new CircuitBreaker(fn, {
timeout: 3000,
errorThresholdPercentage: 50,
resetTimeout: 30000,
...options,
});
// 监听状态变化事件
breaker.on('open', () => {
this.logger.warn(`断路器 [${name}] 已打开 - 熔断中`);
});
breaker.on('halfOpen', () => {
this.logger.log(`断路器 [${name}] 半开 - 尝试恢复`);
});
breaker.on('close', () => {
this.logger.log(`断路器 [${name}] 已关闭 - 恢复正常`);
});
breaker.fallback(() => ({
success: false,
message: '服务暂不可用,请稍后重试',
}));
this.breakers.set(name, breaker);
return breaker;
}
}
typescript
在业务服务中使用
// src/modules/order/order.service.ts
import { Injectable } from '@nestjs/common';
import { CircuitBreakerService } from '../../shared/circuit-breaker.service';
@Injectable()
export class OrderService {
private paymentBreaker;
constructor(private readonly circuitBreakerService: CircuitBreakerService) {
// 初始化支付服务的断路器
this.paymentBreaker = this.circuitBreakerService.getBreaker(
'payment-service',
this.callPaymentService.bind(this),
{
timeout: 5000, // 支付服务给 5 秒超时
resetTimeout: 60000, // 1 分钟后尝试恢复
}
);
}
async processOrder(orderId: string, amount: number) {
const result = await this.paymentBreaker.fire(orderId, amount);
return result;
}
private async callPaymentService(orderId: string, amount: number) {
const response = await fetch('http://payment-service/api/charge', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ orderId, amount }),
});
if (!response.ok) {
throw new Error(`支付服务错误: ${response.status}`);
}
return response.json();
}
}
typescript
Opossum 事件体系
Opossum 提供了丰富的事件回调,可以用于监控和日志记录:
| 事件 | 触发时机 | 用途 |
|---|---|---|
success | 函数执行成功 | 记录成功日志 |
failure | 函数执行失败 | 记录错误日志 |
timeout | 请求超时 | 超时告警 |
open | 断路器打开 | 熔断告警通知 |
halfOpen | 断路器半开 | 记录恢复尝试 |
close | 断路器关闭 | 记录恢复正常 |
fallback | 降级函数被执行 | 降级统计 |
reject | 熔断中请求被拒绝 | 被拒绝请求统计 |
semaphoreLocked | 并发数达到上限 | 并发控制 |
breaker.on('success', (result) => {
metrics.increment('breaker.success');
});
breaker.on('failure', (err) => {
metrics.increment('breaker.failure');
logger.error(`调用失败: ${err.message}`);
});
breaker.on('open', () => {
alertService.send('断路器已打开,服务可能异常');
});
typescript
Fallback 降级策略
Opossum 支持设置 fallback 函数,在熔断或失败时返回替代数据:
// 静态降级数据
breaker.fallback(() => ({ items: [], total: 0 }));
// 动态降级(如从缓存读取)
breaker.fallback(async () => {
const cached = await redis.get('products:popular');
return cached ? JSON.parse(cached) : { items: [], total: 0 };
});
// 带参数的降级
breaker.fallback((...args) => {
logger.warn(`降级处理,原始参数: ${JSON.stringify(args)}`);
return { success: false, message: '服务降级中' };
});
typescript
与自实现断路器的对比
| 维度 | 自实现 | Opossum |
|---|---|---|
| 功能完整度 | 基础功能 | 功能丰富(统计、事件、降级等) |
| 生产验证 | 无 | 大量生产环境验证 |
| 维护成本 | 需自行维护 | 社区活跃维护 |
| 统计监控 | 需自行实现 | 内置 stats API |
| 并发控制 | 无 | 内置信号量机制 |
在生产项目中,推荐直接使用 Opossum,不需要重复造轮子。
↑