服务雪崩:服务之间复杂调用,一个服务不可用,导致整个系统受影响不可用(原因:服务器的大量连 接被出现异常的请求占用着,导致其他正常的请求得不到连接,所以导致整个系统不可用)
服务降级 Fallback:服务器忙(挂了),请稍候再试,不让客户端等待并立刻返回一个友好提示
服务熔断 Breaker:类比保险丝达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并 返回友好提示,就好比保险丝.
服务熔断诱因:服务的降级->进而熔断->恢复调用链路
服务限流 Flowlimit:限制某个服务每秒的调用本服务的频率,例如秒杀高并发等操作,严禁一窝蜂的过来拥挤,
应用 Ribbon 和 Hystrix 组合:
第一步:引入 hystrix依赖:
<!-- 引入hystrix进行服务熔断 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
第二步: 开启断路保护功能:@EnableCircuitBreaker
@EnableCircuitBreaker
@MapperScan("com.guigu.cloud.dao")
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService;
@Value("${server.port}")
private String prot;
@RequestMapping("/find")
public Order findOrder(Integer id){
return orderService.findOrder(id);
}
@RequestMapping("/user")
public Map findOrderAndUser(Integer id){
System.out.println("端口号为:"+prot);
return orderService.finOrderAndUser(id);
}
}
第三步: 编写局部降级逻辑
@Service
//@DefaultProperties(defaultFallback = "defaultFallback")
public class OrderService {
@Autowired
private OrderDao orderDao;
@Autowired
private RestTemplate restTemplate;
public Order findOrder(Integer id){
return orderDao.findOrder(id);
}
//通过@HystrixCommand(fallbackMethod="xxx")来指定出错时调用的局部降级 xxx 方法
@HystrixCommand(fallbackMethod = "finOrderAndUserHystrix")
//@HystrixCommand
public Map finOrderAndUser(Integer id){
if(id == 1){
throw new RuntimeException("出异常了");
}
Order order = orderDao.findOrder(id);
Map map = new HashMap<>();
//CLOUD-EUREKA-PROVIDER8001调用服务在eureka注册中心的服务名称
User user = restTemplate.getForObject("http://CLOUD-EUREKA-PROVIDER8001/user/find?id="+id, User.class);
map.put("order",order);
map.put("user",user);
return map;
}
}
第四步: 在本类中编写 xxx 方法,方法参数和原来一样
public Map finOrderAndUserHystrix(Integer id){
Map map = new HashMap<>();
//CLOUD-EUREKA-PROVIDER8001调用服务在eureka注册中心的服务名称
map.put("user",new User(-100,"对不起,网络太拥挤了..."));
return map;
}
第五步:测试.
扩展:编写全局降级逻辑
刚才把 fallback 写在了某个业务方法上,如果这样的方法很多,那岂不是要写很多。所
以可以把 Fallback 配置加在类上,实现默认 fallback;
第一步;在原方法的基础上:
@Service
@DefaultProperties(defaultFallback = "defaultFallback")
public class UserService {}
用@DefaultProperties 中的 defaultFallback 指定当前类中的全局异常处理方法名。
第三步:在当前类(UserService)中提供与原方法一致的降级逻辑
public Map<String, Object> defaultFallback (){
Map<String, Object> result = new HashMap<>();
result.put("movie", 默" 认提示:对不起,网络太拥挤了!");//暂时为null
return result;
}
需要注意:
1.@DefaultProperties(defaultFallback = "defaultFallBack"): 在 类 上 指
明统一的失败降级方法;该类中所有方法返回类型要与处理失败的方法的返回类型一致。
2.对于全局降级方法必须是无参的方法