一、nacos作为配置中心介绍
1.nacos不仅可以用作服务发现,同时也是微服务框架中配置管理中心。每个服务都有一堆属于自己的配置,例如:数据库、redis、分布式中间件,这些配置其实相同的内容只需要维护一份就行了,而且如果其中的某些属性发生了变化,每个微服务都需要进行修改,所以配置中心集中管理微服务配置尤为重要。
二、配置中心使用
1.引入nacos配置中心依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2.创建bootstrap.properties文件
# 配置中心地址
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
springcloud默认加载名称为bootstrap.properties的配置文件,我们将配置中心的地址配置后,再指定需要加载的配置文件,服务启动时就会从nacos服务端拉取对应配置信息。
三、配置动态刷新
@Value("${common.age}")
private String age;
@Value("${common.name}")
private String name;
1.可以使用@Value注解来引用配置,但是如果修改了配置,这个bean中的配置将不会修改,如果想让bean中的属性同步修改需要再添加一个属性 @RefreshScope。
问题: @RefreshScope引入这个注解,则标注了这个bean的作用范围就是@Scope(“refresh”),它不同于单例Bean存在与单例池也不同于原型bean,每次使用时都新生成。这个范围的bean在创建后会存在于BeanLifecycleWrapperCache这个缓存。当配置发生修改后会调用RefreshScope#refreshAll() 进行缓存清理,新生成bean中就有了新属性值,如果在这个bean中使用@Scheduled定义了定时任务那么这个任务就会失效,需要主动调用一下这个bean才会触发定时任务。推荐一下用法
@RestController
@RefreshScope //动态感知修改后的值
public class TestController implements ApplicationListener<RefreshScopeRefreshedEvent>{
@Value("${common.age}")
String age;
@Value("${common.name}")
String name;
@GetMapping("/common")
public String hello() {
return name+","+age;
}
//触发@RefreshScope执行逻辑会导致@Scheduled定时任务失效
@Scheduled(cron = "*/3 * * * * ?") //定时任务每隔3s执行一次
public void execute() {
System.out.println("定时任务正常执行。。。。。。");
}
@Override
public void onApplicationEvent(RefreshScopeRefreshedEvent event) {
this.execute();
}
}
通过监听事件的方式可以使定时任务不失效,因为在清除缓存bean时就会发布一个对应的监听事件,此时调用这个方法又会重新生成bean.
四、客户端拉取配置和服务端推送配置流程
客户端有定时轮询拉取机制,服务端有主动推动机制。实现了配置的变化的快速更新。
五、事件监听机制和发布订阅机制区别
事件监听机制有以下角色:(用spring中的举例)
1.ApplicationEventPublisher 事件发布者(真正发布事件借助事件多播器)
2.ApplicationEventMulticaster 事件多播器(事件监听器注册在事件多播器上)
3.ApplicationListener 事件监听器
4.ApplicationEvent 事件
事件监听机制:事件多播器来发布事件,根据事件类型找到对应事件的监听器,调用监听器的onApplicationEvent方法。
发布订阅角色: (用nacos中的举例)
1.NotifyCenter 事件通知中心(借助事件发布者发布事件)
2.Event 事件
3.EventPublisher 事件发布者(事件订阅者注册在发布者上面)
4.Subscriber 事件订阅者
发布订阅机制:事件发布者发布事件将事件放入阻塞队列,事件发布者根据事件类型找到对应事件的订阅者,从阻塞队列获取事件调用订阅者的onEvent方法