SpringCloud(二) 高可用分布式配置中心(Spring Cloud Config kafka实现动态刷新)

前言: 网上的资料乱七八糟, 很多博主把一些旧的文章复制来粘贴去,  搞得很多新人都无法安心食用. 经过博主我一周的钻研 , 终于研究出一套适用于生产环境可运行的, 高可用分布式配置中心.(文章末尾会有github链接, 请大家安心使用)

 

注:现在楼主拥抱nacos配置中心了, 页面配置, 多环境, 多group, 页面化配置, 更方便更便捷. 文档地址: -> 等待更新

要求:

1. springboot2.0以上

2.springcloud Finchley版本及以上

3.jdk:1.8

4. gitlab

5. kafka(其实 rabbitmq也行,但是谁叫kafka功能强大呢 )

--------------------------------------------------------------------------------------------------------------------------------------------------------------

一. 设计架构以及运行流程分析:

(由本博主亲手画, 如需转载附上原文地址谢谢)

 

1. 我们的配置文件由gitlab保管,

2. 而我们的配置中心(config-server)启动的时候从gitlab中拉取, 启动时候可以根据启动参数启动不同环境的配置中心.

3. 微服务启动的时候就从配置中心(config-server中去拉取), 可以自定义拉取不同环境的配置!!!

4. 当我们修改了配置文件你可以在gitlab上提交更新, 可以通过(手动的方式/自动也行,推荐手动)通过发送post请求给配置中心(config-server),

5. 当我们配置中心集成了 cloudbus(封装kafka)消息总线后,配置中心会发布更新配置的消息(可以单独发给单个微服务,也可以全部刷新),那些拉取配置的微服务会订阅这个消息并且动态刷新自己的配置.

 

---------------------------------------------------------------下面进入实战-------------------------------------------------------------------------------------

工程设计参考自 -- >官方文档地址 

 

二. 在gitlab搭建存放配置文件的配置中心

  • 1.项目目录, 如图下图所示: 

创建规则:  where ${user.home}/config-center is a git repository containing YAML and properties files.(官方文档),意思就是在你工程目录下创建一个属于自己存放yml文件的git仓库

 

  • 2.在不同的文件夹里存放不同的环境的配置文件

备注:其实当然可以根据不同分支来区分不同环境的配置文件, 但是我这样设计是为了方便统一修改, 根据个人喜好.

文件命名格式: {prefix}-{profileName}.yml

 

三.  搭建config-server, 配置中心服务端

 

  1. config-server其实是单独的微服务. 也需要注册到eureka注册中心 , 这个微服务比较简单 只要一个启动类就行了,
  2. pom文件如下: 
    <?xml version="1.0" encoding="UTF-8"?>
    <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">
    
    	<parent>
    		<artifactId>support</artifactId>
    		<groupId>com.zhouzhou</groupId>
    		<version>1.0.0</version>
    	</parent>
    
    	<artifactId>config.server</artifactId>
    	<modelVersion>4.0.0</modelVersion>
    	<packaging>jar</packaging>
    
    	<name>config-server</name>
    
    	<description>配置中心</description>
    
    
    	<properties>
    		<build.final.name>config-server</build.final.name>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    		<java.version>1.8</java.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-config-server</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-starter-netflix-eureka-client</artifactId>
    			<version>2.0.0.RELEASE</version>
    		</dependency>
    
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter-bus-kafka</artifactId>
    		</dependency>
    
    	</dependencies>
    
    	<build>
    		<finalName>${build.final.name}</finalName>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    				<executions>
    					<execution>
    						<goals>
    							<goal>repackage</goal>
    							<goal>build-info</goal>
    						</goals>
    					</execution>
    				</executions>
    			</plugin>
    			<plugin>
    				<artifactId>maven-antrun-plugin</artifactId>
    				<executions>
    					<execution>
    						<phase>package</phase>
    						<goals>
    							<goal>run</goal>
    						</goals>
    						<configuration>
    							<tasks>
    								<delete file="../../deploy/microservice/libs/${build.final.name}.jar" />
    								<copy file="${project.build.directory}/${build.final.name}.jar" tofile="../../deploy/microservice/libs/${build.final.name}.jar"/>
    							</tasks>
    						</configuration>
    					</execution>
    				</executions>
    			</plugin>
    		
    		</plugins>
    	</build>
    
    	<repositories>
    		<repository>
    			<id>spring-milestones</id>
    			<name>Spring Milestones</name>
    			<url>https://repo.spring.io/milestone</url>
    			<snapshots>
    				<enabled>false</enabled>
    			</snapshots>
    		</repository>
    	</repositories>
    
    
    
    </project>
    

     

  3. 项目结构

 

3. 主启动类, 主要是开启@EnableConfigServer 注解

package com.dyhospital.cloudhis;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.config.server.EnableConfigServer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;


@SpringBootApplication
@EnableConfigServer
@EnableEurekaClient
public class ConfigServerApplication {

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

 

4. 配置文件,不同的环境配置的git地址search-path不同

server:
  port: 17006
  servlet:
    context-path: /

spring:
  application:
    name: config-server

  security:
    user:
      name: admin
      password: 1qaz_QAZ

  kafka:
    bootstrap-servers: 192.168.1.49:9092


eureka:
  # 实例配置类: EurekaInstanceConfigBean
  instance:

    # 设置微服务调用地址为IP优先(缺省为false)
    #    perferIpAddress: true
    prefer-ip-address: true
    #    instance-id: ${spring.cloud.client.ipAddress}:${spring.application.name}:${server.port}
    instance-id: ${spring.cloud.client.hostname}:${spring.application.name}:${server.port}
    # 心跳时间,即服务续约间隔时间(缺省为30s)
    #    leaseRenewalIntervalInSeconds: 10
    lease-renewal-interval-in-seconds: 5
    # 发呆时间,即服务续约到期时间(缺省为90s)
    lease-expiration-duration-in-seconds: 30


    # 客户端配置类: EurekaClientConfigBean
  client:
    #从eureka服务器注册表中获取注册信息的时间间隔(s),默认为30秒
    registryFetchIntervalSeconds: 5
    #是否从服务注册中心获取可用的服务清单,默认为true
    fetch-registry: true
    #是否将自己注册到eureka服务注册中心,默认为true
    register-with-eureka: true
    serviceUrl:
      defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@localhost:17001/eureka-server/eureka/

management:
  endpoints:
    web:
      exposure:
        include: '*'

---
spring.profiles: local

spring:
  # 配置git地址 /{search-paths}/{application}-{profile}.yml
  cloud:
    config:
      label: master
      server:
        git:
          uri: http://gitlab.xxxx.com:9001/xxxxx/config-center.git
          search-paths: local
          username: xxxxx
          password: xxxxx

---
spring.profiles: test

spring:
  # 配置git地址 /{search-paths}/{application}-{profile}.yml
  cloud:
    config:
      label: master
      server:
        git:
          uri: http://gitlab.xxxx.com:9001/xxxxxx/config-center.git
          search-paths: test
          username: xxxx
          password: xxxxx

注意的是对应的配置文件位置

 配置git地址 /{search-paths}/路径下的, 这样就可以和我们的环境对应起来.

 

三.将普通的微服务升级为支持配置中心的微服务

1. 添加依赖:

其中spring-cloud-starter-bus-kafka 与 actuator 是消息总线为了实时更新配置所需要的依赖

actuator的文档见这篇博文即可 Spring Boot 2.0官方文档之 Actuator

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

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

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

 

2. 配置文件如下:

server:
  port: 18003


spring:
  application:
    name: auth-service


---
spring:
  profiles: local
  profiles.include: auth, auth-service, springcloud, redis, database, kafka

  cloud:
    config:
      label: master
      uri: http://localhost:17006
      username: zhouzhou
      password: Zz85141734
      name: dyyy


---
spring:
  profiles: test
  profiles.include: auth, auth-service, springcloud, redis, database,kafka

  cloud:
    config:
      label: master
      uri: http://102.102.104.115:17006
      username: zhouzhou
      password: Zz85141734
      name: dyyy

 

1. profiles:代表应用环境.

2. profiles.include下面的数组代表,有哪些配置文件生效,

3. spring.cloud.config.name 代表配置文件前缀

4. spring.cloud.config.label 代表git分支(默认master不变)

5. spring.cloud.config.url 代表配置中心(config-server)部署的ip地址和端口号

例:  spring.profiles = local ,  spring.profile.include = kafka ,spring.cloud.config.name = test

那么他定位的配置文件是 local环境下的 test-kafka.yml的配置文件

 

---------------------------------------------------------  操作实战 -----------------------------------------------------------------------

四. 启动测试:

1. 先启动eureka注册中心, 这边不展开了.

2. 待eureka注册中心启动后 , 启动config中心, 这边必须设置启动参数(设定生效环境)

IDEA设置启动参数如下图:

 

 而命令行启动的脚本如下: 

java -jar $jarname.jar --spring.profiles.active=local -server -Xms512m -Xmx1024m -Xss256k

这样我们配置文件中local环境的配置中心就启动了;

注意启动服务端时候, 里面启动日志里非常重要的两行日志

 Mapped "{[/actuator/bus-refresh],methods=[POST]}" 
 Mapped "{[/actuator/bus-refresh/{destination}],methods=[POST]}"

 其中, /actuator/bus-refresh 代表向服务端发送这个post请求会刷新所有的微服务的配置

另外,/actuator/bus-refresh接口可以指定服务,即使用"destination"参数,比如 "/actuator/bus-refresh?destination=customers:**" 即刷新服务名为customers的所有服务。

3. 启动客户端微服务同理, 配置生效环境为 local

4. 为了测试, 我这边客户端微服务写了一个简单的Controller进行测试,restful接口返回的是配置文件中 变量名为test的变量



/**
 * Description:
 * User: zhouzhou
 * Date: 2019-10-11
 * Time: 17:29
 */
@Api("测试")
@RefreshScope
@RestController
public class TestController {


    @Value("${test}")
    private String testStr;


    @ApiOperation(value = "查询环境变量")
    @GetMapping(value = "/test/getTtr", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public GenericResponse<String> getTestStr(){

        return new GenericResponse<>(testStr);
    }

}

5. 修改我们的配置文件(dyyy-auth-service.yml),增加test的变量

server:
  port: 18003

# 测试变量
test: 7654321


# kafka 消费组id
spring.kafka.consumer.group-id: auth

6. 打开swagger测试页面

测试结果是 7654321. 

接下来我们改变配置中心的这个值,并且提交更新.

现在,我们利用postman工具向config-server发送刷新配置的请求

http://10.73.146.51:17006/actuator/bus-refresh

这个时候服务端日志如下:

2019-10-24 14:53:56.963  INFO 18076 --- [o-17006-exec-10] com.netflix.discovery.DiscoveryClient    : Shutting down DiscoveryClient ...
2019-10-24 14:53:56.964  INFO 18076 --- [o-17006-exec-10] o.s.c.n.eureka.InstanceInfoFactory       : Setting initial instance status as: STARTING
2019-10-24 14:53:59.965  INFO 18076 --- [o-17006-exec-10] com.netflix.discovery.DiscoveryClient    : Unregistering ...

这时候就开始同步消息了,

客户端日志如下, 开始同步:

2019-10-24 14:54:02.869  INFO {faint} [container-0-C-1] com.netflix.discovery.DiscoveryClient    : Shutting down DiscoveryClient ...
2019-10-24 14:54:02.870  INFO {faint} [container-0-C-1] o.s.c.n.eureka.InstanceInfoFactory       : Setting initial instance status as: STARTING
2019-10-24 14:54:05.872  INFO {faint} [container-0-C-1] com.netflix.discovery.DiscoveryClient    : Unregistering ...

接下来. 我们重新通过swagger来获取test配置变量

刷新成1234567了, 无需重启动态 刷新.

至此, 我们的高可用配置中心搭建结束.

------------------------------------------------------------------ 非常感谢您的阅读,若有不明白处,留言即可 ----------------------------------

github地址:https://github.com/zjhzzhouzhou/SpringCloudProject

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值