Spring Cloud(3):配置服務(Config)

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。

本部分參考:https://cloud.spring.io/spring-cloud-config/spring-cloud-config.html#_specifying_multiple_urls_for_the_config_server

 

(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端點便可。這裏省略。

相關文章
相關標籤/搜索