1、为什么要有服务容错保护?
在微服务架构中,我们将系统拆分成很多服务单元,个单元应用间通过服务注册与订阅方式互相依赖。由于每个单元都在不同的进程中运行,依赖通过远程调用方式运行,这样就有可能因为网络原因或者是依赖服务自身问题出现调用故障或延迟,而这些问题会直接导致调用方的对外服务也出现延迟,若此时调用方的请求不断增加,最后就会因为等待出现故障的依赖方响应形成任务积压,最终导致自身服务的瘫痪。
在微服务中存在着那么多的服务单元,若一个单元出现故障,就很容易因依赖关系而引发故障的蔓延,最终导致整个系统瘫痪,这样的架构相对较传统的架构更不稳定,为了解决这样的问题,产生了断路器等一系列的服务保护机制。
2、Hystrix作用
Spring Cloud Hystrix 实现了断路器、线程隔离等一系列服务保护功能。它也是基于Netflix的开源框架Hystrix实现的,该框架的目标在于通过控制那些访问远程系统系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备服务降级、服务熔断、线程和信号隔离、请求缓存、请求合并以及服务监控等强大功能。
1、在ribbon的pom文件中引入Hystrix依赖。
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrixartifactId>
dependency>
2、在RibbonApplication启动类中加入@EnableHystrix注解,申明启用断路器功能。
package com.demo.cloud.ribbon;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
/**
* @ClassName RibbonApplication
* @Description TODO
* @Author shanzz
* @Date 2019/5/28 11:03
* @Version 1.0
**/
@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
public class RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class,args);
}
}
3、在service接口的方法上使用 @HystrixCommand注解并指定fallbackMethod熔断调用的方法。
package com.demo.cloud.ribbon.service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
/**
* @ClassName AdminService
* @Description TODO
* @Author shanzz
* @Date 2019/5/28 13:50
* @Version 1.0
**/
@Service
public class AdminService {
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "errorMsg")
public String sayHi(String message){
return restTemplate.getForObject("http://eureka-client/hi?message="+message,String.class);
}
public String errorMsg(String message){
return String.format("you have an error message;the message is %s",message);
}
}
4、将服务提供者断开连接,模拟测试断路器是否工作,结果如下:
发现此时断路器已经开始工作。
1、因为Feign是自带熔断器的,不过默认熔断器是关闭的,所以我们需要在yml配置文件中将熔断器开启,添加如下配置
feign:
hystrix:
enabled: true
2、在service接口中指定fallback方法
package com.demo.cloud.eurekafeign.service;
import com.demo.cloud.eurekafeign.service.impl.FeignServiceHystrix;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(value = "eureka-client",fallback = FeignServiceHystrix.class)
public interface FeignService {
@RequestMapping(value = "hi",method = RequestMethod.GET)
public String sayHi(@RequestParam(value = "message") String message);
}
3、创建熔断实现类,并实现service方法
package com.demo.cloud.eurekafeign.service.impl;
import com.demo.cloud.eurekafeign.service.FeignService;
import org.springframework.stereotype.Component;
/**
* @ClassName FeignServiceHystrix
* @Description TODO
* @Author shanzz
* @Date 2019/5/29 14:40
* @Version 1.0
**/
@Component
public class FeignServiceHystrix implements FeignService {
@Override
public String sayHi(String message) {
return String.format("you have an bad request,your send msg is %s",message);
}
}
4、关闭服务提供者,访问http://localhost:8765/hi?message=helloFeign可发现如下结果
ribbon 和feign的方式相同
1、在pom文件中引入Hystrix dashboard依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboardartifactId>
dependency>
2、在application启动类加入@EnableHystrixDashboard 注解 开启仪表盘
package com.demo.cloud.eurekafeign;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableDiscoveryClient
@EnableFeignClients//开启Spring Cloud Feign支持
@SpringBootApplication
@EnableHystrixDashboard//开启Hystrix仪表监控
public class EurekaFeignApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaFeignApplication.class, args);
}
}
3、创建一个Hystrix。stream的servlet配置类
package com.demo.cloud.eurekafeign.config;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @ClassName HystrixDashboardConfiguration
* @Description TODO
* @Author shanzz
* @Date 2019/5/29 15:11
* @Version 1.0
**/
@Configuration
public class HystrixDashboardConfiguration {
@Bean
public ServletRegistrationBean getServlet(){
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
4、启动,访问http://localhost:8765/hystrix 可看到如下结果
点击Monitor Stream,进入如下界面,第一次进入,为发生访问时
多次访问http://localhost:8765/hi?message=helloFeign可发现变化
【参考资料】
《Spring Cloud微服务实战》
https://www.funtl.com/
https://www.funtl.com/zh/spring-cloud-netflix/Spring-Cloud-使用熔断器防止服务雪崩.html