zoukankan      html  css  js  c++  java
  • nacos作为配置中心

    分布式配置中心

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

    Nacos

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

    正题

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

    --

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

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.3.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.example</groupId>
        <artifactId>demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>demo</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
            <mysql.version>5.1.47</mysql.version>
            <druid.version>1.1.15</druid.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba.boot</groupId>
                <artifactId>nacos-config-spring-boot-starter</artifactId>
                <version>0.2.1</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.0.0</version>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.7.0</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.mybatis.generator</groupId>
                    <artifactId>mybatis-generator-maven-plugin</artifactId>
                    <version>1.3.7</version>
                    <configuration>
                        <verbose>true</verbose>
                        <overwrite>true</overwrite>
                    </configuration>
                    <executions>
                        <execution>
                            <id>mybatis-generator</id>
                            <goals>
                                <goal>generate</goal>
                            </goals>
                        </execution>
                    </executions>
                    <dependencies>
                        <dependency>
                            <groupId>mysql</groupId>
                            <artifactId>mysql-connector-java</artifactId>
                            <version>${mysql.version}</version>
                        </dependency>
                    </dependencies>
                </plugin>
            </plugins>
        </build>
    
        <profiles>
            <profile>
                <id>dev</id>
                <properties>
                    <spring.profiles>dev</spring.profiles>
                </properties>
                <activation>
                    <activeByDefault>true</activeByDefault>
                </activation>
            </profile>
            <profile>
                <id>test</id>
                <properties>
                    <spring.profiles>test</spring.profiles>
                </properties>
            </profile>
            <profile>
                <id>pro</id>
                <properties>
                    <spring.profiles>pro</spring.profiles>
                </properties>
            </profile>
        </profiles>
    
    </project>

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

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

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

     generatorConfig.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
    
    <generatorConfiguration>
        <context id="context1">
    
            <!-- 这里引入扩展插件 -->
            <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/>
    
            <commentGenerator>
                <!--  关闭自动生成的注释  -->
                <property name="suppressAllComments" value="true"/>
            </commentGenerator>
    
    
            <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                            connectionURL="jdbc:mysql://localhost:3306/mytest?useSSL=false"
                            userId="root"
                            password="1234"/>
            <javaModelGenerator targetPackage="com.example.demo.model"
                targetProject="src/main/java" />
            <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources" />
            <javaClientGenerator targetPackage="com.example.demo.dao"
                targetProject="src/main/java" type="XMLMAPPER" />
    
            <!--数据库的表名-->
            <table tableName="user">
                <generatedKey column="id" sqlStatement="MySql" identity="true" />
            </table>
    
           </context>
       </generatorConfiguration>

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

    选择这里可以切换环境

    logback-spring.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration scan="true" scanPeriod="60 seconds">
        <springProperty scope="context" name="LOG_HOME" source="logging.path"/>
        
        <springProfile name="dev,test,pro">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
            <property name="log_pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger Line:%-3L - %msg%n"/>
        </springProfile>
    
        <appender name="app" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <File>${LOG_HOME}/app.log</File>
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <pattern>${log_pattern}</pattern>
            </encoder>
            <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
                <level>INFO</level>
            </filter>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <FileNamePattern>${LOG_HOME}/app.%d{yyyy-MM-dd}.log</FileNamePattern>
                <!--日志文件保留天数 -->
                <MaxHistory>30</MaxHistory>
            </rollingPolicy>
        </appender>
    
        <appender name="app-error" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <File>${LOG_HOME}/app_error.log</File>
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] [%-5level] [%logger:%L] %msg [TxId:%X{PtxId},SpanId:%X{PspanId}]%n</pattern>
            </encoder>
            <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
                <level>ERROR</level>
            </filter>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <FileNamePattern>${LOG_HOME}/app_error.%d{yyyy-MM-dd}.log</FileNamePattern>
            </rollingPolicy>
        </appender>
    
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <outputPatternAsHeader>true</outputPatternAsHeader>
                <pattern>%black(%d{yyyy-MM-dd HH:mm:ss}) %highlight(%-6level) %black([%thread]) %boldCyan(%logger) %boldMagenta(#%method %-3L) : %black(%msg%n)</pattern>
            </encoder>
        </appender>
    
        <!-- 开发环境 -->
        <springProfile name="dev">
            <logger name="org" level="INFO"/>
            <!-- level: FATAL,ERROR,WARN,INFO,DEBUG,TRACE -->
            <root level="DEBUG">
                <appender-ref ref="CONSOLE"/>
                <appender-ref ref="app"/>
                <appender-ref ref="app-error"/>
            </root>
        </springProfile>
    
        <!-- 测试&生产环境 -->
        <springProfile name="test,pro">
            <logger name="org" level="INFO"/>
            <root level="INFO">
                <appender-ref ref="app"/>
                <appender-ref ref="app-error"/>
            </root>
        </springProfile>
    </configuration>

    application.yml

    spring:
      profiles:
        active: @spring.profiles@
    logging:
      config: classpath:logback-spring.xml

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

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

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

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

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

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

    application-dev.yml

    server:
      port: 8080
      address: 0.0.0.0
    nacos:
      config:
        server-addr: localhost:8848
        namespace: 0d5b0e7c-485c-469b-9b3c-eb20dc9d9bb1
    logging:
      path: "./logs"

    application-test.yml

    server:
      port: 8080
      address: 0.0.0.0
    nacos:
      config:
        server-addr: localhost:8848
        namespace: b49147ed-72de-45e9-8d90-34644585a000
    logging:
      path: /AppLogs/boot-nacos-test

    application-pro.yml

    server:
      port: 8080
      address: 0.0.0.0
    nacos:
      config:
        server-addr: localhost:8848
        namespace: 5fb0883c-2db7-4344-9883-0394edb5c858
    logging:
      path: /AppLogs/boot-nacos

     DatabaseConfig

    package com.example.demo.config;
    
    import com.alibaba.nacos.api.config.annotation.NacosValue;
    import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
    import org.springframework.stereotype.Component;
    
    
    @Component
    @NacosPropertySource(dataId = "database",groupId = "DEFAULT_GROUP",autoRefreshed = true)
    public class DatabaseConfig {
    
        @NacosValue(value = "${driver_class_name}", autoRefreshed = true)
        private String driverClassName;
    
        @NacosValue(value = "${url}", autoRefreshed = true)
        private String url;
    
        @NacosValue(value = "${user_name}", autoRefreshed = true)
        private String username;
    
        @NacosValue(value = "${password}", autoRefreshed = true)
        private String password;
    
        public String getDriverClassName() {
            return driverClassName;
        }
    
        public String getUrl() {
            return url;
        }
    
        public String getUsername() {
            return username;
        }
    
        public String getPassword() {
            return password;
        }
    
    }

    MybatisConfiguration

    package com.example.demo.config;
    
    import com.alibaba.druid.pool.DruidDataSource;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.core.io.support.ResourcePatternResolver;
    
    import javax.sql.DataSource;
    
    @Configuration
    @MapperScan(basePackages={"com.example.demo.dao"})
    public class MybatisConfiguration {
        @Autowired
        private DatabaseConfig dataBaseConfig;
    
        @Bean
        public DataSource dataSource() {
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setDriverClassName(dataBaseConfig.getDriverClassName());
            dataSource.setUrl(dataBaseConfig.getUrl());
            dataSource.setUsername(dataBaseConfig.getUsername());
            dataSource.setPassword(dataBaseConfig.getPassword());
            return dataSource;
        }
    
        @Bean
        public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
    
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(dataSource());
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
    
            return sqlSessionFactoryBean.getObject();
        }
    
    }

    UserService

    package com.example.demo.service;
    
    import com.example.demo.model.User;
    
    import java.util.List;
    
    
    public interface UserService {
    
        List<User> getUserList();
    }

    UserServiceImpl

    package com.example.demo.service.impl;
    
    import com.example.demo.dao.UserMapper;
    import com.example.demo.model.User;
    import com.example.demo.model.UserExample;
    import com.example.demo.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    
    @Service
    public class UserServiceImpl implements UserService {
    
        @Autowired
        private UserMapper userMapper;
    
        @Override
        public List<User> getUserList() {
            UserExample example = new UserExample();
            return userMapper.selectByExample(example);
        }
    }

    UserController

    package com.example.demo.controller;
    
    import com.example.demo.model.User;
    import com.example.demo.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.List;
    
    
    @RestController
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        @RequestMapping("/users")
        public List<User> getUsers(){
            return userService.getUserList();
        }
    }

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

    日志在项目根目录:

    下面访问:

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

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

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

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

    访问:

     完整地址:GitHub

  • 相关阅读:
    进程详解(1)——可能是最深入浅出的进程学习笔记
    贪吃蛇游戏C语言源代码学习
    经典功率谱估计及Matlab仿真
    CAN总线(一)
    实验楼课程管理程序-深入学习《C++ Primer第五版》实验报告&学习笔记1
    Linux驱动开发概述
    assert的用法
    基于WDF的PCI/PCIe接口卡Windows驱动程序(4)- 驱动程序代码(源文件)
    基于WDF的PCI/PCIe接口卡Windows驱动程序(3)- 驱动程序代码(头文件)
    C语言中的union
  • 原文地址:https://www.cnblogs.com/LUA123/p/10656079.html
Copyright © 2011-2022 走看看