• Spring Cloud Config


    一、概念

    1,简介

      微服务意味着要将单体应用中的业务拆分为一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。

    2,作用

    • 集中管理配置文件
    • 不同环境不同配置,动态化的配置更新,分环境部署比如dev/test/prod/beta/release
    • 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
    • 当配置发生变动时,服务不需要重启即可感知配置的变化并应用新的配置(post、curl访问刷新)

    二、案例

    源码:cloud-config

    1,配置SpringCloud Config Server

    源码:cloud-config-center3344

      添加依赖:
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
      配置application.yml文件:
    server:
      port: 3344
    spring:
      application:
        name: cloud-config-center
      cloud:
        config:
          server:
            git:
              uri:  https://gitee.com/xiaocheng0902/spring-cloud.git #填写你自己的github路径
              search-paths:
                - spring-cloud-config
          label: master
    eureka:
      client:
        service-url:
          defaultZone:  http://localhost:7001/eureka
      启动类中添加注解:@EnableConfigServer
      访问:http://localhost:3344 + ...
    /{application}/{profile}[/{label}]
    /{application}-{profile}.yml
    /{label}/{application}-{profile}.yml  
    /{application}-{profile}.properties
    /{label}/{application}-{profile}.properties

    2,配置SpringCloud Config Client

    源码:cloud-config-client3355

      pom文件配置
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>

      bootstrap.yaml文件

    spring:
      application:
        name: config-client
      cloud:
        config:
          label: master #分支分支名称
          name: config #配置文件名称
          profile: dev #配置后缀名称  上述三个综合:master分支上config-dev.yml的配置文件被读取为  http://localhost:3344/master/config-dev.yml
          uri: http://localhost:3344 #配置中心地址

      启动类

    @SpringBootApplication
    @EnableEurekaClient
    public class ConfigClientMain3355 { public static void main(String[] args) { SpringApplication.run( ConfigClientMain3355.class,args); } }

    问题

    1,修改gitee上的配置文件内容
    2,刷新3344,发现ConfigServer配置中心立刻响应
    3,刷新3355,发现ConfigServer客户端没有任何响应(除非重启或重新加载)

    3,Config客户端之动态刷新

    源码:cloud-config-client3355

       pom文件添加

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

       bootstrap.yaml中添加暴露端点

    management:
      endpoints:
        web:
          exposure:
            include: "*"

       需要引用gitee配置中心的上添加注解:@RefreshScope

       gitee上文件更新后,发送请求:curl -X POST "http://localhost:3355/actuator/refresh"

    问题:

    如果有多个微服务客户端3355/3366/3377...那么是否每次修改都需要每个未付手动刷新?

    三、SpringCloud配置动态刷新

    安装erlang和rabbitmq

    http://erlang.org/download/otp_win64_21.3.exe  #直接下一步就行
    https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.14/rabbitmq-server-3.7.14.exe #直接下一步
    #安装完成之后进入rabbitmq安装的sbin目录执行命令,之后就可以在控制台启动了http://localhost:15672/
    rabbitmq-plugins enable rabbitmq_management

    1,采用SpringCloud Bus刷新

    a)服务端

      pom中添加

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bus-amqp</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>com.xcc</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

      bootstrap.yaml中添加

    server:
      port: 3344
    spring:
      application:
        name: cloud-config-center
      cloud:
        config:
          server:
            git:
              uri:  https://gitee.com/xiaocheng0902/spring-cloud.git #填写你自己的github路径
              search-paths:
                - spring-cloud-config
          label: master
      rabbitmq:
        host: localhost
        port: 5672
        username: guest
        password: guest
    
    eureka:
      client:
        service-url:
          defaultZone:  http://localhost:7001/eureka
    
    management:
      endpoints:
        web:
          exposure:
            include: 'bus-refresh'

      application应用类为

    @SpringBootApplication
    @EnableConfigServer
    public class ConfigCenterMain3344 {
        public static void main(String[] args) {
            SpringApplication.run(ConfigCenterMain3344 .class,args);
        }
    }

    b)客户端

      pom文件

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bus-amqp</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

      bootstrap.yaml

    server:
      port: 3355
    
    spring:
      application:
        name: config-client
      cloud:
        config:
          label: master #分支分支名称
          name: config #配置文件名称
          profile: dev #配置后缀名称  上述三个综合:master分支上config-dev.yml的配置文件被读取为  http://localhost:3344/master/config-dev.yml
          uri: http://localhost:3344 #配置中心地址
      rabbitmq:
        host: localhost
        port: 5672
        username: guest
        password: guest
    eureka:
      client:
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka
    
    #暴露端点
    management:
      endpoints:
        web:
          exposure:
            include: "*"

      application类中

    @SpringBootApplication
    @EnableEurekaClient
    public class ConfigClientMain3355 {
        public static void main(String[] args) {
            SpringApplication.run( ConfigClientMain3355.class,args);
        }
    }

      引用文件的类

    @RestController
    @RefreshScope
    public class ConfigClientController {
        @Value("${config.version}")
        private String configVersion;
        @GetMapping("/configVersion")
        public String getConfigVersion(){
            return configVersion;
        }
    }

    2,采用webhook全自动刷新

    四、Cloud Stream

      SpringCloud Stream是一个构建消息驱动微服务的框架

         

    1,常用API

    组成说明
    Middleware 中间件,目前只支持RabbitMQ和Kafka
    Binder Binder是应用于消息中间件之间的封装,目前实行了Kafka和RabbitMQ的Binder,通过Binder可以很方便的连接中间件,可以动态的改变消息类型(对应于Kafka的topic,RabbitMQ的exchange),这些都可以通过配置文件来实现
    @Input 注解标识输入通道,通过该输入通道接收到的消息进入应用程序
    @Output 注解标识输出通道,发布的消息将通过该通道离开应用程序
    @StreamListener 监听队列,用于消费者的队列的消息接收
    @EnableBinding 指信道channel和exchange绑定在一起

    2,生产者

    源码:cloud-stream-rabbitmq-provider8801

      pom文件

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

      yaml文件

    server:
      port: 8801
    spring:
      application:
        name: cloud-stream-provider
      cloud:
        stream:
          binders: # 在此处配置要绑定的rabbitmq的服务信息;
            defaultRabbit: # 表示定义的名称,用于于binding整合
              type: rabbit # 消息组件类型
              environment: # 设置rabbitmq的相关的环境配置
                spring:
                  rabbitmq:
                    host: localhost
                    port: 5672
                    username: guest
                    password: guest
          bindings: # 服务的整合处理
            output: # 这个名字是一个通道的名称 通道1
              destination: studyExchange # 表示要使用的Exchange名称定义
              content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain”
              default-binder: defaultRabbit  # 设置要绑定的消息服务的具体设置 与定义的binders对应
            output1: # 这个名字是一个通道的名称 通道2
              destination: studyExchange1 # 表示要使用的Exchange名称定义
              content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain”
              default-binder: defaultRabbit  # 设置要绑定的消息服务的具体设置 与定义的binders对应
            output2: # 这个名字是一个通道的名称 通道3
              destination: studyExchange2 # 表示要使用的Exchange名称定义
              content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain”
              default-binder: defaultRabbit  # 设置要绑定的消息服务的具体设置 与定义的binders对应
    eureka:
      client: # 客户端进行Eureka注册的配置
        service-url:
          defaultZone: http://localhost:7001/eureka
      instance:
        lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒)
        lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒)
        instance-id: send-8801.com  # 在信息列表时显示主机名称
        prefer-ip-address: true     # 访问的路径变为IP地址

      启动类

    @EnableEurekaClient
    @SpringBootApplication
    public class StreamMQMain8801 {
        public static void main(String[] args) {
            SpringApplication.run(StreamMQMain8801.class, args);
        }
    }

      定义source源

    /**
     * 自定义mq的source数据源
     */
    public interface MqMessageSource {
    
        String OUT_PUT = "output";
        String OUT_PUT1 = "output1";
        String OUT_PUT2 = "output2";
    
        @Output(OUT_PUT)
        MessageChannel output();
    
        @Output(OUT_PUT1)
        MessageChannel output1();
    
        @Output(OUT_PUT2)
        MessageChannel output2();
    
    }
    View Code

      发送消息

    @EnableBinding(MqMessageSource.class) //定义消息的推送管道
    public class MessageProviderImpl implements IMessageProvider {
    
        @Resource(name = MqMessageSource.OUT_PUT)
        private MessageChannel output;
        @Resource(name = MqMessageSource.OUT_PUT1)
        private MessageChannel output1;
        @Resource(name = MqMessageSource.OUT_PUT2)
        private MessageChannel output2;
    
        @Override
        public String send() {
            String serial = IdUtil.simpleUUID();
            boolean send = output.send(MessageBuilder.withPayload(serial).build());
            System.out.println("output******************serial: "+serial+"	发送情况"+send);
            return serial;
        }
    
        @Override
        public String send1() {
            String serial = IdUtil.simpleUUID();
            boolean send = output1.send(MessageBuilder.withPayload(serial).build());
            System.out.println("output1******************serial: "+serial+"	发送情况"+send);
            return serial;
        }
    
        @Override
        public String send2() {
            String serial = IdUtil.simpleUUID();
            boolean send = output2.send(MessageBuilder.withPayload(serial).build());
            System.out.println("output2******************serial: "+serial+"	发送情况"+send);
            return serial;
        }
    
    }
    View Code

    3,消费者

    源码:cloud-stream-rabbitmq-consumer8803

      pom文件

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

      yam文件

    server:
      port: 8803
    
    spring:
      application:
        name: cloud-stream-consumer
      cloud:
        stream:
          binders: # 在此处配置要绑定的rabbitmq的服务信息;
            defaultRabbit: # 表示定义的名称,用于于binding整合
              type: rabbit # 消息组件类型
              environment: # 设置rabbitmq的相关的环境配置
                spring:
                  rabbitmq:
                    host: localhost
                    port: 5672
                    username: guest
                    password: guest
          bindings: # 服务的整合处理
            input: # 这个名字是一个通道的名称
              destination: studyExchange # 表示要使用的Exchange名称定义
              content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain”
              default-binder: defaultRabbit  # 设置要绑定的消息服务的具体设置 与定义的binders对应
              group: xcc01 #消费者组,防止消息重复消费和消息的丢失
            input1: # 这个名字是一个通道的名称
              destination: studyExchange1 # 表示要使用的Exchange名称定义
              content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain”
              default-binder: defaultRabbit  # 设置要绑定的消息服务的具体设置 与定义的binders对应
              group: xcc01
            input2: # 这个名字是一个通道的名称
              destination: studyExchange2 # 表示要使用的Exchange名称定义
              content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain”
              default-binder: defaultRabbit  # 设置要绑定的消息服务的具体设置 与定义的binders对应
              group: xcc01
    
    eureka:
      client: # 客户端进行Eureka注册的配置
        service-url:
          defaultZone: http://localhost:7001/eureka
      instance:
        lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒)
        lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒)
        instance-id: receive-8803.com  # 在信息列表时显示主机名称
        prefer-ip-address: true     # 访问的路径变为IP地址

      启动类

    @EnableEurekaClient
    @SpringBootApplication
    public class StreamMQMain8803 {
        public static void main(String[] args) {
            SpringApplication.run(StreamMQMain8803.class, args);
        }
    }

      自定义管道sink

    /**
     * 自定义mq的管道输出
     */
    public interface MqMessageSink {
    
        String IN_PUT = "input";
        String IN_PUT1 = "input1";
        String IN_PUT2 = "input2";
    
        @Input(IN_PUT)
        SubscribableChannel input();
    
        @Input(IN_PUT1)
        SubscribableChannel input1();
    
        @Input(IN_PUT2)
        SubscribableChannel input2();
    
    }
    View Code

      消息消费

    @Component
    @EnableBinding(MqMessageSink.class)
    public class ReceiveMessageListenerController {
    
        @Value("${server.port}")
        private String serverPort;
    
        @StreamListener(MqMessageSink.IN_PUT)
        public void input(Message<String>message) {
            System.out.println("input 消费者2号,接受:"+message.getPayload()+"	 port:"+serverPort);
        }
    
        @StreamListener(MqMessageSink.IN_PUT1)
        public void input1(Message<String>message) {
            System.out.println("input1 消费者2号,接受:"+message.getPayload()+"	 port:"+serverPort);
        }
    
        @StreamListener(MqMessageSink.IN_PUT2)
        public void input2(Message<String>message) {
            System.out.println("input2 消费者2号,接受:"+message.getPayload()+"	 port:"+serverPort);
        }
    
    }
    View Code
  • 相关阅读:
    【基础】jquery全选、反选、全不选代码
    【基础】jquery全选、反选、全不选代码
    收集一些程序员励志经典名言
    收集一些程序员励志经典名言
    收集一些程序员励志经典名言
    防止表单重复提交的解决方案整理
    Git使用教程
    2019牛客暑期多校训练营(第二场)J Subarray
    Hibernate-配置
    与项目欧拉速度比较:C vs Python与Erlang vs Haskell
  • 原文地址:https://www.cnblogs.com/bbgs-xc/p/13805931.html
Copyright © 2020-2023  润新知