什么是服务雪崩
在微服务调用链路中,因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程,就叫服务雪崩效应。
导致服务不可用的原因:

解决方案
1、超时机制

2、服务限流
3、舱壁隔离(资源隔离)
4、服务熔断降级


技术选型: Sentinel or Hystrix

对比

Sentinel快速开始

spring boot 微服务 应用接入Sentinel控制台
<!--引入依赖 sentinel -->
<!--引入依赖 sentinel --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
配置 application.yml 文件
server:
port: 8800
#开启Sentinel 对 Feign 的支持
feign:
sentinel:
enabled: true
spring:
application:
name: mall-user-sentinel-demo
cloud:
nacos:
discovery:
server-addr: 192.168.56.1:8848
username: nacos
password: nacos
openfeign: #openfeign的配置
client:
config:
mall-order: # 对应微服务
loggerLevel: FULL
# 连接超时时间
connectTimeout: 3000
# 请求处理超时时间
readTimeout: 5000
okhttp:
enabled: true
sentinel:
transport:
dashboard: 192.168.116.156:8858
# datasource:
# flow-rules:
# nacos:
# server-addr: 192.168.56.1:8848
# namespace: xulk
# username: nacos
# password: nacos
# dataId: ${spring.application.name}-flow-rules
# groupId: SENTINEL_GROUP
# data-type: json
# rule-type: flow
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ms_user?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: root
druid:
initial-size: 10
max-active: 100
min-idle: 10
max-wait: 60000
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
test-while-idle: true
test-on-borrow: false
test-on-return: false
stat-view-servlet:
enabled: true
url-pattern: /druid/*
filter:
stat:
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: false
wall:
config:
multi-statement-allow: true
#暴露actuator端点 http://localhost:8800/actuator/sentinel
management:
endpoints:
web:
exposure:
include: '*'
logging:
level:
com.tuling.mall.sentineldemo.feign: debug
com.alibaba.cloud.nacos.client.NacosPropertySourceBuilder: debug
controller 类
@RequestMapping(value = "/findOrderByUserId/{id}")
//@SentinelResource(value = "findOrderByUserId",blockHandler = "handleException")
public R findOrderByUserId(@PathVariable("id") Integer id) {
return R.ok( "11111111111");
}
远程调用 feign 接口
import com.tuling.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient(value = "mall-order",path = "/order",fallbackFactory = FallbackOrderFeignServiceFactory.class)
public interface OrderFeignService {
@RequestMapping("/findOrderByUserId/{userId}")
public R findOrderByUserId(@PathVariable("userId") Integer userId);
}
进入降级类
import com.tuling.common.utils.R;
import com.tuling.mall.sentineldemo.feign.OrderFeignService;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
@Component
public class FallbackOrderFeignServiceFactory implements FallbackFactory<OrderFeignService> {
@Override
public OrderFeignService create(Throwable throwable) {
return new OrderFeignService() {
@Override
public R findOrderByUserId(Integer userId) {
return R.error(-1,"=======服务降级了5555555========");
}
};
}
}
自定义异常 MyBlockExceptionHandler
mport com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tuling.common.utils.R;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import java.io.PrintWriter;
@Slf4j
@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
log.info("BlockExceptionHandler BlockException================"+e.getRule());
R r = null;
if (e instanceof FlowException) {
r = R.error(100,"接口限流了111");
} else if (e instanceof DegradeException) {
r = R.error(101,"服务降级了2222");
} else if (e instanceof ParamFlowException) {
r = R.error(102,"热点参数限流了3333");
} else if (e instanceof SystemBlockException) {
r = R.error(103,"触发系统保护规则了444");
} else if (e instanceof AuthorityException) {
r = R.error(104,"授权规则不通过5555");
}
//返回json数据
response.setStatus(500);
response.setCharacterEncoding("utf-8");
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
new ObjectMapper().writeValue(response.getWriter(), r);
}
}
配置流控规则 默认没持久化,重启服务 后会丢失


测试 http://localhost:8800/user/findOrderByUserId/1


降级/熔断处理配置


sentinel 持久化
<!--sentinel 从nacos拉取规则 --> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency>
配置文件 添加nacos的地址和配置文件


访问 http://localhost:8800/user/findOrderByUserId/1

自动持久化到 nacos
