微服务怎么限流?算法+框架+实战!

时间:2024-10-28 08:38:48
  • 降级:当服务出问题或者影响到核心流程的性能则需要暂时屏蔽掉

  • 限流:解决服务雪崩,级联服务发生阻塞时,及时熔断,防止请求堆积消耗占用系统的线程、IO等资源,造成其他级联服务所在服务器的崩溃

这里我们主要说一下限流,限流的目的应当是通过对并发访问/请求进行限速或者一个时间窗口内的的请求进行限速来保护系统,一旦达到限制速率就可以拒绝服务、等待、降级。 首先,我们需要去了解最基本的两种限流算法。

限流算法

====

  • 漏桶算法

  • 令牌桶算法

  • 计算器算法

限流框架

====

下面说一下现有流行的限流工具

guava


Google的Guava工具包中就提供了一个限流工具类——RateLimiter。

RateLimiter是基于“令牌通算法”来实现限流的。

hystrix


hystrix主要是通过资源池以及信号量来限流,暂时能支持简单的限流

sentinel


限流比较主流的三种算法:漏桶,令牌桶,滑动窗口。而Sentinel采用的是最后一种,滑动窗口来实现限流的。当然sentinel不仅仅局限于限流,它是一个面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。

限流实战

====

有很多应用都是可以直接在调用端、代理、网关等中间层进行限流,下面简单介绍下集中中间件限流方式

nginx限流


nginx限流方式有三种

  • limit_conn_zone

  • limit_req_zone

  • ngx_http_upstream_module

但是nginx限流不够灵活,不好动态配置。

zuul限流


除了zuul引入限流相关依赖

spring-cloud-zuul-ratelimit

2.0.

相关配置如下:

zuul:

ratelimit:

key-prefix: your-prefix #对应用来标识请求的key的前缀

enabled: true

repository: REDIS #对应存储类型(用来存储统计信息)默认是IN_MEMORY

behind-proxy: true #代理之后

default-policy: #可选 - 针对所有的路由配置的策略,除非特别配置了policies

limit: 10 #可选 - 每个刷新时间窗口对应的请求数量限制

quota: 1000 #可选- 每个刷新时间窗口对应的请求时间限制(秒)

refresh-interval: 60 # 刷新时间窗口的时间,默认值 (秒)

type: #可选 限流方式

  • user

  • origin

  • url

policies:

myServiceId: #特定的路由

limit: 10 #可选- 每个刷新时间窗口对应的请求数量限制

quota: 1000 #可选- 每个刷新时间窗口对应的请求时间限制(秒)

refresh-interval: 60 # 刷新时间窗口的时间,默认值 (秒)

type: #可选 限流方式

  • user

  • origin

  • url

注意这里的仓库如果是针对全局限流,那么可以考虑存到redis中,这里的可以设置为redis,但是如果扩容后则需要动态调整,不过灵活,所以这里我建议还是选择本地内存(INM_MOMERY)或者不设置,这样伸缩容后可以自动扩展,不用变更配置,

如果需要动态更新,可以集成apollo配置进行动态更新,

public class ZuulPropertiesRefresher implements ApplicationContextAware {

private ApplicationContext applicationContext;

@Autowired

private RouteLocator routeLocator;

@ApolloConfigChangeListener(interestedKeyPrefixes = “zuul.”,value=“”)

public void onChange(ConfigChangeEvent changeEvent) {

refreshZuulProperties(changeEvent);

}

private void refreshZuulProperties(ConfigChangeEvent changeEvent) {

(“Refreshing zuul properties!”);

/**

  • rebind configuration beans, . ZuulProperties

  • @see #onApplicationEvent

*/

(new EnvironmentChangeEvent(()));

/**

  • refresh routes

  • @see #onApplicationEvent

*/

(new RoutesRefreshedEvent(routeLocator));

(“Zuul properties refreshed!”);

}

@Override

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

= applicationContext;

}

}

springcloud gateway限流


在Spring Cloud Gateway中,有Filter过滤器,因此可以在“pre”类型的Filter中自行实现上述三种过滤器。

但是限流作为网关最基本的功能,Spring Cloud Gateway官方就提供了RequestRateLimiterGatewayFilterFactory这个类,适用Redis和lua脚本实现了令牌桶的方式。

具体实现逻辑在RequestRateLimiterGatewayFilterFactory类中,lua脚本在如下图所示的文件夹中:

具体源码不打算在这里讲述,读者可以自行查看,代码量较少,先以案例的形式来讲解如何在Spring Cloud Gateway中使用内置的限流过滤器工厂来实现限流。

首先在工程的pom文件中引入gateway的起步依赖和redis的reactive依赖,代码如下:

spring-cloud-starter-gateway

spring-boot-starter-data-redis-reactive

复制代码在配置文件中做以下的配置:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后希望可以帮助到大家!

千千万万要记得:多刷题!!多刷题!!

之前算法是我的硬伤,后面硬啃了好长一段时间才补回来,算法才是程序员的灵魂!!!!

篇幅有限,以下只能截图分享部分的资源!!

(1)多线程(这里以多线程为代表,其实整理了一本JAVA核心架构笔记集)

image

(2)刷的算法题(还有左神的算法笔记)

image

(3)面经+真题解析+对应的相关笔记(很全面)

image

(4)视频学习(部分)

ps:当你觉得学不进或者累了的时候,视频是个不错的选择

在这里,最后只一句话:祝大家offer拿到手软!!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
)多线程(这里以多线程为代表,其实整理了一本JAVA核心架构笔记集)

[外链图片转存中…(img-tB2Qr8qm-1712921329222)]

(2)刷的算法题(还有左神的算法笔记)

[外链图片转存中…(img-omR5eGUr-1712921329222)]

(3)面经+真题解析+对应的相关笔记(很全面)

[外链图片转存中…(img-PqJUeaLu-1712921329223)]

(4)视频学习(部分)

ps:当你觉得学不进或者累了的时候,视频是个不错的选择

在这里,最后只一句话:祝大家offer拿到手软!!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!