大家之前有没有听过或遇到过以下类似场景:

针对以上场景,相信很多小伙伴很快就能想到对系统设置限流和熔断机制,以保证系统的稳定性。是的,今天要和大家介绍的大咖就是用来保障系统稳定性的sentinel。Sentinel它是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、熔断降级、系统过载保护、热点防护等多个维度来保护系统稳定性。github地址:https://github.com/alibaba/Sentinel。

sentinel最新版(奇技淫巧-系统稳定性保障利剑Sentinel)(1)

Sentinel技术专题将分为四篇文章来分享


Sentinel服务端和客户端通讯原理

Sentinel源码中有几个核心模块:sentinel-dashboard、sentinel-core、sentinel-transport。其中sentinel-dashboard是Sentinel控制台,用以配置规则等;sentinel-core是处理限流等操作的核心代码块,用以客户端依赖;sentinel-transport是用于dashboard中规则和core通信的桥梁,通讯协议包含http、netty或springmvc等方式。

在介绍Sentinel服务端(dashboard)和客户端(微服务)通讯原理之前,请大家思考以下几个问题

sentinel最新版(奇技淫巧-系统稳定性保障利剑Sentinel)(2)

接下来,通过上面图来详细回答以上三个问题来了解服务端和客户端的通讯原理

  1. 在客户端启动之前,需要配置csp.sentinel.dashboard.Server=ip:port指定服务端地址,客户端通过指定的地址定时发送心跳,向服务端注册客户端基本信息,如app名称、app类型、版本信息、IP和端口。另外,客户端本地会启动一个发送的IP和端口的Server监听;后续服务端有推送新消息或实时拉取指标数据时,均可通过上传的IP和端口进行消息推送。客户端类HeartbeatSenderInitFunc,服务端类MachineRegistryController。(Sentinel采用心跳机制注册的好处:告知服务端基本信息和通讯IP以及端口,后续服务端可以使用这个地址进行消息推送;二是用于保活,既可以节省系统资源,又可保证服务端和客户端通讯时能够正常通讯);

  2. 在步骤1中,客户端通过心跳机制向服务端注册后,服务端可以拿到客户端发送的IP和端口信息,服务端会有一个定时任务实时拉取指标数据,可参考服务端类MetricFetcher;另外,当有新的规则配置时,服务端通过API推送方式至客户端,以提供使用

  3. 步骤2中的说到类MetricFetcher会定时拉取实时指标数据,如passQps、blockQps、successQps、exceptionQps、rt,但是在拉取之前,会进行客户端健康状态检查工作,判断客户端是否已dead,已dead,则自动移除客户端机器信息。计算公式:当前时间-最近一次心跳时间,是否超过阈值,若超过则移除此机器。

//如果机器挂了if(machine.isDead()) {latch.countDown(); //移除机器 appManagement.getDetailApp(app).removeMachine(machine.getIp(),machine.getPort());continue;}

那么服务端宕机了,客户端是否能自动切换到其它服务端呢?通过查看代码发现sentinel这块容错机制并未实现,如下代码。

privateEndpointgetAvailableAddress(){ if(addressList==null||addressList.isEmpty()){ returnnull; } if(currentAddressIdx<0){ currentAddressIdx=0; } intindex=currentAddressIdx%addressList.size(); returnaddressList.get(index); }


Sentinel控制台介绍

Sentinel控制台配置有两个核心概念:资源 Rule。如对什么资源配置什么规则,规则包括统计类型、阈值,超过阈值后的效果等等。

资源:只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源;Rule:围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。

sentinel最新版(奇技淫巧-系统稳定性保障利剑Sentinel)(3)


Sentinel控制台具备功能点:实时指标监控、流控规则配置、授权配置、熔断配置等等。那么这些数据展示和规则配置是来源哪里以及如何让客户端生效新规则?这里拿流控规则设置原理解读。

@PostMapping("/rule") @AuthAction(PrivilegeType.WRITE_RULE) publicResult<FlowRuleEntity>apiAddFlowRule(@RequestBodyFlowRuleEntityentity){ //参数校验 Result<FlowRuleEntity>checkResult=checkEntityInternal(entity); if(checkResult!=null){ returncheckResult; } //初始化流控实体 entity.setId(null); Datedate=newDate(); entity.setGmtCreate(date); entity.setGmtModified(date); entity.setLimitApp(entity.getLimitApp().trim()); entity.setResource(entity.getResource().trim()); try{ //保存数据 entity=repository.save(entity); //按照机器和规则维度一次性将全量流控规则推送到客户端 publishRules(entity.getApp(),entity.getIp(),entity.getPort()).get(5000,TimeUnit.MILLISECONDS); returnResult.ofSuccess(entity); }catch(Throwablet){ Throwablee=tinstanceofExecutionException ?t.getCause():t; logger.error("Failedtoaddnewflowrule,app={},ip={}",entity.getApp(),entity.getIp(),e); returnResult.ofFail(-1,e.getMessage()); } }

sentinel最新版(奇技淫巧-系统稳定性保障利剑Sentinel)(4)


下一篇:Sentinel限流和熔断等核心链路源码分析

sentinel最新版(奇技淫巧-系统稳定性保障利剑Sentinel)(5)









,