Netflix Zuul 自定义错误处理

默认情况下,spring-cloud-zuul-ratelimit 会提供一种通用的错误响应机制,但这种响应可能并不满足所有应用程序的需求。我们可以通过实现 RateLimiterErrorHandler 接口,自定义错误处理,根据具体的业务场景和用户体验需求,提供更加定制化的错误响应。

RateLimiterErrorHandler 接口

RateLimiterErrorHandler 是 spring-cloud-zuul-ratelimit 中的一个重要接口,它主要用于处理限流过程中出现的各种错误。

接口源码:

package com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.config.repository;

/**
 * Handles the backend storage errors.
 *
 * @author Liel Chayoun
 */
public interface RateLimiterErrorHandler {

    void handleSaveError(String key, Exception e);

    void handleFetchError(String key, Exception e);

    void handleError(String msg, Exception e);

}

该接口包含三个方法:

  • handleSaveError(String key, Exception e)  该方法主要用于处理在保存限流信息时出现的错误。例如,当系统试图将用户的请求频率、剩余请求次数等信息存储到存储介质中时,如果出现异常,此方法会被调用,以便进行相应的错误处理,比如记录日志、抛出特定的异常、尝试重试等。

  • handleFetchError(String key, Exception e)  该方法主要负责处理在尝试从存储中获取限流信息时发生的错误。例如,当系统需要根据 key 从存储系统中读取用户的限流状态时,如果读取操作失败,该方法会被调用,以进行相应的错误处理,例如返回默认的限流状态、通知管理员、向用户发送错误信息等。

  • handleError(String msg, Exception e)  该方法是一个通用的错误处理方法,用于处理在限流操作过程中出现的其他错误。它提供了一个更宽泛的错误处理范围,适用于那些无法明确归类到 handleSaveError 或 handleFetchError 的错误情况。

默认实现 DefaultRateLimiterErrorHandler

DefaultRateLimiterErrorHandler 是 spring-cloud-zuul-ratelimit 提供的一个默认的限流错误处理类,它实现了 RateLimiterErrorHandler 接口。该类主要负责处理在限流过程中出现的各种错误情况,确保在出现异常时系统能够采取适当的措施。

在使用 spring-cloud-zuul-ratelimit 进行限流时,如果没有自定义的 RateLimiterErrorHandler,系统会默认使用 DefaultRateLimiterErrorHandler 来处理限流过程中出现的错误。

它可以作为基础的错误处理机制,为开发人员提供了基本的错误信息输出和异常处理,保证系统在遇到问题时能够有基本的响应。

一般情况下,只要将 spring-cloud-zuul-ratelimit 集成到项目中,DefaultRateLimiterErrorHandler 会自动被 Spring 容器管理,无需额外的配置。

DefaultRateLimiterErrorHandler 源码:

package com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.config.repository;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Liel Chayoun
 */
public class DefaultRateLimiterErrorHandler implements RateLimiterErrorHandler {

    private static Logger log = LoggerFactory.getLogger(DefaultRateLimiterErrorHandler.class);

    @Override
    public void handleSaveError(String key, Exception e) {
        log.error("Failed saving rate for " + key + ", returning unsaved rate", e);
    }

    @Override
    public void handleFetchError(String key, Exception e) {
        log.error("Failed retrieving rate for " + key + ", will create new rate", e);
    }

    @Override
    public void handleError(String msg, Exception e) {
        log.error(msg, e);
    }
}

从上述源码可知,DefaultRateLimiterErrorHandler 仅仅使用日志框架记录了日志,没有做其他处理。

自定义错误处理

在实际的生产环境中,开发人员通常会根据具体的业务需求和系统架构,通过实现 RateLimiterErrorHandler 接口或者继承 DefaultRateLimiterErrorHandler 类来自定义错误处理,以提供更完善、更贴合业务需求的错误处理机制。这有助于提高系统的稳定性和用户体验,在限流操作出现异常时能够更加合理地处理错误,保证系统的正常运行。

例如:通过继承 DefaultRateLimiterErrorHandler 类自定义错误处理。

package com.hxstrive.hystrix_demo.custom;

import com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.config.repository.DefaultRateLimiterErrorHandler;
import org.springframework.stereotype.Component;

/**
 * 自定义限流异常处理
 * @author hxstrive.com
 */
@Component
public class RateLimiterErrorHandler extends DefaultRateLimiterErrorHandler {

    @Override
    public void handleSaveError(String key, Exception e) {
        System.out.println("handleSaveError: " + key + "自定义限流异常处理: " + e.getMessage());
    }

    @Override
    public void handleFetchError(String key, Exception e) {
        System.out.println("handleFetchError: " + key + "自定义限流异常处理: " + e.getMessage());
    }

    @Override
    public void handleError(String msg, Exception e) {
        System.out.println("handleError: " + msg + "自定义限流异常处理: " + e.getMessage());
    }

}

重启 Zuul 服务,并且将 Redis 停掉,再次访问 http://localhost:9000/api/product/product/get?id=1 地址,输出信息如下图:

3b87bd5c45e50494ab84b15f6732f8cf_1734945030346-39500ab0-0ec1-432e-aea7-6191cd02eb37.png

注意,自定义的错误处理器需要通过 @Component、@Service 注解或者通过配置类的形式纳入 Spring 容器。

 

点击下载/查看本教程相关资料或者源代码。
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号