zoukankan      html  css  js  c++  java
  • Zookeeper发布订阅之SpringBoot+Mybatis多数据源

       1.前言

       数据发布/订阅系统,即所谓的配置中心,顾名思义就是发布者将数据发布到Zookeeper的一个或一系列节点上,供订阅者进行数据订阅,进而达到动态获取数据的目的,实现配置信息的集中管理和数据的动态更新。

              发布订阅一般有两种模式,分别是推(Push)和拉(Pull)模式。在推拉模式中,服务端主动将数据更新发送给所有订阅的客户端;而拉模式则是客户端主动发起请求来获取最新数据。Zookeeper采取推和拉相结合的方式:客户端会向相应的客户端发送Watcher事件通知,客户端接收到这个消息通知后,需要主动到服务端获取最新的数据。

         “配置管理”的实际案例来展示Zookeeper在"数据发布/订阅"场景下的使用方式。

       2.案例

               将敏感的配置信息存放与Zookeeper中。启动项目时,自动从Zookeeper中获取。

              Maven坐标:

          

     1  <dependency>
     2             <groupId>org.springframework.boot</groupId>
     3             <artifactId>spring-boot-starter-web</artifactId>
     4         </dependency>
     5         <dependency>
     6             <groupId>org.springframework.boot</groupId>
     7             <artifactId>spring-boot-starter-jdbc</artifactId>
     8         </dependency>
     9         <dependency>
    10             <groupId>org.projectlombok</groupId>
    11             <artifactId>lombok</artifactId>
    12             <optional>true</optional>
    13         </dependency>
    14         <dependency>
    15             <groupId>org.apache.zookeeper</groupId>
    16             <artifactId>zookeeper</artifactId>
    17             <version>3.4.10</version>
    18         </dependency>
    19         <dependency>
    20             <groupId>org.apache.curator</groupId>
    21             <artifactId>curator-framework</artifactId>
    22             <version>2.9.0</version>
    23         </dependency>
    24         <dependency>
    25             <groupId>org.apache.curator</groupId>
    26             <artifactId>curator-recipes</artifactId>
    27             <version>2.9.0</version>
    28         </dependency>
    29         <dependency>
    30             <groupId>org.mybatis</groupId>
    31             <artifactId>mybatis</artifactId>
    32             <version>3.4.3</version>
    33         </dependency>
    34         <dependency>
    35             <groupId>org.mybatis</groupId>
    36             <artifactId>mybatis-spring</artifactId>
    37             <version>1.3.1</version>
    38         </dependency>
    39         <dependency>
    40             <groupId>mysql</groupId>
    41             <artifactId>mysql-connector-java</artifactId>
    42         </dependency>
    43         <dependency>
    44             <groupId>com.zaxxer</groupId>
    45             <artifactId>HikariCP</artifactId>
    46             <version>2.7.4</version>
    47         </dependency>
    48         <dependency>
    49             <groupId>org.springframework.boot</groupId>
    50             <artifactId>spring-boot-starter-test</artifactId>
    51             <scope>test</scope>
    52         </dependency>

             自动从Zookeeper中获取”配置信息“,并放入Enviroment中

                 配置ApplicationContextInitializer,项目在启动先调用该类,进行加载环境变量到Enviroment中去(这里采用在classpath路径下新建META-INF/spring.factories文件方式,其它两种方式为:

        1.使用SpringApplication 对象,调用 addInitializers()

        2.在配置文件中配置 context.initializer.classes =xx)

                   spring.factories文件

         

    1 # Initializers
    2 org.springframework.context.ApplicationContextInitializer=
    3 com.example.zkconfig.config.GlobalConfigInit

         

    GlobalConfigIn类进行一系列配置文件加载及Zk连接,我用的Curator框架

    我的application.properties此刻内容
    server.port=8076
    #zk 配置信息
    com.unconfig.info=/config/zk-config

     application-dev 则对应具体连接机器

    #zk
    com.zookeeper.url=zk://192.168.159.129:2181

     从zk取配置信息放入spring环境

     1 @Slf4j
     2 public class GlobalConfigInit implements ApplicationContextInitializer<ConfigurableApplicationContext> {
     3 
     4     @Override
     5     public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
     6         ConfigurableEnvironment environment = configurableApplicationContext.getEnvironment();
     7         String zkUri = environment.getProperty("com.zookeeper.url");
     8         if (null == zkUri) {
     9             log.warn("could not find zk uri,unconf not configured..");
    10         } else {
    11             ZookeeperUtils zookeeperUtils = new ZookeeperUtils();
    12             zookeeperUtils.setZkUri(zkUri);
    13             String unconf = environment.getProperty("com.unconfig.info");
    14             if (null != unconf) {
    15                 log.info("config uniconf .. {}", unconf);
    16                 ZkPropertySource propertySource = new ZkPropertySource("default", zookeeperUtils.getEnv(unconf));
    17                 environment.getPropertySources().addLast(propertySource);
    18             } else {
    19                 log.warn("unconf not configured..");
    20             }
    21         }
    22     }
    23 
    24     public String getEnv(Environment environment) {
    25         String zkUrl = environment.getProperty("com.zookeeper.url");
    26         if (null != zkUrl && !zkUrl.isEmpty()) {
    27             return zkUrl;
    28         } else {
    29             String unConfig = environment.getProperty("com.unconfig.info");
    30             if (unConfig != null && !unConfig.isEmpty()) {
    31                 ZookeeperURI parse = ZookeeperURI.parse(unConfig);
    32                 String inferZkUrl = "zk://" + parse.getServers();
    33                 System.setProperty("com.zookeeper.url", inferZkUrl);
    34                 log.info("inferred zk uri from unconf zk {}", inferZkUrl);
    35                 return inferZkUrl;
    36             } else {
    37                 return null;
    38             }
    39         }
    40     }
    41 }

         这里不再多说,接下来配置数据源。

      

     1 @Configuration
     2 @MapperScan(basePackages = {"com.example.zkconfig.dao.write"}, sqlSessionFactoryRef = "writeSqlSessionFactory")
     3 public class WriteDataSourceConfig {
     4 
     5     @Value("${write.datasource.mappers}")
     6     private String location;
     7 
     8     @Bean(name = "writeDataSource")
     9     @ConfigurationProperties(prefix = "write.datasource")
    10     public DataSource dataSource() {
    11         return DataSourceBuilder.create().type(HikariDataSource.class).build();
    12     }
    13 
    14     @Bean(name = "writeSqlSessionFactory")
    15     public SqlSessionFactory writeSqlSessionFactory(@Qualifier("writeDataSource") DataSource dataSource) throws Exception {
    16         SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
    17         sqlSessionFactoryBean.setDataSource(dataSource);
    18         sqlSessionFactoryBean.setMapperLocations(
    19                 new PathMatchingResourcePatternResolver().getResources(location));
    20         return sqlSessionFactoryBean.getObject();
    21     }
    22 
    23     @Bean(name = "writeTransactionManager")
    24     public DataSourceTransactionManager writeTransactionManager(@Qualifier("writeDataSource") DataSource dataSource) {
    25         return new DataSourceTransactionManager(dataSource);
    26     }
    27 }

          而我实际在zookeeper节点配置的数据

      

        

    测试走一波,启动成功。

  • 相关阅读:
    DbContext 和ObjectContext两者的区别
    程序员的四大境界
    使用Entity Framework 4进行代码优先开发 转
    转 .Net 中的序列化与反序列化
    关于asp使用CreateObject("Excel.Application")出现无法创建ActiveX对象的错误
    内存泄漏的方法
    用Entities Framework实现代码优先和依赖注入所遇到的问题总结
    SQL去掉前面的0
    关于SVN限制填写备注和自动更新代码到网站的研究
    也许是离开的时候啦。
  • 原文地址:https://www.cnblogs.com/coding400/p/9333558.html
Copyright © 2011-2022 走看看