引言
为什么需要Sentinel,以防业务做的太好,流量太多炸了。再者万一微服务走了个神,也不能让上帝的客户在那苦苦等待吧
为什么需要Sleuth,说白了就是便于咱取排错,为了对咱友好,还Zipkin可视化一下
Sentinel
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。
对于限流熔断降级这些概念我就不乱科普了,还是取人家主页看看吧link
1整合Sentinel
1.导入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2.下载控制台
去link下载对应的控制台版本,启动并访问
(base) xu@xu-H110M-S2:~/SOFT$ java -jar sentinel-dashboard-1.8.0.jar --server.port=8888
浏览器访问link
3.配置sentinel的控制台地址信息
#配置sentinel的控制台地址信息
spring.cloud.sentinel.transport.dashboard=localhost:8888
#spring.cloud.sentinel.transport.port=8719 #传输端口
management.endpoints.web.exposure.include=*
4.在控制台调整参数
默认所有的流控设置保存在内存中,重启失效
2允许Endpoints访问
Sentinel Endpoint 里暴露的信息非常有用。包括当前应用的所有规则信息、日志目录、当前实例的 IP,Sentinel Dashboard 地址,Block Page,应用与 Sentinel Dashboard 的心跳频率等等信息。
<!--添加sentinel审计模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.2.11.RELEASE</version>
</dependency>
management.endpoints.web.exposure.include=*
参考link整合远程调用熔断以及网关层的流控
熔断降级
服务器的资源是有限的,而请求是无限的
限流:限制并发的请求访问量,超过阈值则拒绝;
降级:服务分优先级,牺牲非核心服务(不可用或简单处理:fallback(退路)错误处理信息),保证核心服务稳定;从整体负荷考虑;
熔断(服务降级的特殊情况):依赖的下游服务故障触发熔断,避免引发本系统崩溃(应对微服务雪崩效应的一种链路保护机制);当检测到该节点微服务调用响应正常后,恢复调用链路。
1.Feign配置服务降级
在调用放配置
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
配置文件打开 Sentinel 对 Feign 的支持:
feign.sentinel.enabled=true
# 解决Read Timeout 异常
feign.client.config.default.read-timeout=5000
feign.client.config.default.connect-timeout=100
就以product调用seckill为例
@FeignClient(value = "gulimall-seckill",fallback = SeckillFeignServiceFallback.class)
public interface SeckillFeignService {
@GetMapping("/sku/seckill/{skuId}")
public R getSkuSeckillInfo(@PathVariable("skuId") Long skuId);
}
@Slf4j
@Component
public class SeckillFeignServiceFallback implements SeckillFeignService {
@Override
public R getSkuSeckillInfo(Long skuId) {
log.info("远程调用异常,已降级getSkuSeckillInfo");
return R.error(BazCodeEnum.TO_MANY_REQUEST.getCode(), BazCodeEnum.TO_MANY_REQUEST.getMsg());
}
}
4.网关层流控与自定义资源限流
1.网关层流控
流控还是得从源头把好关,论一夫当关的重要性
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
PS:为啥我给sentinel-gateway单独加了个版本呢,因为我在这吃了个亏,没给com.alibaba.cloud版本管理,也没给版本,然后也没检查依没依赖上,然后就。。。
下面给出SpringCloud Alibaba以及SpringCloud的版本依赖示例,以此警醒。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
你会发现下面控制台中,gateway处可以流控降级的资源都是路由
起初没有网关的界面不对,参考link,在启动类主函数中增加 System.setProperty(“csp.sentinel.app.type”, “1”); 重启sentinel控制台
2.自定义资源限流
com/atguigu/gulimall/seckill/service/impl/SeckillServiceImpl.java
public List<SeckillSkuRedisTo> blockHandler(BlockException e) {
log.error("getCurrentSeckillSkus被限流了");
return null;
}
/**
* 返回当前时间可以参与的面纱商品信息
* @return
*/
@SentinelResource(value = "getCurrentSeckillSkus",blockHandler = "blockHandler") //注解方式定义资源
@Override
public List<SeckillSkuRedisTo> getCurrentSeckillSkus() {
...
// 定义一段受保护的资源
try (Entry entry = SphU.entry("seckillSkus")){ //抛出异常的方式定义资源
....
}catch (BlockException e){
log.warn("资源被限流:" + e.getMessage());
}
}
Sleuth+Zipkin
Spring Cloud Sleuth为springCloud实现了一个分布式链路追踪解决方案,可追踪一个请求的跳转在链路的各个部分耗时(含传输、服务的业务处理)为后续优化提供参考,同时如果在整个链路中发生了错误,会泛红提醒,进入可查看错误原因。
<!--引入sleuth链路追踪-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
各微服务中开启debug日志(这个还是算了,还是用zipkin图形可视化)
#开启debug日志
logging.level.org.springframework.cloud.openfeign=debug
logging.level.org.springframework.cloud.sleuth=debug
安装zipkin服务
docker run -d -p 9411:9411 openzipkin/zipkin
<!--该zipkin依赖集成了sleuth依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
# zip服务器地址
#spring.zipkin.base-url=
#关闭服务发现,否则会把zipkin的url当作服务器名称
spring.zipkin.discovery-client-enabled=false
#设置传输方式
spring.zipkin.sender.type=web
#设置抽样采集率,默认为0.1即10%
spring.sleuth.sampler.probability=1
配置号之后显著区别是,多了三逗号,,,
咱去浏览器zipkin可视化看看,看到有条泛红的链路,进去看看,访问link
原来是seckill服务的上传三天秒杀商品在获取coupon中的last3daysession时出错了,往右看看各部分的时间点
CS -》SS -》… -》 SF -》CF 相邻的相对时间一减就能获取相对耗时(无论是网络传输还是计算)
再往下看看到底是哪错了,原来是读取超时(刚刚服务忘记启动了)
备用参考link