Spring Cloud Alibaba 入门学习笔记第三篇:OpenFeign负载均衡调用

Spring Cloud Alibaba 入门学习笔记第二篇:Nacos注册中心+Loadbalancer负载均衡
学习完使用Spring Cloud Loadbalancer进行的负载均衡调用后,会发现调用的代码不是很优雅,使用OpenFeign能够让调用代码变得如调用本地服务一样!!!

OpenFeign简介

OpenFeign是一个声明式 Web 服务客户端。它使编写 Web 服务客户端变得更容易。要使用 Feign 创建一个接口并对其进行注释。它具有可插入的注释支持,包括 Feign 注释和 JAX-RS 注释。Feign 还支持可插拔的编码器和解码器。Spring Cloud 添加了对 Spring MVC 注解的支持,并支持使用HttpMessageConvertersSpring Web 中默认使用的注解。Spring Cloud 集成了 Eureka、Spring Cloud CircuitBreaker 和 Spring Cloud LoadBalancer,在使用 Feign 时提供负载均衡的 http 客户端。

在Spring Cloud 2020版之前是基于Ribbon进行的优化处理(因为Feign当时内置的Ribbon),在Spring Cloud 2020版后基于Spring Cloud LoadBalancer进行的优化处理。

官方文档:https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/#spring-cloud-feign

核心注解

@EnableFeignClients

主要作用:在springboot启动类上添加,告诉程序去识别@FeignClient注解。
主要属性如下:

String[] value() default {}; //指定扫描的包 String[] basePackages() default {}; //指定扫描的包 Class<?>[] basePackageClasses() default {}; //指定扫描的包 Class<?>[] defaultConfiguration() default {}; //针对FeignClient的默认配置信息 Class<?>[] clients() default {}; //指定扫描的FeignClient

通常是无需配置各项属性,直接使用即可。

@FeignClient

标注用于声明Feign客户端可访问的Web服务

@AliasFor("name") String value() default ""; //和value等价,必填 通常填需要调用的服务名,例如:在注册中心存在一个名为Pay的服务,这里填写Pay就会去自动调用Pay服务 String contextId() default ""; //针对同一个服务的调用(即name相同)写在多个类当中,就用contextId进行区分 @AliasFor("value") String name() default ""; String[] qualifiers() default {}; //别名 String url() default ""; //Pay服务存在 192.168.1.1 192.168.1.2等多个地址时,指定具体地址 boolean decode404() default false; // 调用服务出现404,是否抛出异常,还是解析数据 Class<?>[] configuration() default {}; // feignClient相关配置,例如: 链接超时,日志级别,响应解码等等 Class<?> fallback() default void.class; //出现异常,回滚 Class<?> fallbackFactory() default void.class; //异常回滚工厂处理 String path() default ""; //请求统一前缀 boolean primary() default true; //存在多个相同的bena,定义为首选的bean

参考文章:那天晚上和@FeignClient注解的深度交流

代码实现

第一步 引入JAR包

<!-- spring cloud 版本管理 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2020.0.2</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2021.1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- spring cloud 注册中心 ,负载均衡,openfeign --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- spring boot web 相关jar--> <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> </dependencies>

第二步 代码实现

创建一个名为feign-provider的服务注册到注册中心

spring: cloud: nacos: server-addr: 127.0.0.1:8848 discovery: service: feign-provider
@SpringBootApplication @EnableDiscoveryClient public class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); } }
@RestController public class ProviderController { /** * 获取name * * @param name * @return {@link String} */ @RequestMapping("/provider/{name}") public String getName(@PathVariable String name) { return "Hello Im provider" + name; } }

创建调用服务用来调用feign-provider

@SpringBootApplication @EnableDiscoveryClient //开启服务注册与发现 @EnableFeignClients //开启FeignClien的支持 public class ConsumeApplication { public static void main(String[] args) { SpringApplication.run(ConsumeApplication.class, args); } }
@FeignClient("feign-provider") //指定调用注册中心里面名为feign-provider的服务 @Service //注入为bean public interface OpenFeignService { /** * 获取name * * @param name * @return {@link String} */ @RequestMapping("/provider/{name}") String getName(@PathVariable String name); }
@RestController public class ConsumeController { @Autowired OpenFeignService openFeignService; //注入feignService 进行调用 @RequestMapping("/consume/{name}") public String getName(@PathVariable String name) { return openFeignService.getName(name); } }
server: port: 8102 spring: cloud: nacos: server-addr: 127.0.0.1:8848 discovery: service: feign-consume # feign 完整配置信息见文档:https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/#netflix-feign-starter feign: client: config: feign-provider: #为 feign-provider这个FeignClient配置属性 如果是default 则所有FeignClient都生效 connectTimeout: 3000 # 请求链接时间 默认是1s readTimeout: 3000 # 请求响应超时时间 默认是1s loggerLevel: full # 请求日志打印详情 要配合下面的 debug一起使用 logging: level: cn.hjljy.springcloud.openfeign.consume.OpenFeignService: debug

启动测试

1 启动Nacos注册中心
2 启动feign-privoder服务
3 启动feign-consume服务
4 浏览器输入:http://127.0.0.1:8102/consume/123456

image.png

最后

OpenFeign 在使用上,让调用者感觉不出是在进行远程调用,还是挺不错的。同时OpenFeign还能够支持对调用结果的解压,例如通常返回的数据结构是:

private int code; private String msg; private T data;

常常数据是在data里面,就可以通过自定义的encoder进行处理,还有重试机制等等!!!


标题:Spring Cloud Alibaba 入门学习笔记第三篇:OpenFeign负载均衡调用
作者:hjljy
地址:https://www.aliuying.com/articles/2021/05/30/1622363370319.html

评论

  1. 才看到,不用设置,默认是8080

  2. feign-provider项目不用设置server port吗?

取消