OpenFeign简介
与dubbo相似,可通过消费者controller调用提供者service层方法。
与之不同的是,OpenFeign只能调用提供者的controller,即,将controller作为接口,消费者来调用这个接口的方法。
相当于调用提供者的controller,与RestTemplate没有本质区别
Feign作用
Feign中集成了Ribbon,并在Ribbon+Rest
Template的基础上进一步封装。(只需创建一个接口并使用注解的方式来配置)简化了使用SpringcloudRibbon时,自动封装服务调用客户端的开发量。
Feign利用Ribbon维护了Payment的服务列表信息,并通过轮询实现了客户端的负载均衡。
但,与Ribbon区别是,feign只需定义服务绑定接口且以声明式的方法,更简单的实现了服务调用。
Feign自带负载均衡配置,不用手动配置。
项目测试:
创建消费者模块:cloud-consumer-feign-order80 pom.xml文件中添加依赖
<dependencies>
<!-- Open Feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- eureka Client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<groupId>com.usan.commons</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.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-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
编写yml配置文件
server:
port: 80
spring:
application:
name: cloud-consumer-feign-service
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
编写启动类
@SpringBootApplication
@EnableFeignClients // 开启使用feign客户端功能
public class CustomerFeignMain80 {
public static void main(String[] args) {
SpringApplication.run(CustomerFeignMain80.class, args);
}
}
编写feign客户端
// 标识当前接口是一个feign客户端,并且指定调用哪一个微服务
@FeignClient(value = "cloud-payment-service")
public interface PaymentFeignService {
@GetMapping("payment/{id}")
CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
}
编写controller
@RestController
public class CustomerFeignController {
@Autowired
private PaymentFeignService paymentFeignService;
@GetMapping("consumer/feign/payment/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
return paymentFeignService.getPaymentById(id);
}
}
启动测试
需要启动 eureka7001,7002、服务提供方 8001 8002
超时控制
在8001服务提供方的controller里面定义一个故意超时方法
@GetMapping("payment/timeout")
public String testTimeOut(){
/*try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "这是一个模拟超时的服务......";
}
在feign客户端PaymentFeignService里面定义
@GetMapping("payment/timeout")
public String testTimeOut();
在消费方controller类里面定义
//调用超时的服务
@GetMapping("order/feign/timeout")
public String testTimeOut(){
return this.orderFeignClient.testTimeOut();
}
启动进行测试,这个时候经过三秒后服务器给我们返回结果
OpenFeign日志打印
首先编写一个config配置类
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
添加yml配置文件
logging:
level:
com.jiyun.client.OrderFeignClient: debug #这里是通过调用client类进行日志配置
启动测试,访问http://localhost/order/feign/2,看控制台最终效果