Nacos是Spring Cloud Alibaba中一个核心的服务,用于服务发现及配置分发,相当于Spring Cloud Netflix中的Eureka和Spring Cloud Config。由于目前Eureka已经停止更新,因此,后期将不可避免地会从Spring Cloud Netflix迁移到其他活跃的平台。
Nacos是一个相对独立的组件,不同于Eureka等需要与现有的SpringBoot工程集成,Nacos本身就以二进制的方式发布,因此,可以单独将其部署。
下载并解压Nacos之后,进入其conf目录,执行nacos-mysql.sql,在预先准备好的MySQL数据库中创建nacos的数据结构。创建完成后,修改application.properties文件,取消注释掉一部分必要的配置,最终配置大概是像下面这样:
# # Copyright 1999-2018 Alibaba Group Holding Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #*************** Spring Boot Related Configurations ***************# ### Default web context path: server.servlet.contextPath=/nacos ### Default web server port: server.port=8848 #*************** Network Related Configurations ***************# ### If prefer hostname over ip for Nacos server addresses in cluster.conf: # nacos.inetutils.prefer-hostname-over-ip=false ### Specify local server's IP: # nacos.inetutils.ip-address= #*************** Config Module Related Configurations ***************# ### If use MySQL as datasource: spring.datasource.platform=mysql ### Count of DB: db.num=1 ### Connect URL of DB: db.url.0=jdbc:mysql://10.177.48.26:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC db.user=adasfsf db.password=sdasdasdfa #*************** Naming Module Related Configurations ***************# ### Data dispatch task execution period in milliseconds: nacos.naming.distro.taskDispatchPeriod=200 ### Data count of batch sync task: nacos.naming.distro.batchSyncKeyCount=1000 ### Retry delay in milliseconds if sync task failed: nacos.naming.distro.syncRetryDelay=5000 ### If enable data warmup. If set to false, the server would accept request without local data preparation: nacos.naming.data.warmup=true ### If enable the instance auto expiration, kind like of health check of instance: nacos.naming.expireInstance=true nacos.naming.empty-service.auto-clean=true nacos.naming.empty-service.clean.initial-delay-ms=50000 nacos.naming.empty-service.clean.period-time-ms=30000 #*************** CMDB Module Related Configurations ***************# ### The interval to dump external CMDB in seconds: nacos.cmdb.dumpTaskInterval=3600 ### The interval of polling data change event in seconds: nacos.cmdb.eventTaskInterval=10 ### The interval of loading labels in seconds: nacos.cmdb.labelTaskInterval=300 ### If turn on data loading task: nacos.cmdb.loadDataAtStart=false #*************** Metrics Related Configurations ***************# ### Metrics for prometheus management.endpoints.web.exposure.include=* ### Metrics for elastic search management.metrics.export.elastic.enabled=false #management.metrics.export.elastic.host=http://localhost:9200 ### Metrics for influx management.metrics.export.influx.enabled=false #management.metrics.export.influx.db=springboot #management.metrics.export.influx.uri=http://localhost:8086 #management.metrics.export.influx.auto-create-db=true #management.metrics.export.influx.consistency=one #management.metrics.export.influx.compressed=true #*************** Access Log Related Configurations ***************# ### If turn on the access log: server.tomcat.accesslog.enabled=true ### The access log pattern: server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i ### The directory of access log: server.tomcat.basedir= #*************** Access Control Related Configurations ***************# ### If enable spring security, this option is deprecated in 1.2.0: #spring.security.enabled=false ### The ignore urls of auth, is deprecated in 1.2.0: nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/** ### The auth system to use, currently only 'nacos' is supported: nacos.core.auth.system.type=nacos ### If turn on auth system: nacos.core.auth.enabled=false ### The token expiration in seconds: nacos.core.auth.default.token.expire.seconds=18000 ### The default token: nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789 ### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay. nacos.core.auth.caching.enabled=true #*************** Istio Related Configurations ***************# ### If turn on the MCP server: nacos.istio.mcp.server.enabled=false ###*************** Add from 1.3.0 ***************### #*************** Core Related Configurations ***************# ### set the WorkerID manually # nacos.core.snowflake.worker-id= ### Member-MetaData # nacos.core.member.meta.site= # nacos.core.member.meta.adweight= # nacos.core.member.meta.weight= ### MemberLookup ### Addressing pattern category, If set, the priority is highest nacos.core.member.lookup.type=[file,address-server,discovery] ## Set the cluster list with a configuration file or command-line argument # nacos.member.list=192.168.16.101:8847?raft_port=8807,192.168.16.101?raft_port=8808,192.168.16.101:8849?raft_port=8809 ## for DiscoveryMemberLookup # If you want to use cluster node self-discovery, turn this parameter on nacos.member.discovery=false ## for AddressServerMemberLookup # Maximum number of retries to query the address server upon initialization nacos.core.address-server.retry=5 #*************** JRaft Related Configurations ***************# ### Sets the Raft cluster election timeout, default value is 5 second nacos.core.protocol.raft.data.election_timeout_ms=5000 ### Sets the amount of time the Raft snapshot will execute periodically, default is 30 minute nacos.core.protocol.raft.data.snapshot_interval_secs=30 ### Requested retries, default value is 1 nacos.core.protocol.raft.data.request_failoverRetries=1 ### raft internal worker threads nacos.core.protocol.raft.data.core_thread_num=8 ### Number of threads required for raft business request processing nacos.core.protocol.raft.data.cli_service_thread_num=4 ### raft linear read strategy, defaults to index nacos.core.protocol.raft.data.read_index_type=ReadOnlySafe ### rpc request timeout, default 5 seconds nacos.core.protocol.raft.data.rpc_request_timeout_ms=5000
重点是数据库连接部分的配置。
配置完成后,回到nacos下的bin目录,在此处打开一个命令行。Nacos提供了单机和集群两种方式,启动脚本默认是以集群模式启动,在未做集群配置的情况下会报错,因此,需要指定为单机模式启动:
startup.cmd -m standalone
启动之后,访问http://localhost:8848/nacos,即可使用默认账户nacos/nacos登录。
接下来,我们需要把原先声学Horizon平台的一个admin-service服务迁移到以Nacos为核心的新的平台上。
原先的Horizon平台,采用的配置中心是原生的Spring Cloud Config,配置并不是通过数据库进行存储的,而是通过Git进行托管,虽然可以省掉一套数据库服务器,但是Git并不是百分百可靠,如果Git宕机,则会导致配置无法得到及时刷新,从而影响其他服务(但实际上不会影响服务运行,因为Spring Cloud Config本身存在缓存机制,在配置源不可用的情况下会使用本地缓存的最新配置)。切换为Nacos之后,换成了传统的数据库存储方式,相对来说更为可靠一些。
首先需要将原先的admin-service的配置导入Nacos。
此处额外加了一部分Nacos服务发现的配置:
spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 username: nacos password: nacos
这里需要注意的一个问题:dataId,一定要是服务名-环境.后缀的形式,这一点在Nacos官网有明确说明:
所以,上述dataId我定义的是admin-service-dev.yml,admin-service是服务名,dev是环境,yml是后缀。Group部分,建议指定一个专门的Group,比如,这个服务隶属于接口平台,此处我将其定义为API-Platform。
回到IDE中,建立Spring多模块项目的方式不多说,建立父工程之后,建立一个admin的模块,而后引入下述依赖:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-server</artifactId> <version>2.2.3</version> </dependency> <dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-server-ui</artifactId> <version>2.2.3</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>2.2.1.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2.2.1.RELEASE</version> </dependency> </dependencies>
除了标准的SpringBoot依赖之外,还有springBootAdmin相关的两个依赖,以及nacos相关的两个依赖。
老规矩,先给启动类加一个@EnableAdminServer注解来启用SpringBootAdmin的功能。而后,给默认的配置文件做一些修改。
spring: profiles: active: dev cloud: nacos: config: server-addr: 127.0.0.1:8848 username: nacos password: nacos file-extension: yml group: API-Platform application: name: admin-service
基本上还是Spring Cloud Config那一套,指定一下配置中心的相关信息,以及告诉配置中心“我是谁”(spring.application.name),“我是哪个版本”(spring.profiles.active),需要注意的是,这里需要指明你的配置文件的后缀(和上述的dataId中的后缀保持一致),以及指定Group(和上述的Group保持一致),这样,在应用启动的时候,就可以从配置中心获取到配置并顺利启动了:
2020-08-14 11:39:55.330 INFO 32248 --- [ main] c.a.n.c.c.impl.LocalConfigInfoProcessor : LOCAL_SNAPSHOT_PATH:C:\Users\60054814\nacos\config 2020-08-14 11:39:55.358 INFO 32248 --- [ main] c.a.nacos.client.config.impl.Limiter : limitTime:5.0 2020-08-14 11:39:55.380 WARN 32248 --- [ main] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[admin-service] & group[API-Platform] 2020-08-14 11:39:55.386 WARN 32248 --- [ main] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[admin-service.yml] & group[API-Platform] 2020-08-14 11:39:55.393 INFO 32248 --- [ main] c.a.nacos.client.config.utils.JVMUtil : isMultiInstance:false 2020-08-14 11:39:55.407 INFO 32248 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-admin-service-dev.yml,API-Platform'}, BootstrapPropertySource {name='bootstrapProperties-admin-service.yml,API-Platform'}, BootstrapPropertySource {name='bootstrapProperties-admin-service,API-Platform'}]
这里确定是从配置中心获取配置启动的原因是,只有配置中心存储了7012这个端口号,SpringBootAdmin的默认端口号是8080,因此,只有在7012端口上启动时,才能确定是动态配置启动的:
与此同时,在Nacos的服务列表中,同样可以看到admin-service已经注册到Nacos中:
需要额外说明的一点是,如果pom依赖中没有任何一个组件依赖了spring-boot-starter-web,则服务无法注册到Nacos中,因此,需要手动引入一下spring-boot-starter-web的依赖。
总结下来,Nacos由于是一个独立部署的组件,集成了服务发现和配置中心的功能,相对来说还是较为方便的。