SpringCloud combat (XI) - better distributed configuration solutions (Apollo)

This article is SpringCloud combat (XI) - better distributed configuration solutions (Apollo), to focus on the first article, please click the portal:

SpringCloud combat (X) - container automated cluster deployment (Swarm)

We previously introduced container automated cluster deployment. This article describes Ctrip Apollo, it is relative to SpringCloud Config it should be said that a better distribution center solutions, because he comes with a configuration management interface, users do not need to upload the configuration file to the GitLab, but it also self with dynamic configuration refresh, that is when we updated the configuration file in the Apollo Dashboard, in which case a reference to the micro-service configuration file will be updated in real time to achieve, but if by the previous SpringCloud Config to do this thing the will need two things, a GitLab of webhook, a SpringCloud bus message bus can do so from above with respect to these two points Apollo SpringCloud Config considered a better solution for a distributed configuration.

A, Apollo Profile

 Apollo is an open source configuration management center Ctrip framework sector research and development, to centrally manage the configuration used in different environments, different clusters, after configuration changes in real time pushed to the application side, and about rights management, process management and other functions, related Chart as follows:

Second, prepare for work 

Java environment: JDK1.8

MySQL: As the author mentioned apollo table structure for timestamp using multiple default declaration is required 5.6.5 or later.

Note: If the package is compiled to work on the deployment of operating the machine, you need to install maven (version3.5 above), you will not need.

Third, installation and deployment

Based docker installation is relatively simple, step by step I will explain below.

1. Download

First we download Apollo docker related documents in the official GitHub, Portal:

Apollo mirror source files provided by the official GitHub

Here his download in the bottom of the article (the link is not easy to find), illustrated as follows:

wiki relevant address: Details see use case Wiki

点击上面的链接我们跳转到了Apollo官方GitHub,然后我们点击Code,图示如下:

将Apollo部署文件下载到本地 ,图示如下:

 将下载到本地的文件上传到服务器上,图示如下:

  

修改docker-compose.yaml的配置文件,修改数据库配置,这里因为我只需要一个开发环境,所以我只配置了PORTAL_DB、DEV_DB,其他环境的配置注释掉就可以了。

version: '2.2'
services:
  apollo:
    image: idoop/docker-apollo:latest
    container_name: apollo
    network_mode: "host"
    restart: always
#    volumes:
#    - ./application-ldap.yml:/apollo-portal/config/application-ldap.yml:ro #ldap配置文件挂载路径
# 启动前,确认对应环境的数据库已经建立,否则apollo无法启动.
# 默认端口:portal:8070; dev:8080,8090; fat:8081,8091; uat:8082,8092; pro:8083,8093
    environment:
      PORTAL_DB: jdbc:mysql://192.168.3.203:3306/ApolloPortalDB?characterEncoding=utf8
      PORTAL_DB_USER: root
      PORTAL_DB_PWD: aidclouddb@123!@#
#      PORTAL_PORT: 80
#      PORTAL_LDAP: "TRUE"

      DEV_DB: jdbc:mysql://192.168.3.203:3306/ApolloConfigDB?characterEncoding=utf8
      DEV_DB_USER: root
      DEV_DB_PWD: aidclouddb@123!@#

      #FAT_DB: jdbc:mysql://10.0.0.8:3306/ApolloConfigDBFat?characterEncoding=utf8
      FAT_DB_USER: root
      FAT_DB_PWD: password

      #UAT_DB: jdbc:mysql://10.0.0.8:3306/ApolloConfigDBUat?characterEncoding=utf8
      UAT_DB_USER: root
      UAT_DB_PWD: password

 docker-compose.yaml修改后,图示如下:

然后在相应数据库中执行Apollo提供的SQL脚本,地址是

Apollo官方GitHub地址

脚本文件所在相对目录是 /scripts/db/migration/configdb/V1.0.0__initialization.sql、/scripts/db/migration/portaldb/V1.0.0__initialization.sql两个文件,图示如下:

 

将这两个SQL脚本分别在两个数据库中执行,图示如下:

  

数据库配置完成之后,我们进入compose文件所在目录进行执行

    $ /usr/local/docker-apollo-master
    $ docker-compose up -d

 注意:所有docker-compose命令必须在compose文件所在目录执行。

然后我们访问 http://192.168.3.206:8070/,账号密码:apollo/admin,浏览器显示如下:

到此Apollo部署完成。 

四、配置管理

部署好之后我们就可以新建一个项目,这里我已经创建好了一个,使用的是这个教程之前创建的eureka-server工程,我将之前这个工程的配置信息复制上去,图示如下:

然后我修改eureka-server工程中的pom依赖,添加如下内容:

<dependency>
    <groupId>com.ctrip.framework.apollo</groupId>
    <artifactId>apollo-client</artifactId>
    <version>1.4.0</version>
</dependency>

修改bootstrap.yml文件内容

app:
  id: eureka-server
apollo:
  cluster: eureka-server-cluster
  meta: http://192.168.3.206:8080
  bootstrap:
    enabled: true

启动eureka-server工程,图示如下:

说明eureka-server已经成功从Apollo拿到了配置,启动成功。 

五、全局属性配置

在绝大多数情况下,数据库配置、Redis配置、MongoDB配置、RabbitMQ配置、公私钥配置都需要做成全局属性的形式来提供给服务。

1、namespace配置

配置全局变量首先需要创建一个公共的namespace,图示如下:

这里我创建了一个Common的公共namespace,然后我们将application.name属性移到Common中,图示如下:

然后我们修改bootstrap.yml文件,增加刚刚添加的公共namespace

apollo:
  meta: http://192.168.3.206:8080
  cluster: eureka-server-cluster
  bootstrap:
    enabled: true
    namespaces: application,OASCloud.Common

修改后的bootstrap.yml文件,图示如下:

这里我们不光要配置公共的OASCloud.Common,同时也要配置私有的application,因为你在创建namespace的时候是可以创建私有的namespace的,所以私有namespace也会存在多个,需要你明确一下要使用哪些共有和私有属性。

然后我们启动项目,图示如下:

上图说明我们已经加载到了私有命名空间的8761端口,同时也加载到了公共命名空间的csdn服务名。

2、验证

 我们新建一个类叫做SampleController

@RestController
public class SampleController {

    @Value("${name}")
    private String name;

    @RequestMapping("/getName")
    @ResponseBody
    public String getName() {
        return name;
    }
}

通过@Value获取Apollo上的key为name的属性,然后访问 http://localhost:8761/getName,图示如下:

 

在Apollo中我们也可以看到这条配置信息,图示如下:

说明我们已经成功加读取到了Apollo上的配置信息,验证成功。

六、全局变量设置

在很多情况下,我们可能更希望一份配置文件可以跑多个环境,这个时候我们就不能将配置文件写死,利用Apollo将配置文件拉取到本地然后读取的特性,我们可以在Apollo上设置变量,如图所示:

然后我们可以在环境变量中配置server.port值,设置环境变量方式有很多种,你可以在Idea中设置,也可以在Dockerfile等各类脚本中设置,或者是在docker-compose文件中设置,我这里直接在Idea中设置,如图所示:

然后我们启动一下项目,看一下日志信息,如图所示:

程序启动端口是8790,说明变量生效。 

七、敏感信息加密

在正常的生产环境,我们的数据库密码、Eureka密码、公私钥等敏感信息都是需要加密的,这样才能保证信息安全。

1、maven依赖

在maven中新增追加加解密工具依赖

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>2.1.0</version>
</dependency>

2、加解密接口

这个加解密的接口可以写也可以不写,如果不写的话就直接通过jar包进行加解密,我在这里加上这个接口,可以将加解密功能做成工具类来进行使用。

@Controller
public class JasyptController {

    private static Logger logger = LoggerFactory.getLogger(JasyptController.class);

    @Autowired
    private StringEncryptor stringEncryptor;

    private static final String ENCRYPTED_VALUE_PREFIX = "ENC(";
    private static final String ENCRYPTED_VALUE_SUFFIX = ")";

    public static boolean isEncryptedValue(final String value) {
        if (value == null) {
            return false;
        }
        final String trimmedValue = value.trim();
        return (trimmedValue.startsWith(ENCRYPTED_VALUE_PREFIX) &&
                trimmedValue.endsWith(ENCRYPTED_VALUE_SUFFIX));
    }

    private static String getInnerEncryptedValue(final String value) {
        return value.substring(
                ENCRYPTED_VALUE_PREFIX.length(),
                (value.length() - ENCRYPTED_VALUE_SUFFIX.length()));
    }

    @RequestMapping(value = "/encrypt", method = RequestMethod.POST)
    public
    @ResponseBody
    String encrypt(
            @RequestParam("text") String text) {
        String encrypted = stringEncryptor.encrypt(text.trim());
        logger.info("ORIGINAL: " + text);
        logger.info("ENCRYPTED: " + encrypted);
        logger.info("DECRYPTED: " + stringEncryptor.decrypt(encrypted));
        return String.format("ENC(%s)", encrypted);
    }

    @RequestMapping(value = "/decrypt", method = RequestMethod.POST)
    public
    @ResponseBody
    String decrypt(
            @RequestParam("text") String text) {
        String decrypted = stringEncryptor.decrypt(isEncryptedValue(text) ? getInnerEncryptedValue(text) : text);
        logger.info("ORIGINAL: " + text);
        logger.info("DECRYPTED: " + decrypted);
        logger.info("ENCRYPTED: " + String.format("ENC(%s)", stringEncryptor.encrypt(decrypted)));
        return decrypted;
    }
}

然后我们启动项目,通过postman访问 ,图示如下:

 我们将serverName这个字符串加密之后是ENC(bQdCvnhHB2jYQQNIA8BnX+bgmzkt4qHe),然后将加密后的字符串放到Apollo上进行配置,图示如下:

然后我们重启项目并查看日志信息,图示如下:

我们发现从Apollo上取到的spring.application.name已经被解密成明文,我们在本地缓存的配置文件中也可以看出来这点,我这台机器的本地缓存文件目录是 C:\opt\data\eureka-server\config-cache。

可以看到配置文件中的spring.application.name仍然是密文显示,说明我们敏感信息加密解密已经完成了。之前我说加解密除了通过定义接口进行之外,还可以通过Jar包的形式进行

PS C:\Users\Lenovo\.m2\repo\org\jasypt\jasypt\1.9.2> java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="张志翔" password=password algorithm=PBEWithMD5AndDES

----ENVIRONMENT-----------------

Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.211-b12



----ARGUMENTS-------------------

algorithm: PBEWithMD5AndDES
input: 张志翔
password: password



----OUTPUT----------------------

JLPyqyqdPxrTd4Zqy4BmObWRAKe5F/O/


PS C:\Users\Lenovo\.m2\repo\org\jasypt\jasypt\1.9.2> java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI input="JLPyqyqdPxrTd4Zqy4BmObWRAKe5F/O/" password=password algorithm=PBEWithMD5AndDES

----ENVIRONMENT-----------------

Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.211-b12



----ARGUMENTS-------------------

algorithm: PBEWithMD5AndDES
input: JLPyqyqdPxrTd4Zqy4BmObWRAKe5F/O/
password: password



----OUTPUT----------------------

张志翔

首先通过Maven将jasypt的Jar包下载下来,然后去本地maven中寻找jasypt的Jar,找到之后执行上面的操作,就可以实现敏感信息加解密了。

发布了352 篇原创文章 · 获赞 390 · 访问量 37万+

Guess you like

Origin blog.csdn.net/qq_19734597/article/details/90487388