zoukankan      html  css  js  c++  java
  • Spring Cloud(3):配置服务(Config)

    Spring Cloud Config的目标是在在大量的微服务中,将服务配置信息和和服务的实际物理部署分离,且服务配置服务不应与服务实例一起部署。配置信息应该作为环境变量传递给正在启动的服务,或者在服务启动时从存储库(文件系统,Git)中读取。

    下面,分别从个方面来讲Config:Config Server,Config Client,High availability Config Server,使用Spring Security保护Config Server,配置自动刷新。

    (1)搭建Config Server

    首先,在pom.xml中添加依赖spring-cloud-config-server。

    <!-- Spring cloud: config server -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>

    其次,在启动类ServerConfigApplication中加入@EnableConfigServer注解。

    @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 Solution

    Git Solution就是把配置文件放到Git Repository中,下面代码使用HTTPS跳过SSL验证,使用username和password来连接Git Repository:

    bootstrap.yml

    # 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端点即可。这里省略。

  • 相关阅读:
    详解git pull和git fetch的区别
    什么是移臂调度,什么是旋转调度?
    常用的资源分配策略有哪两种?在每一种策略中,资源请求队列的排序原则是什么?
    什么是虚拟资源,对主存储器而言,用户使用的虚拟资源是什么?
    进程调度的任务是什么,线程调度的任务是什么?
    用于进程控制的原语主要由哪几个,每个原语的执行将使进程的状态发生什么变化?
    试说明进程创建的主要功能是什么?
    什么是线程,线程与进程有什么区别?
    什么是进程互斥,什么是进程同步,同步和互斥这两个概念有什么联系和区别?
    n个并发进程共用一个公共变量Q,写出用信号灯实现n个进程互斥的程序描述,给出信号灯值得取值范围,并说明每个取值范围的物理意义。
  • 原文地址:https://www.cnblogs.com/storml/p/11011253.html
Copyright © 2011-2022 走看看