作者:微信小助手
发布时间:2019-11-25T08:14:29
在基于Spring Cloud构建的微服务体系中,服务之间的调用链路会随着系统的演进变得越来越长,这无疑会增加了整个系统的不可靠因素。在并发流量比较高的情况下,由于网络调用之间存在一定的超时时间,链路中的某个服务出现宕机都会大大增加整个调用链路的响应时间,而瞬间的流量洪峰则会导致这条链路上所有服务的可用线程资源被打满,从而造成整体服务的不可用,这也就是我们常说的“雪崩效应”。
而在微服务系统设计的过程中,为了应对这样的糟糕情况,最常用的手段就是进行”流量控制“以及对网络服务的调用实现“熔断降级”。所谓流量控制就是根据服务的承载能力指定一个策略,对一定时间窗口内的网络调用次数进行限制,例如1s内某个服务最多只能处理10个请求,那么1s内的第11+的请求会被被限制丢弃;而熔断降级的概念则是说在A服务→B服务调用过程中,按照一定的规则A服务发现调用B服务经常失败或响应时间过长,如果触发了A服务对B服务调用的熔断降级规则,那么在一定时间窗口内,A服务在处理请求的过程中对于B服务的调用将会直接在A服务的逻辑中被熔断降级,请求则不会通过网络打到B服务,从而避免A服务由于过长的超时时间导致自身资源被耗尽的情况发生。
二、Sentinel+Apollo架构说明
因此从这种意义上说,Sentinel的使用应该是并不复杂的,它应该与Hystrix一样,在Spring Cloud微服务应用中引入相关依赖即可。事实上从某种程度来说的确如此,只不过Sentinel提供了比Hystrix要强一点的规则配置能力,提供了可以进行限流、熔断降级以及热点、授权等其他规则统一配置和管理的控制台服务->sentinel-dashboard。
虽然如此,但这也并没有改变Sentinel作为客户端限流组件性质,通过控制台配置的规则依然要推送到微服务应用Sentinel客户端本身才能生效,而微服务之间的调用链路等指标信息也需要推送给Sentinel控制台,才能比较方便地使用Sentinel提供的一些能力,因此在开源的架构版本中需要微服务应用本身开启独立端口与sentinel-dashboard进行通信,从而获取配置规则以及上送微服务应用各类指标信息。而这一点,显然也会占用微服务额外的资源,并且由于sentinel-dashboard在此条件下并不具备集群部署能力,因此也会形成一个单节点问题,但是有一套控制台总好过于没有,如果希望比较方便快速地应用Sentinel这也是一种代价。此时的Sentinel架构如下图所示:
Sentinel+Apollo架构
在开源版本架构中,通过sentinel-dashboard控制台配置的限流、熔断降级等规则都是存储于Sentinel控制台服务内存之中的,如果控制台服务重启或者微服务应用重启都会导致规则丢失。而这在生产环境下是不可接受的,因此Sentinel在官方的生产架构指导中也是推荐使用第三方数据源(如本文的Apollo)作为永久存储中心,这样各个微服务的限流、降级规则都可以永久存储。虽然Sentinel官方推荐使用第三方数据源作为规则存储中心,目前也提供了针对Apollo、Nacos、Zookeeper、Redis、Consul、Spring Cloud Config等多种存储源的依赖集成Jar,但是却并没有针对这些数据源提供一个可以实际使用的sentinel-dashboard第三方数据源存储版本,所以当你选择了一种数据源那么就需要你自己对sentinel-dashboard项目进行改造,这里作者针对Sentinel 1.7.0(成文时最新版本)使用Apollo数据源改造了一个版本,所有规则基本可用,但可能会有细节的Bug需要自行Fix。具体代码改造点见Github链接:
https://github.com/manongwudi/Sentinel/commit/f3a27adb6fdbf13d9eaa4510e317c1b55c206e89
关于以上sentinel-dashboard接入Apollo数据源的代码改造情况,大家可以详细参考上述链接,这里作者只说以下几个重点:
目前官方推荐的方式是通过Apollo的开放平台授权的方式进行写入,因此我们需要在sentinel-dashboard项目pom.xml文件引入以下依赖:
<!-- Apollo配置依赖 -->
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-openapi</artifactId>
<version>1.5.0</version>
</dependency>
之后我们需要在Apollo Portal创建一个针对sentinel-dashboard的应用,具体创建方法如下图所示:
以上我们创建了一个针对Sentinel控制台的应用(这里的应用是Apollo配置中心的基本概念,具体微服务接入Apollo的方法,大家可以自行搜索)。
创建应用后,未来Sentinel控制台在启动是需要指定Apollo应用ID才能接入Apollo,而接入Apollo之后Sentinel的规则需要写入该应用下的namespace空间,因此还需要创建针对该应用的namespace空间,具体创建方式如下图所示: