当前位置:   article > 正文

Spring Cloud Config结合RabbitMQ实现统一配置中心_spring cloud config配置中心配置本地文件,连接rabbitmq

spring cloud config配置中心配置本地文件,连接rabbitmq

统一配置中心概述

如果微服务架构中没有使用统一配置中心时,所存在的问题:

  • 配置文件分散在各个项目里,不方便维护
  • 配置内容安全与权限,实际开发中,开发人员是不知道线上环境的配置的
  • 更新配置后,项目需要重启

在SpringCloud中我们使用config组件来作为统一配置中心:
Spring Cloud Config - 统一配置中心


Config Server

废话不多说,本小节我们来开发统一配置中心的server端,在IDEA中新建一个Spring Initializr项目,并选择相应的模块:
Spring Cloud Config - 统一配置中心

项目的pom.xml文件配置的依赖如下:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-monitor</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-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
   </dependency>
</dependencies>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

因为config server是需要到git上拉取配置文件的,所以还需要在远程的git上新建一个存放配置文件的仓库,我这里使用的是码云:
Spring Cloud Config - 统一配置中心

创建好后,新建一个文件,然后把订单服务的配置文件内容粘贴进来:
Spring Cloud Config - 统一配置中心

注:我这里事先已经存在一个商品服务和订单服务

回到config项目中,编辑application.yml配置文件内容如下:

spring:
  application:
    name: config
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/Zero-One/config-repo  # 远程git仓库的地址
          username: username  # 以及相应的账户名
          password: password  # 和密码
          basedir: E:Java_IDEAconfigasedir  # 可以使用这个配置项来指定本地git仓库的路径
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8974
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在启动类上,加上@EnableConfigServer注解,声明这是一个config-server。代码如下:

package org.zero.springcloud.config;

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 ConfigApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigApplication.class, args);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

启动项目,访问如下地址,可以看到能够访问到配置文件的内容:
Spring Cloud Config - 统一配置中心

如果访问.properties格式的,还会自动进行转换:
Spring Cloud Config - 统一配置中心

.json格式的也能够进行转换:
Spring Cloud Config - 统一配置中心

注:如果配置文件的内容格式有问题的话,访问会报500错误。我们可以利用这个特性,来检查我们的配置文件是否正确

在上图访问的地址中可以发现,访问的配置文件名后面还有一个-a,这其实是config的访问规则。后面必须要跟个-xxx,所以在创建文件的时候,最好是按这种命名规则来创建。配置文件的访问规则如下:

/{name}-{profiles}.yml
/{label}/{name}-{profiles}.yml

name : 文件名,一般以服务名来命名
profiles : 一般作为环境标识
lable : 分支(branch),指定访问某分支下的配置文件
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

有一点值得注意的是,如果有两个前缀名相同文件,例如一个order.yml,一个order-dev.yml。那么在访问相同前缀的文件时,config-server会对这两个文件进行一个合并。例如order.yml有一段配置是order-dev.yml没有的,理应访问order-dev.yml的时候是没有那段配置的,但访问的结果却是它俩合并之后的内容,即order-dev.yml会拥有order.yml里所配置的内容。


Config Client

在上一小节中,我们介绍了config-server的使用以及配置文件的访问规则,本小节将介绍config-client端的使用,我们以订单服务为例。

在订单服务工程的pom.xml文件中,增加如下依赖配置:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-client</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4

注:商品服务工程中也增加这个依赖,这样两个服务都可以从config-server中读取配置了

然后将application.yml重命名为bootstrap.yml,并修改内容如下:

spring:
  application:
    name: order
  cloud:
    config:
      discovery:
        enabled: true
        service-id: CONFIG  # 注册中心的服务名
      profile: dev  # 指定配置文件的环境
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

注:之所以要用bootstrap.yml,是因为启动SpringBoot项目时,会优先读取bootstrap.yml里的配置,然后才会读取application.yml。如果不通过bootstrap.yml里的配置,先从配置中心拉下相应的配置文件,就会报错

重启项目,使用创建订单接口,测试一下是否正常:
Spring Cloud Config - 统一配置中心

统一配置中心和服务注册中心一样,都是需要高可用的,不然配置文件都没有的话,项目自然没法跑起来了。所以我们来看看如何使config-server能够高可用。

config-server也属于是一个微服务,所以让其高可用很简单,只需要启动多个服务实例即可。首先我们来复制几个config-server的实例,跑在不同的端口上:
Spring Cloud Config - 统一配置中心

启动后,到eureka上可以看到也都注册成功了,这样我们就有了三个config-server实例:
Spring Cloud Config - 统一配置中心

其他服务通过负载均衡策略,就能够调用这几个config-server实例,轻松实现高可用

还有一个需要注意的点是服务注册中心地址端口的问题,我们都知道eureka-server的默认端口是8761,如果我们现在将eureka-server的端口改成8762,那么订单服务就会启动不了。因为在bootstrap.yml配置文件中,并没有配置eureka-server的地址。

项目启动的时候会优先读取bootstrap.yml,按照配置的内容去配置中心拉取配置文件,但是在此之前订单服务需要先去注册中心上找配置中心的调用地址,如果eureka-server端口更改了的话,就会访问不到配置中心,自然也就无法调用配置中心拉取配置文件了,现在我们之所以可以访问是因为SpringBoot默认访问的是本地的8761端口。

所以我们需要修改远程git仓库上的配置文件内容如下:
Spring Cloud Config - 统一配置中心

然后在bootstrap.yml中增加eureka-server的配置才对:

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  • 1
  • 2
  • 3
  • 4

这也是一个小细节,如果没有注意的话,容易掉进这个坑。


Spring Cloud Bus

在上两个小节中,我们学习了统一配置中心的server端以及client端的使用,也成功拉取了相应的配置文件。但是这样仍然不够,因为还不能做到自动刷新配置文件,例如我在git上更改了配置文件,还需要重启服务才能够读取到最新的配置。所以本小节将介绍一下如何使用Spring Cloud Bus实现自动刷新配置,Bus在这里是总线的意思。

示意图:
Spring Cloud Config - 统一配置中心

Spring Cloud Bus会向外提供一个http接口,即图中的/actuator/bus-refresh。我们将这个接口配置到远程的git上,当git上的文件内容发生变动时,就会自动调用/bus-refresh接口。Bus就会通知config-server,config-server会发布更新消息到消息队列中,其他服务订阅到该消息就会信息刷新,从而实现整个微服务进行自动刷新。


RabbitMQ的安装

由于实现配置自动刷新,需要用到消息中间件,所以还得安装,我这里使用RabbitMQ。并且是在CentOS上使用docker进行安装,docker的版本如下:

[root@01server ~]# docker info |grep "Server Version"
Server Version: 18.03.1-ce
[root@01server ~]# 
  • 1
  • 2
  • 3

安装并启动rabbitmq:

[root@01server ~]# docker run -d --hostname my-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3.7.3-management
...
[root@01server ~]#
  • 1
  • 2
  • 3

进入容器里,添加超级管理员用户:

[root@01server ~]# docker exec -it 1ca60f11d6d9 bash  # 进入容器
root@my-rabbit:/# rabbitmqctl add_user admin password  # 添加用户,用户名为admin,密码为password
Adding user "admin" ...
root@my-rabbit:/# rabbitmqctl set_user_tags admin administrator  # 设置用户权限为超级管理员
Setting tags for user "admin" to [administrator] ...
root@my-rabbit:/# rabbitmqctl  set_permissions -p /${user_name}  admin '.*' '.*' '.*' # 设置远程登录权限
root@my-rabbit:/# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

如果你的系统防火墙没有关闭的话,还需要开放相应的端口:

[root@01server ~]# firewall-cmd --zone=public --add-port=15672/tcp --permanent
success
[root@01server ~]# firewall-cmd --zone=public --add-port=5672/tcp --permanent
success
[root@01server ~]# firewall-cmd --reload
success
[root@01server ~]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

使用浏览器访问${ip}:15672,进入登录界面:
Spring Cloud Config - 统一配置中心

登录之后才能进入到管理页面:
Spring Cloud Config - 统一配置中心


实现刷新配置

安装好RabbitMQ后,我们就可以着手实现配置的刷新了。首先我们需要在config项目中,增加Spring Cloud Bus依赖:

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

注:商品服务以及订单服务也需要加入这个依赖

然后在配置文件中,配置rabbitmq的地址以及用户密码,修改config服务的配置如下:

spring:
  application:
    name: config
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/Zero-One/config-repo
          username: username
          password: password
          basedir: E:Java_IDEAconfigasedir
  # 配置rabbitmq的地址以及用户密码
  rabbitmq:  
    host: 192.168.190.129
    port: 5672
    username: admin
    password: admin
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

# 允许/actuator/bus-refresh接口被外部调用
management:  
  endpoints:
    web:
      exposure:
        include: "*"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

修改商品服务的配置如下:

spring:
  application:
    name: product
  cloud:
    config:
      discovery:
        enabled: true
        service-id: CONFIG
      profile: dev
  rabbitmq:
    host: 192.168.190.129
    port: 5672
    username: admin
    password: admin
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

修改订单服务的配置如下:

spring:
  application:
    name: order
  cloud:
    config:
      discovery:
        enabled: true
        service-id: CONFIG
      profile: dev
  rabbitmq:
    host: 192.168.190.129
    port: 5672
    username: admin
    password: admin
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

配置好后,将以上项目都重启,然后到RabbitMQ上,可以看到注册上来的队列:
Spring Cloud Config - 统一配置中心

确认都能够正常注册到rabbitmq后,我们到码云上,规范配置文件的名称。修改之前的order.yml为order-dev.yml,并且增加商品服务的配置文件,如下:
Spring Cloud Config - 统一配置中心

并在order-dev.yml文件里,增加一段env配置:
Spring Cloud Config - 统一配置中心

完成配置文件的修改后,再到订单服务项目里,增加一个 EnvController 类,加上@RefreshScope注解实现自动刷新配置,用来测试配置刷新是否正常。代码如下:

package org.zero.springcloud.order.server.controller;

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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @program: sell_order
 * @description:
 * @author: 01
 * @create: 2018-08-20 23:17
 **/
@RestController
@RequestMapping("/env")
@RefreshScope  // 这个注解声明了刷新配置的范围,如果使用config配置类的话,就声明到配置类上即可
public class EnvController {

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

    @GetMapping("/print")
    public String print(){
        return env;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

重启订单服务项目,访问/env/print接口,返回的结果如下:
Spring Cloud Config - 统一配置中心

这时,我们再到码云上修改order-dev.yml文件里的env配置为beat,如下:
Spring Cloud Config - 统一配置中心

然后访问bus用于刷新配置的接口:
Spring Cloud Config - 统一配置中心

稍等一会,控制台应该会打印刷新日志,接着再访问之前的测试接口,返回beta则说明刷新是有效的。因为这个过程中,我们并没有重启订单服务或配置中心服务:
Spring Cloud Config - 统一配置中心


集成WebHooks实现动态更新

到了本小节,就代表我们已经成功集成了RabbitMQ以及Spring Cloud Bus进行配置文件的动态刷新,但是我们目前依旧需要手动去访问Bus用于刷新配置的接口,才能完成配置文件的动态刷新。我们希望的是,当git仓库的文件更新时就能够实现动态刷新配置文件。要实现这个功能就需要Git仓库能够在配置文件更新后,自动调用Bus用于刷新配置的接口。那么要怎么实现这个功能呢?这就需要用到WebHooks了,好在码云和GitHub都支持WebHooks,我们只需要配置一下接口地址即可。这也是我们本小节需要演示的。

注:SpringCloud需要2.0.0以上的版本才开始支持码云的WebHooks,低版本对码云的WebHooks不兼容

首先打开仓库的管理界面,选择WebHooks,并点击右上角的添加:
Spring Cloud Config - 统一配置中心

然后输入相应的配置信息,注意这里不是配置/actuator/bus-refresh接口了 ,而是配置 spring cloud config 里特定给WebHooks调用的/monitor接口。至于域名,我这里使用了内网穿透的地址(natapp.cn获取):
Spring Cloud Config - 统一配置中心

添加完成后,点击右上角的测试,返回结果如下,则代表测试通过:
Spring Cloud Config - 统一配置中心

现在我们用之前的order-dev.yml配置文件进行一个测试,把env的值改为test,如下:
Spring Cloud Config - 统一配置中心

然后在不重启任何项目的情况下,访问之前打印env配置的接口。返回结果如下代表自定刷新成功了:
Spring Cloud Config - 统一配置中心

]

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/390905
推荐阅读
相关标签
  

闽ICP备14008679号