微服务之六集群配置中心(1)

一: 概述

背景:多个项目,多个配置,需要重启多次。为了解决这个问题,出现了集群配置中心Spring Cloud Config

二: Spring Cloud Config

2.1 介绍

配置服务器功能

  • 提供访问配置的服务接口
  • 对属性进行加密和解密
  • 方便嵌入Spring boot项目中

配置客户端功能:

  • 绑定配置服务器,使用远程的属性初始化spring 容器
  • 对属性进行加密和解密
  • 属性改变时,可以对他们进行重新加载
  • 提供了与配置相关的几个管理端点
  • 在初始化引导程序的上下文时,进行绑定配置服务器和属性解密等工作,当然,也可以实现其他工作

2.2 应用结构

SpringCloud Config为分布式集群系统提供了配置服务器与配置客户端,通过对这两者的配置,可以实现对集群中的配置进行管理,在实际应用中,我们会将配置文件放置外部系统(Git、SVN等),SpringCloud Config服务器会到Git/SVN读取配置文件并且使用,Config服务器和客户端可以很容易通过增加依赖集成到系统中。
在这里插入图片描述

2.3 引导程序介绍

Spring Cloud 的程序在进行容器初始化时会先创建一个“引导上下文”(Bootstrap Context),再去创建主应用程序的上下文。

  • 引导上下文读取的配置文件是:bootstrap.yml文件,
  • 主应用程序读取的配置文件是:application.yml

若两者的配置有相同时,后者会覆盖前者的配置。

三:搭建SVN环境

spring cloud 默认为Git,

四:Spring Cloud Config例子(SVN)

4.1 Config 服务端

4.1.1 依赖(server)

<!-- Config-Server -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

<!-- SVN-Kit -->
<dependency>
    <groupId>org.tmatesoft.svnkit</groupId>
    <artifactId>svnkit</artifactId>
    <version>1.9.0</version>
</dependency>

4.1.2 application.yml配置文件(Server)

server:
  port: 8888
##为了方便测试,关闭安全管理机制
management:
  security:
    enabled: false
##配置SVN仓库
spring:
  profiles:
    active: subversion
  cloud:
    config:
      server:
        svn:
          uri: https://localhost/svn/test-project
          username: aitemi
          password: aitemi
        ##默认到SVN根目录下的trunk目录中读取配置文件
        default-label: wps

配置说明spring -cloud -config -server有四种配置

  • git:默认值,表示去Git仓库读取配置文件
  • subversion:表示去SVN仓库读取配置文件
  • native:将会去本地的文件系统中读取配置文件
  • vault:去Vault中读取配置文件,Vault是一款资源控制工具,可对资源实现安全访问

4.1.3 启动类(server)

package com.atm.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@SpringBootApplication
@EnableConfigServer//开启服务器
public class ConfigServerApp {

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

4.1.4 测试

在svn中创建test -project项目。在项目中创建wps目录,并创建first-test.yml文件,
浏览器访问http://127.0.0.1:8888/first-test.yml可以看到first-test.yml的文件

4.2 Config客户端

4.2.1 依赖(Client)

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>1.5.4.RELEASE</version>
</dependency>
<!-- 查看集群实例端点 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    <version>1.5.4.RELEASE</version>
</dependency>

4.2.2 控制层、启动类(Client)

package com.atm.cloud;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 读取远程的配置
 */
@RestController
public class ReadConfigController {

    @Autowired
    private Environment environment;

    @GetMapping("/read")
    public String readConfig() {
        return environment.getProperty("test.user.name");
    }
}
   public static void main(String [] args){
   ........
   }

4.2.3 配置(Client)

在配置客户端新建 bootstrap.yml文件,配置连接SVN仓库

spring:
  ## 配置了spring.application.name,和cloud.config.profile,则读取atm-config-client-dev.yml
  application:
    name: atm-config-client
  cloud:
    config:
      url: http://localhost:8888      
      ## 读取的文件是 atm-config-client-dev.yml
      profile: dev

在bootstrap.yml文件中

  • spring.cloud.config.url:指定配置服务器的地址
  • spring.cloud.config.profile:指定读取的配置文件(atm-config-client-dev.yml)

通过上面的配置,最终配置客户端(Client)先去配置服务器(Server),然后再去SVN服务器寻找svn/test-project/wps/atm-config-client-dev.yml文件
所以在SVN服务器中,建立对应目录下的配置文件(atm-config-client-dev.yml)
个人理解:
在这里插入图片描述

4.3 目录配置总结

前面对服务器和客户端的配置进行简单的配置,总结如下

  • 服务端

    • spring.cloud.config.server.svn.uri=http://localhost/svn/test-project 配置需要连接的SVN地址
    • spring.cloud.config.server.default-label=default-config 到SVN下的指定目录中读取
  • 客户端

    • spring.application.name=atm-config-client,读取的配置文件的名称,
    • spring.cloud.config.profile=dev

4.4 刷新配置

远程SVN中的配置更新后,需要通知客户端该表配置。
解决方法:访问客户端的“/refresh”进行刷新
模拟POST请求

package com.atm.cloud;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class RefreshClientMain {

    public static void main(String[] args) throws Exception {
        CloseableHttpClient client = HttpClients.createDefault();
        // 发送post请求
        HttpPost post = new HttpPost("http://localhost:8080/refresh");
        HttpResponse response = client.execute(post);
        System.out.println(EntityUtils.toString(response.getEntity()));
    }
}

4.5 刷新Bean

在实际应用中,往往不仅之刷新一个配置的值那么简单。在spring容器中,有很多Bean会根据某个属性值进行初始化,配置一旦更新,需要重建这个Bean实例。为了解决上述的问题,spring Cloud提供了@RefreshBean注解。
刷新流程
在spring容器中,有一个类型为RefreshBean的Bean。当/refresh端点被访问时,负责处理刷新的ContextRefresher类会先去远程的配置服务器刷新新配置,然后再调用RefreshBean的refreshAll方法来处理实例,容器中使用了@RefreshBean注解进行修饰的Bean,都会在缓存中进行销毁,当这些Bean被再次引用时,就会创建新的实例,以达到“刷新”的目的
在这里插入图片描述

package com.atm.cloud;

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;

@Configuration
public class MyConfig {

    @Bean
    @RefreshScope
    public Person person(Environment env) {
        // 读取名字创建Person
        String name = env.getProperty("test.user.name");
        // 输出Person名字
        System.out.println("初始化Person bean:" + name);
        // 创建一个Bean
        Person p = new Person();
        p.setName(name);
        return p;
    }
}

五: 配置的加密和解密

  • 配置客户端到服务端读取配置时,会涉及到敏感的信息,如数据库的密码。所以应该对这些数据进行加密和解密。对加密后的密文传输给客户端之前会进行解密
  • 配置服务器支持对称(AES)/非对称加密(RSA)
  • 服务器的加密和解密依赖JCE(Java Cryptography Extension)
  • /encrypt 加密的服务端点
  • /decrypt 解密的服务端点

5.1 对称加密

5.1.1 修改配置服务器(spring-config-server)的application.yml

encrypt:
  key: aitemi
## 为了方便测试,关闭安全管理
management:
  security:
    enabled: false

5.1.2 加密测试(spring-config-server)

加下来编写一个HttpClient客户端去请求加密接口,并且传入需要加密的内容

package com.atm.cloud;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class EncryptMain {

    public static void main(String[] args) throws Exception {
        CloseableHttpClient client = HttpClients.createDefault();
        // 发送post请求
        HttpPost post = new HttpPost("http://localhost:8888/encrypt");

        // 设置请求的参数,对20180323进行加密,编码格式为UTF-8
        HttpEntity entity = new StringEntity("20180323", Consts.UTF_8);
        post.setEntity(entity);

        HttpResponse response = client.execute(post);
        System.out.println(EntityUtils.toString(response.getEntity()));
    }
}

5.1.3 解密(spring-config-server)

package com.atm.cloud;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class DecryptMain {

    public static void main(String[] args) throws Exception {
        CloseableHttpClient client = HttpClients.createDefault();
        // 发送post请求
        HttpPost post = new HttpPost("http://localhost:8888/decrypt");

        // 设置请求的参数,对2cdf324e7d8c6271d883a7a9bdcac532d027141545f1fed273f8c2b803bc3e9d进行解密,编码格式为UTF-8
        HttpEntity entity = new StringEntity("2cdf324e7d8c6271d883a7a9bdcac532d027141545f1fed273f8c2b803bc3e9d", Consts.UTF_8);
        post.setEntity(entity);

        HttpResponse response = client.execute(post);
        System.out.println(EntityUtils.toString(response.getEntity()));
    }
}

加密和解密测试,属于同一个项目,但是在不同类中。

5.2 SVN存储加密数据

在SVN仓库的yml配置文件中,使用“{ciper}密文”的格式来保存加密后的数据。在SVN仓库中test-project/default-config/sping-book-server-dev.yml文件进行下面的配置

test:
 user:
  name: aitemi
  ## 使用'{cipher} xxxx',xxxx代表需要解密的内容
  ## 在properties文件中不需要单引号
  password: '{cipher}fca358013a71b250c4a4a40cd844fdd6d47f8ddc13fb366893fa1ef29c79d55c'

5.3 非对称加密

对称加密和解密使用同一个秘钥,而非对称加密和解密使用不同的秘钥---------公钥和私钥
使用JDK自带keytool工具生成密钥对

keytool -genkeypair -alias "myKey" -keyalg "RSA" -keystore "D:\keys\mykey.keystore"

将密钥对拷贝到配置服务器(spring-config-server)项目resources目录下 。并修改同目录下的application.yml文件,

encrypt:
  keyStore:
    location: classpath:/myKey.keystore  # 密钥对的别名
    password: 123456  # 密钥对的别名
    alias: myKey   # 密钥对的别名 
    secret: 123456       # 密钥口令                   

使用方法和上面的对称加密解密一样,

  • 访问http://localhost:8888/encrypt可以得到加密后的密文
  • http://localhost:8888/decrypt可以得到解密后的值。
  • 在SVN的配置文件中同样使用“{cipher}密文”的格式,访问相应配置时,配置服务器会自动进行解密。

六 其他配置

除了上面的配置外,接下来对服务端和客户端的其他功能进行介绍

6.1 服务器健康指示器

  • 配置服务器访问SVN仓库的uri时,当无法访问时,状态设置为DOWN
  • 除了检测SVN的URI是否连接正常,还可以检测URI下的目录是否可以连接
spring:
  cloud:
    config:
      server:
        svn:
          uri: http://localhost/svn/test-project
          username:admin
          password:123456
          default-label:default-config
        health:
          repositories:
            ## 名称
            test-service:
              ## 是否有这个文件
              label: health-test

配置服务器会向SVN中连接http://localhost/svn/test-project/health-test目录,如果svn连接不上这个目录,在访问服务器的/health端点时,则会出现状态为DOWN的信息。

6.2 客户端的错误提前与重试机制

  • 错误提前
    • 实际应用中,客户端比较关心配置服务器是否能连接上(因为客户端在启动之前会去配置服务器读取配置文件,然后启动自身容器,如果配置服务器连接不上,那么客户端则无法启动,为了防止配置客户端带着错误启动,这里就引入了错误提前机制,在启动失败的时候直接抛出错误)
    • 遇到无法连接时,宁可自己启动失败,也不能带着“错误”启动容器。

基于上述错误,可以使用Spring Cloud Config的错误提前机制。在客户端的bootstrap.yml中,设置

sping.cloud.config.failFast=true

通过上面的设置,即可实现错误提前,只要在启动时无法连接(一次)配置服务器,则会中止容器的启动

  • 重试机制
    • 如果连接错误,就会有与之配套的重试机制。现将
spring.cloud.config.failFast=true

再在客户端添加依赖

<!-- 重试 -->
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.2.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <version>1.5.3.RELEASE</version>
</dependency>
  • 重试机制的主要配置
    • spring.cloud.config.retry.initial-interval:初始的重试间隔,默认为1000毫秒
    • spring.cloud.config.retry.max-attempts:最大重试次数,默认为6次
    • spring.cloud.config.retry.max-interval:最大的重试间隔,默认为2000毫秒
    • spring.cloud.config.retry.multiplier:重试间隔的递增系数,默认为1.1,第二次和第三次之间的重试间隔就会 *递增系数

6.3 安全配置

  • 之前都是配置客户端直接连接服务器,来抓取配置的,在实际环境中,不可能任何客户端连接过来,服务器均接受
  • 就实现一个访问的机制:客户端登录服务器,获取配置

6.3.1 配置服务器端,添加依赖

pom.xml

<!-- 安全机制 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>1.5.3.RELEASE</version>
</dependency>

application.yml添加配置

security:
  user:
    name: root
    password: 123456

6.3.2 客户端,修改配置项

bootstrap.yml

spring:
  cloud:
    config:
      username: root
      password: 123456
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程介绍 【完善体系+精品资料】本课程总计115课时,打造全网最全的微服务体系课程;从微服务是什么、能够做什么开始讲起,绝对零基础入门到精通类型。课程整体脉络十分清晰,每个章节一个知识点,画图+源码+运行讲解,不信你学不会。1、课程先讲解了什么是单体架构、什么是微服务架构、他们之间有什么区别和联系,各自有什么优缺点。2、从本质入手,使用最简单的Spring Boot搭建微服务,让你认清微服务是一种思想和解决问题的手段,而不是新兴技术。3、讲解Spring Boot 与 Spring Cloud 微服务架构之间的联系,原生的RestTemplate工具,以及Actuator监控端点的使用。4、带着微服务所带来的各种优缺点,为大家引入服务发现与注册的概念和原理,从而引入我们的第一个注册中心服务Eureka。5、引入负载均衡的理念,区分什么是服务端负载均衡,什么是客户端负载均衡,进而引入Ribbon负载均衡组件的详细使用。6、为了解决微服务之间复杂的调用,降低代码的复杂度,我们引入了Feign声明式客户端,让你几行代码学习服务的远程调用。7、为了解决服务之间的稳定性,避免发生雪崩问题,我们引入了Hystrix断路器,服务降级和熔断机制。8、微服务集群十分庞大,监控起来是十分困难的,尤其是对每一个接口的熔断情况进行监控,因此我们引入了Turbine微服务监控。9、微服务的调用是杂乱无章的,可以网状调用,怎么做到统一的入口出口,统一的授权、加密、解密、日志过滤,我们引入了第一代网关Zuul。10、微服务配置分散,每次要修改配置都要重启服务,因此我们引入了Config配置中心。11、跟上主流,Consul是当前主流的服务注册与发现、配置中心一体化的解决方案。12、阿里的Nacos服务注册与发现、配置中心在国内炙手可热,Nacos 经历过双十一的微服务中间件。13、Turbin做微服务监控还是太弱,我们需要更强大,可视化,操作性更强的监控系统,因此我引入了Spring Boot Admin体系。14、Zuul已经停止更新支持,Spring Cloud官方推荐的二代网关Spring Cloud Gateway更加强大。15、微服务的安全架构体系虽然复杂,但是是有学习条例的,什么是认证授权、什么是OAuth2.0的原理、 JWT、怎么样去开发实现。 课程资料 【独家资料】1、课程附带全部63个项目源码,其中Hoxton版本项目源码37个,Edgware版本项目26个,2、230页高清PDF正版课件。3、附带nacos、consul、cmder等视频配套软件。学习方法1、每一节课程均有代码,较好的方式为一边听我的讲解,一边使用我提供的项目代码进行观察和运行。2、课程体系庞大,但是并不杂乱,每个章节只针对一个知识点,减轻学习压力。3、坚持每天学习1~2个章节,可以在地铁、公交上用手机学习。【完善知识体系图】
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值