如何在Feign这个组件里面,Feign这个组件里面使用Hystrix,也就是Feign如何搭配Hystrix,我们可以先来看一下Feign这个
组件,看他都依赖了哪些组件,我们pom文件里面引的是spring-cloud-starter-feign,你看到这里面,这里面其实有一个feign
hystrix,你看他引导了hystrix-core,说明他里面已经集成好了hystrix,我们不需要单独的引入hystrix包,可以直接来用,
那么使用的时候,怎么用呢,第一你需要配置一下,feign.hystrix,注意是没有提示的,所以我们写的时候得注意一下,不要写错了,
feign.hystrix.enabled=true
需要首先做这么一个配置,然后我们再来看一下productClient,这块代码写到哪儿,这段代码写到product服务里面,这里提供
一个jar包,我们只是引用而已,这里面怎么使用Hystrix呢,你不能加一个HystrixCommand注解了,这边都是interface,不一样了,
那这里面怎么用呢,@FeignClient这里面有一个参数,可以传,叫做fallback,fallback里面的内容要填一个class,还没有创建的
一个class
@Component
public class ProductClientFallback implements ProductClient {
@Override
public List<ProductInfo> listForOrder(@RequestBody List<String> productIdList) {
return null;
}
}
实现ProductClient,把他里面的方法都给实现了,如果产生服务降级的话呢,比如产生服务降级的话,那么他就会访问到
这儿来,返回一个null,我们先返回一个null,这个class要加一个注解,这个是要注意的一点,很容易被大家忽略掉,注意看
一下他的用法,在FeignClient里面加一个fallback的字段,指定如果产生服务降级的话,那么访问到的实际的方法,接下来我们
启动order的服务,我们怎么观察服务降级呢,如果是出现服务降级的话,那么返回的结果应该是null,你看一下我们的ProductClient,
看一下我们的client,看一下这里面的代码
@Component
public class ProductClientFallback implements ProductClient {
@Override
public List<ProductInfo> listForOrder(@RequestBody List<String> productIdList) {
return null;
}
}
加了@Component这个注解,我们希望class载入到Spring的容器里面,那么问题来了,我问一下大家,这块代码到底是在哪个
项目里面运行的,这块代码虽然写是写在Product项目,是order服务里面来引用,这块其实就可以理解为是order里面的一块
代码了,他已经在order项目里面了,这就是一片代码,所以运行的时候呢,他肯定是在order里面来运行的,那么为什么不起作用呢,
这是因为我们的启动类里面没有扫描到
https://blog.csdn.net/huanxianglove/article/details/80914504
@SpringCloudApplication
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
// Spring应用启动起来
SpringApplication.run(OrderApplication.class,args);
}
}
我们要配置一下扫描,现在已经成功启动了,我们使用postman下一个但试一试
localhost:8010/createOrder
[
{
productId: "00000",
productName: "太阳面",
productPrice: null,
productStock: null,
productDescription: null,
productIcon: null,
productStatus: null,
categoryType: null,
createTime: null,
updateTime: null
}
]
可以看到productId就是"00000",我们product压根就没有启动,他就是null,所以证明我们的服务降级已经
起作用了,因为是null,所以报了一个空指针,他并没有像之前一样的,报找不到这个服务,我们再来回顾一下,
Feign组件里面使用Hystrix,第一点就是配置,这一点可能很多人会忘记
feign.hystrix.enabled=true
这一点特别要注意,你这个地方配错了就不生效了,还有一个地方就是启动类,包扫描,因为我们使用的是Product
服务,所以你得把它配置进来,扫描得到,;=另外就是降级fallback的这个类,这上面注解不要忘记了,这三点大家
切记
<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
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.learn</groupId>
<artifactId>order</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>cn.learn</groupId>
<artifactId>microcloud02</artifactId>
<version>0.0.1</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
</dependencies>
<!-- 这个插件,可以将应用打包成一个可执行的jar包 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
server.port=8010
eureka.client.serviceUrl.defaultZone=http://admin:1234@10.40.8.152:8761/eureka
spring.application.name=order
eureka.instance.prefer-ip-address=true
eureka.instance.instance-id=${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
spring.rabbitmq.host=59.110.158.145
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.port=5672
spring.cloud.stream.bindings.myMessage.group=order
spring.cloud.stream.bindings.myMessage.content-type=application/json
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=1000
hystrix.command.getProductInfoList.execution.isolation.thread.timeoutInMilliseconds=5000
feign.hystrix.enabled=true
package com.learn.client;
import java.util.List;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import com.learn.dto.ProductInfo;
@FeignClient(name = "product",fallback = ProductClientFallback.class)
public interface ProductClient {
@PostMapping("/listForOrder")
public List<ProductInfo> listForOrder(@RequestBody List<String> productIdList);
}
package com.learn.client;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
import com.learn.dto.ProductInfo;
@Component
public class ProductClientFallback implements ProductClient {
@Override
public List<ProductInfo> listForOrder(@RequestBody List<String> productIdList) {
ProductInfo p = new ProductInfo();
p.setProductId("00000");
p.setProductName("太阳面");
List<ProductInfo> list = new ArrayList<ProductInfo>();
list.add(p);
return list;
}
}
package com.learn.controller;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.learn.client.ProductClient;
import com.learn.dto.ProductInfo;
@RestController
public class OrderFeignController {
@Autowired
private ProductClient productClient;
@GetMapping("/createOrder")
public List<ProductInfo> listForOrder() {
return this.productClient.listForOrder(Arrays.asList("1111"));
}
}
package com.learn;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
//@SpringBootApplication
//@EnableRabbit
//@EnableEurekaClient
//@EnableCircuitBreaker
@SpringCloudApplication
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
// Spring应用启动起来
SpringApplication.run(OrderApplication.class,args);
}
}