接入统一配置管理-nacos
在整个完成的过程中,我们遇到过一个问题:我们很多的配置都是放在配置文件中的。比如上一节我们接入了,他的配置就是放在application.properties文件中。而还有些不方便放到代码中的配置,比如发送需要的阿里云的账号信息,这些私密的配置我们用取巧的方式放到了本机其他的目录下。本次介绍一种分布式系统中经常使用的统一配置管理
使用场景
如果我们改动了配置,比如发送短信验证码的阿里云账号的AK,SK泄露了,我们需要重新生成一份。我们的应用部署在了几十上百台机器上
如果是之前的配置,我们需要登录每一台机器,修改AK、SK的配置。然后重启应用。这个过程在一些基础建设比较差的公司,就需要花上大半天的时间。即使有自动化的发布系统可以批量重启,也需要依赖系统分批发布时间,应用重启时间。这就会大大影响开发效率。我们可以将需要修改的配置放到统一配置中心进行管理。配置修改后会动态分发下去,支持在运行时生效,不需要重启系统,达到秒级生效的效果。如下图所示
统一配置中心提供了操作配置的界面,只要在应用中引入对应的client,就可以通过接口来读取配置中心的配置。配置中心的内容改变后,应用中的client也会感知到变化,实时地更新对应的配置,达到了不需要登录每个机器,不需要重启就将配置生效的效果,也经常用于类似开关的场景上,达到服务降级的效果。比如在电商系统中,现在跑着一个准确率非常高,但性能非常差的推荐算法。如果此时在进行大促,流量预计会有5分钟的突增。那为了确保系统不被打挂,可以通过统一配置中心修改下开关配置,从而调整程序的逻辑,走到一个准确率一般,但性能比较好的算法上。
Nacos介绍
这是一款阿里巴巴提供的统一配置中心的开源产品,主要有2个常用的功能,第一个就是提供统一配置的能力,第二个是提供服务注册和发现能力。本节我们只使用了它统一配置的能力。Nacos也是Spring Cloud Alibaba的一个组件,已经出现在了Apache官方文档中,提供给全世界的程序员使用。
以下是nacoas的官方文档:
以下是spring官网上spring cloud alibaba的文档
nacos安装
目前nacos开源不久,兼容性有点差,加上我系统比较老,安装的时候遇到了几个问题,记录下
==> start.out <==
dyld: lazy symbol binding failed: Symbol not found: ____chkstk_darwin
Referenced from: /private/var/folders/qp/3wjqwfpx68sfy1tm8wf8pxtr0000gn/T/librocksdbjni8357728138471088310.jnilib (which was built for Mac OS X 10.15)
Expected in: /usr/lib/libSystem.B.dylib
dyld: Symbol not found: ____chkstk_darwin
Referenced from: /private/var/folders/qp/3wjqwfpx68sfy1tm8wf8pxtr0000gn/T/librocksdbjni8357728138471088310.jnilib (which was built for Mac OS X 10.15)
Expected in: /usr/lib/libSystem.B.dylib
于是下了评论中对应的nacos版本1.4.1,安装了下依旧报错
23:09:27,550 WARN Failed to scan [jar:file:/opt/nacos-1.4.1/target/nacos-server.jar!/BOOT-INF/lib/spring-webmvc-5.1.18.RELEASE.jar!/] from classloader hierarchy
Unable to open root Jar file 'war:file:/opt/nacos-1.4.1/target/nacos-server.jar*/BOOT-INF/lib/spring-webmvc-5.1.18.RELEASE.jar' :
at org.springframework.boot.loader.jar.Handler.getRootJarFile(Handler.java:318)
at org.springframework.boot.loader.jar.Handler.getRootJarFileFromUrl(Handler.java:300)
at org.springframework.boot.loader.jar.Handler.openConnection(Handler.java:86)
at java.base/java.net.URL.openConnection(URL.java:1094)
...
Unable to open root Jar file 'war:file:/opt/nacos-1.4.1/target/nacos-server.jar*/BOOT-INF/lib/spring-webmvc-5.1.18.RELEASE.jar' :
at org.springframework.boot.loader.jar.Handler.getRootJarFile(Handler.java:318)
at org.springframework.boot.loader.jar.Handler.getRootJarFileFromUrl(Handler.java:300)
at org.springframework.boot.loader.jar.Handler.openConnection(Handler.java:86)
at java.base/java.net.URL.openConnection(URL.java:1094)
at java.base/java.net.URL.openStream(URL.java:1161)
...
最后试了第二个版本1.4.3才成功。
启动命令(默认是集群启动,我就一台机器,指定为单机模式):
sh startup.sh -m standaone
启动后打开如下链接
http://localhost:8848/nacos
输入默认的用户名和密码,都为nacos。下方左边就是统一配置的功能,右边加号可以创建配置。
代码中引入nacos依赖
和以往一样,我们在中,创建一个分支来记录本节的内容
git branch 202205_nacos
git checkout 202205_nacos
首先我们在pom.xml中先引入spring-cloud和spring-cloud-alibaba的依赖定义。注意,是在dependencyManagement标签下面,
最新的版本号可以在https://mvnrepository.com/中搜索
<dependencyManagement>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2021.0.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后在dependency标签下面加入如下依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
第二个依赖是让bootstrap.properties文件能被加载,这个文件是给spring-cloud用的,会在application.properties文件前被加载。
nacos配置
打开nacos控制台:
http://localhost:8848/naco
创建一个配置
编写配置类代码
新建一个NacosConfig.java, 里面就一个name字段, @RefreshScope可以在配置发生变化的时候,动态地更新name自动,代码非常简洁,如下所示
package com.fudy.shop.infrastructure.config;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
@Component
@RefreshScope
public class NacosConfig {
@Value("${name}")
@Getter
private String name;
}
我们写个单元测试NacosConfigTest.java, 1分钟内每隔10秒打印一下name的值。
package com.fudy.shop.infrastructure.config;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
public class NacosConfigTest {
private NacosConfig config;
public void test1() throws Exception{
int i=6;
while(i-- > 0) {
System.out.println("name: " + config.getName());
Thread.sleep(10000);
}
}
}
期间我们在nacos后台修改下name的值
修改后测试类的控制台上打印了我们最新修改的数据
这就说明了在程序运行的过程中,我们通过nacos控制台修改配置,是可以直接改掉程序中对应的值的,具有动态配置的能力。