限流的几种方式
主要是窗口算法和桶算法,两者各有优势。
窗口算法实现简单,逻辑清晰,可以很直观的得到当前的 QPS 情况,但是会有时间窗口的临界突变问题,而且不像桶一样有队列可以缓冲。
桶算法虽然稍微复杂,不好统计 QPS 情况,但是桶算法也有优势所在。
漏桶模式消费速率恒定,可以很好的保护自身系统,可以对流量进行整形,但是面对突发流量不能快速响应。
令牌桶模式可以面对突发流量,但是启动时会有缓慢加速的过程,不过常见的开源工具中已经对此优化。
单机限流与分布式限流
上面演示的基于代码形式的窗口算法和桶算法限流都适用于单机限流,如果需要分布式限流可以结合注册中心、负载均衡计算每个服务的限流阈值,但这样会降低一定精度,如果对精度要求不是太高,可以使用。
而 Redis 的限流,由于 Redis 的单机性,本身就可以用于分布式限流。使用 Redis 可以实现各种可以用于限流算法,如果觉得麻烦也可以使用开源工具如 redisson,已经封装了基于 Redis 的限流。
其他限流工具
文中已经提到了 Guava 的限流工具包,不过它毕竟是单机的,开源社区中也有很多分布式限流工具,如阿里开源的 Sentinel 就是不错的工具,Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
StringJoiner
类提供了更强大的字符串拼接功能,不仅可以指定拼接时的分隔符,还可以指定拼接时的前缀和后缀,这里我们可以使用它的 add() 方法来拼接字符串。
Predicate
函数接口 它可以 接受一个泛型 参数,返回值为布尔类型,Predicate 常用于数据过滤。
RMI (Remote Method Invocation)
模型是一种分布式对象应用,使用 RMI 技术可以使一个 JVM 中的对象,调用另一个 JVM 中的对象方法并获取调用结果。这里的另一个 JVM 可以在同一台计算机也可以是远程计算机。因此,RMI 意味着需要一个 Server 端和一个 Client 端。