Spring Cloud Alibaba整合OpenFeign
这里的配置可以看我的SpringCloud笔记,配置都是差不多的
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
/**
* name 指定调用rest接口所对应的服务名
* path 指定调用rest接口所在的Controller指定的@RequestMapping
*/
@FeignClient(name = "springcloud-provider-dept",path = "/dept")
public interface DeptClientService {
//与Mybatis一样,通过动态代理的模式进行调用方法
//声明需要调用的rest接口对应的方法
@GetMapping("/msg")
String getMessage();
}
复制模块springcloud-consumer-dept-80,取名为springcloud-consumer-dept-feign-80
修改springcloud-consumer-dept-feign-80模块下的DeptController.class
@RestController
@RequestMapping("/consumer")
@SuppressWarnings("all")
public class DeptController {
//注入我们的feign接口类
@Autowired
private DeptClientService clientService;
@GetMapping("/dept/msg")
public String getMessage(){
return this.clientService.getMessage();
}
}
@EnableFeignClients(basePackages = "com.vinjcent.springcloud")
@SpringBootApplication
@EnableFeignClients(basePackages = "com.vinjcent.springcloud")
public class SpringCloud_Consumer_Feign_80 {
public static void main(String[] args) {
SpringApplication.run(SpringCloud_Consumer_Feign_80.class,args);
}
}
1)启动springcloud-consumer-dept-feign-80
2)启动springcloud-provider-dept-8001
3)启动springcloud-provider-dept-8002
4)启动springcloud-provider-dept-8003
5)访问http://localhost/consumer/dept/msg,看结果能不能访问成功
Feign提供了很多的扩展机制,让用户更加灵活的使用
有时候遇到Bug,比如接口调用失败、参数接受失败等问题,或者想看看调用的性能,就需要配置Feign的日志
全局配置
1)在模块springcloud-consumer-dept-feign-80中定义一个配置类,指定日志级别
注意选择的Level是feign.logger包下的
通过源码可以看到日志等级有4中
2)在模块springcloud-consumer-dept-feign-80下的application.yml
增加以下字段
# springboot默认的日志级别是info,feign的debug日志级别就不会输入
logging:
level:
# 选择一个包下的feign进行日志输出,如果设置logging.level=true,则会出现所有的日志进行输出
com.vinjcent.springcloud.service: debug
3)测试
局部配置
将springcloud-consumer-dept-feign-80模块下的FeignConfig.class的@Configuration
注解注释掉,同时将该模块下的pom.xml文件下的springcloud-api
依赖移除
在springcloud-api模块的service包移动到springcloud-consumer-dept-feign-80模块下
在springcloud-consumer-dept-feign-80模块下修改DeptClientService.class接口(在注释中添加configuration参数)
/**
* name 指定调用rest接口所对应的服务名
* path 指定调用rest接口所在的Controller指定的@RequestMapping
*/
@FeignClient(name = "springcloud-provider-dept",path = "/dept",configuration = FeignConfig.class)
public interface DeptClientService {
//与Mybatis一样,通过动态代理的模式进行调用
//声明需要调用的rest接口对应的方法
@GetMapping("/msg")
String getMessage();
}
@EnableFeignClients
的注解后面的参数进行删除1)重新启动springcloud-consumer-dept-feign-80
2)访问http://localhost/consumer/dept/msg,回到控制面板
3)查看
这里的全局配置和局部配置看起来都一样,但是本质还是有区别的
根据application.yml文件进行配置
DeptClientService.class
接口文件application.yml
文件中添加feign日志局部配置server:
port: 80
spring:
application:
name: springcloud-consumer-dept-feign
# 配置nacos
cloud:
nacos:
# nacos 服务地址
server-addr: 192.168.159.100:7070,192.168.159.100:7080,192.168.159.100:7090
discovery:
username: nacos # nacos用户名
password: nacos
namespace: public # 分隔开发环境和测试环境使用
# 调用的服务提供方
springcloud-provider-dept:
ribbon:
# 复制NacosRule类的引用路径
NFLoadBalancerRuleClassName: com.vincjent.ribbon.MyRibbon
ribbon:
eager-load:
# 开启饥饿加载
enabled: true
# 配置服务名为springcloud-provider-dept使用ribbon饥饿加载,多个服务可以使用","分隔
clients: springcloud-provider-dept
# springboot默认的日志级别是info,feign的debug日志级别就不会输入
logging:
level:
# 选择一个包下的feign进行日志输出,如果设置logging.level=true,则会出现所有的日志进行输出
com.vincjent.springcloud.service: debug
# feign日志局部配置
feign:
client:
config:
# 提供者服务名
springcloud-provider-dept:
loggerLevel: BASIC
1)重新启动springcloud-consumer-dept-feign-80
2)访问http://localhost/consumer/dept/msg,回到控制面板
3)查看
Spring Cloud在Feign的基础上做了扩展,使用Spring MVC的注解完成Feign的功能。原生的Feign不支持Spring MVC注解,原生的Feign使用原生的注解方式来定义消费者客户端也是可以的,通过配置契约来改变这个配置
方式一(通过配置类注入)
在springcloud-consumer-dept-feign-80模块下的配置类FeignConfig中配置Feign的原生类
@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLogger(){
return Logger.Level.FULL;
}
/**
*修改契约配置,支持Feign原生的注解
*/
@Bean
public Contract feignContract(){
return new Contract.Default();
}
}
【注意】使用了feign原生注解之后,接口的调用不再支持Spring MVC的注解,需要使用Feign的原生注解,不然就会报错
即
@GetMapping("/dept/msg") ===> @RequestLine("GET /dept/msg")
@PathVariable("id") ===> @Param("id")
方式二(application.yml文件)
在springcloud-consumer-dept-feign-80模块下的application.yml
文件添加一下字段
# feign日志局部配置
feign:
client:
config:
# 提供者服务名
springcloud-provider-dept:
loggerLevel: BASIC
contract: feign.Contract.Default #设置为默认的契约,还原原生注解
【注意】修改Controller中Spring MVC的接口注解
方式一(通过配置类注入)
在springcloud-consumer-dept-feign-80模块下的配置类FeignConfig中配置
@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLogger(){
return Logger.Level.FULL;
}
/**
*超时时间配置
*/
@Bean
public Request.Options options(){
return new Request.Options(5000,10000);
}
}
方式二(application.yml文件)
# feign日志局部配置
feign:
client:
config:
# 提供者服务名
springcloud-provider-dept:
loggerLevel: BASIC
contract: feign.Contract.Default #设置为默认的契约,还原原生注解
# 连接超时时间,默认2s A =请求=> B
connectTimeout: 5000
# 请求处理超时时间,默认5s
readTimeout: 3000
方式一(通过配置类注入)
public class FeignInterceptor implements RequestInterceptor {
//记录当前类的信息
Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void apply(RequestTemplate requestTemplate) {
// TODO
requestTemplate...
logger.info("自定义Feign拦截器");
}
}
@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLogger(){
return Logger.Level.FULL;
}
@Bean
public Request.Options options(){
return new Request.Options(5000,10000);
}
/**
* 自定义拦截器
*/
@Bean
public FeignInterceptor feignInterceptor(){
return new FeignInterceptor();
}
}
方式二(application.yml)
# feign日志局部配置
feign:
client:
config:
# 提供者服务名
springcloud-provider-dept:
loggerLevel: BASIC
contract: feign.Contract.Default #设置为默认的契约,还原原生注解
# 连接超时时间,默认2s A =请求=> B
connectTimeout: 5000
# 请求处理超时时间,默认5s
readTimeout: 3000
requestInterceptors[0]:
com.vincjent.springcloud.interceptor.FeignInterceptor # 自定义拦截器的完整类路径
官方文档:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config
Nacos 提供用于存储配置和其它元数据的 key/value 存储,为分布式系统中的外部配置提供服务器端和客户端的支持。使用SpringCloud Alibaba Nacos Config,可以在Nacos Server 集中管理你Spring Cloud 应用的外部属性配置
springcloud config 对比
三大优势:
对比项目/配置中心 | springcloud config | apollo | nacos |
---|---|---|---|
开源时间 | 2014.9 | 2016.5 | 2018.6 |
配置实时推送 | 支持(Spring Cloud Bus) | 支持(Http 长轮询1s内) | 支持(Http 长轮询1s内) |
版本管理 | 支持(Git) | 自动管理 | 自动管理 |
配置回滚 | 支持(Git) | 支持 | 支持 |
灰度发布 | 支持 | 支持 | 待支持 |
权限管理 | 支持 | 支持 | 待支持 |
多集群多环境 | 支持 | 支持 | 支持 |
监听查询 | 支持 | 支持 | 支持 |
多语言 | 只支持Java | Go,C++,Python,Java,net,OpenAPI | Python,Java,Nodejs,OpenAPI |
分布式高可用 | Config-Server*2 + Git + MQ | Config2 + Admin3 + Portal*2 + MySQL =8 | Nacos*3 + MySQL = 4 |
配置格式校验 | 不支持 | 支持 | 支持 |
通信协议 | HTTP 和 AMQP | HTTP | HTTP |
数据一致性 | Git 保证数据一致性,Config-Server从 Git 读取数据 | 数据库模拟消息队列,Apollo定时读消息 | HTTP异步通知 |
单机读(tps) | 7(限流所制) | 9000 | 15000 |
单机写(tps) | 5(限流所制) | 1100 | 1800 |
3节点读 | 21(限流所制) | 27000 | 45000 |
3节点写 | 5(限流所制) | 3300 | 5600 |
要使 Nacos 服务与发现中的权限管理生效,需要在application.properties修改内容
启动权限:修改application.properties
登录vinjcent用户
因为给该角色的用户设置只读,所以在Nacos服务中心很多功能无法实现
【注】需要在Nacos配置文件application.properties
中设置了
nacos.core.auth.enabled=true
权限管理才会生效
配置官网:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config
新建一个springcloud-provider-dept-config-nacos-8004模块
导入依赖
<dependencies>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>
dependencies>
application.yml
,bootstrap.yml
application.yml
server:
port: 8004
bootstrap.yml
spring:
application:
# 会自动根据服务名获取DataId对应的配置文件 如果DataId跟服务名不一致 就需要手动指定DataId
name: com.vinjcent.provider
cloud:
nacos:
# 配置Nacos服务地址
server-addr: 192.168.159.100:7070
config:
namespace: public
访问http://192.168.159.100:7070/nacos/index.html#/
@SpringBootApplication
public class Springcloud_Config_Nacos_8004 {
public static void main(String[] args) throws InterruptedException {
ConfigurableApplicationContext applicationContext = SpringApplication.run(Springcloud_Config_Nacos_8004.class, args);
while (true) {
String userName = applicationContext.getEnvironment().getProperty("user.username");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
System.err.println("user name :" + userName + "; age: " + userAge);
//动态实时监听
TimeUnit.SECONDS.sleep(1);
}
// nacos 客户端 每10ms去注册中心进行判断,根据MD5判断客户端与注册中心是否一致
}
}
修改bootstrap.yml
spring:
application:
# 会自动根据服务名获取DataId对应的配置文件 如果DataId跟服务名不一致 就需要手动指定DataId
name: com.vinjcent.provider
cloud:
nacos:
# 配置Nacos服务地址
server-addr: 192.168.159.100:7070
username: nacos
password: nacos
# 解决控制台循环打印ClientWorker日志
# config:
# namespace: public
重新启动
扩展配置
概念
用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等
在没有明确指定 ${spring.cloud.nacos.config.namespace}
配置的情况下, 默认使用的是 Nacos 上 Public 这个namespase
【注】该配置必须放在 bootstrap.properties
文件中。此外 spring.cloud.nacos.config.namespace
的值是 namespace 对应的 id,id 值可以在 Nacos 的控制台获取。并且在添加配置时注意不要选择其他的 namespase,否则将会导致读取不到正确的配置
spring-cloud-starter-alibaba-nacos-config 在加载配置的时候,不仅仅加载了以 dataid 为 ${spring.application.name}.${file-extension:properties}
为前缀的基础配置,还加载了dataid为 ${spring.application.name}-${profile}.${file-extension:properties}
的基础配置。在日常开发中如果遇到多套环境下的不同配置,可以通过Spring 提供的 ${spring.profiles.active}
这个配置项来配置
spring.profiles.active=develop
【注】${spring.profiles.active}
当通过配置文件来指定时必须放在 bootstrap.properties
文件中
在没有明确指定 ${spring.cloud.nacos.config.group}
配置的情况下, 默认使用的是 DEFAULT_GROUP 。如果需要自定义自己的 Group,可以通过以下配置来实现
spring.cloud.nacos.config.group=DEVELOP_GROUP
【注】该配置必须放在 bootstrap.properties
文件中。并且在添加配置时 Group 的值一定要和 spring.cloud.nacos.config.group
的配置值一致
Spring Cloud Alibaba Nacos Config 从 0.2.1 版本后,可支持自定义 Data Id 的配置
spring.application.name=opensource-service-provider
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# config external configuration
# 1、Data Id 在默认的组 DEFAULT_GROUP,不支持配置的动态刷新
spring.cloud.nacos.config.extension-configs[0].data-id=ext-config-common01.properties
# 2、Data Id 不在默认的组,不支持动态刷新
spring.cloud.nacos.config.extension-configs[1].data-id=ext-config-common02.properties
spring.cloud.nacos.config.extension-configs[1].group=GLOBALE_GROUP
# 3、Data Id 既不在默认的组,也支持动态刷新
spring.cloud.nacos.config.extension-configs[2].data-id=ext-config-common03.properties
spring.cloud.nacos.config.extension-configs[2].group=REFRESH_GROUP
spring.cloud.nacos.config.extension-configs[2].refresh=true
spring.cloud.nacos.config.extension-configs[n].data-id
的配置方式来支持多个 Data Id 的配置spring.cloud.nacos.config.extension-configs[n].group
的配置方式自定义 Data Id 所在的组,不明确配置的话,默认是 DEFAULT_GROUPspring.cloud.nacos.config.extension-configs[n].refresh
的配置方式来控制该 Data Id 在配置变更时,是否支持应用中可动态刷新, 感知到最新的配置值。默认是不支持的【注】
多个 Data Id 同时配置时,他的优先级关系是 spring.cloud.nacos.config.extension-configs[n].data-id
其中 n 的值越大,优先级越高
spring.cloud.nacos.config.extension-configs[n].data-id
的值必须带文件扩展名,文件扩展名既可支持 properties
,又可以支持 yaml/yml
。 此时 spring.cloud.nacos.config.file-extension
的配置对自定义扩展配置的 Data Id 文件扩展名没有影响
通过自定义扩展的 Data Id 配置,既可以解决多个应用间配置共享的问题,又可以支持一个应用有多个配置文件
为了更加清晰的在多个应用间配置共享的 Data Id ,你可以通过以下的方式来配置:
# 配置支持共享的 Data Id
spring.cloud.nacos.config.shared-configs[0].data-id=common.yaml
# 配置 Data Id 所在分组,缺省默认 DEFAULT_GROUP
spring.cloud.nacos.config.shared-configs[0].group=GROUP_APP1
# 配置Data Id 在配置变更时,是否动态刷新,缺省默认 false
spring.cloud.nacos.config.shared-configs[0].refresh=true
spring.cloud.nacos.config.shared-configs[n].data-id
来支持多个共享 Data Id 的配置spring.cloud.nacos.config.shared-configs[n].group
来配置自定义 Data Id 所在的组,不明确配置的话,默认是 DEFAULT_GROUPspring.cloud.nacos.config.shared-configs[n].refresh
来控制该Data Id在配置变更时,是否支持应用中动态刷新,默认falseSpring Cloud Alibaba Nacos Config 目前提供了三种配置能力从 Nacos 拉取相关的配置
spring.cloud.nacos.config.shared-configs[n].data-id
支持多个共享 Data Id 的配置spring.cloud.nacos.config.extension-configs[n].data-id
的方式支持多个扩展 Data Id 的配置当三种方式共同使用时,他们的一个优先级关系是:A < B < C
application.yml
server:
port: 8004
spring:
profiles:
active: dev
# 在配置中心,可以通过profile进行设置
# 只有默认的配置文件才能结合profile进行使用
# 对应的 DataId:${spring.application.name}-${profile}.${file-extension:properties}
# profile的后缀必须跟随默认配置文件的格式来
bootstrap.yml
spring:
application:
# 会自动根据服务名获取DataId对应的配置文件 如果DataId跟服务名不一致 就需要手动指定DataId
# 跟服务名相同的DataId的配置文件,称之为默认的配置文件
# 除了默认的配置文件,其它配置文件必须写上后缀
name: com.vinjcent.provider
cloud:
nacos:
# 配置Nacos服务地址
server-addr: 192.168.159.100:7070
username: nacos
password: nacos
# 配置Nacos配置中心
config:
# 关闭动态刷新,客户端将无法感知配置的变化 (一般不需要配置)
#refresh-enabled: false
# 支持自定义 namespace 的配置,默认是public (根据Nacos配置中心中的命名空间ID修改)
namespace: dd3358a9-058e-47d7-8470-7decd2b0c639
# Nacos客户端 默认是properties的文件扩展名,只针对默认配置文件和profile
file-extension: yaml
# 默认是DEFAULT_GROUP
# group: DEFAULT_GROUP
shared-configs:
- dataId: com.vinjcent.provider.properties # 下标[0]
refresh: true
# 默认为group: DEFAULT_GROUP
- dataId: com.vinjcent.provider02.properties # 下标[1]
refresh: true
extension-configs[0]:
dataId: com.vinjcent.provider03.properties
refresh: true
# 配置文件的优先级 (优先级大的会覆盖优先级小的,并且会形成互补)
# profile > 配置文件 > extension-configs(相同情况下,下标越大,优先级越大) >shared-configs (相同情况下,下标越大,优先级越大)
public环境
dev环境
<dependencies>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
@RestController
@RequestMapping("/dept")
public class DeptController {
@Value("${user.username}")
private String username;
@RequestMapping("/show")
public String show() {
return username;
}
}
启动主启动类
访问http://localhost:8004/dept/show
修改Nacos配置中心对应的文件属性字段user.username
再次访问http://localhost:8004/dept/show
可以看到服务并没有实现配置和实例刷新的
@RefreshScope
@RestController
@RequestMapping("/dept")
@RefreshScope
public class DeptController {
@Value("${user.username}")
private String username;
@RequestMapping("/show")
public String show() {
return username;
}
}