Spring Cloud Config的目标是在在大量的微服务中,将服务配置信息和和服务的实际物理部署分离,且服务配置服务不该与服务实例一块儿部署。配置信息应该做为环境变量传递给正在启动的服务,或者在服务启动时从存储库(文件系统,Git)中读取。html
下面,分别从个方面来说Config:Config Server,Config Client,High availability Config Server,使用Spring Security保护Config Server,配置自动刷新。git
(1)搭建Config Servergithub
首先,在pom.xml中添加依赖spring-cloud-config-server。spring
<!-- Spring cloud: config server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency>
其次,在启动类ServerConfigApplication中加入@EnableConfigServer注解。bootstrap
@SpringBootApplication @EnableConfigServer public class ServerConfigApplication { public static void main(String[] args) { SpringApplication.run(ServerConfigApplication.class, args); } }
咱们知道,Config Server是用来集中管理配置文件的地方,那么在哪存放这些配置文件呢?Config Server提供了两种方法,分别是Git Solution和Classpath and file-based solution。服务器
(1.1)Git Solutionapp
Git Solution就是把配置文件放到Git Repository中,下面代码使用HTTPS跳过SSL验证,使用username和password来链接Git Repository:curl
bootstrap.ymlide
# bootstrap.yml用来程序引导时执行,应用于更加早期配置信息读取,如能够使用来配置application.yml中使用到参数等
# bootstrap.yml先于application.yml加载
spring:
application:
name: server-config
# 使用对称加密设置secret key(https://blog.csdn.net/u012702547/article/details/78499458)
# curl http://{confgit server host}:{port}/server-config/encrypt -d {pass} (need remove security)
encrypt:
key: my-secret-key
application.yml微服务
# Git solution spring: cloud: config: server: git: uri: https://github.com/lyz170/spring-cloud-demo.git # https://cloud.spring.io/spring-cloud-config/spring-cloud-config.html#_skipping_ssl_certificate_validation skipSslValidation: true # https://cloud.spring.io/spring-cloud-config/spring-cloud-config.html#_placeholders_in_git_search_paths searchPaths: 'config/{application}' username: xxxxxxxx password: '{cipher}xxxxxxxxxxxxx'
咱们能够看到,咱们使用了一个叫spring-cloud-demo的repository,由于用了HTTPS访问,因此咱们跳过SSL验证,经过查找仓库中config目录下的全部applications,使用username和password来链接Git Repository。这里的password使用了JCE加密,须要从Oracle官网上下载额外的jar包,若是不了解的话能够查阅相关资料。
关于更多的Git配置,能够查阅https://cloud.spring.io/spring-cloud-config/spring-cloud-config.html#_git_backend。
(1.2)Classpath and file-based solution
就是把配置文件所有放在项目中(这里是src/main/resources/config),经过classpath去读取:
bootstrap.yml
spring:
application:
name: server-config
application.yml
# Classpath and file-based solution spring: profiles: active: native cloud: config: server: native: searchLocations: classpath:config,classpath:config/app1,classpath:config/app2
不管是用(1.1)仍是(1.2),目录和文件的命名都是有要求的。目录是spring.application.name的值,文件为{application}-{profile}.yml。假设有2个application(app1,app2),和2个环境(dev,prod),目录和文件的命名以下:
config |--app1 |--app1.yml |--app1-dev.yml |--app1-prod.yml |--app2 |--app2.yml |--app2-dev.yml |--app2-prod.yml
[注] 启动时不管环境参数是dev仍是prod,都会先读取默认的{app}.yml,而后用dev或prod中的参数覆盖默认的{app}.yml。因此,能够把一些共通的配置配到{app}.yml中,把须要改变或增长的配置配到相应的{app}-{profile}.yml中。
配置完成后,咱们启动该服务,能够经过下面的格式看到配置文件的内容:
http://{hostname}:{port}/{应用名}/{环境名}[/{分支名}] http://{hostname}:{port}/{应用名}-{环境名}.yml http://{hostname}:{port}/{分支名}/{应用名}-{环境名}.yml
例如:http://127.0.0.1:10010/server-config/app1/prod,http://127.0.0.1:10010/server-config/app1-dev.yml
(2) 搭建Config Client
先引入依赖包spring-cloud-starter-config。
<!-- Spring cloud starter: config client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>
在配置文件(bootstrap.yml)中添加配置,指定config server服务的位置。
spring: application: name: app-db cloud: config: uri: http://localhost:10010/server-config
这样,在服务启动时,会根据参数[--spring.profiles.active={env}],去Config Server拿到相应环境的配置文件后,再启动项目。
(3) 搭建High availability Config Server
既然是高可用的,因此首先须要建立多个Config Server实例。而后这里有两种方式:Eureka Service Discovery和Multiple Urls。
(3.1)Eureka Service Discovery
这里使用了Spring Cloud Netflix and Eureka Service Discovery,即把全部Config Server做为Eureka Client注册Eureka Server中,再经过Eureka的Discovery,只需配置一个service-id便可链接多个Config Server。
如何把Config Server注册Eureka Server中再也不赘述,能够去看Spring Cloud(3):服务发现(Eureka)的第2部分。配置好Eureka后,须要分别配置Config Server和Config Client。
Config Server - bootstrap.yml
# If the Config Server is secured with HTTP Basic, you can configure the credentials as user and password. # Also, if the Config Server has a context path, you can set configPath. # http://cloud.spring.io/spring-cloud-static/Greenwich.RELEASE/single/spring-cloud.html#discovery-first-bootstrap eureka: instance: metadataMap: # user: xxxxxxxx # password: '{cipher}xxxxxxxx' configPath: /server-config
[注] 若是配置了server.servlet.ocntext-path,则须要配置configPath;若是使用了HTTP Basic,则要在这里配置认证信息。
Config Client - bootstrap.yml
spring: application: name: app-db cloud: config:
# 使用service-id代替url实现config高可用 discovery: enabled: true serviceId: server-config
[注] 这里的service-id就是Config Server的application name,也是在Eureka Server中注册的application name。
在配置Config Client时,咱们发现,配置Config Server的优先级很高,在bootstrap.yml中。然而,使用Discovery的方式必须在配置Config Server前配置好Eureka。这也就致使了bootstrap.yml中的配置过多,而且不能把这些配置配到Config Server中。在多环境中,咱们还要在本地建立多个bootstrap-{profile}.yml。这个问题目前我尚未解决方法。
本部分参考:https://cloud.spring.io/spring-cloud-config/spring-cloud-config.html#discovery-first-bootstrap
(3.2)Multiple Urls
其实就是(2)中配置多个URL便可。
spring: application: name: app-db cloud: config: uri: "http://localhost:10010/server-config,\ http://127.0.0.1:10011/server-config,\ http://127.0.0.1:10012/server-config"
须要说明的是,Config Client会逐个链接,只有在Config Server未运行时(即应用程序已退出时)或发生链接超时时,才能确保高可用性(即跳过当前url链接下一个url)。可是,若是Config Server返回500(内部服务器错误)响应或Config Client从Config Server收到401(因为凭据错误或其余缘由),表示用户问题而不是可用性问题,则Config Client不会尝试去链接下一个url。
(4)使用Spring Security保护Config Server
首先,须要添加spring-cloud-starter-security依赖。
<!-- Spring cloud starter: security --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency>
而后,添加一个user和password用于登陆便可。
@EnableWebSecurity public class ServerConfigWebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Bean public PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //@formatter:off PasswordEncoder encoder = new BCryptPasswordEncoder(); auth.inMemoryAuthentication() .withUser("config-user").password("{bcrypt}" + encoder.encode("config-user")).roles("USER"); //@formatter:on } }
当Config Client链接时,若是使用了Eureka Service Discovery方式,只需在Config Server中添加以下配置:
# 使用对称加密设置secret key(https://blog.csdn.net/u012702547/article/details/78499458) # curl http://{confgit server host}:{port}/server-config/encrypt -d {pass} (need remove security) encrypt: key: my-secret-key # If the Config Server is secured with HTTP Basic, you can configure the credentials as user and password. # Also, if the Config Server has a context path, you can set configPath. # https://cloud.spring.io/spring-cloud-config/spring-cloud-config.html#discovery-first-bootstrap # 该配置只用于Eureka Service Discovery(spring.cloud.config.discovery.serviceId) 若是使用了Multiple Urls则不须要配置 eureka: instance: metadataMap: user: xxxxxxxx password: '{cipher}xxxxxxxx' configPath: /server-config
若是使用了Url或Multiple Urls,能够在Config Client中这样写:
encrypt: key: my-secret-key config: username: xxxxxxxx password: '{cipher}xxxxxxxx' spring: application: name: app-db cloud: config: uri: "http://${config.username}:${config.password}@localhost:10010/server-config,\ http://${config.username}:${config.password}@127.0.0.1:10011/server-config,\ http://${config.username}:${config.password}@127.0.0.1:10012/server-config"
(5)配置自动刷新
简要来讲,就是使用@RefreshScope注解,而后客户端执行/refresh端点便可。这里省略。