美文网首页springboot
Spring boot 2.0 消息总线(Spring Clou

Spring boot 2.0 消息总线(Spring Clou

作者: 风中吃西瓜 | 来源:发表于2018-10-31 09:33 被阅读30次

版本

  • spring-boot 2.0.6.RELEASE
  • spring-cloud Finchley.SR2

目录结构

image.png

eurka-server 服务注册中心

pom.xml


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

application.yml

server:
  port: 18080

spring:
  application:
    name: eurka-server

eureka:
  instance:
    hostname: localhost   # 主机地址
  client:
    register-with-eureka: false  # 注册中心告诉自己不能向自己注册自己,默认为true
    fetch-registry: false  # 获取注册信息
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  server:
    enable-self-preservation: false     # 关闭自我保护
    eviction-interval-timer-in-ms: 60000  # 清理时间间隔  服务器清理服务列表的定时器 单位 毫秒

注册中心 启动类 EurekaServerApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer   //表示是一个 eureka 服务
@SpringBootApplication
public class EurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

在自己的git上上传一个配置文件(在统一配置中心config-server 配置git仓库地址时需要使用这个作为远程配置文件仓库)

image.png

config-server 统一配置中心

pom.xml

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</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>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>
        <!--配置中心监控-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-monitor</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

application.yml

server:
  port: 18082
spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          search-paths: /**    #远程仓库的目录,本例子配置文件在根目录中
          uri: https://github.com/wangqiang/MySpringCloudConfig.git   # 配置自己的git仓库地址
          #username: ''   # 访问git仓库的用户名   如果Git仓库为公开仓库,可以不填写用户名和密码,如果是私有仓库需要填写,
          #password: ''   # 访问git仓库的用户密码
          default-label: master  # 配置仓库的分支

    #消息总线配置
    bus:
      enabled: true
      trace:
        enabled: true
      refresh:
        enabled: true  #开启总线消息更新功能

  # rabbitmq 配置
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: rabbit
    password: 123456
    virtual-host: /


eureka:
  client:
    service-url:
      defaultZone: http://localhost:18080/eureka/  #注册中心地址
    registry-fetch-interval-seconds: 20      # 多久拉取服务注册信息 表示从“发现”服务器获取注册表信息的频率(以秒为单位)。
  instance:
    # 60s未收到心跳,剔除instance 要比心跳时间大 服务器端等待的时间,因为它收到了最后的心跳,然后才可以从它的视图中删除这个实例,并且不允许流量进入这个实例。将这个值设置得太长可能意味着,即使实例不存在,流量也可以被路由到实例。将这个值设置得太小可能意味着,由于临时网络故障,该实例可能会被排除在流量之外。这个值的设置至少要高于leaseRenewalIntervalInSeconds中指定的值。默认90s
    lease-expiration-duration-in-seconds: 60
    # 心跳时间 即每15秒发送一次心跳  表明客户端需要将心跳发送到服务器端,以表明它还活着。如果心跳停止的时间超过了服务器设置的等待时间,那么服务器端将会从它的服务列表中删除该实例,从而将流量排除在该实例之外。默认30s
    lease-renewal-interval-in-seconds: 15
    prefer-ip-address: true
    ip-address: 127.0.0.1
    hostname: localhost
    instance-id: ${spring.cloud.client.ip-address}:${server.port}   #eureka client向eureka server注册使用真实ip设置 默认为本机机器名



# 屏蔽安全验证
management:
  endpoints:
    web:
      exposure:
        include: '*'  # 可以选择【"health","mappings","bus-refresh"】三种选项暴露那些端点

统一配置中心 启动类 ConfigServerApplication

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;

@EnableConfigServer  //标记为 Config Server
@EnableEurekaClient  //标记为eureka client
@SpringBootApplication
public class ConfigServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}

auth-server 业务的微服务

image.png

pom.xml

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <exclusions>
                <!-- 排除默认日志插件 -->
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</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-bus-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <!-- 排除默认日志插件 -->
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.12</version>
        </dependency>

        <!-- druid 连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.11</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.49</version>
        </dependency>
        <!-- 使用log4j2 日志 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

        <!-- Log4j2 异步支持 -->
        <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.4.2</version>
        </dependency>
        <!-- sql 日志待参数输出 -->
        <dependency>
            <groupId>com.googlecode.log4jdbc</groupId>
            <artifactId>log4jdbc</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <!-- 排除默认日志插件 -->
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <dependencies>
                    <!-- spring热部署 -->
                    <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>springloaded</artifactId>
                        <version>1.2.8.RELEASE</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

bootstrap.yml

配置中心的客户端要使用bootstrap.yml
bootstrap.yml优先于 application.yml 加载 即 bootstrap.yml加载完后才加载 application.yml

server:
  tomcat:
    uri-encoding: UTF-8
  port: 18088

spring:
  application:
    name: auth-server  # 对应配置中心配置文件中的{application}部分 名称需要与子服务名称以及读取的配置文件库中文件名称一致   
  cloud:
    config:
      discovery:
        enabled: true  # 配置中心的servieId,即服务名
        service-id: config-server  # 配置中心的服务名
      label: master    # 指明远程仓库的分支
      profile: dev     # 对应配置中心配置文件中的{profile}部分 本例子中读取的配置文件为 auth-server-dev.yml dev开发环境配置文件  test测试环境   pro正式环境
      name: auth-server  # 对应配置中心配置文件中的{application}部分  多个用,隔开
      fail-fast: true
    #消息总线配置
    bus:
      enabled: true
      trace:
        enabled: true
      refresh:
        enabled: true  #开启总线消息更新功能


eureka:
  client:
    service-url:
      defaultZone: http://localhost:18080/eureka/  #注册中心地址
    registry-fetch-interval-seconds: 20      # 多久拉取服务注册信息 表示从“发现”服务器获取注册表信息的频率(以秒为单位)。
  instance:
    # 60s未收到心跳,剔除instance 要比心跳时间大 服务器端等待的时间,因为它收到了最后的心跳,然后才可以从它的视图中删除这个实例,并且不允许流量进入这个实例。将这个值设置得太长可能意味着,即使实例不存在,流量也可以被路由到实例。将这个值设置得太小可能意味着,由于临时网络故障,该实例可能会被排除在流量之外。这个值的设置至少要高于leaseRenewalIntervalInSeconds中指定的值。默认90s
    lease-expiration-duration-in-seconds: 60
    # 心跳时间 即每15秒发送一次心跳  表明客户端需要将心跳发送到服务器端,以表明它还活着。如果心跳停止的时间超过了服务器设置的等待时间,那么服务器端将会从它的服务列表中删除该实例,从而将流量排除在该实例之外。默认30s
    lease-renewal-interval-in-seconds: 15
    prefer-ip-address: true
    ip-address: 127.0.0.1
    hostname: localhost
    instance-id: ${spring.cloud.client.ip-address}:${server.port}   #eureka client向eureka server注册使用真实ip设置 默认为本机机器名

# 屏蔽安全验证
management:
  endpoints:
    web:
      exposure:
        include: '*'  # 可以选择【"health","mappings","bus-refresh"】三种选项暴露那些端点

业务微服务端 启动类 AuthServerApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableEurekaClient
@SpringBootApplication
public class AuthServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(AuthServerApplication.class, args);
    }
}

业务微服务端 测试类

在需要更新的配置类上加@RefreshScope注解,@RefreshScope必须加,否则客户端会收到服务端的更新消息,但是更新不了,因为不知道更新哪里的。

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RefreshScope  // 需要更新的配置类上加@RefreshScope注解,@RefreshScope必须加,否则客户端会收到服务端的更新消息,但是更新不了,因为不知道更新哪里的
public class Test {

    @Value("${name}")
    private String name;

    @GetMapping("test")
    public String test() {
        return name;
    }
}

依次启动 eurka-server -> config-server -> auth-server

访问远程git上的配置文件 http://127.0.0.1:18082/auth-server/dev

18082: 是统一配置中心的端口
/auth-server/dev 对应远程配置文件的auth-server-dev.yml
/{name}-{profiles}.yml
/{label}/{name}-{profiles}.yml
name : 文件名,一般以服务名来命名
profiles : 一般作为环境标识
lable : 分支(branch),指定访问某分支下的配置文件

image.png
{
    "name": "auth-server",
    "profiles": [
        "dev"
    ],
    "label": null,
    "version": "69b2e80b7f8dbd6f84f24152a389bf091d5333dc",
    "state": null,
    "propertySources": [
        {
            "name": "https://github.com/wangqiang/MySpringCloudConfig.git/auth-server-dev.yml",
            "source": {
                "name": "之歌刘",
                "spring.rabbitmq.host": "127.0.0.1",
                "spring.rabbitmq.port": 5672,
                "spring.rabbitmq.username": "rabbit",
                "spring.rabbitmq.password": 123456,
                "spring.rabbitmq.virtual-host": "/"
            }
        }
    ]
}

业务微服务端 获取远程配置文件中的属性值

业务微服端的测试接口:http://127.0.0.1:18088/test

image.png

远程配置文件更新后,客户端自动更新

修改配置文件并提交到git上

name: 啊哈哈哈哈
  1. 首先发布一个post请求 http://localhost:18088/actuator/bus-refresh 手动刷新配置
    或者请求 http://localhost::18082/actuator/refresh
    18088 是配置客户端应用 config-client
    18082 是配置服务中心 config-server
    image.png
    image.png
image.png
  1. 再次访问测试接口 http://127.0.0.1:18088/test
    image.png

我们发现再不重启服务的情况下就能获取到修改的属性值

只要开启 Spring Cloud Bus 后,不管是对 config-server 还是 config-client 执行/actuator/bus-refresh都是可以更新配置的,
如果有多个客户端,多个客户端都会接收到刷新配置的消息,并刷新配置。

局部刷新配置(只刷新某些客户端)

某些场景下(例如灰度发布),我们可能只想刷新部分微服务的配置,此时可通过/actuator/bus-refresh/{destination}端点的 destination 参数来定位要刷新的应用程序。例如:/actuator/bus-refresh/customers:8000,这样消息总线上的微服务实例就会根据 destination 参数的值来判断是否需要要刷新。其中,customers:8000指的是各个微服务的 ApplicationContext ID。destination 参数也可以用来定位特定的微服务。例如:/actuator/bus-refresh/customers:**,这样就可以触发 customers 微服务所有实例的配置刷新。

集成WebHooks实现动态更新

远程配置文件修改后,不需要手动调用http://localhost:18088/actuator/bus-refresh 即可刷新配置

  1. 在远程配置文件的MySpringCloudConfig.git仓库中添加密钥


    image.png
    image.png
  2. 在远程配置文件git仓库中找到Webhooks


    image.png
  3. 点击Add webhook,添加一个webhook


    image.png
  • Payload URL: push 代码后自动运行的脚本 http://localhost:18082/actuator/bus-refresh(配置能够被git访问到的请求地址,根据git内外网情况自行配置)

  • Content type :我们选择application/json

  • Secret: 通讯密钥 用来认证身份

选择Just the push event.,因为我们只需要push的时候进行回调,然后添加即可

每当我们更新远程配置文件后,push到git后,就会触发Payload URL(配置的是访问刷新配置的地址)

相关文章

网友评论

    本文标题:Spring boot 2.0 消息总线(Spring Clou

    本文链接:https://www.haomeiwen.com/subject/mqpgtqtx.html