Hystrix在cloud有两种使用方式,我感觉有三种。
1、Hystrix+ribbon;
2、Hystrix+feign;
3、zuul(集成的降级处理机制)-后面zuul会提到;
首先创建一个hystrix模块。
再创建hystrixribbon、hystrixfeign模块。
一、hystrix配合ribbon
项目工程如下:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelversion>4.0.0</modelversion>
<parent>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-parent</artifactid>
<version>2.3.2.RELEASE</version>
</parent>
<groupid>com.cloud</groupid>
<artifactid>hystrixribbon</artifactid>
<version>0.0.1-SNAPSHOT</version>
<name>hystrixribbon</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.6.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencies>
<!--eureka客户端-->
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-netflix-eureka-client</artifactid>
<version>1.4.6.RELEASE</version>
</dependency>
<!--熔断器-->
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-hystrix</artifactid>
<version>1.4.4.RELEASE</version>
</dependency>
</dependencies>
<!--指定下载源和使用springcloud的版本-->
<dependencymanagement>
<dependencies>
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-dependencies</artifactid>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupid>com.alibaba.cloud</groupid>
<artifactid>spring-cloud-alibaba-dependencies</artifactid>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencymanagement>
<build>
<plugins>
<plugin>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-maven-plugin</artifactid>
</plugin>
</plugins>
</build>
</project>
application.yml
spring:
application:
name: service-ribbon-hystrix #服务应用名称
server:
port: 8088 #服务端口号
eureka:
client:
healthcheck:
enabled: false #启动服务健康状态的检查
serviceUrl:
defaultZone: http://localhost:8090/eureka #注册服务组件的url
instance:
prefer-ip-address: true #使用ip前缀
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000 #熔断的超时时间
HystrixribbonApplication.java(作为客户端注册到注册中心。增加熔断器注解@EnableCircuitBreaker)
package com.cloud.hystrixribbon;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class HystrixribbonApplication {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(HystrixribbonApplication.class, args);
}
}
TestController
package com.cloud.hystrixribbon.controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* <b>技术支持:</b> (c)
*
* @author lx.w
* @version 1.0
* @since JDK1.8
*/
@RestController
@RequestMapping("/hystrix/ribbon")
public class TestController {
@Autowired
private RestTemplate restTemplate;
@PostMapping("/test")
@HystrixCommand(fallbackMethod = "fallTest")
public String test(@RequestParam String s) {
String str = restTemplate.postForObject("http://client-service/client/hello/world?str=" + s, null, String.class);
System.out.println("hystrixRibbon");
return str + " hystrixRibbon";
}
/**
* @desc: 熔断降级方法
* @author: lx.w
* @params: params
*/
private String fallTest(String s) {
System.out.println("进入熔断降级方法");
return "no Service" + s;
}
}
注意看这个TestController的test方法,在头部增加了熔断器的注解@HystrixCommand(fallbackMethod = "fallTest"),通过该注解,当调用的下游服务不可用时,请求会回调到fallbackMethod指定的方法中。
postman直接访问hystrixribbon服务的test接口
当下游服务正常运行时
当下游服务停止时(此时配置在@HystrixCommand(fallbackMethod = "fallTest")中方法fallTest设置的返回值返回)
二、hystrix配合feign
项目工程如下:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelversion>4.0.0</modelversion>
<parent>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-parent</artifactid>
<version>2.3.2.RELEASE</version>
</parent>
<groupid>com.cloud</groupid>
<artifactid>hystrixfeign</artifactid>
<version>0.0.1-SNAPSHOT</version>
<name>hystrixfeign</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.6.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencies>
<!--eureka客户端-->
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-netflix-eureka-client</artifactid>
<version>1.4.6.RELEASE</version>
</dependency>
<!--熔断器-->
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-hystrix</artifactid>
<version>1.4.4.RELEASE</version>
</dependency>
<!--feign-->
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-openfeign</artifactid>
</dependency>
</dependencies>
<!--指定下载源和使用springcloud的版本-->
<dependencymanagement>
<dependencies>
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-dependencies</artifactid>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupid>com.alibaba.cloud</groupid>
<artifactid>spring-cloud-alibaba-dependencies</artifactid>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencymanagement>
<build>
<plugins>
<plugin>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-maven-plugin</artifactid>
</plugin>
</plugins>
</build>
</project>
application.yml(比hystrix+ribbon多了一个feign.hystrix.enabled=true feign熔断器开启的配置)
spring:
application:
name: service-feign-hystrix #服务应用名称
server:
port: 8087 #服务端口号
eureka:
client:
healthcheck:
enabled: false #启动服务健康状态的检查
serviceUrl:
defaultZone: http://localhost:8090/eureka #注册服务组件的url
instance:
prefer-ip-address: true #使用ip前缀
##开启feign的熔断器hystrix
feign:
hystrix:
enabled: true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000 #熔断的超时时间
HystrixfeignApplication.java
package com.cloud.hystrixfeign;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* <b>技术支持:</b> (c)
*
* @author lx.w
* @version 1.0
* @since JDK1.8
*/
@EnableFeignClients
@EnableDiscoveryClient
@EnableCircuitBreaker
@SpringBootApplication
public class HystrixfeignApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixfeignApplication.class, args);
}
}
在FeignService中添加的注解
@FeignClient中有属性fallbackFactory作为熔断降级属性,也可以使用fallback作为熔断降级属性。即存在两种熔断降级的配置方法。
package com.cloud.hystrixfeign.feign;
import com.cloud.hystrixfeign.feign.fallback.HystrixClientFallBack;
import com.cloud.hystrixfeign.feign.fallback.HystrixClientFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* <b>技术支持:</b> (c)
*
* @author lx.w
* @version 1.0
* @since JDK1.8
*/
@FeignClient(value = "client-service", fallbackFactory = HystrixClientFallbackFactory.class)
public interface FeignService {
@PostMapping("/client/hello/world")
String helloWorld(@RequestParam("str") String str);
}
TestController.java
package com.cloud.hystrixfeign.controller;
import com.cloud.hystrixfeign.feign.FeignService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* <b>技术支持:</b> (c)
*
* @author lx.w
* @version 1.0
* @since JDK1.8
*/
@RestController
@RequestMapping("/hystrix/feign")
public class TestController {
@Autowired
private FeignService feignService;
@PostMapping("/test")
public String test(@RequestParam String s) {
System.out.println("hystrixFeign");
return feignService.helloWorld(s) + " hystrixFeign";
}
}
接下来是关键点了,在FeignService中有两种熔断降级的配置方法。首先先讲第一种fallbackFactory。在FeignService的类中,注解@FeignClient(value = "client-service", fallbackFactory = HystrixClientFallbackFactory.class) 使用到的属性为fallbackFactory。
同时需要配置以下两个配置类:
1、HystrixClientWithFallbackFactory
package com.cloud.hystrixfeign.feign.fallback;
import com.cloud.hystrixfeign.feign.FeignService;
public interface HystrixClientWithFallbackFactory extends FeignService {
}
2、HystrixClientFallbackFactory
package com.cloud.hystrixfeign.feign.fallback;
import com.cloud.hystrixfeign.feign.FeignService;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
@Component
public class HystrixClientFallbackFactory implements FallbackFactory<feignservice> {
@Override
public FeignService create(Throwable arg0) {
// TODO Auto-generated method stub
return new HystrixClientWithFallbackFactory() {
@Override
public String helloWorld(String str) {
return "error client ";
}
};
}
}
</feignservice>
使用postman直接访问接口http://localhost:8087/hystrix/feign/test;
当调用下游服务正常运行时
当调用下游服务异常时(此时配置在HystrixClientFallbackFactory类中降级返回的参数返回)
第二种配置@FeignClient(value = "client-service", fallback = HystrixClientFallBack.class)使用到的属性为fallback(需要将第一种配置类HystrixClientFallbackFactory的配置注解@Component注释下)
配置类HystrixClientFallBack.java
package com.cloud.hystrixfeign.feign.fallback;
import com.cloud.hystrixfeign.feign.FeignService;
import org.springframework.stereotype.Component;
/**
* <b>技术支持:</b> (c)
*
* @author lx.w
* @version 1.0
* @since JDK1.8
*/
@Component
public class HystrixClientFallBack implements FeignService {
@Override
public String helloWorld(String str) {
System.out.println("进入熔断降级");
return "error client " + str;
}
}
使用postman直接访问接口http://localhost:8087/hystrix/feign/test;
当调用下游服务正常运行时
当调用下游服务异常时(此时配置在HystrixClientFallbackFactory类中降级返回的参数返回)
思考一下,hystrix+ribbon与hystrix+feign两种组合,第一种组合个人觉得好像不怎么适用,他涉及到服务自己去做熔断降级的措施,我理解在微服务中熔断降级应该统一管理(如果想法不对请在评论区留言讨论)。第二种 hystrix+feign在配置面上好像简单了很多,但是感觉还是有点个性化了。面对再对阿里的sentinel熔断器作深入探讨
Original: https://blog.csdn.net/Sorry_No_konw/article/details/123483231
Author: 哟,Liberty
Title: springcloud-熔断器(Hystrix)