SpringCloud Bus消息总线

在微服务架构中,通常会使用轻量级的消息代理来构建一个共用的消息主题来连接各个微服务实例,它广播的消息会被所有在注册中心的微服务实例监听和消费,也称消息总线。 

SpringCloud中也有对应的解决方案,SpringCloud Bus 将分布式的节点用轻量的消息代理连接起来,可以很容易搭建消息总线,配合SpringCloud config 实现微服务应用配置信息的动态更新。

 

消息总线其实通过消息中间主题模式他使用广播消息的机制被所有在注册中心微服务实例进行监听和消费。以广播形式将消息推送给所有注册中心服务列表


消息代理属于中间件。设计代理的目的就是为了能够从应用程序中传入消息,并执行一些特别的操作。开源产品很多如ActiveMQ、Kafka、RabbitMQ、RocketMQ等
目前springCloud仅支持RabbitMQ和Kafka。本文采用RabbitMQ实现这一功能。

 

图示:

  

 

 通过客户端去通知每个服务 更新配置文件

  

升级  通过消息总线的方式:

 

 

 

 消息总线框架底层是MQ实现的,引入相应的jar包,底层框架实现好了,每个服务里面引入了相应的jar包后,自动创建队列 绑定交换机等等

 配置文件的应用场景就很符合。

 

 环境搭建:

       

 每个服务对于分布式配置中心来说是 client端

 配置文件环境 dev test  pre prd

 配置文件命名规范  client服务名称(注册中心名称)-版本.yml 

 

创建好这个文件

 

 

互联网项目场景中的配置文件 不是存放在本底的  是存放在远程服务器

写在本地 需要重启服务器  !!

下面开始搭建分布式配置中心 SpringCloude  组件  Config

   

1、配置文件存放在git 或者 svn

2、搭建分布式配置中心服务

3、客户端读取分布式配置中心服务

 

 configServer端:

配置文件:

  pom:

 <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>
  <groupId>com.toov5</groupId>
  <artifactId>SpringCloud-eureka-server</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <!-- 管理依赖 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.M7</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!--SpringCloud eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
            <!-- hystrix断路器 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        
    </dependencies> 
    <!-- 注意: 这里必须要添加, 否者各种依赖有问题 -->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
  
</project>

yml:

###服务注册到eureka地址
eureka:
  client:
    service-url:
           defaultZone: http://localhost:8100/eureka
spring:
  application:
    ####注册中心应用名称
    name: config-server
  cloud:
    config:
      server:
        git:
          ###git环境地址
          uri: https://gitee.com/toov5/distributed_configuration_file.git
          ####搜索目录
          search-paths:
            - Test  
      ####读取分支      
      label: master
####端口号      
server:
  port: 8888

启动:

package com.toov5.app;

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;

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

启动Eureka后启动 configServer

 

 访问地址: http://127.0.0.1:8888//appConfig-dev.yml

 

Client端:

pom:

 

<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>
  <groupId>com.toov5</groupId>
  <artifactId>SpringCloud_config_client</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>

    <dependencies>
        <!-- SpringBoot整合Web组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
            <version>2.0.2.RELEASE</version>
        </dependency>
        <!-- SpringBoot整合eureka客户端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.0.2.RELEASE</version>
        </dependency>

    </dependencies>
    <!-- 注意: 这里必须要添加, 否者各种依赖有问题 -->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
  
</project>

Controller:

package com.toov5.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexController {
     @Value("${userAge}")  //配置中心的 我们这个字段在本地没有配置
     private String userAge;
     
     @RequestMapping("/getUserAge")
     public String getUerAge() {
          return userAge;
     }
}

启动类:

package com.toov5.controller;

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

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

yml:

对应命名规范去配置!

spring:
  application: 
    ####注册中心应用名称    对应命名规范去配置 appConfig-dev.yml
    name:  appConfig
  cloud:
    config:
    ####读取后缀
      profile: dev   #对应命名规范去配置
      ####读取config-server注册地址
      discovery:
        service-id: config-server   ##服务的名字
        enabled: true
#####    eureka服务注册地址    
eureka:
  client:
    service-url:
           defaultZone: http://localhost:8100/eureka    
server:
  port: 8882  

访问结果:

如果此时 修改了配置文件,刷新出来的还是不变的!缓存到当前的jvm中了  重启client端就OK了   可以做定时刷新

 

升级: 不重启服务器自动刷新

 1.手动通知刷新单个jvm值

 2. 消息总线通知整个微服务刷新

 

1. 通过监控中心

   手动actuator端点刷新数据

   引入mavn 到client   

<!-- actuator监控中心 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

 

 yml

   开启监控服务

  

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

 此时的yml:

spring:
  application: 
    ####注册中心应用名称    对应命名规范去配置 appConfig-dev.yml
    name:  appConfig
  cloud:
    config:
    ####读取后缀
      profile: dev   #对应命名规范去配置
      ####读取config-server注册地址
      discovery:
        service-id: config-server   ##服务的名字
        enabled: true
#####    eureka服务注册地址    
eureka:
  client:
    service-url:
           defaultZone: http://localhost:8100/eureka    
server:
  port: 8882
  
  
#开启所有服务端点权限  
management:
  endpoints:
    web:
      exposure:
        include: "*"
  

 

然后Controller 加上 刷新的注解   @RefreshScope

package com.toov5.controller;

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

@RestController
@RefreshScope
public class IndexController {
     @Value("${userAge}")  //配置中心的 我们这个字段在本地没有配置
     private String userAge;
     
     @RequestMapping("/getUserAge")
     public String getUerAge() {
          return userAge;
     }
}

对应的值 不用重启就可以刷新了

 启动后:修改git的文件值

发送post请求:

http://127.0.0.1:8882/actuator/refresh

 

有个缺点,如果configClient做个集群

如要去刷新每个 服务的值!  postman 搞一遍

 

升级:这样就需要消息总线了!

 

   

 SpringCloud整合rabbitmq 和 kafka

 本文采用的是rabbitmq去作为案例讲解:

  rabbitmq 的加交换机有四种: fanout  direct  topic  head

 

  在这个体系中  微服务有多少个 就会在MQ中创建多少个队列,当手动刷新一个服务时候,会通过rabbitmq 去把消息同时发给交换机,然后通过交换机发送给其他的微服务 。

 

 

 环境的搭建:

   引入maven: bus的核心jar包

   client和servler端都需要引入   

    <!--核心jar包 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>
        <!-- actuator监控中心 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

如果报错添加:

 <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-bus-parent</artifactId>
                <version>2.0.0.RC2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

客户端需要yml开启bus刷新:client端

###开启bus刷新
management:
  endpoints:
    web:
      exposure:
        include: bus-refresh  

 同时需要配置mq的连接信息:

此时的client端yml:

spring:
  rabbitmq:
  ####连接地址
    host: 192.168.91.6
   ####端口号  
    port: 5672
   ####账号
    username: admin
   ####密码 
    password: admin
   ### 地址  主机独立的virtualhost
    virtual-host: /admin_toov5
  application: 
    ####注册中心应用名称    对应命名规范去配置 appConfig-dev.yml
    name:  appConfig
  cloud:
    config:
    ####读取后缀
      profile: dev   #对应命名规范去配置
      ####读取config-server注册地址
      discovery:
        service-id: config-server   ##服务的名字
        enabled: true
#####    eureka服务注册地址    
eureka:
  client:
    service-url:
           defaultZone: http://localhost:8100/eureka    
server:
  port: 8882
  
###开启bus刷新
management:
  endpoints:
    web:
      exposure:
        include: bus-refresh

server:

###服务注册到eureka地址
eureka:
  client:
    service-url:
           defaultZone: http://localhost:8100/eureka
spring:
  rabbitmq:
  ####连接地址
    host: 192.168.91.6
   ####端口号  
    port: 5672
   ####账号
    username: admin
   ####密码 
    password: admin
   ### 地址  主机独立的virtualhost
    virtual-host: /admin_toov5
  application:
    ####注册中心应用名称
    name: config-server
  cloud:
    config:
      server:
        git:
          ###git环境地址
          uri: https://gitee.com/toov5/distributed_configuration_file.git
          ####搜索目录
          search-paths:
            - Test  
      ####读取分支      
      label: master
####端口号      
server:
  port: 8888

###开启bus刷新
management:
  endpoints:
    web:
      exposure:
        include: bus-refresh

 

底层会帮助创建 mq队列 主题  两个client  一个 server

 

 

 

 

 访问一个接口  8882 的,其他的服务8883也会跟着改了!

http://127.0.0.1:8882/actuator/bus-refresh

 

就是玩了个  yml+jar包 而已

 

posted @ 2019-01-19 23:42  toov5  阅读(4083)  评论(0编辑  收藏  举报