跨境电商技术架构 错误处理 系统稳定性 故障恢复

错误处理策略

作者: 系统架构师 | 发布于: 2025年4月20日

跨境电商系统错误处理策略

在跨境电商系统中,错误处理是保障系统稳定性和用户体验的关键环节。本文将分享跨境电商系统中错误处理的最佳实践和策略。

错误分类与处理原则

跨境电商系统中的错误可以分为以下几类:

  1. API集成错误:与第三方平台API交互时的错误
  2. 系统内部错误:系统组件内部发生的异常
  3. 业务逻辑错误:业务规则验证失败产生的错误
  4. 网络与基础设施错误:网络连接、服务器故障等

针对不同类型的错误,我们需要采用不同的处理策略,但总体原则是:

  • 优雅降级:核心功能不可用时提供备选方案
  • 透明可见:错误应当被记录并可被监控系统捕获
  • 用户友好:向最终用户展示有意义的错误信息
  • 自动恢复:尽可能实现系统的自动恢复

API错误处理策略

1. 统一错误码映射

将各平台的错误码映射为统一的内部错误码:

// 错误码映射配置
const ERROR_CODE_MAPPING = {
  // Amazon错误码映射
  'amazon': {
    'QuotaExceeded': 'API_RATE_LIMIT_EXCEEDED',
    'Unauthorized': 'AUTHENTICATION_ERROR',
    'ResourceNotFound': 'RESOURCE_NOT_FOUND',
    // ...其他错误码
  },
  // eBay错误码映射
  'ebay': {
    '18000': 'API_RATE_LIMIT_EXCEEDED',
    '931': 'AUTHENTICATION_ERROR',
    '11001': 'RESOURCE_NOT_FOUND',
    // ...其他错误码
  },
  // ...其他平台
};

// 错误码映射函数
function mapErrorCode(platform: string, originalCode: string): string {
  const platformMapping = ERROR_CODE_MAPPING[platform.toLowerCase()];
  if (!platformMapping) {
    return 'UNKNOWN_ERROR';
  }
  
  return platformMapping[originalCode] || 'UNKNOWN_ERROR';
}

2. 智能重试策略

根据错误类型实施不同的重试策略:

class RetryStrategy {
  // 根据错误类型确定是否应该重试
  shouldRetry(error: ApiError): boolean {
    // 这些错误类型可以重试
    const retryableErrors = [
      'API_RATE_LIMIT_EXCEEDED',
      'TEMPORARY_ERROR',
      'SERVICE_UNAVAILABLE',
      'GATEWAY_ERROR',
      'NETWORK_ERROR'
    ];
    
    return retryableErrors.includes(error.code);
  }
  
  // 计算重试延迟时间
  calculateDelay(attempt: number, error: ApiError): number {
    // 基础延迟时间(毫秒)
    const baseDelay = 1000;
    
    // 指数退避策略
    let delay = baseDelay * Math.pow(2, attempt);
    
    // 添加随机抖动,避免多个请求同时重试
    delay = delay * (0.5 + Math.random() * 0.5);
    
    // 根据错误类型调整延迟
    if (error.code === 'API_RATE_LIMIT_EXCEEDED') {
      // 限流错误使用更长的延迟
      delay = Math.max(delay, error.retryAfter || 5000);
    }
    
    // 设置最大延迟上限
    return Math.min(delay, 60000);
  }
  
  // 执行带重试的操作
  async executeWithRetry<T>(
    operation: () => Promise<T>,
    maxRetries: number = 3
  ): Promise<T> {
    let attempt = 0;
    let lastError: ApiError | null = null;
    
    while (attempt <= maxRetries) {
      try {
        return await operation();
      } catch (error) {
        lastError = this.normalizeError(error);
        
        // 检查是否应该重试
        if (!this.shouldRetry(lastError) || attempt >= maxRetries) {
          throw lastError;
        }
        
        // 计算延迟时间
        const delay = this.calculateDelay(attempt, lastError);
        
        // 记录重试信息
        console.log(`Retrying operation after ${delay}ms (attempt ${attempt + 1}/${maxRetries})`);
        
        // 等待后重试
        await this.sleep(delay);
        
        attempt++;
      }
    }
    
    throw lastError;
  }
  
  // 辅助方法
  private normalizeError(error: any): ApiError {
    // 将各种错误格式标准化为ApiError
    // ...
  }
  
  private sleep(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

3. 断路器模式

实现断路器模式,防止级联故障:

class CircuitBreaker {
  private state: 'CLOSED' | 'OPEN' | 'HALF_OPEN' = 'CLOSED';
  private failureCount: number = 0;
  private lastFailureTime: number = 0;
  private readonly failureThreshold: number;
  private readonly resetTimeout: number;
  
  constructor(failureThreshold: number = 5, resetTimeout: number = 30000) {
    this.failureThreshold = failureThreshold;
    this.resetTimeout = resetTimeout;
  }
  
  async execute<T>(operation: () => Promise<T>): Promise<T> {
    // 检查断路器状态
    if (this.state === 'OPEN') {
      // 检查是否应该进入半开状态
      if (Date.now() - this.lastFailureTime >= this.resetTimeout) {
        this.state = 'HALF_OPEN';
      } else {
        throw new Error('Circuit breaker is open');
      }
    }
    
    try {
      const result = await operation();
      
      // 操作成功,重置断路器
      this.reset();
      
      return result;
    } catch (error) {
      // 记录失败
      this.recordFailure();
      
      // 检查是否应该打开断路器
      if (this.state === 'HALF_OPEN' || this.failureCount >= this.failureThreshold) {
        this.state = 'OPEN';
        this.lastFailureTime = Date.now();
      }
      
      throw error;
    }
  }
  
  private reset(): void {
    this.failureCount = 0;
    this.state = 'CLOSED';
  }
  
  private recordFailure(): void {
    this.failureCount++;
  }
}

系统内部错误处理

1. 结构化错误日志

采用结构化日志格式,便于分析和监控:

interface ErrorLogEntry {
  timestamp: string;
  errorId: string;
  level: 'ERROR' | 'WARNING' | 'CRITICAL';
  service: string;
  component: string;
  message: string;
  code: string;
  stackTrace?: string;
  context?: Record<string, any>;
  userId?: string;
  requestId?: string;
}

class ErrorLogger {
  log(error: Error, context: Partial<ErrorLogEntry> = {}): void {
    const entry: ErrorLogEntry = {
      timestamp: new Date().toISOString(),
      errorId: this.generateErrorId(),
      level: context.level || 'ERROR',
      service: context.service || 'unknown',
      component: context.component || 'unknown',
      message: error.message,
      code: this.extractErrorCode(error),
      stackTrace: error.stack,
      ...context
    };
    
    // 输出到日志系统
    console.error(JSON.stringify(entry));
    
    // 对于严重错误,触发告警
    if (entry.level === 'CRITICAL') {
      this.triggerAlert(entry);
    }
  }
  
  // 辅助方法
  private generateErrorId(): string {
    return Math.random().toString(36).substring(2, 15);
  }
  
  private extractErrorCode(error: any): string {
    return error.code || 'UNKNOWN_ERROR';
  }
  
  private triggerAlert(entry: ErrorLogEntry): void {
    // 实现告警逻辑
    // ...
  }
}

2. 全局错误处理中间件

在API层实现全局错误处理中间件:

// Express错误处理中间件示例
function errorHandlerMiddleware(
  err: any,
  req: Request,
  res: Response,
  next: NextFunction
): void {
  // 标准化错误
  const normalizedError = normalizeError(err);
  
  // 记录错误
  errorLogger.log(normalizedError, {
    service: 'api-gateway',
    component: req.path,
    requestId: req.headers['x-request-id'] as string,
    userId: req.user?.id
  });
  
  // 构造错误响应
  const errorResponse = {
    error: {
      code: normalizedError.code,
      message: getClientErrorMessage(normalizedError),
      requestId: req.headers['x-request-id']
    }
  };
  
  // 设置HTTP状态码
  const statusCode = getHttpStatusCode(normalizedError);
  
  // 发送响应
  res.status(statusCode).json(errorResponse);
}

// 获取适合展示给客户端的错误信息
function getClientErrorMessage(error: NormalizedError): string {
  // 生产环境不暴露内部错误细节
  if (process.env.NODE_ENV === 'production' && error.isInternal) {
    return '系统处理请求时遇到问题,请稍后再试';
  }
  
  return error.clientMessage || error.message;
}

// 根据错误类型确定HTTP状态码
function getHttpStatusCode(error: NormalizedError): number {
  const statusCodeMap: Record<string, number> = {
    'VALIDATION_ERROR': 400,
    'AUTHENTICATION_ERROR': 401,
    'AUTHORIZATION_ERROR': 403,
    'RESOURCE_NOT_FOUND': 404,
    'RATE_LIMIT_EXCEEDED': 429,
    'INTERNAL_ERROR': 500,
    'SERVICE_UNAVAILABLE': 503
  };
  
  return statusCodeMap[error.code] || 500;
}

业务错误处理

1. 领域特定错误类型

定义领域特定的错误类型,提高代码可读性:

// 基础错误类
class DomainError extends Error {
  constructor(message: string) {
    super(message);
    this.name = this.constructor.name;
  }
}

// 订单领域错误
class OrderNotFoundError extends DomainError {
  constructor(orderId: string) {
    super(`Order with ID ${orderId} not found`);
  }
}

class InsufficientInventoryError extends DomainError {
  constructor(productId: string, requested: number, available: number) {
    super(`Insufficient inventory for product ${productId}: requested ${requested}, available ${available}`);
  }
}

// 支付领域错误
class PaymentFailedError extends DomainError {
  constructor(reason: string) {
    super(`Payment failed: ${reason}`);
  }
}

// 使用示例
function processOrder(orderId: string): void {
  const order = orderRepository.findById(orderId);
  
  if (!order) {
    throw new OrderNotFoundError(orderId);
  }
  
  // 处理订单...
}

2. 错误恢复策略

实现业务级错误恢复策略:

class OrderProcessor {
  async processOrder(orderId: string): Promise<void> {
    try {
      // 尝试处理订单
      await this.doProcessOrder(orderId);
    } catch (error) {
      // 根据错误类型执行恢复策略
      if (error instanceof PaymentFailedError) {
        await this.handlePaymentFailure(orderId, error);
      } else if (error instanceof InventoryAllocationError) {
        await this.handleInventoryFailure(orderId, error);
      } else {
        // 无法恢复的错误
        await this.markOrderAsFailed(orderId, error);
        throw error;
      }
    }
  }
  
  private async handlePaymentFailure(orderId: string, error: PaymentFailedError): Promise<void> {
    // 记录支付失败
    await this.logOrderEvent(orderId, 'PAYMENT_FAILED', error.message);
    
    // 检查重试次数
    const retryCount = await this.getPaymentRetryCount(orderId);
    
    if (retryCount < 3) {
      // 安排稍后重试支付
      await this.schedulePaymentRetry(orderId, retryCount + 1);
    } else {
      // 超过重试次数,通知客户
      await this.notifyCustomerAboutPaymentIssue(orderId);
      await this.markOrderAsPaymentFailed(orderId);
    }
  }
  
  private async handleInventoryFailure(orderId: string, error: InventoryAllocationError): Promise<void> {
    // 记录库存分配失败
    await this.logOrderEvent(orderId, 'INVENTORY_ALLOCATION_FAILED', error.message);
    
    // 尝试从其他仓库分配库存
    const allocated = await this.tryAlternativeInventoryAllocation(orderId);
    
    if (!allocated) {
      // 无法分配库存,通知客户
      await this.notifyCustomerAboutInventoryIssue(orderId);
      await this.markOrderAsBackordered(orderId);
    }
  }
  
  // 其他辅助方法...
}

监控与告警

错误处理系统需要与监控系统集成:

class ErrorMonitor {
  // 记录错误指标
  recordErrorMetrics(error: NormalizedError): void {
    const tags = {
      service: error.service,
      component: error.component,
      code: error.code,
      environment: process.env.NODE_ENV
    };
    
    // 增加错误计数
    metrics.increment('errors.count', 1, tags);
    
    // 记录错误响应时间
    if (error.duration) {
      metrics.histogram('errors.duration', error.duration, tags);
    }
  }
  
  // 检查错误模式
  detectErrorPatterns(): void {
    // 实现错误模式检测算法
    // 例如:短时间内同类错误突增
    // ...
  }
  
  // 生成错误报告
  generateErrorReport(timeRange: TimeRange): ErrorReport {
    // 聚合错误数据,生成报告
    // ...
  }
}

案例分析:订单系统错误处理优化

我们对某跨境电商客户的订单系统错误处理进行了优化,取得了显著成效:

  • 系统可用性从99.9%提升到99.99%
  • 订单处理失败率从2%降至0.2%
  • 错误恢复时间从平均30分钟降至5分钟

结论

完善的错误处理策略是构建稳定、可靠的跨境电商系统的关键。通过实施统一错误码映射、智能重试策略、断路器模式、结构化错误日志和业务级错误恢复策略,我们可以显著提升系统的稳定性和用户体验。

在未来的文章中,我们将深入探讨特定业务场景下的错误处理最佳实践,如订单处理、支付集成等。

目录

加载中...