Hystrix的使用4和OpenFeign结合使用

编程

Hystrix的使用4-和OpenFeign结合使用

1.简介

OpenFeign中已经集成了Hystrix,不用再引入Hystrix依赖。

2.代码实现

2.1 父工程POM文件

  <packaging>pom</packaging>

<modules>

<!-- 公共工程,请看我的github -->

<module>cloud-api-commons</module>

<!-- Eureka注册中心 -->

<module>cloud-eureka-server7001</module>

<!-- 服务提供者 -->

<module>cloud-provider-payment-hystrix8001</module>

<!-- 服务消费者 -->

<module>cloud-consumer-order-hystrix80</module>

</modules>

<!-- 统一管理jar包版本 -->

<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<maven.compiler.source>1.8</maven.compiler.source>

<maven.compiler.target>1.8</maven.compiler.target>

<junit.version>4.12</junit.version>

<log4j.version>1.2.17</log4j.version>

<lombok.version>1.16.18</lombok.version>

<spring.boot.version>2.2.2.RELEASE</spring.boot.version>

<spring.cloud.version>Hoxton.SR1</spring.cloud.version>

<hutool-all.version>5.1.0</hutool-all.version>

<liuhangs.cloud.api.version>1.0.0-SNAPSHOT</liuhangs.cloud.api.version>

</properties>

<distributionManagement>

<site>

<id>website</id>

<url>scp://webhost.company.com/www/website</url>

</site>

</distributionManagement>

<!-- 子模块继承之后,提供作用:锁定版本 + 子module不用谢groupId和version -->

<dependencyManagement>

<dependencies>

<!--spring boot 2.2.2-->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-dependencies</artifactId>

<version>2.2.2.RELEASE</version>

<type>pom</type>

<scope>import</scope>

</dependency>

<!--spring cloud Hoxton.SR1-->

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-dependencies</artifactId>

<version>Hoxton.SR1</version>

<type>pom</type>

<scope>import</scope>

</dependency>

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<version>${lombok.version}</version>

</dependency>

<dependency>

<groupId>cn.hutool</groupId>

<artifactId>hutool-all</artifactId>

<version>${hutool-all.version}</version>

</dependency>

</dependencies>

</dependencyManagement>

2.2 服务提供者cloud-provider-payment-hystrix8001

2.2.1 服务提供者POM文件

因为我们不在服务提供者代码里测试Hystrix,所以不用引入Hystrix依赖。

    <dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>

</dependency>

<dependency>

<groupId>com.liuhangs.springcloud</groupId>

<artifactId>cloud-api-commons</artifactId>

<version>${liuhangs.cloud.api.version}</version>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<!--监控-->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-actuator</artifactId>

</dependency>

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<optional>true</optional>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

</dependencies>

2.2.2 服务提供者application.yml

server:

port: 8001

spring:

application:

name: cloud-provider-payment-hystrix

eureka:

client:

#是否注册到eureka

register-with-eureka: true

# 是否在本地缓存注册表信息

fetch-registry: true

service-url:

# 配置eureka的地址,如果多台则逗号分隔。

defaultZone: http://eureka7001.com:7001/eureka

2.2.3 服务提供者service

service接口:

import com.liuhangs.springcloud.api.entities.CommonResult;

/**payment服务接口

*/

public interface PaymentHystrixService {

/**

* 正常方法

* @param id

* @return

*/

public CommonResult getPaymentOK(Long id);

/**

* 给80服务消费者准备的超时方法,避免和前面的服务降级方法混淆

*/

public CommonResult getPaymentTimeOutFor80(Long id);

}

service实现类:

import com.liuhangs.springcloud.api.entities.CommonResult;

import com.liuhangs.springcloud.payment.service.PaymentHystrixService;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**这个类里一个需要5秒才能返回值的接口 */

@Service

@Slf4j

public class PaymentHystrixServiceImpl implements PaymentHystrixService {

@Value("${server.port}")

private String SERVER_PORT;

@Override

public CommonResult getPaymentOK(Long id)

{

return new CommonResult(200, "请求ID为:" + id + ", 当前线程是:" + Thread.currentThread().getName() +

"," +

" " +

"服务端口:" +

SERVER_PORT);

}

/**

* 给80服务消费者准备的超时方法,避免和前面的服务降级方法混淆

* 此方法会睡眠5秒

* @param id

* @return

*/

@Override

public CommonResult getPaymentTimeOutFor80(Long id)

{

try

{

TimeUnit.MILLISECONDS.sleep(5000);

}

catch (InterruptedException e)

{

e.printStackTrace();

}

return new CommonResult(200, "请求ID为:" + id + ", 当前线程是:" + Thread.currentThread().getName() + ", 服务端口:" +

SERVER_PORT + ", 线程睡眠5秒");

}

}

2.2.4 服务提供者controller

import com.liuhangs.springcloud.api.entities.CommonResult;

import com.liuhangs.springcloud.api.entities.Payment;

import com.liuhangs.springcloud.payment.service.PaymentHystrixService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;

/**服务提供者对外提供的接口

*/

@RequestMapping("provider/payment/hystrix")

@RestController

public class PaymentHystrixController {

@Autowired

private PaymentHystrixService paymentHystrixService;

@GetMapping("/ok/{id}")

public CommonResult getPaymentOK(@PathVariable("id") Long id)

{

return paymentHystrixService.getPaymentOK(id);

}

/**

* 给80服务消费者准备的超时接口

* @param id

* @return

*/

@GetMapping("/timeoutfor80/{id}")

public CommonResult getPaymentTimeOutFor80(@PathVariable("id") Long id)

{

return paymentHystrixService.getPaymentTimeOutFor80(id);

}

}

2.2.4 服务提供者启动类

/**服务提供者启动类

*/

@SpringBootApplication

public class PaymentHystrixStart8001 {

public static void main(String[] args)

{

SpringApplication.run(PaymentHystrixStart8001.class, args);

}

}

2.3 Eureka注册中心cloud-eureka-server7001

2.3.1 注册中心POM文件

    <dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>

</dependency>

<dependency>

<groupId>com.liuhangs.springcloud</groupId>

<artifactId>cloud-api-commons</artifactId>

<version>${liuhangs.cloud.api.version}</version>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<!--监控-->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-actuator</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

</dependencies>

2.3.2 注册中心application.yml

server:

port: 7001

spring:

application:

name: cloud-eureka-server

eureka:

instance:

hostname: eureka7001.com

client:

# 是否将当前服务注册到eureka

registerWithEureka: false

# 是否在本地缓存注册表信息,默认为true

fetchRegistry: true

serviceUrl:

# 配置自己就是单机,配置其他eureka的地址就是集群,如果多台则逗号分隔。

defaultZone: http://eureka7001.com:7001/eureka

2.3.3 注册中心启动类

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**注册中心启动类

*/

@SpringBootApplication

@EnableEurekaServer

public class EurekaStart7001 {

public static void main(String[] args)

{

SpringApplication.run(EurekaStart7001.class, args);

}

}

2.4 服务消费者cloud-consumer-order-hystrix80

2.4.1 服务消费者POM文件

    <dependencies>

<!-- OpenFeign中已经集成了Hystrix,不用再引入Hystrix依赖。 -->

<!-- <dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>

</dependency>-->

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-openfeign</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>

</dependency>

<dependency>

<groupId>com.liuhangs.springcloud</groupId>

<artifactId>cloud-api-commons</artifactId>

<version>${liuhangs.cloud.api.version}</version>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<!--监控-->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-actuator</artifactId>

</dependency>

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<optional>true</optional>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

</dependencies>

2.4.2 服务消费者application.yml

需要注意:

  • OpenFeign的超时调用时间需要调大(默认为1秒),否则看不到服务降级的效果。通过ribbon.ReadTimeoutribbon.ConnectTimeout设置。
  • 服务提供者需要通过 feign.hystrix.enabled开启Hystrix降级处理。
  • 可以通过hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds设置超时降级时间(Hystrix默认一秒)。

server:

port: 80

eureka:

client:

#是否注册到eureka

register-with-eureka: true

# 是否在本地缓存注册表信息

fetch-registry: true

service-url:

# 配置eureka的地址,如果多台则逗号分隔。

defaultZone: http://eureka7001.com:7001/eureka

#需要将接口超时的时间调大(默认1秒),否则在调用服务消费者时会直接报超时异常。

ribbon:

#调用接口读取超时时间

ReadTimeout: 6000

#调用接口连接超时时间

ConnectTimeout: 2000

#开启Hystrix降级处理

feign:

hystrix:

enabled: true #在Feign中开启Hystrix。如果处理自身的容错就开启。开启方式与生产端不一样。

#设置超时降级时间(spring-cloud-starter-openfeign中的HystrixCommandProperties默认为1000毫秒)

hystrix:

command:

default:

execution:

isolation:

thread:

timeoutInMilliseconds: 3000

#设置hystrix日志级别是DEBUG

logging:

level:

com.netflix.hystrix: DEBUG

2.4.3 服务消费者service接口

这里是使用的OpenFeign,所以需要使用接口,并且在接口上加上OpenFeign客户端注解@FeignClient

加上需要使用Hystrix进行服务降级,所以在@FeignClient注解中配置fallback属性,配置统一的服务降级处理类。这里配置的服务降级处理类为PaymentHystrixFallBackService。

import com.liuhangs.springcloud.api.entities.CommonResult;

import org.springframework.cloud.openfeign.FeignClient;

import org.springframework.stereotype.Service;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

/**fallback属性为统一的服务降级处理类

*/

@FeignClient(name="CLOUD-PROVIDER-PAYMENT-HYSTRIX", fallback = PaymentHystrixFallBackService.class)

@Service

public interface PaymentHystrixService {

@GetMapping("provider/payment/hystrix/ok/{id}")

public CommonResult getPaymentOK(@PathVariable("id") Long id);

/**

* 调用服务提供者的getPaymentTimeOutFor80接口

* @param id

* @return

*/

@GetMapping("provider/payment/hystrix/timeoutfor80/{id}")

public CommonResult getPaymentTimeOutFor80(@PathVariable("id") Long id);

}

2.4.4 服务消费者统一的服务降级处理类

注意:服务降级处理类需要实现OpenFeign客户端调用类PaymentHystrixService。

/**PaymentHystrixService类对应的服务降级处理类

* 这个类要实现调用服务消费的OpenFeign接口PaymentHystrixService

*/

@Service

public class PaymentHystrixFallBackService implements PaymentHystrixService {

@Override

public CommonResult getPaymentOK(Long id)

{

return new CommonResult(200, "使用id:" + id

+"调用PaymentHystrixService服务的getPaymentOK方法失败,进入降级处理方法getPaymentOK");

}

@Override

public CommonResult getPaymentTimeOutFor80(Long id)

{

return new CommonResult(200, "使用id:" + id

+"调用PaymentHystrixService服务的getPaymentTimeOut方法失败,进入降级处理方法getPaymentTimeOutFor80");

}

}

2.4.5 服务消费者controller

import com.liuhangs.springcloud.api.entities.CommonResult;

import com.liuhangs.springcloud.order.service.PaymentHystrixService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

/**服务消费者对外提供的接口

*/

@RequestMapping("/consumer/order/hystrix")

@RestController

public class OrderHystrixController {

@Autowired

private PaymentHystrixService paymentHystrixService;

@GetMapping("/ok/{id}")

public CommonResult getPaymentOK(@PathVariable("id") Long id) {

return paymentHystrixService.getPaymentOK(id);

}

@GetMapping("/timeout/{id}")

public CommonResult getPaymentTimeOut(@PathVariable("id") Long id) {

return paymentHystrixService.getPaymentTimeOutFor80(id);

}

}

2.4.6 服务消费者启动类

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

import org.springframework.cloud.openfeign.EnableFeignClients;

/**服务消费者启动类

*/

@SpringBootApplication

@EnableFeignClients //开启OpenFeign

public class OrderHystrixStart80 {

public static void main(String[] args)

{

SpringApplication.run(OrderHystrixStart80.class, args);

}

}

2.5 测试

启动Eureka、服务提供者、服务消费者。

2.5.1 调用正常返回的方法

浏览器访问:http://localhost/consumer/order/hystrix/ok/1 ,返回如下:

2.5.2 调用超时降级方法

浏览器访问:http://localhost/consumer/order/hystrix/timeout/1 ,返回如下:

3.代码请见

https://github.com/ainydexiaohai/cloud2020

4.参考文章

  • 尚硅谷SpringCloud培训课程

以上是 Hystrix的使用4和OpenFeign结合使用 的全部内容, 来源链接: utcz.com/z/518491.html

回到顶部