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
最后
OpenFeign 在使用上,让调用者感觉不出是在进行远程调用,还是挺不错的。同时OpenFeign还能够支持对调用结果的解压,例如通常返回的数据结构是:
private int code;
private String msg;
private T data;
常常数据是在data里面,就可以通过自定义的encoder进行处理,还有重试机制等等!!!