前文
SpringCloud —— 服务注册进 Eureka 集群
SpringCloud —— SpringCloud Consul 实现服务注册中心
文章目录
什么是 OpenFeign?
Feign 是一个声明式 WebService 客户端,使用 Feign 能让编写 Web Service 客户端更加简单
它的使用方法是 定义一个服务接口然后在上面添加注解。Feign 也支持可插拔式的编码器和解码器。SpringCloud 对 Feign 进行了封装,使其支持了 SpringMVC 标准注解和 HttpMessageConverters。Feign 可以与 Eureka 和 Ribbon 组合使用以支持负载均衡
简单地说:Feign 是一个声明式的 Web 服务客户端,让编写 Web 服务客户端变得非常容易,只需创建一个接口并在接口上添加注解即可
Feign 能干什么?
Feign 旨在使编写 Java Http 客户端变得更加容易
在前面的文章里使用 Ribbon + RestTemplate 时 SpringCloud —— Ribbon
,利用 RestTemplate 对 http 请求的封装处理,形成了一套模板化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常会针对每个微服务自行封装一些客户端类来包装这些依赖的调用。所以,Feign 在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。
在 Feign 的实现下,我们 只需创建一个接口并使用注解的方式来配置它(以前是 Dao 接口上面标注 @Mapper 注解,现在是一个微服务接口上面标注一个 @Feign 注解即可),即可完成对服务提供方的接口绑定,简化了使用 SpringCloud Ribbon 时自动封装服务调用客户端的开发量
Feign 集成了 Ribbon
利用 Ribbon 维护了提供方的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与 Ribbon 不同的是,通过 Feign 只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用
Feign 和 OpenFeign 的区别
新建 Module(80)
编写 application.yml 文件
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defualtZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com/eureka/
编写启动类
package com.java.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author Woo_home
* @create 2020/3/27 20:48
*/
@SpringBootApplication
@EnableFeignClients
public class OrderOpenFeignMain80 {
public static void main(String[] args){
SpringApplication.run(OrderOpenFeignMain80.class,args);
}
}
编写业务接口
package com.java.springcloud.service;
import com.java.springcloud.entity.CommonResult;
import com.java.springcloud.entity.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @author Woo_home
* @create 2020/3/27 20:50
*/
@Component
@FeignClient(value = "DEMO-PROVIDER-PAYMENT") // 服务实例名称
public interface OpenFeignPaymentService {
// 跟 8001 的访问路径一致
@GetMapping(value = "/payment/get/{id}")
CommonResult<Payment> getPayment(@PathVariable("id") Long id);
}
编写控制器代码
package com.java.springcloud.controller;
import com.java.springcloud.entity.CommonResult;
import com.java.springcloud.entity.Payment;
import com.java.springcloud.service.OpenFeignPaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @author Woo_home
* @create 2020/3/27 20:56
*/
@RestController
@Slf4j
public class OpenFeignController {
@Resource
private OpenFeignPaymentService paymentFeignService;
@GetMapping(value = "/consumer/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
// 使用接口调用服务
return paymentFeignService.getPayment(id);
}
}
启动服务
先后启动 8001、8002、7001、7002,最后启动新建的 OrderOpenFeignMain80
连续刷新页面
OK,可以实现轮询访问
OpenFeign 超时控制
超时演示出错情况
服务提供方 8001 故意写暂停程序
服务消费方 80 添加超时方法 OpenFeignPaymentService
服务消费方 80 添加超时方法 OpenFeignController
测试
报错页面,因为 Feign 客户端只等待一秒钟,导致 Feign 客户端不想等待了,直接返回报错
修改 application.yml 开启 OpenFeign 客户端超时控制
为了避免这样的情况,有时候我们需要设置 Feign 客户端的超时控制,如下:
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
# 设置 feign 客户端超时时间(OpenFeign 默认支持 Ribbon)
ribbon:
# 指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
ReadTimeout: 5000
# 指的是建立连接后从服务器读取到可用资源所用的时间
ConnectTimeout: 5000
再来测试下
正常访问
在 application.yml 文件中开启配置
OpenFeign 日志打印功能
Feign 提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解 Feign 中 HTTP 请求细节
简单地说:就是 对 Feign 接口的调用情况进行监控和输出
日志级别
- NONE:默认的,不显示任何日志
- BASIC:仅记录请求方法、URL、响应状态码以及执行时间
- HEADERS:除了 BASIC 中定义的信息之外,还有请求和响应的头信息
- FULL:除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据
配置 Bean
package com.java.springcloud.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Woo_home
* @create 2020/3/28 2:06
*/
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
// 除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据
return Logger.Level.FULL;
}
}
修改 application.yml 文件
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
#设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
ReadTimeout: 5000
#指的是建立连接后从服务器读取到可用资源所用的时间
ConnectTimeout: 5000
logging:
level:
# Feign 日志以什么级别监控哪个接口(这里扫描的是接口)
com.java.springcloud.service.OpenFeignPaymentService: debug
启动服务访问页面
控制台输出
完整代码
完整代码已上传至码云,感兴趣的朋友可以下载来运行下 项目地址