如果应用程序需要在超过速率限制访问时收到通知,则可以通过监听 RateLimitExceededEvent 事件来实现。
RateLimitExceededEvent 是 spring-cloud-zuul-ratelimit 中的一个事件类,它通常在请求超过限流限制时被触发。该事件是 Spring 的 ApplicationEvent 的子类,用于在 Spring 应用程序中进行事件发布和监听。
RateLimitExceededEvent 源码:
public final class RateLimitExceededEvent extends ApplicationEvent { private static final long serialVersionUID = 5241485625003998587L; private final Policy policy; private final String remoteAddress; public RateLimitExceededEvent(RateLimitPreFilter source, Policy policy, String remoteAddress) { super(source); this.policy = Objects.requireNonNull(policy, "Policy should not be null."); this.remoteAddress = Objects.requireNonNull(remoteAddress, "RemoteAddress should not be null."); } /** * Return the {@link Policy} which raised the event. * * @return the {@link Policy} */ public Policy getPolicy() { return this.policy; } /** * Return the remote IP address. * * @return the remote IP address */ public String getRemoteAddress() { return this.remoteAddress; } }
通过使用事件机制,可以将限流逻辑和业务逻辑进行解耦。当请求超过限流限制时,不直接在限流代码中处理业务逻辑,而是发布一个 RateLimitExceededEvent 事件,让其他感兴趣的组件通过监听该事件来执行相应的业务逻辑,这样可以使代码结构更加清晰,易于维护和扩展。
允许不同的业务组件根据自己的需求对限流超限情况进行响应,而不是将所有的处理逻辑都硬编码在限流代码中。例如,不同的服务可能需要不同的处理方式,有的可能需要记录日志,有的可能需要向用户发送通知,通过事件机制可以灵活地实现这些需求。
通过监听该事件,可以对限流超限情况进行集中监控和管理。可以收集和分析限流超限的信息,以便优化限流策略,发现潜在的问题或攻击行为,例如,统计某个时间段内限流超限的次数,对超限情况进行告警等。
下面示例通过 Spring 的 @EventListener 注解来监听 RateLimitExceededEvent 事件。
@EventListener 是 Spring 框架提供的一个注解,用于在应用程序中注册事件监听器。它允许你在 Spring 管理的 Bean 中轻松地监听 Spring 的应用程序事件,并在事件发生时执行相应的处理逻辑。
实现代码:
package com.hxstrive.hystrix_demo.event; import com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.support.RateLimitExceededEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; /** * 监听限流事件 * @author hxstrive.com */ @Component public class RateLimitEventListener { @EventListener public void observe(RateLimitExceededEvent event) { // 自定义代码 System.out.println("限流了!!" + event.getPolicy() + " limit exceeded"); } }
重启 Zuul 服务,频繁访问 http://localhost:9000/api/product/product/get?id=1 地址,触发限流。此时,将收到限流事件通知,如下图:
点击下载/查看本教程相关资料或者源代码。