前提
最近由于业务发展,需要调研一套完善和主流的基础架构,进行中台化(微服务)的实施,考虑到技术栈切换到SOFAStack 。既然整个体系都切换到蚂蚁金服的技术栈,那么自然考虑一些基础组件如服务注册发现、配置管理等都切换为阿里的技术栈。考虑到目前比较热的服务发现组件是Nacos ,需要调研SpringBoot 服务接入Nacos 的可行性,为以后强制要求新服务使用SOFAStack + Nacos 的技术栈进行服务开发打下基础。

Nacos简介
下面的简介来源于Nacos 的官网:
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。Nacos 是构建以服务为中心的现代应用架构(例如微服务范式、云原生范式)的服务基础设施。
Nacos 地图:

Nacos 生态图:

从Nacos 提供的发展地图来看,它基本提供了目前微服务实施中一些核心问题:监控、服务发现注册、配置灰度发布、配置回滚等等。另外,它在生态上能够融入目前主流的K8S 、Docker 、SpringCloud 、Consul 、Zookeeper 等等(有点像屏蔽底层细节,只需少量配置就可以切换底层架构的实现),这一点十分重要。目前Nacos 在阿里云上提供了商用版本(记得有前辈说过开源的终极目标就是商用,大概如此)。如果在项目中使用的是SpringCloud 全家桶,引入Nacos 以及它和SpringCloud 之间的胶水层,可以完全替代Eureka 组件的功能,替代和强化部分Spring Cloud Config 的功能。
Nacos服务部署
Nacos-Server 部署相对简单,它的发布版本见Github的Releases页面。下载完成后进行解压,Windows 系下启动Nacos-Server 只需进入解压后的${解压目录}nacosbin 目录,执行startup.cmd 即可,服务启动成功的结果如下:

单机模式在不修改配置的前提下直接启动,使用的是内存数据库,重启后数据会被清空。如果需要数据持久化,则需要建立数据库,具体的步骤是:
- 建表的脚本在
${解压目录}nacosconf 目录下,见schema.sql 和nacos-mysql.sql 两个文件。
- 自行通过建表的脚本建立数据库。
- 需要指定数据库,则需要修改
${解压目录}nacosconfapplication.properties ,在文件的尾部追加数据源的连接配置,下面是官方给出的多数据源的例子:
# 需要确保多个数据源的用户名和密码一致
db.num=2
db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.url.1=jdbc:mysql://11.163.152.9:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=nacos_devtest
db.password=nacos
测试获取已经注册的服务:
λ curl -X GET http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName
{"hosts":[],"name":"DEFAULT_GROUP@@nacos.naming.serviceName","clusters":""}
访问http://127.0.0.1:8848/nacos 即可打开Nacos-Console ,初始的登录账号和密码都是nacos :

更多运维部署相关的内容见文档运维指南中的一节。

SpirngBoot应用使用Nacos作为注册中心
SpringBoot 应用使用Nacos 作为注册中心需要引入依赖nacos-discovery-spring-boot-starter ,笔者编写本文的时候(2020-01-01),该依赖的最新版本为0.2.4 ,对应于SpringBoot 的版本为2.0.3.RELEASE ,引入如下依赖:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>0.2.4</version>
</dependency>
</dependencies>
为了方便起见,笔者把控制器、服务注册的代码都写在启动类ProvideApplication 中:
@RestController
@SpringBootApplication(scanBasePackages = "club.throwable.provide")
public class ProvideApplication implements CommandLineRunner {
@NacosInjected
private NamingService namingService;
@Value("${spring.application.name}")
private String applicationName;
@Value("${server.port}")
private Integer serverPort;
public static void main(String[] args) {
SpringApplication.run(ProvideApplication.class,args);
}
@GetMapping(path = "/hello")
public String hello(@RequestParam(name = "name") String name) {
return String.format("%s say hello!",name);
}
@Override
public void run(String... args) throws Exception {
// 通过Naming服务注册实例到注册中心
namingService.registerInstance(applicationName,"127.0.0.1",serverPort);
}
}
配置文件application-provide.properties 内容如下:
spring.application.name=provide-service
server.port=9092
nacos.discovery.server-addr=127.0.0.1:8848
使用spring.profiles.active=provide 启动ProvideApplication ,启动成功后用浏览器打开Nacos-Console :

暂时可知服务的提供方已经注册成功。接着编写服务的消费方代码,引入的最小依赖和服务提供方完全一致,编写启动类ConsumeApplication 如下:
@SpringBootApplication(scanBasePackages = "club.throwable.consume")
public class ConsumeApplication implements CommandLineRunner {
@NacosInjected
private NamingService namingService;
public static void main(String[] args) {
SpringApplication.run(ConsumeApplication.class,args);
}
@Override
public void run(String... args) throws Exception {
// 根据服务名从注册中心获取一个健康的服务实例
Instance instance = namingService.selectOneHealthyInstance("provide-service");
// 这里只是为了方便才新建RestTemplate实例
RestTemplate template = new RestTemplate();
String url = String.format("http://%s:%d/hello?name=throwable",instance.getIp(),instance.getPort());
String result = template.getForObject(url,String.class);
System.out.println(String.format("请求URL:%s,响应结果:%s",url,result));
}
}
消费服务的配置文件application-consume.properties 内容如下:
spring.application.name=consume-service
server.port=9091
nacos.discovery.server-addr=127.0.0.1:8848
使用spring.profiles.active=consume 启动ConsumeApplication ,CommandLineRunner 执行完毕后控制台打印:
请求URL:http://127.0.0.1:9092/hello?name=throwable,响应结果:throwable say hello!
这种方式使用起来会感觉模板代码比较多,不够简洁。如果在SpringCloud 体系中,结合Feign 客户端则可以省略这些模板代码。
SpirngBoot应用使用Nacos管理配置
如果使用Nacos 进行配置管理,则需要引入nacos-config-spring-boot-starter 依赖,笔者编写本文的时候(2020-01-01),该依赖的最新版本为0.2.4 :
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>0.2.4</version>
</dependency>
新建一个启动类ConfigApplication 如下:
@RestController
@NacosPropertySource(dataId = "example",autoRefreshed = true)
@SpringBootApplication(scanBasePackages = "club.throwable.config")
public class ConfigApplication {
@NacosValue(value = "${counter:0}",autoRefreshed = true)
public Long counter;
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class,args);
}
@GetMapping(path = "/get")
public String get() {
return String.format("Counter value:%d",counter);
}
}
笔者定义了一个长整型的计数器,设置了autoRefreshed (自动刷新)为true ,新建一个配置文件application-config.properties :
spring.application.name=config-service
server.port=9093
nacos.config.server-addr=127.0.0.1:8848
使用spring.profiles.active=config 启动ConfigApplication ,启动成功后通过CURL 调用下面的接口:
λ curl -X GET http://127.0.0.1:9093/get
Counter value:0
接着通过Nacos-Console 添加一个配置:


点击发布按钮后再次调用接口:
λ curl -X GET http://127.0.0.1:9093/get
Counter value:10086
可见计数器的值已经动态刷新。配置项里面还有很多高级配置如:指定配置生效的服务、Beta 发布等等,可以按照合适的场景进行设置。
另外,Nacos Server 提供Open API 从而可以使用HTTP 客户端就可以轻松进行配置查询、配置更新发布等操作(目前这些API没有做鉴权,社区也有人曾提出这样会引发安全性问题,Nacos官方已经立项在后续新版本中加入鉴权的功能,目前建议屏蔽或者仅允许内网访问这些Open API):
- 获取配置:
curl -X GET http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=${DATA_ID}&group=${GROUP}
- 发布配置:
curl -X POST http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=${DATA_ID}&group=${GROUP}&content=${CONFIG_CONTENT}
小结
本文只是简单介绍了SpringBoot 中使用Nacos 作为注册中心以及进行配置管理。Nacos 项目Github 仓库当前(2020-01-01)的star 数已经接近10000,社区也十分活跃,Issues 和交流群的响应都十分迅速。加之Netflix 的部分开源产品如Eureka 、Hystrix 等已经停止迭代,但Nacos 还在飞速迭代,甚至已经在阿里云衍生出商业版本,所以笔者认为Nacos 值得使用,在相对熟悉它的大部分特性之后会付之于生产环境中使用。
参考资料:
本文的Demo 项目:
下一篇博文会介绍一下SOFAStack 中基于SOFABoot 、SOFARpc 以及Nacos 等组件作为基础架构搭建一套微服务的详细过程。
原文链接
- 个人博客【Github Page】:http://throwable.club/2020/01/01/spring-boot-nacos-get-start
- 个人博客【Coding Page】:http://throwable.coding.me/2020/01/01/spring-boot-nacos-get-start
(本文完 c-2-d e-a-20200101 23:11)
技术公众号(《Throwable文摘》),不定期推送笔者原创技术文章(绝不抄袭或者转载):

娱乐公众号(《天天沙雕》),甄选奇趣沙雕图文和视频不定期推送,缓解生活工作压力:
 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|