关于spring cloud的组件前面已经介绍两个了, 学习的过程也是循序渐进的, 如果前面写的关于Eureka和Feign两个组件还没有看的同学,可以点击以下链接进行学习;
spring cloud之Eureka--服务治理
spring cloud使用过Eureka怎么进行服务间相互访问--Feign
下面是我自己在github上的spring cloud的demo
spring_cloud_demo
下面进入正题;
1.Hystrix
HystrixHystrix对应的中文名字是“豪猪”,豪猪周身长满了刺,能保护自己不受天敌的伤害,代表了一种防御机制,这与Hystrix本身的功能不谋而合,因此Netflix团队将该框架命名为Hystrix,并使用了对应的卡通形象做作为logo
1.1什么是Hystrix
在一个分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,这个就是Hystrix需要做的事情。Hystrix提供了熔断、隔离、Fallback、cache、监控等功能,能够在一个、或多个依赖同时出现问题时保证系统依然可用。
1.2为什么使用Hystrix
在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC) 。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。
如下图所示:A作为服务提供者,B为A的服务消费者,C和D是B的服务消费者。A不可用引起了B的不可用,并将不可用像滚雪球一样放大到C和D时,雪崩效应就形成了。
1.3Hystrix是如何实现
(1)通过HystrixCommand或者HystrixObservableCommand来封装对外部依赖的访问请求,这个访问请求一般会运行在独立的线程中,资源隔离
(2)对于超出我们设定阈值的服务调用,直接进行超时,不允许其耗费过长时间阻塞住。这个超时时间默认是99.5%的访问时间,但是一般我们可以自己设置一下
(3)为每一个依赖服务维护一个独立的线程池,或者是semaphore,当线程池已满时,直接拒绝对这个服务的调用
(4)对依赖服务的调用的成功次数,失败次数,拒绝次数,超时次数,进行统计
(5)如果对一个依赖服务的调用失败次数超过了一定的阈值,自动进行熔断,在一定时间内对该服务的调用直接降级,一段时间后再自动尝试恢复
(6)当一个服务调用出现失败,被拒绝,超时,短路等异常情况时,自动调用fallback降级机制
(7)对属性和配置的修改提供近实时的支持
2.项目中使用Hystrix
2.1添加依赖
<!--添加熔断器依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
该依赖加在我的demo中的父项目中
2.2添加注解
在spring boot的启动类上添加注解@EnableHystrix
package cn.cooplan.order;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableHystrix //开启熔断器
@EnableFeignClients
@EnableEurekaClient //开启Eureka客户端服务
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
//Feigx依赖的请求对象
@Bean
RestTemplate restTemplate (){
return new RestTemplate();
}
}
2.3测试+解释
需要在你请求的方法上添加 @HystrixCommand("发生异常时访问的方法名") 在同一个类中编写异常时进行的方法处理, 具体实现如下:
package cn.cooplan.order.service.impl;
import cn.cooplan.order.feign.GoodsFeignClient;
import cn.cooplan.order.service.OrderService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import dao.OrderDao;
import dao.OrderGoodsDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import pojo.Goods;
import pojo.Order;
import pojo.OrderGoods;
import java.util.ArrayList;
import java.util.List;
/**
* @Author MaoLG
* @Date 2018/12/7 14:03
*/
@Service
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderDao orderDao;
@Autowired
private OrderGoodsDao orderGoodsDao;
@Autowired
private GoodsFeignClient goodsFeignClient;
/*在你请求的方法上添加@HystrixCommand注解, 参数指定发生错误时调取的方法
该方法要保持参数列表相同, 返回值相同, 抛出异常相同, 非静态方法;
总结的说就是除了方法名不一样,其他都一样;
*/
@HystrixCommand(fallbackMethod = "getOrderInGoodsHystrix")
@Override
public List<Goods> getOrderInGoods(Integer orderId) {
OrderGoods o = new OrderGoods();
o.setOrderId(orderId);
QueryWrapper queryWrapper = new QueryWrapper(o);
List<OrderGoods> ogs = orderGoodsDao.selectList(queryWrapper);
List<Goods> goodses = new ArrayList<>();
for (OrderGoods og: ogs) {
Goods goods = goodsFeignClient.getGoodsById(og.getGoodsId());
goodses.add(goods);
}
return goodses;
}
//请求的方法发生错误/请求超时调取该方法
public List<Goods> getOrderInGoodsHystrix(Integer orderId){
List<Goods> goodses = new ArrayList<>();
Goods goods = new Goods();
goods.setName("商品错误");
goodses.add(goods);
return goodses;
}
}
Hystrix成功后:
无异常情况
异常情况
进入的方法:
进入方法.jpg
异常效果
有错误.jpg
详细请见github上的spring cloud的demo
spring_cloud_demo
欢迎大家在下面留言讨论;
网友评论