springcloud5

分布式配置中心能做什么

  • 比如使用同一个redis的不同微服务,都需要单独进行redis配置,这是很麻烦的,因此可以通过分布式配置中心抽取公共配置
  • 修改配置文件,需要重启系统,因此需要实现配置文件的热加载

分布式配置中心搭建

jar包导入

  • <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
    

启动类

  • package com.xiangxue.jack;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.config.server.EnableConfigServer;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    
    /*
    post
    * 加密:http://localhost:8085/encrypt?data=123456
    * 解密:http://localhost:8085/decrypt
    * */
    @SpringBootApplication(scanBasePackages = {
          
          "com.xiangxue.jack"})
    @EnableConfigServer
    // 注册到eureka
    @EnableEurekaClient
    public class MicroConfigServerApplication {
          
          
        public static void main(String[] args) {
          
          
            SpringApplication.run(MicroConfigServerApplication.class,args);
        }
    }
    
    
    • @EnableConfigServer的注解

分布式配置中心的配置规则

配置文件

  • 此处是用的github,也可以用git、gitlab、svn等等

  • spring.cloud.config.server.git.uri=https://github.com/zg-jack/zg-config-repo
    spring.cloud.config.server.git.search-paths=config-repo
    spring.cloud.config.server.git.username=zg-jack
    spring.cloud.config.server.git.password=zg0001jack
    

客户端使用分布式配置中心

jar包导入

  • <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
        <version>LATEST</version>
    </dependency>
    

配置文件

  • #环境
    spring.cloud.config.profile=dev
    #分支
    spring.cloud.config.label=master
    #这种配置是configserver还单机情况,直接连接这个单机服务就行
    spring.cloud.config.uri=http://localhost:8085/
    

实例使用

  • package com.xiangxue.jack.controller;
    
    import com.xiangxue.jack.bean.ConsultContent;
    import com.xiangxue.jack.service.UserService;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.core.env.Environment;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpServletRequest;
    import java.util.List;
    
    @RefreshScope
    @RestController
    @RequestMapping("/user")
    public class UserController {
          
          
    
        private org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
    
        @Autowired
        UserService userService;
    
        @Value("${username}")
        private String username;
    
        @Value("${redis.password}")
        private String redispass;
    
        @Value("${db.password}")
        private String dbpass;
    
        @Autowired
        Environment environment;
    
        @RequestMapping("/queryContent")
        public List<ConsultContent> queryContent(HttpServletRequest request) {
          
          
            logger.info(""+this.hashCode());
            logger.info("==================已经调用==========" + request.getRemotePort());
            logger.info("@Value======username======" + username);
            logger.info("Environment======username======" + environment.getProperty("username"));
            logger.info("@Value======redispass======" + redispass);
            logger.info("Environment======redispass======" + environment.getProperty("redis.password"));
    
    
            logger.info("zookeeper======zk.jack.url======" + environment.getProperty("configzk.jack.url8"));
            return userService.queryContent();
        }
    }
    
    • 方法1:@Value("${username}")
      • 依赖注入时实际就是通过方法2获取的
    • 方法2:environment.getProperty(“username”)
  • github的master分支下有一个文件micro-order-dev.properties

    • username=zg-jack-dev---20200224-9-bus
      password=123456cc
      spring.datasource.url=jdbc:mysql://127.0.0.1:3306/consult?serverTimezone=UTC
      redis.password={cipher}一个加密串
      

客户端快速失败和重试

  • 当你启动客户端时,发现连不上,此时就不需要启动服务了,可以快速失败

    • #如果连接不上获取配置有问题,快速响应失败
      spring.cloud.config.fail-fast=true
      
  • 启动过程的重试

    • #默认重试的间隔时间,默认1000ms
      spring.cloud.config.retry.multiplier=1000
      #下一间隔时间的乘数,默认是1.1
      #spring.cloud.config.retry.initial-interval=1.1
      #最大间隔时间,最大2000ms
      spring.cloud.config.retry.max-interval=2000
      #最大重试次数,默认6次
      spring.cloud.config.retry.max-attempts=6
      
    • 同时需要导入jar包

      • <dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>
        

配置信息的加密

  • 比如对一些敏感信息,像账号密码

    • 加密:http://localhost:8085/encrypt?data=123456
      解密:http://localhost:8085/decrypt
      
    • 需要加入密钥配置,非对称加密是通过RSA算法实现,有公钥和私钥,根据私钥加密,根据公钥解密,加密和解密都有密钥,是成对存在的

      • 在/jdk/jre/bin/keytool.exe中执行如下指令,会在该目录下生成密钥文件config-server.keystore,输入指令的过程中会需要输入密码,之后需要配置到配置文件中,encrypt.key-store.password和encrypt.key-store.secret

        • keytool -genkeypair -alias config-server -keyalg RSA -keystore config-server.keystore -validity 365
          
      • 配置项

        • #加密配置
          #生成的密钥文件
          encrypt.key-store.location=config-server.keystore
          #与keytool指令对应
          encrypt.key-store.alias=config-server
          encrypt.key-store.password=123456
          encrypt.key-store.secret=123456
          
      • 把密钥文件放在resource下面,同时修改pom文件,把**/*.keystore加进去

        • <resources>
              <resource>
                  <directory>src/main/java</directory>
                  <includes>
                      <include>**/*.properties</include>
                      <include>**/*.xml</include>
                  </includes>
                  <filtering>false</filtering>
              </resource>
              <resource>
                  <directory>src/main/resources</directory>
                  <includes>
                      <include>**/*.properties</include>
                      <include>**/*.xml</include>
                      <include>**/*.txt</include>
                      <include>**/*.keystore</include>
                  </includes>
                  <filtering>false</filtering>
              </resource>
          </resources>
          

config server的缓存

  • #本地缓存目录
    spring.cloud.config.server.git.basedir=C:/work/config/tmp
    #强制从GitHub配置中心中拉取配置信息,不走缓存
    spring.cloud.config.server.git.force-pull=true
    
  • 强制不走缓存,防止更新无效

服务化配置中心

  • 如何在客户端设置配置中心?

    • 1.直接指定机器

      • #这种配置是configserver还单机情况,直接连接这个单机服务就行
        spring.cloud.config.uri=http://localhost:8085/
        
    • 2.配置中心启动成功,通过配置中心名称连接

      • #开启configserver服务发现功能
        spring.cloud.config.discovery.enabled=true
        #服务发现的服务名称
        spring.cloud.config.discovery.service-id=config-server
        

高可用

  • 将配置中心项目打成jar包,在不同机器上分别启动1个配置中心

配置动态刷新

  • @Value("${username}")
    private String username;
    
    @Value("${redis.password}")
    private String redispass;
    
    @Value("${db.password}")
    private String dbpass;
    
    @Autowired
    Environment environment;
    
    • 这些属性在启动时已经依赖注入了,如何使值动态改变?

      • 需要调用接口:http://localhost:8086/actuator/refresh,调用接口之后,再去请求,发现@value的方式还是旧值,environment的方式是新值了
      • 没有加注解@RefreshScope前,调用刷新接口后@Value值并没有更新,加了注解@RefreshScope后,调用刷新接口@Value的值也实现了动态刷新
    • Environment,只要调用刷新接口就能成功动态刷新新的参数

缺点

  • 1.必须手动调用,才能刷新接口

    • 可以借助github的通知功能,配置一个回调地址
  • 2.对多机情况,调用刷新接口,只对单机生效,要调n次才能刷新完

    • 消息总线可以解决

消息总线

导入jar包

  • <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bus-amqp</artifactId>
    </dependency>
    

mq的配置信息

  • spring.rabbitmq.host=192.168.67.139
    spring.rabbitmq.port=5672
    spring.rabbitmq.username=admin
    spring.rabbitmq.password=admin
    

刷新总线配置

  • # 刷新配置url  http://localhost:8085/actuator/bus-refresh
    spring.cloud.bus.refresh.enabled=true
    spring.cloud.bus.trace.enabled=true
    

测试

  • 调用总线刷新接口后,所有分布式配置中心的客户端都会自动刷新,这是广播-发布与订阅实现的,调用总线刷新接口后,就会往mq队列插一条消息,并且广播给所有的客户端,客户端会消费这条消息,并刷新最新配置
    • 192.168.67.139:15672/#/queues,rabbitmq的控制台

猜你喜欢

转载自blog.csdn.net/Markland_l/article/details/115376476
今日推荐