Sentinel集群限流探索(一)

wg204wg
发布于 2022-6-13 17:38
浏览
0收藏

 

最近看了下关于分布式限流的部分,看到Sentinel的分布式限流,也就是集群限流的部分,想搭个环境看看,结果发现网上关于这方面的内容基本可以说没有,你甚至很难跑起来他的demo,就算能跑起来,估计也得自己研究半天,麻烦的要死。

我猜测很重要的原因可能就是Sentinel关于这块做的并不完善,而且从官方的Issue中能看出来,其实官方对于这块后续并没有计划去做的更好。

那么废话不多说,在此之前,肯定要先说下关于Sentinel集群限流方面的原理,没有原理一切都是空中楼阁。

集群限流原理

原理这方面比较好解释,就是在原本的限流规则中加了一个clusterMode参数,如果是true的话,那么会走集群限流的模式,反之就是单机限流。

如果是集群限流,判断身份是限流客户端还是限流服务端,客户端则和服务端建立通信,所有的限流都通过和服务端的交互来达到效果。

对于Sentinel集群限流,包含两种模式,内嵌式和独立式。

内嵌式
什么是内嵌式呢,简单来说,要限流那么必然要有个服务端去处理多个客户端的限流请求,对于内嵌式来说呢,就是整个微服务集群内部选择一台机器节点作为限流服务端(Sentinel把这个叫做token-server),其他的微服务机器节点作为限流的客户端(token-client),这样的做法有缺点也有优点。

Sentinel集群限流探索(一)-鸿蒙开发者社区

 限流-嵌入式

首先说优点:这种方式部署不需要独立部署限流服务端,节省独立部署服务端产生的额外服务器开支,降低部署和维护复杂度。

再说缺点,缺点的话也可以说是整个Sentinel在集群限流这方面做得不够好的问题。

先说第一个缺点:无自动故障转移机制。

无论是内嵌式还是独立式的部署方案,都无法做到自动的故障转移。

所有的server和client都需要事先知道IP的请求下做出配置,如果server挂了,需要手动的修改配置,否则集群限流会退化成单机限流。

比如你的交易服务有3台机器A\B\C,其中A被手动设置为server,B\C则是作为client,当A服务器宕机之后,需要手动修改B\C中一台作为server,否则整个集群的机器都将退化回单机限流的模式。

但是,如果client挂了,则是不会影响到整个集群限流的,比如B挂了,那么A和C将会继续组成集群限流。

如果B再次重启成功,那么又会重新加入到整个集群限流当中来,因为会有一个自动重连的机制,默认的时间是N*2秒,逐渐递增的一个时间。

这是想用Sentinel做集群限流并且使用内嵌式需要考虑的问题,要自己去实现自动故障转移的机制,当然,server节点选举也要自己实现了。

对于这个问题,官方提供了可以修改server/client的API接口,另外一个就是可以基于动态的数据源配置方式,这个我们后面再谈。

第二个缺点:适用于单微服务集群内部限流。

这个其实也是显而易见的道理,都内部选举一台作为server去限流了,如果还跨多个微服务的话,显然是不太合理的行为,现实中这种情况肯定也是非常少见的了,当然你非要想跨多个微服务集群也不是不可以,只要你开心就好。

第三个缺点:server节点的机器性能会受到一定程度的影响。

这个肯定也比较好理解的,作为server去限流,那么其他的客户端肯定要和server去通信才能做到集群限流啊,对不对,所以一定程度上肯定会影响到server节点本身服务的性能,但是我觉得问题不大,就当server节点多了一个流量比较大的接口好了。

具体上会有多大的影响,我没有实际对这块做出实际的测试,如果真的流量非常大,需要实际测试一下这方面的问题。

我认为影响还是可控的,本身server和client基于netty通信,通信的内容其实也非常的小。

独立式
说完内嵌式的这些点,然后再说独立式,也非常好理解,就是单独部署一台机器作为限流服务端server,就不在本身微服务集群内部选一台作为server了。

Sentinel集群限流探索(一)-鸿蒙开发者社区

 限流-独立式

很明显,优点就是解决了上面的缺点。

  1. 不会和内嵌式一样,影响到server节点的本身性能
  2. 可以适用于跨多个微服务之间的集群限流
    优点可以说就是解决了内嵌式的两个缺点,那么缺点也来了,这同样也是Sentinel本身并没有帮助我们去解决的问题。

缺点一:需要独立部署,会产生额外的资源(钱)和运维复杂度

缺点二:server默认是单机,需要自己实现高可用方案

缺点二很致命啊,官方的server实现默认就是单机的,单点问题大家懂的都懂,自己实现高可用,我真的是有点服了。

这么说Sentinel这个集群限流就是简单的实现了一下,真正复杂的部分他都没管,你可以这么理解。

run起来

那基本原理大概了解之后,还是要真正跑起来看看效果的,毕竟开头我就说了,网上这方面真的是感觉啥也搜不到,下面以嵌入式集群的方式举例。

无论集群限流还是单机限流的方式,官方都支持写死配置和动态数据源的配置方式,写的话下面的代码中也都有,被我注释掉了,至于动态数据源的配置,会基于Apollo来实现。

理解一下动态数据源的配置方式,基于这个我们可以实现限流规则的动态刷新,还有重点的一点可以做到基于修改配置方式的半自动故障转移。

动态数据源支持推和拉两种方式,比如文件系统和Eureka就是拉取的方式,定时读取文件内容的变更,Eureka则是建立HTTP连接,定时获取元数据的变更。

推送的方式主要是基于事件监听机制,比如Apollo和Nacos,Redis官方则是基于Pub/Sub来实现,默认的实现方式是基于Lettuce,如果想用其他的客户端要自己实现。

Sentinel集群限流探索(一)-鸿蒙开发者社区

 限流-集群工作模式

首先,该引入的包还是引入。

<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-annotation-aspectj</artifactId>
  <version>1.8.4</version>
</dependency>

<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-transport-simple-http</artifactId>
  <version>1.8.4</version>
</dependency>

<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-cluster-client-default</artifactId>
  <version>1.8.4</version>
</dependency>
<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-cluster-server-default</artifactId>
  <version>1.8.4</version>
</dependency>
<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-datasource-apollo</artifactId>
  <version>1.8.4</version>
</dependency>

 

实现SPI,在resources目录的META-INF/services下新增名为com.alibaba.csp.sentinel.init.InitFunc的文件,内容写上我们自己实现的类名,比如我的com.irving.demo.init.DemoClusterInitFunc。

Sentinel集群限流探索(一)-鸿蒙开发者社区

文章转自公众号:艾小仙

分类
标签
已于2022-6-13 17:38:59修改
收藏
回复
举报
回复
    相关推荐