大白话实战Sentinel

打印 上一主题 下一主题

主题 1013|帖子 1013|积分 3039

Sentinel是SpringCloudAlibaba提供的用来做服务保护的框架,而服务保护的常见本事就是限流和熔断降级。在大型分布式系统里面,由于微服务浩繁,所以服务之间的稳固性需要做特别关注,Sentinel的核心包就提供了从多个维度去保护服务稳固的策略,而且这些保护策略都可以毗连上Sentinel的控制台,在可视化界面进行设置,我们把这些保护策略可以称为规则,设置的这些保护规则也可以存储到Zookeeper、Nacos等等具有设置中心功能的中心件中,而且Sentinel还设置了多种微服务架构,好比SpringCloud、Dubbo等,如下图所示:

我们可以看一下Sentinel的工作原理,加上分布式系统中有许多微服务,每个微服务中都有许多资源需要我们进行保护,什么是资源呢,其实万物皆可为资源,它可以是一个HTTP哀求,也可以是一个远程调用,或者是一段业务逻辑代码,也可以是访问数据库的一些方法,每个应用都有非常多的资源,我们只需要引入Sentinel客户端,这些客户端就可以连上Sentinel的控制台,在Sentinel控制台里面可以对每一种资源的规则进行界说,好比限流规则,熔断降级规则,黑白名单等等,固然这些规则一般由运维职员进行界说,界说的这些规则可以存储到Nacos、Zookeeper等这些设置中心,固然存在内存也没题目,只不外重启就失效了,而且假如这些规则发生了变动,Sentinel控制台还可以实时把这些规则推送给每个微服务,这样我们每次访问资源的时间,Sentinel客户端就会来检测每种资源的规则,然后判断是不是违背这些规则,假如没有违背则放行,假如违背就拒绝服务,通过这种本事来保护系统的稳固性,架构原理图如下:

在这个图里面和我们编码相关的就两个,一个是资源,一个是规则。
而使用Sentinel想要界说一个资源也非常简单:

界说好了资源,就需要在Sentinel的控制台来界说保护这些资源的规则,Sentinel提供了上面的规则,第一种流量控制,就是我们常说的限流,好比哀求量一大,假如我们把全部哀求都接收过来在后台进行处置惩罚,有可能导致这个微服务所在的机器资源耗尽,所以可以对哀求进行限流,好比每秒只允许通过100个哀求,超出的哀求全部拒绝掉,这样的话,纵然上万并发,后台也只处置惩罚100个,不至于后台崩了。第二种规则叫熔断降级,这就是防服务雪崩的,而且在OpenFeign的时间也演示了一旦远程调用失败去走兜底数据。第三种规则叫系统保护,可以根据当前机器是CPU负载、内存使用率,看到CPU太忙了,可以限制哀求流量进入。第四种规则叫泉源访问控制,只允许哪些上游来访问下游资源。第五种规则叫界说热门参数,这个后面细说。
总之一句话,想要使用Sentinel,你要想清楚要保护哪些资源,这些资源怎么找到,是通过主动适配发现的还是通过编程界说的还是声明式的。有了这些资源后,再界说各种保护规则,当这两个界说好后,Sentinel就可以进行工作了。
它的工作原理是,用户去来访问一个资源,好比访问一个HTTP哀求,假设就是创建订单,而这些资源我们给它界说了一个规则,每次访问的时间Sentinel就会检查这些规则,假设我们界说一个流量控制规则,每秒只能通过一个哀求,对于这个规则的检查就会出现两种环境,是否违法了这些规则,假如没有违法这次哀求就放行,假如违背了这些规则,Sentinel就会抛出异常,对于这个异常我们就要进行针对性的处置惩罚,这就要看我们有没有编写兜底处置惩罚的方法,假如没有就抛出错误,假如编写了兜底处置惩罚,好比OpenFeign的fallback兜底回调,就会返回兜底数据。详细流程如下图:

通过这个原理图我们知道,在Sentinel的使用中我们关注三点,第一点怎么界说一个资源,第二点界说资源的保护规则,第三点一旦违背了规则,怎么处置惩罚异常。
整合-底子场景

先做第一步,启动一个Sentinel Dashboard控制台,方便我们在控制台界说控制资源的一些规则,在官网下载sentinel-dashboard-1.8.8.jar ,然后启动 sentinel-dashboard:

启动后访问:

默认账号和密码都是sentinel。

因为还没有任何微服务接入sentinel,所以在控制台里面没有显示任何数据,接入后就会有全部的微服务列表。
第二步,给微服务整个sentinel场景,并设置链接上sentinel控制台,那这个应用的全部资源,通过注解或代码埋点的这些资源,都可以在控制台界说它们的规则。
我们之前在学习OpenFeign的时间,由于已经整合了sentinel,只不外其时sentinel依赖只放到了order里面,由于每个微服务都需要被保护起来,所以我们直接在services里面同一引入sentinel依赖。引入好依赖,这样每个微服务都需要设置毗连上sentinel控制台,我们在order设置文件中设置毗连sentinel的地址:
由于sentinel默认用的是懒加载机制,整合之后,只有我们访问了哀求,控制台才能显示出应用的信息,所以为了方便起见,可以让它提前加载,在sentinel设置中把eager设置为true,就可以项目一启动,主动连上sentinel控制台:
  1. spring:
  2.   cloud:
  3.     openfeign:
  4.       client:
  5.         config:
  6.           default:
  7.             logger-level: full
  8.             connect-timeout: 1000
  9.             read-timeout: 2000
  10.           service-product:
  11.             logger-level: full
  12.             connect-timeout: 3000
  13.             read-timeout: 5000
  14.     sentinel:
  15.       transport:
  16.         dashboard: localhost:8080
  17.       eager: true
  18. #            response-interceptor:
  19. #              com.example.order.interceptor.XTokenRequestInterceptor
  20. #            retryer: feign.retryer.Default
  21. feign:
  22.   sentinel:
  23.     enabled: true
复制代码
每个服务都设置好即可。
然后我们启动订单和商品两个微服务。首先看它们能不能连上sentinel控制台,将本身的应用信息正确显示,启动后刷新控制台:

这样在这个控制台里面就可以设置许多的规则,但是这些规则都是对资源设置的,那什么是资源呢?我们一起来看看它的默认行为,它把系统全部web接口都以为的资源,包罗openfeign的远程调用也以为的一个资源,或者我们用注解和编程的方式都可以界说资源,那么接下来就以创建订单为例,由于创建订单是一个web哀求,所以谁来发送web哀求,会走创建订单服务,创建订单服务里面又会远程调用查询商品,假设以为创建订单这个方法是一个资源,我将来想保护它,对它进行一些流控等一些设置,那么可以用最简单的方式,使用一个注解叫@SentinelResource(value = “createOrder”)

重新启动订单服务,然后发送一个创建订单的哀求:

在sentinel控制台有个簇点链路就会看到这个调用过程:

首先我们发送了一个create哀求,它以为create是一个资源,create里面又调用了createOrder,它以为这个也是一个资源,这个资源是我们通过注解界说的,而create哀求是sentinel主动勘察的一个web接口,而在createOrder里面又调用了商品的接口,也是可以被控制的资源。只要有了这些资源,我们可以对任意资源进行控制各种规则,我们先来测试流控:

点击新增后就可以在流控规则中看到了:

我们先测试一下,假如刷慢一点,每秒访问一个,发现都正常:

假如我刷新快一点,就返回一个默认错误:

异常处置惩罚-web接口

从上面可以看到sentinel每秒只会放行1个哀求,放行的哀求才会实行目的方法的创建订单,而被壅闭的哀求,目的方法是不会被实行的,这样就不会占用系统资源,纵然高并发的哀求,只有少量的目的方法实行,那就不会导致服务雪崩的题目,但是现在还有一个题目,假如一旦哀求被限制后,返回的是默认sentinel错误提示页,而我们一般大型的系统都是前后分离的,后台微服务要给前端返回json数据,这就牵扯到sentinel的异常处置惩罚机制,在sentinel里面异常处置惩罚是一个比力复杂的流程,

假如我们想要改掉默认的web页面显示的异常信息,就要自界说一个BlockExceptionHandler,我们先来解决web接口的异常处置惩罚方式。我们本身写一个BlockExceptionHandler,只要把它放到容器中就可以生效:

我们先在model模块中自界说一个通用的返回对象R:
  1. package com.example.common;
  2. import lombok.Data;
  3. @Data
  4. public class R {
  5.    
  6.     private Integer code;
  7.     private String msg;
  8.     private Object data;
  9.     public static R ok() {
  10.    
  11.         R r = new R();
  12.         r.setCode(200);
  13.         return r;
  14.     }
  15.     public static R ok(String msg, Object data) {
  16.    
  17.         R r = new R();
  18.         r.setCode(200);
  19.         r.setMsg(msg);
  20.         r.setData(data);
  21.         return r;
  22.     }
  23.     public static R error() {
  24.    
  25.         R r = new R();
  26.         r.setCode(500);
  27.         return r;
  28.     }
  29.     public static R error(Integer code, String msg) {
  30.    
  31.         R r = new R();
  32.         r.setCode(
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

宝塔山

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表