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由於是一個獨立部署的組件,集成了服務發現和配置中心的功能,相對來說還是較為方便的。
