springcloud config 分布式配置中心

一、介绍

1、场景:

微服务系统中,系统多、实例多,如果每个系统都有自己一套配置加载、维护的机制,会导致在生产过程中因为配置问题引发的不必要的沟通成本、故障风险。需要采用分布式配置中心统一管理、统一实现方式。

2、Spring cloud config特性

服务端:存储方式(git、svn、本地文件)、配置读取方式(环境化、多项目仓库)、安全性(访问密码、加密存储)、自动刷新。
客户端:加载远程配置、刷新配置、@refreshscope作用域刷新、集成消息总线。

3、作用

1、Springcloud config把配置文件都集中起来管理,使得分布式项目管理更加科学高效。
2、当配置文件修改时,可以实现自动热更新,不用重启项目。

二、环境搭建

除了运行Java程序必须的环境之外,这里还需要有gitlab(在公网上运行的也可以用GitHub,Git能访问到你项目就可以)、rabbitMQ。gitlab的安装教程:docker的下载安装和运行gitlab、rabbitmq的方式, git的相关知识可以看 https://blog.csdn.net/w1lgy/article/category/8833458,rabbitMQ 的相关知识看:https://blog.csdn.net/w1lgy/article/category/8102651。

设置允许向本地网络发出请求

为了在后面配置文件发生变化时,git能够调用项目monitor接口,安装好gitlab之后,除了正常使用git需要的配置之外,还需要设置网络;步骤如下:

1、登录超级管理员

使用超级管理员登录,默认下可以用admin@example.com 或者 root 登录超级管理员,密码就是安装之后第一次访问设置的那个密码。

2、设置允许向本地网络发出请求

点击Configure GitLab,
在这里插入图片描述
点击setting下的network
在这里插入图片描述
勾上allow requests to the local network from hooks and services,并点save changes保存。
在这里插入图片描述

三、注册中心eureka

说明:以下代码注释说明得非常清楚,就不多做解释,有疑问的欢迎留言提问!需要的可以看我的上一篇讲eureka的文章:spring cloud eureka(服务注册中心)
1、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>
	<!-- spring boot 封装spring  
		 starter封装、自动配置autoconfiguration
	 -->
	<parent>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-parent</artifactId>
		<version>Dalston.SR1</version>
		<relativePath />
	</parent>
	<groupId>com.dongnaoedu.springcloud</groupId>
	<artifactId>lession-2-eureka</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Dalston.SR1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<dependencies>
		<!-- spring-boot-starter-web web项目,集成容器tomcat -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- spring-boot-starter-actuator 管理工具/web 查看堆栈,动态刷新配置 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<!-- cloud eureka组件 注册中心 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka-server</artifactId>
		</dependency>
	</dependencies>

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

2、application.yml:

# 上下文初始化加载
info:
  name: Eureka server
  contact: 动脑科技VIP

spring:
  profiles:
    active: dev
---
spring:
  profiles: dev
server:
  port: 8761
eureka:
  client:
    # 是否注册到eurekaserver
    registerWithEureka: true
    # 是否拉取信息
    fetchRegistry: false
    # eureka server地址
    serviceUrl:
      defaultZone: http://127.0.0.1:8761/eureka/
  server:
    waitTimeInMsWhenSyncEmpty: 0
    # false 关闭自我保护,不管如何都要剔除心跳检测异常的服务
    enableSelfPreservation: true
  instance:
    hostname: eureka1

3、bootstrap.yml

# 比application context先加载
# 应用名称
spring:
  application:
    name: eureka-server

4、启动类

package com.dongnaoedu.springcloud;

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

@SpringBootApplication
@EnableEurekaServer
public class EurekaApp {
	public static void main(String[] args) {
		new SpringApplicationBuilder(EurekaApp.class).web(true).run(args);
	}
}

四、server

1、application.yml:

info:
  name: 配置中心
  contact: 动脑VIP

server:
  port: 8888
# 使得/refresh和查看env不需要验权
management:
  security:
    enabled: false
# 访问时需要提供用户和密码
security:
  # 这个接口不做用户名密码校验, /monitor接收git刷新通知
  ignored: /monitor
  user:
    name: user
    password: 12345678
encrypt:
  # 加解密用的秘钥
  key: 12345678

# rabbitmq的地址 用户名 密码
spring:
  rabbitmq:
    host: 192.168.99.100
    username: guest
    password: guest
  profiles:
    active: dev

# 不同环境的配置
---
spring:
  profiles: dev
eureka:
  client:
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      defaultZone: http://127.0.0.1:8761/eureka/
  instance:
    preferIpAddress: true
---
spring:
  profiles: prod
eureka:
  client:
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      defaultZone: http://eureka1:8761/eureka/,http://eureka2:8762/eureka/,http://eureka3:8763/eureka/
  instance:
    preferIpAddress: true

补充:

##定义env 和 health的开放 2.0中这个方式已经被取消
#management:
#   security:
#       enabled: true
​
​
##定义env 和health的开放 2.X版本应该这么写
​
management:
  endpoints:
      web:
          exposure:
              include: env

2、bootstrap.yml:

spring:
  application:
    # 配置文件就是用这个来做文件名的,要对应的哦。
    name: lession-2-config-server
  profiles:
    active: dev,git
  cloud:
    config:
      server:
        # 本地文件
        native:
          # 用本地文件夹存储配置,仅作配置示例,没起作用。要想起作用,将上面的 active中git 改为 native
          searchLocations: file:D:\\cloud\\dongnao\\configrepo
        # git仓库 gitlab地址
        git:
          # 记得在先gitlab上创建一个对应的project
          uri: http://192.168.99.100:18080/root/project1.git
          search-paths: /
          username: root
          password: 12345678
          repos: 
            # 不同环境不同的库,这里的话,只有当应用中的spring.profiles.active=staging的时候才生效
            lession-2-sms-sys-staging:
              pattern: '*/staging'
              # 记得在先gitlab上创建一个对应的project
              uri: http://192.168.99.100:18080/root/lession-2-config-repo-staging.git
            # 不同项目不同库
            lession-2-sms-webmvc: 
              pattern: 
                # 这里是根据服务名称匹配的spring.application.name
                - lession-2-sms-webmvc/**
                - lession-2-sms-webmvc*
              # 这里面的是本地git仓库的,不知道配置本地git仓库的也可以像上面一样配置成远程git地址
              uri: file:D:\cloud\dongnao\config-repo
        # 加解密
        encrypt:
          enabled: true
# svn环境  
# spring.profiles.active=subversion
# spring.cloud.config.server.svn.uri=http:#127.0.0.1:1234/sms-sys/development/trunk
# spring.cloud.config.server.svn.username=xxx
# spring.cloud.config.server.svn.password=xxx

3、启动类

@SpringBootApplication
@EnableConfigServer
@EnableEurekaClient
public class ConfigServerApplication {
	public static void main(String[] args) {
		new SpringApplicationBuilder(ConfigServerApplication.class).web(true).run(args);
	}
}

4、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>
	<!-- spring boot 封装spring  
		 starter封装、自动配置autoconfiguration
	 -->
	<parent>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-parent</artifactId>
		<version>Dalston.SR1</version> 
		<relativePath /> 
	</parent>
	<groupId>com.dongnaoedu.springcloud</groupId>
	<artifactId>lession-2-config-server</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Dalston.SR1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<dependencies>
		<!-- spring-boot-starter-web web项目,集成容器tomcat -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- spring-boot-starter-actuator 管理工具/web 查看堆栈,动态刷新配置 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		<!-- spring-boot-starter-security -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<!-- cloud config组件 配置中心 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-config-server</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>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

五、客户端

1、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>
	<!-- spring boot 封装spring  
		 starter封装、自动配置autoconfiguration
	 -->
	<parent>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-parent</artifactId>
		<version>Dalston.SR1</version>
		<relativePath />
	</parent>
	<groupId>com.tony</groupId>
	<artifactId>lession-2-sms-sys</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Dalston.SR1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<dependencies>
		<!-- spring-boot-starter-web web项目,集成容器tomcat -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- spring-boot-starter-actuator 管理工具/web 查看堆栈,动态刷新配置 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>
		<!-- spring bus 事件通知实现自动刷新 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>
        <dependency>
        	<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
			<version>2.9.0</version>
        </dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

2、application.yml

# eureka是必须的


spring:
  profiles:
    # 这里的意思是启用dev环境
    active: dev

---
spring:
  profiles: dev
eureka:
  client:
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      defaultZone: http://127.0.0.1:8761/eureka
  instance:
    preferIpAddress: true
    
---
spring:
  profiles: prod
eureka:
  client:
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      # 这里写成eureka1,是因为我修改系统的hosts, 127.0.0.1 eureka1
      defaultZone: http://eureka1:8761/eureka
  instance:
    preferIpAddress: true

3、bootst.yml

spring:
  application:
    name: lession-2-sms-sys
  cloud:
    config:
      discovery:
        # 使用eureka发现配置中心服务
        enabled: true
        # 配置中心服务名称/ID
        serviceId: lession-2-config-server
      # 登录用户名和密码
      username: user
      password: 12345678
      # 覆盖本地配置
      overrideNone: false
      failFast: true
      name: ${spring.application.name}
      profile: ${spring.profiles.active}
      # git仓库中,可以使用label来做不同版本的配置管理,默认是master,可以用来做版本管理。比如“2.0”
      label: 'master'

4、启动类

package com.dongnaoedu.springcloud.service;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan("com.dongnaoedu")
@EnableEurekaClient
public class SmsServiceApplication {
	public static void main(String[] args) {
		new SpringApplicationBuilder(SmsServiceApplication.class).web(true).run(args);
	}
}

5、controller

package com.dongnaoedu.springcloud.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RefreshScope // 此处很重要 +++
public class SmsController {

	@Value("${tony.configString}")
	private String configString;

	// 测试注入tony.configString配置
	@RequestMapping("/test")
	public String sendSms() {
		return "configString的值:" + configString;
	}

	@Autowired
	Environment env;

	@RequestMapping("/get/{configName}")
	public String test(@PathVariable String configName) {
		return configName + "的值为:" + env.getProperty("tony." + configName);
	}
}

6、redis

package com.dongnaoedu.springcloud.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import redis.clients.jedis.JedisPool;

@Configuration
@RestController
@RequestMapping("/redis")
public class RedisController {
	@Autowired
	Environment env;

	@Bean
	@RefreshScope// 在refresh之后,这个实例会被刷新
	public JedisPool jedisPool() {
		String host = env.getProperty("redis.host");
		int port = env.getProperty("redis.port", Integer.class);
		return new JedisPool(host, port);
	}

	@Autowired
	private JedisPool jedisPool;

	// 获取一个key的值 并打印出来
	@RequestMapping("/get/{key}")
	public String sendSms(@PathVariable String key) {
		String value = jedisPool.getResource().get(key);
		return "	redis中" + key + "的值为:" + value;
	}
}
热更新

当我们的配置修改之后提交到gitlab上,各客户端服务是不会主动获取配置的改变的,客户端获取新的配置信息的方式有两种:
1、手动调用项目refresh(post接口)接口刷新。
2、在gitlab项目上的setting->Integrations设置集成路径,这里的ip和端口是springcloud config项目的ip和端口
在这里插入图片描述
这样当git配置文件上传到gitlab上时,就会触发这个接口,给各个项目刷新配置文件信息。

六、MVC

1、springmvc中的配置加载 和 环境化
profile激活不同环境,加载不同的配置
普通mvc程序通过 xml中 <beans profile="dev">...</beans> 方式可以进行配置

  <beans profile="test">  
    <bean id="testDatasource" class="xxxxx.datasource"/>  
  </beans>  
    <beans profile="prod">  
    <bean id="prodDatasource" class="xxxxx.datasource"/>
    </beans>  

2、在xml配置文件中配置<context:property-placeholder location="classpath:sms.properties"/>就可以设置${}里取到的变量值就是sms.properties里配置的值。
3、spring cloud config 工作模式
配置项怎么配置? 通过配置文件进行配置并存储在git中
谁去读配置文件? configserver配置中心
应用系统中配置信息从哪来? 从configserver远程获取
3、全局刷新怎么实现的?
通过rabbitmq发送消息, 订阅的客户端(应用系统)收到消息后,判断是否需要刷新
具体实现后面spring cloud stream/bus会讲到

4、自动刷新是什么一个机制?
gitlab提交配置更新的时候,触发一个事件(项目-设置-集成-webhook)

发起http请求到config-server monitor组件
http://192.168.99.1:8888/monitor 这是配置中心地址

configserver解析请求,通过spring cloud bus消息总线发送通知给各服务(和/bus/refresh一样)
对应的webapi类:PropertyPathEndpoint#notifyByPath
5、安全机制:如何保证配置的保密性?
项目中的密码 不应该明文存储,应该是密文
configserver访问控制:用户名密码
文件内容加密:configserver中设置spring.cloud.config.server.encrypt.enabled=true
再配置一个秘钥:encrypt.key=12345678
配置文件中密文需要以{cipher}做为标识:如spring.rabbitmq.password= ‘{cipher}31010f99731d4bd8aa7e3ce76152b5686265e1160043aac7cf769c3c8e1bb7ef’

对应的web api:EncryptionController#encrypt 加密
EncryptionController#decrypt 解密

6、config server web接口访问配置信息:
application 默认就是我们的spring.application.name
profile 环境(dev/prod)
label git中的分支(可以用它实现版本管理),这个操作回看视频

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值