分布式配置中心

在微服务架构中,为什么需要一个统一的配置中心呢?如果用一句话来说那就是方便管理,降低出错的可能。比如:你开发环境是一套配置,测试环境是一套,生产环境又是一套。你如果手动去修改,难免会出错吧。

Nacos

阿里开源的产品,可以作为配置中心,也可以代替Zookeeper作为服务注册中心。

正题

为了方便,我在本地建立三个不同的数据库,分别代表开发环境、测试环境、生产环境的数据库。

--

新建一个Springboot工程,修改pom文件,引入相关依赖

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.1.3.RELEASE</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.example</groupId>
  12. <artifactId>demo</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>demo</name>
  15. <description>Demo project for Spring Boot</description>
  16.  
  17. <properties>
  18. <java.version>1.8</java.version>
  19. <mysql.version>5.1.47</mysql.version>
  20. <druid.version>1.1.15</druid.version>
  21. </properties>
  22.  
  23. <dependencies>
  24. <dependency>
  25. <groupId>org.springframework.boot</groupId>
  26. <artifactId>spring-boot-starter-web</artifactId>
  27. </dependency>
  28. <dependency>
  29. <groupId>com.alibaba.boot</groupId>
  30. <artifactId>nacos-config-spring-boot-starter</artifactId>
  31. <version>0.2.1</version>
  32. </dependency>
  33. <dependency>
  34. <groupId>org.mybatis.spring.boot</groupId>
  35. <artifactId>mybatis-spring-boot-starter</artifactId>
  36. <version>2.0.0</version>
  37. </dependency>
  38.  
  39. <dependency>
  40. <groupId>mysql</groupId>
  41. <artifactId>mysql-connector-java</artifactId>
  42. <version>${mysql.version}</version>
  43. </dependency>
  44. <dependency>
  45. <groupId>com.alibaba</groupId>
  46. <artifactId>druid</artifactId>
  47. <version>${druid.version}</version>
  48. </dependency>
  49.  
  50. <dependency>
  51. <groupId>org.springframework.boot</groupId>
  52. <artifactId>spring-boot-devtools</artifactId>
  53. <scope>runtime</scope>
  54. </dependency>
  55. <dependency>
  56. <groupId>org.projectlombok</groupId>
  57. <artifactId>lombok</artifactId>
  58. <optional>true</optional>
  59. </dependency>
  60. <dependency>
  61. <groupId>org.springframework.boot</groupId>
  62. <artifactId>spring-boot-starter-test</artifactId>
  63. <scope>test</scope>
  64. </dependency>
  65. </dependencies>
  66.  
  67. <build>
  68. <plugins>
  69. <plugin>
  70. <groupId>org.springframework.boot</groupId>
  71. <artifactId>spring-boot-maven-plugin</artifactId>
  72. </plugin>
  73. <plugin>
  74. <groupId>org.apache.maven.plugins</groupId>
  75. <artifactId>maven-compiler-plugin</artifactId>
  76. <version>3.7.0</version>
  77. <configuration>
  78. <source>1.8</source>
  79. <target>1.8</target>
  80. <encoding>UTF-8</encoding>
  81. </configuration>
  82. </plugin>
  83. <plugin>
  84. <groupId>org.mybatis.generator</groupId>
  85. <artifactId>mybatis-generator-maven-plugin</artifactId>
  86. <version>1.3.7</version>
  87. <configuration>
  88. <verbose>true</verbose>
  89. <overwrite>true</overwrite>
  90. </configuration>
  91. <executions>
  92. <execution>
  93. <id>mybatis-generator</id>
  94. <goals>
  95. <goal>generate</goal>
  96. </goals>
  97. </execution>
  98. </executions>
  99. <dependencies>
  100. <dependency>
  101. <groupId>mysql</groupId>
  102. <artifactId>mysql-connector-java</artifactId>
  103. <version>${mysql.version}</version>
  104. </dependency>
  105. </dependencies>
  106. </plugin>
  107. </plugins>
  108. </build>
  109.  
  110. <profiles>
  111. <profile>
  112. <id>dev</id>
  113. <properties>
  114. <spring.profiles>dev</spring.profiles>
  115. </properties>
  116. <activation>
  117. <activeByDefault>true</activeByDefault>
  118. </activation>
  119. </profile>
  120. <profile>
  121. <id>test</id>
  122. <properties>
  123. <spring.profiles>test</spring.profiles>
  124. </properties>
  125. </profile>
  126. <profile>
  127. <id>pro</id>
  128. <properties>
  129. <spring.profiles>pro</spring.profiles>
  130. </properties>
  131. </profile>
  132. </profiles>
  133.  
  134. </project>

先来看一下最终目录结构:

generatorConfig.xml是用来自动生成Mapper文件的,logback是用来生成日志的,config包里面是读取nocas上面的配置的,其他都是简单的东西。

-------------------------------------------

generatorConfig.xml

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
  3.  
  4. <generatorConfiguration>
  5. <context id="context1">
  6.  
  7. <!-- 这里引入扩展插件 -->
  8. <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/>
  9.  
  10. <commentGenerator>
  11. <!-- 关闭自动生成的注释 -->
  12. <property name="suppressAllComments" value="true"/>
  13. </commentGenerator>
  14.  
  15. <jdbcConnection driverClass="com.mysql.jdbc.Driver"
  16. connectionURL="jdbc:mysql://localhost:3306/mytest?useSSL=false"
  17. userId="root"
  18. password="1234"/>
  19. <javaModelGenerator targetPackage="com.example.demo.model"
  20. targetProject="src/main/java" />
  21. <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources" />
  22. <javaClientGenerator targetPackage="com.example.demo.dao"
  23. targetProject="src/main/java" type="XMLMAPPER" />
  24.  
  25. <!--数据库的表名-->
  26. <table tableName="user">
  27. <generatedKey column="id" sqlStatement="MySql" identity="true" />
  28. </table>
  29.  
  30. </context>
  31. </generatorConfiguration>

在这里双击运行即可生成需要的java类。

选择这里可以切换环境

logback-spring.xml

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <configuration scan="true" scanPeriod="60 seconds">
  3. <springProperty scope="context" name="LOG_HOME" source="logging.path"/>
  4.  
  5. <springProfile name="dev,test,pro">
  6. <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
  7. <property name="log_pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger Line:%-3L - %msg%n"/>
  8. </springProfile>
  9.  
  10. <appender name="app" class="ch.qos.logback.core.rolling.RollingFileAppender">
  11. <File>${LOG_HOME}/app.log</File>
  12. <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
  13. <pattern>${log_pattern}</pattern>
  14. </encoder>
  15. <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
  16. <level>INFO</level>
  17. </filter>
  18. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  19. <FileNamePattern>${LOG_HOME}/app.%d{yyyy-MM-dd}.log</FileNamePattern>
  20. <!--日志文件保留天数 -->
  21. <MaxHistory>30</MaxHistory>
  22. </rollingPolicy>
  23. </appender>
  24.  
  25. <appender name="app-error" class="ch.qos.logback.core.rolling.RollingFileAppender">
  26. <File>${LOG_HOME}/app_error.log</File>
  27. <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
  28. <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] [%-5level] [%logger:%L] %msg [TxId:%X{PtxId},SpanId:%X{PspanId}]%n</pattern>
  29. </encoder>
  30. <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
  31. <level>ERROR</level>
  32. </filter>
  33. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  34. <FileNamePattern>${LOG_HOME}/app_error.%d{yyyy-MM-dd}.log</FileNamePattern>
  35. </rollingPolicy>
  36. </appender>
  37.  
  38. <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
  39. <encoder>
  40. <outputPatternAsHeader>true</outputPatternAsHeader>
  41. <pattern>%black(%d{yyyy-MM-dd HH:mm:ss}) %highlight(%-6level) %black([%thread]) %boldCyan(%logger) %boldMagenta(#%method %-3L) : %black(%msg%n)</pattern>
  42. </encoder>
  43. </appender>
  44.  
  45. <!-- 开发环境 -->
  46. <springProfile name="dev">
  47. <logger name="org" level="INFO"/>
  48. <!-- level: FATAL,ERROR,WARN,INFO,DEBUG,TRACE -->
  49. <root level="DEBUG">
  50. <appender-ref ref="CONSOLE"/>
  51. <appender-ref ref="app"/>
  52. <appender-ref ref="app-error"/>
  53. </root>
  54. </springProfile>
  55.  
  56. <!-- 测试&生产环境 -->
  57. <springProfile name="test,pro">
  58. <logger name="org" level="INFO"/>
  59. <root level="INFO">
  60. <appender-ref ref="app"/>
  61. <appender-ref ref="app-error"/>
  62. </root>
  63. </springProfile>
  64. </configuration>

application.yml

  1. spring:
  2. profiles:
  3. active: @spring.profiles@
  4. logging:
  5. config: classpath:logback-spring.xml

下面打开nacos,做一下不同环境的配置

新建三个命名空间,之后进入配置管理页面,可以看到多了三个页签。

在每一个页签下添加我们需要的配置即可。(注意不同环境的数据库不一样)

  1. url=jdbc:mysql://localhost:3306/mytest_pro?useSSL=false&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true
  2. user_name=root
  3. password=1234
  4. driver_class_name=com.mysql.jdbc.Driver

不同的命名空间有不同的命名空间ID,这个有用,我们下一步会用到

属性文件的namespace填写对应的命名空间ID

application-dev.yml

  1. server:
  2. port: 8080
  3. address: 0.0.0.0
  4. nacos:
  5. config:
  6. server-addr: localhost:8848
  7. namespace: 0d5b0e7c-485c-469b-9b3c-eb20dc9d9bb1
  8. logging:
  9. path: "./logs"

application-test.yml

  1. server:
  2. port: 8080
  3. address: 0.0.0.0
  4. nacos:
  5. config:
  6. server-addr: localhost:8848
  7. namespace: b49147ed-72de-45e9-8d90-34644585a000
  8. logging:
  9. path: /AppLogs/boot-nacos-test

application-pro.yml

  1. server:
  2. port: 8080
  3. address: 0.0.0.0
  4. nacos:
  5. config:
  6. server-addr: localhost:8848
  7. namespace: 5fb0883c-2db7-4344-9883-0394edb5c858
  8. logging:
  9. path: /AppLogs/boot-nacos

DatabaseConfig

  1. package com.example.demo.config;
  2.  
  3. import com.alibaba.nacos.api.config.annotation.NacosValue;
  4. import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
  5. import org.springframework.stereotype.Component;
  6.  
  7. @Component
  8. @NacosPropertySource(dataId = "database",groupId = "DEFAULT_GROUP",autoRefreshed = true)
  9. public class DatabaseConfig {
  10.  
  11. @NacosValue(value = "${driver_class_name}", autoRefreshed = true)
  12. private String driverClassName;
  13.  
  14. @NacosValue(value = "${url}", autoRefreshed = true)
  15. private String url;
  16.  
  17. @NacosValue(value = "${user_name}", autoRefreshed = true)
  18. private String username;
  19.  
  20. @NacosValue(value = "${password}", autoRefreshed = true)
  21. private String password;
  22.  
  23. public String getDriverClassName() {
  24. return driverClassName;
  25. }
  26.  
  27. public String getUrl() {
  28. return url;
  29. }
  30.  
  31. public String getUsername() {
  32. return username;
  33. }
  34.  
  35. public String getPassword() {
  36. return password;
  37. }
  38.  
  39. }

MybatisConfiguration

  1. package com.example.demo.config;
  2.  
  3. import com.alibaba.druid.pool.DruidDataSource;
  4. import org.apache.ibatis.session.SqlSessionFactory;
  5. import org.mybatis.spring.SqlSessionFactoryBean;
  6. import org.mybatis.spring.annotation.MapperScan;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.context.annotation.Bean;
  9. import org.springframework.context.annotation.Configuration;
  10. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  11. import org.springframework.core.io.support.ResourcePatternResolver;
  12.  
  13. import javax.sql.DataSource;
  14.  
  15. @Configuration
  16. @MapperScan(basePackages={"com.example.demo.dao"})
  17. public class MybatisConfiguration {
  18. @Autowired
  19. private DatabaseConfig dataBaseConfig;
  20.  
  21. @Bean
  22. public DataSource dataSource() {
  23. DruidDataSource dataSource = new DruidDataSource();
  24. dataSource.setDriverClassName(dataBaseConfig.getDriverClassName());
  25. dataSource.setUrl(dataBaseConfig.getUrl());
  26. dataSource.setUsername(dataBaseConfig.getUsername());
  27. dataSource.setPassword(dataBaseConfig.getPassword());
  28. return dataSource;
  29. }
  30.  
  31. @Bean
  32. public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
  33.  
  34. SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
  35. sqlSessionFactoryBean.setDataSource(dataSource());
  36. ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
  37. sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
  38.  
  39. return sqlSessionFactoryBean.getObject();
  40. }
  41.  
  42. }

UserService

  1. package com.example.demo.service;
  2.  
  3. import com.example.demo.model.User;
  4.  
  5. import java.util.List;
  6.  
  7. public interface UserService {
  8.  
  9. List<User> getUserList();
  10. }

UserServiceImpl

  1. package com.example.demo.service.impl;
  2.  
  3. import com.example.demo.dao.UserMapper;
  4. import com.example.demo.model.User;
  5. import com.example.demo.model.UserExample;
  6. import com.example.demo.service.UserService;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.stereotype.Service;
  9.  
  10. import java.util.List;
  11.  
  12. @Service
  13. public class UserServiceImpl implements UserService {
  14.  
  15. @Autowired
  16. private UserMapper userMapper;
  17.  
  18. @Override
  19. public List<User> getUserList() {
  20. UserExample example = new UserExample();
  21. return userMapper.selectByExample(example);
  22. }
  23. }

UserController

  1. package com.example.demo.controller;
  2.  
  3. import com.example.demo.model.User;
  4. import com.example.demo.service.UserService;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RestController;
  8.  
  9. import java.util.List;
  10.  
  11. @RestController
  12. public class UserController {
  13.  
  14. @Autowired
  15. private UserService userService;
  16.  
  17. @RequestMapping("/users")
  18. public List<User> getUsers(){
  19. return userService.getUserList();
  20. }
  21. }

其它文件由generator负责生成。下面测试,我们先本地运行。

日志在项目根目录:

下面访问:

这个是开发环境的数据。现在我们切换到测试环境,重启。

日志在当前项目磁盘的根目录

访问:数据是测试环境的数据

最后切换生产环境。日志文件:

访问:

完整地址:GitHub

nacos作为配置中心的更多相关文章

  1. Nacos系列:基于Nacos的配置中心

    前言 在看正文之前,我想请你回顾一下自己待过的公司都是怎么管理配置的,我想应该会有以下几种方式: 1.硬编码 没有什么配置不配置的,直接写在代码里面,比如使用常量类 优势:对开发友好,开发清楚地知道代 ...

  2. Nacos(四):SpringCloud项目中接入Nacos作为配置中心

    前言 通过前两篇文章: Nacos(二):Nacos与OpenFeign的对接使用 Nacos(三):SpringCloud项目中接入Nacos作为注册中心 相信大家已经对Nacos作为注册中心的基本 ...

  3. java架构之路-(微服务专题)feign的基本使用和nacos的配置中心

    上次回归: 上次我们说了ribbon的基本使用,包括里面的内部算法,算法的细粒度配置,还有我们自己如何实现我们自己的算法,主要还是一些基本使用的知识,还不会使用ribbon的小伙伴可以回去看一下上一篇 ...

  4. nacos作为配置中心动态刷新@RefreshScope添加后取值为null的一个问题

    之前springboot项目常量类如下形式: @Component @RefreshScope//nacos配置中心时添加上 public class Constants { @Value(" ...

  5. Nacos作为配置中心时,多个服务共用一个dataId的配置

    写在前面 本文是对我之前一篇文章<Spring Cloud+nacos+Feign,实现注册中心及配置中心>的补充.此文章中简单写了如何将Nacos作为配置中心.在使用配置中心时,我们会遇 ...

  6. 程序员你是如何使用Nacos作为配置中心的?

    假如你使用的是spring-cloud-alibaba微服务技术栈 单个服务独有配置文件 即去除应用程序的状态,配置统一外部化管理,方便进行水平的伸缩. 集成步骤: 假如我有一个应用app-desig ...

  7. 使用nacos作为配置中心统一管理配置

    基础环境 引入所需依赖包 <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>s ...

  8. SpringBoot项目使用Nacos作为配置中心

    前置条件:jdk.SpringBoot项目.Nacos.Linux服务器(可无) 具体版本:jdk11.SpringBoot 2.3.5.RELEASE.Nacos 2.0.3.Centos 6 目标 ...

  9. Spring Cloud Alibaba基础教程:使用Nacos作为配置中心

    通过本教程的前两篇: <Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现> <Spring Cloud Alibaba基础教程:支持的几种服务消费方 ...

随机推荐

  1. 命令行操作mysql 未完待续......

    复制数据表 create table 新表 like 旧表: 删除表中某个字段 alter table 表名 drop column 字段; 例子: alter table news_apply_lo ...

  2. MySQL中SELECT语句简单使用

    最近开始复习mysql,查漏补缺吧. 关于mysql 1.MySQL不区分大小写,但是在MySQL 4.1及之前的版本中,数据库名.表名.列名这些标识符默认是区分大小写的:在之后的版本中默认不区分大小 ...

  3. 硬杠后端(后端坑系列)——Django前期工作

    Django是一个开放源代码的Web应用框架,由Python写成,采用了MVC的框架模式. MVC MVC是一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织代码,将业务逻辑聚集到一个部件 ...

  4. Git - git branch - 查看本地仓分支列表

    索引: 目录索引 参看代码 GitHub: git.txt 一.示例: git branch 二.说明: 该命令将列出本地所有存在分支, 包括 本地独有分支与远端在本地签出的分支, 但是没有签出的远端 ...

  5. 导入虚拟机vmware,此主机支持Intel VT-x,但Intel VT-x处于禁用状态和黑屏

    解决方法:进入BIOS(按什么键进入bios,需要看你用什么电脑),把Intel Virtualization Technology         设置enabled 然后是黑屏解决方法:管理员模式 ...

  6. python使用rabbitMQ介绍二(工作队列模式)

    一模式介绍 第一章节的生产-消费者模式,是非常简单的模式,一发一收.在实际的应用中,消费者有的时候需要工作较长的时间,则需要增加消费者. 队列模型: 这时mq实现了一下几个功能: rabbitmq循环 ...

  7. NPM -- 初探--01

    NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种: 允许用户从NPM服务器下载别人编写的第三方包到本地使用. 允许用户从NPM服务器下载并 ...

  8. mysql基本操作(1)

    1.mysql数据库客户端安装 brew install mysql-client 2.mysql 连接数据库 mysql -h <数据库地址> -P <端口> -u < ...

  9. Win7下emacs简单配置

    ;;win7下.emacs在C:\Users\用户名\AppData\Roaming目录下 在.emacs文件中添加 ;; cancel welcome page取消欢迎界面(setq inhibit ...

  10. centos修改默认启动级别

    Linux分为7个启动级别: 0 - 系统停机状态 1 - 单用户工作状态 2 - 多用户状态(没有NFS) 3 - 多用户状态(有NFS) 4 - 系统未使用,留给用户 5 - 图形界面 6 - 系 ...