上海市住房和城乡建设厅网站查询,网站设计师和网页设计师的区别,洞头建设局网站,西安短视频制作公司前言
Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件#xff0c;主要以流量为切入点#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
本篇博客介绍sentinel的使用#x…前言
Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件主要以流量为切入点从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
本篇博客介绍sentinel的使用引入依赖和配置结合案例阐述sentinel对消费者进行流控以及对生产者进行熔断降级。
其他关于sentinel的文章如下
Sentinel学习1——CAP理论微服务中的雪崩问题和Hystix的解决方案 Sentinel的相关概念 下载运行 目录 前言引出一、sentinel的使用准备1.上下文和资源2.责任的划分3,引入依赖和配置 二、对消费者进行流量控制1.单机阈值2.预热设置3.排队等待4.关联模式补充自定义限流异常返回 5.链路模式 三、对生产者进行熔断降级1.异常数2.异常比例3.慢调用比例 总结 引出 1.sentinel的使用引入依赖和配置 2.对消费者进行流控 3.对生产者进行熔断降级
一、sentinel的使用准备
1.上下文和资源
上下文 Context 和 context-name Context 代表调用链路上下文。是一个根节点在整个调用链路的开始处Sentinel 会创建上下文Context 对象并且为它指定一个 name 相当于根资源。在 Sentinel 中不同的调用链路可能使用同一个上下文 Context 对象共一个根节点。在这里 和 Spring MVC 整合 我们的调用链路都是在 sentinel_spring_web_context 中 资源Resource和 resource-name 在 Sentinel 中对于每一份资源Sentinel 会为赋予一个 name或者你手动指定,和 Spring MVC整合时Sentinel 使用的是 URI 来作为 Controller 方法的资源名 在这里Controller 方法就是资源 2.责任的划分
对于消费者而言进行流量控制别人访问我我怕自己失败所以我要限制别人访问我的流量
对于生产者而言进行熔断降级消费者调用生产者怕生产者出问题所以进行熔断降级如果被调用方即生产者出问题时给出相应的应对 3,引入依赖和配置 dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactIdversion2.2.6.RELEASE/version/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-sentinel/artifactId/dependencyspring:cloud:# nacos的配置nacos:discovery:# 能够注册register-enabled: trueserver-addr: http://192.168.111.130:8848/# 命名空间namespace: my-tianju# 组名group: DEV# sentinel的配置sentinel:transport:dashboard: 192.168.111.130:7777port: 8719# 这样一启动能够立马被发现不用请求一次后才被监控eager: true# 链路相关的配置# 默认是true开启上下文整合所有链路在根节点下链路监控就是将请求分开统计web-context-unify: falseapplication:name: springCloud-consumer#feign:
# hystrix:
# enable: true# 打开阿里的 sentinel
feign:sentinel:enabled: true二、对消费者进行流量控制 QPS(Queries Per Second) 表示每秒的查询数。也就是一台服务器每秒能够响应的查询次数。 1.单机阈值
QPS(Queries Per Second) 表示每秒的查询数。也就是一台服务器每秒能够响应的查询次数。 请求次数过多被sentinel限流 2.预热设置 在系统刚启动时允许较少的请求随着系统逐步稳定提升访问允许的阈值 JMeter测试post请求需要加一下请求头参数 Ramp-up时间线程启动的间隔时间如果100个线程10s内启动完成则设置Ramp-up为100/1010s 波形图 全流程解析 1.开始的时候每秒允许3次 2.前10s内逐步提升 3.在10s后达到稳定值每秒允许10次 3.排队等待
排队等待也叫流量整形它让请求以均匀的速度通过单机阈值为每秒通过数量其余的在队列排队等待一段时间即我们设置的时间单位是毫秒没有超过这个时间都能被及时处理如果超过了这个等待时间针对请求的接口没有线程来处理则抛出异常 JMeter参数设置 波形图 限流策略流程 1.每秒允许10个 2.发过来50个通过10个剩余的40个进入队列等待 3.在没有请求的时候通过队列中等待的请求 4.关联模式
关联/important接口的重要程度要高于 /normal接口如果/important接口的访问压力很大那么可以『牺牲』掉 /normal 接口全力保证 /important 接口的正常运行 JMeter参数设置 线程数设置 add成功get被限流 高并发情况add接口没有出现失效 补充自定义限流异常返回
Sentinel 返回的默认信息是 Blocked by Sentinel (flow limiting)如果你对默认响应信息不满意你可以自定义限流返回信息。
Sentinel 提供了 BlockExceptionHandler 接口。不管什么原因触发了 Sentinel 阻断用户的正常请求Sentinel 都将『进入』到用户自定义的 BlockExceptionHandler 接口的实现类中执行 handle方法并传入当前的请求、响应对象以及异常对象并以 handle 方法的执行结果作为返回回传给用户。
package com.tianju.test;import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {Overridepublic void handle(HttpServletRequest request, HttpServletResponse response,BlockException ex) throws Exception {String msg null;if (ex instanceof FlowException) {msg 该请求限流了请稍后重试;} else if (ex instanceof DegradeException) {msg 被熔断了;} else {msg 其它原因;// ParamFlowException 热点参数限流;// SystemBlockException 系统规则负载/...不满足要求;// AuthorityException 授权规则不通过;}// http 状态码response.setStatus(500);response.setCharacterEncoding(utf-8);response.setHeader(Content-Type, application/json;charsetutf-8);response.setContentType(application/json;charsetutf-8);new ObjectMapper().writeValue(response.getWriter(), msg);}
} 需要说明的是不仅仅是因为限流和熔断这一个原因会导致 BlockExceptionhandler 的handle 方法的执行还有其它的原因也会调用这个handler方法因此需要对 handle 方法的BlockException 参数对象进行 instanceof 判断 5.链路模式
链路限流和关联限流的思路很像假设我们要去请求某个微服务该微服务有2个接口/query和/add而这两个接口又调用了同一个service层的方法(如doSomething方法)那么我们可以『站在 doSomething的方法』的角度上进行设置如果是 /query接口在调用service层的doSomething方法那么就进行限流而 /add接口的调用就不限流或设置为更宽松一些的流控
通过配置关闭 sentinel 的 URL 收敛功能 package com.tianju.consumer.service;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.stereotype.Service;Service
public class ConsumerService {SentinelResource(hello)public String hello(){return consumerService;}
}链路模式站在service层的方法的角度上 高并发add接口没有失效 快速点击get方法出现失效情况 三、对生产者进行熔断降级
熔断器3个状态 Closed关闭状态所有请求都正常访问。 Open打开状态所有请求都会被降级。 Hystrix会对请求情况计数当一定时间内失败请求百分比达到阈值则触发熔断断路器会完全打开。默认失败比例的阈值是50%请求次数最少不低于20次。默认是 五秒之内请求20次 如果有10次失败50%则请求不能正常访问。 Half Open半开状态open状态不是永久的打开后会进入休眠时间默认是5S。随后断路器会自动进入半开状态。 此时会释放部分请求通过若这些请求都是健康的则会完全关闭断路器否则继续保持打开再次进行休眠计时 1.异常数
如下配置一秒内发送2次请求如果有1次失败异常则直接熔断然后降级 设置参数 2.异常比例 设置fallback方法 package com.tianju.config;import com.tianju.common.dto.StorageDto;
import com.tianju.common.result.HttpResp;
import com.tianju.config.fallback.StorageFeignFallback;
import com.tianju.entity.Order;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;FeignClient(value storage-server,fallback StorageFeignFallback.class)
public interface StorageFeign {PostMapping(/storage/sub)HttpResp subStorage(RequestBody StorageDto storageDto);}openfeign设置fallback方法 package com.tianju.config;import com.tianju.common.dto.StorageDto;
import com.tianju.common.result.HttpResp;
import com.tianju.config.fallback.StorageFeignFallback;
import com.tianju.entity.Order;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;FeignClient(value storage-server,fallback StorageFeignFallback.class)
public interface StorageFeign {PostMapping(/storage/sub)HttpResp subStorage(RequestBody StorageDto storageDto);
}生产者出现异常情况 用postman进行测试 package com.tianju.config.fallback;import com.tianju.common.dto.StorageDto;
import com.tianju.common.result.HttpResp;
import com.tianju.config.StorageFeign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;/*** 调用库存的feign异常时的返回*/
Component
Slf4j
public class StorageFeignFallback implements StorageFeign {Overridepublic HttpResp subStorage(StorageDto storageDto) {System.out.println(#########################进入了减库存方法的异常中....###########################);log.debug(进入了减库存方法的异常中....);return HttpResp.failed(减库存的openFeign调用失效请稍后重试);}
} package com.tianju.config.fallback;import com.tianju.common.dto.StorageDto;
import com.tianju.common.result.HttpResp;
import com.tianju.config.StorageFeign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;/*** 调用库存的feign异常时的返回*/
Component
Slf4j
public class StorageFeignFallback implements StorageFeign {Overridepublic HttpResp subStorage(StorageDto storageDto) {System.out.println(#########################进入了减库存方法的异常中....###########################);log.debug(进入了减库存方法的异常中....);return HttpResp.failed(减库存的openFeign调用失效请稍后重试);}
}
3.慢调用比例
如下配置在一秒内发5次请求如果每次请求的响应时间超过500毫秒这种比例达到0.550%就进行熔断熔断时长就是10秒。如1秒内有5次请求其中有3次请求响应时间超过了500毫秒那么这个比例就是60%大于50%此时就熔断然后降级。 用Jmeter测试程序中当id1时每次响应都是800毫秒。所以每次的请求都大于500毫秒失败率100%这个时候去请求id4的资源也是无法请求的因为熔断了所以也是直接降级。10s后再次请求id4的就正常了。 总结
1.sentinel的使用引入依赖和配置 2.对消费者进行流控 3.对生产者进行熔断降级