OpenFeign的基本使用介绍
服务调用介绍
spring-cloud环境开发中服务调用包含两种方式:
- Ribbon+RestTemplate 介绍地址
- 前面在使用Ribbon+RestTemplate时,利用RestTemplate 对http请求进行封装,但在实际的开发过程中对服务的依赖可能有很多往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。
OpenFeign在此基础上做了进一步封装,由它来帮助我们定义和实现依赖服务接口的定义,我们只需要创建一个接口并使用注解的方式来配置他,即可完成对服务提供方的接口绑定。
OpenFeign集成了Ribbon并且通过轮询实现了客户端的负载均衡,而与Ribbon不同的是:使用OpenFeign只需要定义服务接口绑定且以声明式的方法,即可优雅而简单的实现服务调用。
环境准备
-
EurekaClient服务提供者增加如下接口
public interface UserServiceInter { /** * 模拟添加用户 */ String addUser(String userName); /** * 模拟查询用户 */ String getUserName(String userId); }
-
EurekaClient服务提供者UserServiceInter的实现类
@Service @Slf4j public class UserServiceInterImpl implements UserServiceInter { @Override public String addUser(String userName) { log.info("###"+userName+"###"); return "添加成功,用户名:"+userName; } @Override public String getUserName(String userId) { log.info("###"+userId+"###"); return "用户id:"+userId+"的用户名是:程序员丁少"; } }
-
EurekaClient服务提供者的Controller增加如下代码
@Autowired private UserServiceInter userServiceInter; @PostMapping(value = "/service/save") public String save(@RequestParam("userName") String userName){ return userServiceInter.addUser(userName)+"-服务端口号"+port; } @GetMapping(value = "/service/get") public String get(@RequestParam("userId") String userId){ return userServiceInter.getUserName(userId)+"-服务端口号"+port; }
搭建消费者端通过OpenFeign实现服务调用
-
新建Module:
feign-client80
-
更改POM文件
<dependencies> <!--openfeign依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--eureka依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</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-actuator</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
-
写YAML文件:application.yml
server: port: 80 #端口号 spring: application: name: feign-client-consumption #服务名称(消费者) eureka: client: serviceUrl: defaultZone: http://eurekaServer8761.com:8761/eureka/,http://eurekaServer8762.com:8762/eureka/ #eurekaServer集群地址
-
添加主启动类
@SpringBootApplication @EnableFeignClients //开启OpenFeign组件 public class FeignClientMain80 { public static void main(String[] args) { SpringApplication.run(FeignClientMain80.class,args); } }
-
建一个接口并使用注解的方式来配置他,即可完成对服务提供方的接口绑定,这句话的意思请看代码
/** * 建一个接口并使用注解的方式来配置他,即可完成对服务提供方的接口绑定 * value:服务提供者对外提供的服务名称 */ @Component @FeignClient(value = "EUREKA-CLIENT-SERVICE") public interface UserServiceInter { /** *这里直接使用的是服务提供者Controller里的方法 * 因为该方法里面调用了服务提供者的service接口 */ @PostMapping(value = "/service/save") public String save(@RequestParam("userName") String userName); @GetMapping(value = "/service/get") public String get(@RequestParam("userId") String userId); }
-
增加业务类Controller完成对服务的调用
@RestController @Slf4j public class TestController { /** * 注入与服务提供者接口绑定的service */ @Autowired private UserServiceInter userServiceInter; @PostMapping(value = "/consumption/save") public String save(@RequestParam("userName") String userName){ return userServiceInter.save(userName); } @GetMapping(value = "/consumption/get") public String get(@RequestParam("userId") String userId){ return userServiceInter.get(userId); } }
-
访问
http://127.0.0.1/consumption/get?userId=123
OpenFeign超时控制
- Feign客户端默认等待时间是1秒钟,如果超过1秒钟服务端还没返回数据就会出现异常
- 设置Feign客户端超时时间
ribbon: ReadTimeout: 5000 #建立连接所用的时间,指的是两端连接的时间设置5秒钟 ConnectTimeout: 5000 #建立连接后从服务器读取到资源所用的时间设置5秒钟
OpenFeign日志打印(消费者端)
-
注入Logger.Level到Spring容器
import feign.Logger; //一定要是feign包下的logger @Configuration public class FeignConfig { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
-
更改YML文件
logging: level: com.dwj.springcloud.service.UserServiceInter: debug #feign日志以debug级别监控与服务提供者绑定的接口
-
再次访问
http://127.0.0.1/consumption/get?userId=123
控制台会打印以下详细日志