配置中心环境介绍:
数据发布/订阅即所谓的配置中心:发布者将数据发布到ZooKeeper一系列节点上面,订阅者进行数据订阅,当数据有变化时,可以及时得到数据的变化通知,达到动态及时获取数据的目的
现在项目中有两个提供者,配置了相同的数据源,如果此时要修改数据源,必须同时修改两个才可以。
我们将数据源中需要的配置信息配置存储在zookeeper中,如果修改数据源配置,使用zookeeper的watch机制,同时对提供者的数据源信息更新。
实现配置中心:
1、在zookeeper中创建所需节点和节点所对应的数据
/config/jdbc.driver
/config/jdbc.url
/config/jdbc.user
/config/jdbc.password
2、在dubbo-common下创建工具类SettingCenterUtil
在zookeeper中创建所需节点和节点所对应的数据
注意:这里是改成自己自己对于的数据库信息
create /config jdbcConfig
create /config/jdbc.url "jdbc:mysql:///test"
create /config/jdbc.driver "com.mysql.jdbc.Driver"
create /config/jdbc.user "root"
create /config/jdbc.password "123"
SettingCenterUtil具体实现:
(1)在dubbo-common创建工具类SettingCenterUtil
(2)SettingCenterUtil具体实现
package com.shenwang.utils;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.TreeCache;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.AbstractApplicationContext;
import java.util.Properties;
/**
* @author: shenwang
* Date: 2021/7/2
*/
public class SettingCenterUtil extends PropertyPlaceholderConfigurer implements ApplicationContextAware {
private AbstractApplicationContext applicationContext;
/**
* 读取zookeeper中数据库配置
* @param properties
*/
private void loadZk(Properties properties){
//连接字符串 host:port
String connectionString="192.168.59.128:2181";
//会话超出时间
int sessionTimeoutMs=1000;
//连接超出时间
int connectionTimeoutMs=1000;
//创建重试策略
RetryPolicy retryPolicy =new ExponentialBackoffRetry(1000,1);
//创建客户端
CuratorFramework client= CuratorFrameworkFactory.newClient(connectionString,sessionTimeoutMs,connectionTimeoutMs,retryPolicy);
//启动客户端
client.start();
try {
String driver= new String(client.getData().forPath("/config/jdbc.driver"));
String url=new String(client.getData().forPath("config/jdbc.url"));
String user=new String(client.getData().forPath("config/jdbc.user"));
String password=new String(client.getData().forPath("config/jdbc.password"));
//设置数据库的配置
properties.setProperty("jdbc.driver",driver);
properties.setProperty("jdbc.url",url);
properties.setProperty("jdbc.user",user);
properties.setProperty("jdbc.password",password);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 处理properties内容,相当于标签:
* <context:property-placeholder location="classpath:database.properties"/>
* @param beanFactoryToProcess
* @param props
* @throws BeansException
*/
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException {
//载入zookeeper信息,即从Zookeeper中获取数据源连接信息
loadZk(props);
addWatch(props);
super.processProperties(beanFactoryToProcess, props);
}
/**
* 添加对zookeeper中对数据库配置的监听
* @param properties
*/
public void addWatch(Properties properties){
//连接字符串 host:port
String connectionString="192.168.59.128:2181";
//会话超出时间
int sessionTimeoutMs=1000;
//连接超出时间
int connectionTimeoutMs=1000;
//创建重试策略
RetryPolicy retryPolicy =new ExponentialBackoffRetry(1000,1);
//创建客户端
CuratorFramework client= CuratorFrameworkFactory.newClient(connectionString,sessionTimeoutMs,connectionTimeoutMs,retryPolicy);
//启动客户端
client.start();
TreeCache treeCache = new TreeCache(client,"/config");
try {
treeCache.start();
//添加监听
treeCache.getListenable().addListener(new TreeCacheListener() {
@Override
public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {
if(treeCacheEvent.getType() == TreeCacheEvent.Type.NODE_UPDATED){
// 如果是jdbc.url的值变更
if(treeCacheEvent.getData().getPath().equals("/config/jdbc.url")){
properties.setProperty("jdbc.url",new String(treeCacheEvent.getData().getData()));
}else if(treeCacheEvent.getData().getPath().equals("/config/jdbc.driver")){
// 如果 jdbc.driver变更
properties.setProperty("jdbc.driver",new String(treeCacheEvent.getData().getData()));
}else if(treeCacheEvent.getData().getPath().equals("/config/jdbc.user")){
// 用户名修改了
properties.setProperty("jdbc.user",new String(treeCacheEvent.getData().getData()));
}else if(treeCacheEvent.getData().getPath().equals("/config/jdbc.password")){
// 密码修改了
properties.setProperty("jdbc.password",new String(treeCacheEvent.getData().getData()));
}
// 刷新spring容器
applicationContext.refresh();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获得spring容器
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext=(AbstractApplicationContext)applicationContext;
}
}
上面代码的具体实现步骤小结:
1、修改数据源,读取zookeeper中数据源所需配置数据
(1)在dubbo-common创建工具类 :SettingCenterUtil,继承PropertyPlaceholderConfigurer
(2)编写载入zookeeper中配置文件,传递到Properties属性中
(3)重写processProperties方法
2、配置监听
(1)添加监听
(2)获取容器对象,刷新spring容器:SettingCenterUtil,实现ApplicationContextAware
修改spring-dao.xml文件:
(1)将标签<context:property-placeholder location="classpath:database.properties"/>注释
(2)添加SettingCenterUtil的引用
<!--<context:property-placeholder location="classpath:database.properties"/>-->
<!--创建配置中心对象-->
<bean class="com.shenwang.utils.SettingCenterUtil"/>
最后我们的dubbo配置中心就弄完啦~
当然本文章的dubbo配置中心是基于ssm集成zookeeper+dubbo的哦
如果不知道ssm集成zookeeper+dubbo的小伙伴可以看我上一篇博客呀 嘿嘿
链接:https://blog.csdn.net/gloamer/article/details/118354272?spm=1001.2014.3001.5501