大纲
1.Nacos生产集群Web端口与数据库配置
2.Nacos生产集群的Distro协议核心参数
3.Nacos打通CMDB实现跨机房的就近访问
4.Nacos基于SPI动态扩展机制来获取CMDB的数据
5.基于Nacos SPI机制开发CMDB动态扩展
6.Nacos基于CMDB来实现多机房就近访问
7.Nacos生产集群Prometheus + Grafana监控
8.Nacos生产集群的其他一些配置参数
1.Nacos生产集群Web端口与数据库配置
参考的系统参数文档:
bash
https://nacos.io/zh-cn/docs/v2/guide/admin/system-configurations.html
shell
#*************** Spring Boot Related Configurations ***************#
### Default web context path:
server.servlet.contextPath=/nacos
### Include message field
server.error.include-message=ALWAYS
### Default web server port:
server.port=8848
#*************** Network Related Configurations ***************#
### If prefer hostname over ip for Nacos server addresses in cluster.conf:
### cluster.conf里是否应该填hostname
# nacos.inetutils.prefer-hostname-over-ip=false
### Specify local server's IP:
### 本机IP,该参数设置后,将会使用这个IP去cluster.conf里进行匹配,请确保这个IP的值在cluster.conf里是存在的
# 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:
### 第一个数据库的URL
# db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
## 第一个数据库连接的用户名
# db.user.0=nacos
### 第一个数据库连接的密码
# db.password.0=nacos
### Connection pool configuration: hikariCP
### 数据库连接池参数,使用的是hikari连接池,参数与hikari连接池相同,如db.pool.config.connectionTimeout或db.pool.config.maximumPoolSize
db.pool.config.connectionTimeout=30000
db.pool.config.validationTimeout=10000
db.pool.config.maximumPoolSize=20
db.pool.config.minimumIdle=2
2.Nacos生产集群的Distro协议核心参数
shell
#*************** Naming Module Related Configurations ***************#
### Data dispatch task execution period in milliseconds: Will removed on v2.1.X, replace with nacos.core.protocol.distro.data.sync.delayMs
### 同步任务生成的周期,单位为毫秒
# nacos.naming.distro.taskDispatchPeriod=200
### Data count of batch sync task: Will removed on v2.1.X. Deprecated
### 同步任务每批的key的数目
# nacos.naming.distro.batchSyncKeyCount=1000
### Retry delay in milliseconds if sync task failed: Will removed on v2.1.X, replace with nacos.core.protocol.distro.data.sync.retryDelayMs
### 同步任务失败的重试间隔,单位为毫秒
# nacos.naming.distro.syncRetryDelay=5000
### If enable data warmup. If set to false, the server would accept request without local data preparation:
### 是否在Server启动时进行数据预热
# nacos.naming.data.warmup=true
### If enable the instance auto expiration, kind like of health check of instance:
### 是否自动摘除临时实例
# nacos.naming.expireInstance=true
#*************** Distro Related Configurations ***************#
### Distro data sync delay time, when sync task delayed, task will be merged for same data key. Default 1 second.
# nacos.core.protocol.distro.data.sync.delayMs=1000
### Distro data sync timeout for one sync data, default 3 seconds.
# nacos.core.protocol.distro.data.sync.timeoutMs=3000
### Distro data sync retry delay time when sync data failed or timeout, same behavior with delayMs, default 3 seconds.
# nacos.core.protocol.distro.data.sync.retryDelayMs=3000
### Distro data verify interval time, verify synced data whether expired for a interval. Default 5 seconds.
# nacos.core.protocol.distro.data.verify.intervalMs=5000
### Distro data verify timeout for one verify, default 3 seconds.
# nacos.core.protocol.distro.data.verify.timeoutMs=3000
### Distro data load retry delay when load snapshot data failed, default 30 seconds.
# nacos.core.protocol.distro.data.load.retryDelayMs=30000
3.Nacos打通CMDB实现跨机房的就近访问
(1)多机房部署时跨机房访问的延迟问题
(2)Nacos的服务发现组件对接CMDB实现相同地域的就近访问
(1)多机房部署时跨机房访问的延迟问题
当服务进行多机房或者多地域部署时,跨地域的服务访问往往延迟较高。一个城市内的机房间的典型网络延迟在1ms左右,而跨城市的网络延迟,例如广州到北京大概为50ms。
(2)Nacos的服务发现组件对接CMDB实现相同地域的就近访问
此时的希望就是能否让服务消费者和服务提供者实现同地域就近访问。一般在企业的生产实践中,这样的需求是通过打通CMDB来实现的。
CMDB一般用于存放与机器设备、应用、服务等相关的元数据,当企业的机器达到一定规模后就需要CMDB来存储和管理它们的元数据。
有一些广泛使用的属性,如机器的IP、主机名、机房、应用、Region等,这些数据一般会在机器部署时录入到CMDB,运维或者监控平台会使用这些数据进行展示或者相关的运维操作。
通过让Nacos的服务发现组件对接CMDB,然后配置好访问规则,就可以实现服务消费者到服务提供者的就近访问。
如果Nacos进行了多机房部署,由于CMDB会存储多机房的元数据,那么就可以基于CMDB实现同机房就近访问。
4.Nacos基于SPI动态扩展机制来获取CMDB的数据
(1)Nacos应如何获取CMDB里的数据
(2)Nacos对CMDB抽象的概念
(3)Nacos对CMDB约定的接口
(1)Nacos应如何获取CMDB里的数据
基本上每个企业都会购买或自研搭建自己的CMDB。为了能够解耦各企业的CMDB,一个比较好的策略是使用SPI机制。
Nacos约定CMDB的抽象调用接口,然后由各企业添加自己的CMDB插件,无需任何代码上的重新构建,即可在运行状态下对接上企业的CMDB。
Nacos定义了一个SPI接口,里面包含了与第三方CMDB约定的一些方法。依照约定实现相应的SPI接口后,将实现打成jar包放到Nacos安装目录,重启Nacos即可让Nacos与CMDB的数据打通。
所以如果希望Nacos可以获取加载CMDB里的数据,那么就需要根据Nacos的SPI接口,编写CMDB实现类并配置到Nacos中。
这样Nacos启动时就会动态扫描和加载编写的CMDB接口实现类。通过编写的CMDB实现类,就可以加载CMDB里的数据了。
(2)Nacos对CMDB抽象的概念
一.实体Entity
实体是CMDB里数据的承载方。在一般的CMDB中,一个实体可以指一个IP、应用或者服务。Nacos的这个实体会有很多属性,比如IP的机房信息,服务的版本信息等。
typescript
package com.alibaba.nacos.api.cmdb.pojo;
import java.util.Map;
//CMDB entity.
public class Entity {
private String type;
private String name;
private Map<String, String> labels;
public String getType() { return type; }
public void setType(String type) { this.type = type; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Map<String, String> getLabels() { return labels; }
public void setLabels(Map<String, String> labels) { this.labels = labels; }
}
二.实体类型Entity Type
Nacos并不限定实体一定是IP、应用或者服务,这取决于实际的业务场景。比如在服务发现场景,实体类型就是IP。
三.标签Label
Label是Nacos抽象出的Entity属性,Label定义为一个描述Entity属性的K-V键值对,Label的key和value的取值范围一般都是预先定义好的。当需要对Label进行变更,需要调用单独的接口并触发相应的事件。
一个常见的Label的例子是IP的机房信息。可认为机房(site)是Label的key,机房的集合(site1, site2)是Label的value。那么这个Label的定义就是:site: {site1, site2, site3}。
typescript
package com.alibaba.nacos.api.cmdb.pojo;
import java.util.Set;
//CMDB lable.
public class Label {
private String name;
private Set<String> values;
private String description;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Set<String> getValues() { return values; }
public void setValues(Set<String> values) { this.values = values; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
}
四.实体事件Entity Event
实体的标签的变更事件。当CMDB的实体属性发生变化,需要有一个事件机制来通知所有订阅方。为了保证实体事件携带的变更信息是最新的,该事件只会包含变更实体的标识以及变更事件的类型,不会包含变更标签的值。
(3)Nacos对CMDB约定的接口
第三方CMDB插件必须实现的接口:
java
package com.alibaba.nacos.api.cmdb.spi;
import com.alibaba.nacos.api.cmdb.pojo.Entity;
import com.alibaba.nacos.api.cmdb.pojo.EntityEvent;
import com.alibaba.nacos.api.cmdb.pojo.Label;
import java.util.List;
import java.util.Map;
import java.util.Set;
//Service to visit CMDB store.
public interface CmdbService {
//Get all label names stored in CMDB.
Set<String> getLabelNames();
//Get all possible entity types in CMDB.
Set<String> getEntityTypes();
//Get label info.
Label getLabel(String labelName);
//Get label value of label name of ip.
String getLabelValue(String entityName, String entityType, String labelName);
//Get all label value of ip.
Map<String, String> getLabelValues(String entityName, String entityType);
//Dump all entities in CMDB.
Map<String, Map<String, Entity>> getAllEntities();
//get label change events.
List<EntityEvent> getEntityEvents(long timestamp);
//Get single entity.
Entity getEntity(String entityName, String entityType);
}
一.获取标签列表的接口
scss
SetgetLabelNames();
这个方法将返回CMDB中需要被Nacos识别的标签名集合,CMDB插件可以按需决定返回什么标签给Nacos。
不在这个集合的标签将会被Nacos忽略,即使该标签出现在实体的属性里。允许该集合会在运行时动态变化,Nacos会定时调用该接口刷新标签集合。
二.获取实体类型的接口
scss
SetgetEntityTypes();
获取CMDB里实体的类型集合,不在这个集合的实体类型会被Nacos忽略。服务发现模块目前需要的实体类型是IP。如果要通过打通CMDB数据来实现服务负载均衡,要在返回集合里包含IP。
三.获取标签详情的接口
arduino
Label getLabel(String labelName);
获取标签的详细信息,返回的Label类包含标签的名字和标签值的集合。如果某个实体的这个标签的值不在标签值集合里,将会被视为无效。
四.查询实体的标签值的接口
arduino
MapgetLabelValues(String entityName,String entityType);
获取实体所有标签的键值对,参数里包含实体的值和实体的类型。这个方法并不会每次在Nacos内部触发查询时调用,因为Nacos内部有一个CMDB数据缓存。只有当这个缓存失效或者不存在时,才会去访问CMDB插件查询数据。为了让CMDB插件的实现简单,Nacos内部实现了相应的缓存和刷新逻辑。
五.查询实体的接口
arduino
Map<string, map> getAllEntities();
Entity getEntity(String entityName, String entityType);
查询实体包含两个方法:查询所有实体的方法和查询单个实体的方法。
查询单个实体目前其实就是查询这个实体的所有标签。不过Nacos将这个方法与获取所有标签的方法区分开来,因为查询单个实体方法后面可能会扩展,比查询所有标签获取的信息要多。
查询所有实体则是一次性将CMDB的所有数据拉取过来。该方法可能会比较消耗性能,无论对于Nacos还是CMDB都一样消耗性能。Nacos调用该方法的策略是:通过可配置的定时任务来定时拉取所有数据。
在实现该CMDB插件时,也要关注CMDB服务本身性能,来采取合适策略。
六.查询实体事件的接口
scss
ListgetEntityEvents(long timestamp);
该方法意在获取最近一段时间内实体的变更消息,增量去拉取变更的实体。因为Nacos不会实时去访问CMDB插件查询实体,需要这个拉取事件的方法来获取实体的更新。参数里的timestamp为上一次拉取事件的时间,CMDB插件可选择使用或忽略这个参数。
5.基于Nacos SPI机制开发CMDB动态扩展
具体的参考例子是:
vbnet
https://github.com/nacos-group/nacos-examples
nacos-examples里已经给出了一个示例plugin的实现,具体步骤如下:
步骤一:新建一个maven工程,引入依赖nacos-api
xml
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-api</artifactId>
<version>0.7.0</version>
</dependency>
步骤二:引入打包插件
xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
步骤三:实现com.alibaba.nacos.api.cmdb.CmdbService接口
java
public class ExampleCmdbServiceImpl implements CmdService {
private int index = 1;
...
}
步骤四:在"src/main/resource/"目录下新建目录"META-INF/services"
步骤五:在"src/main/resources/META-INF/services"目录下新建文件
文件名是com.alibaba.nacos.api.cmdb.CmdbService,在文件里将第三步中创建的实现类全名写入该文件:
com.alibaba.nacos.example.cmdb.plugin.ExampleCmdbServiceImpl
步骤六:代码自测完成后,执行如下命令进行打包:
vbnet
$ mvn package assembly:single -Dmaven.test.skip=true
步骤七:将target目录下的包含依赖的jar包上传到Nacos CMDB插件目录
arduino
{nacos.home}/plugins/cmdb
步骤八:在Nacos的application.properties里打开加载插件开关
ini
nacos.cmdb.loadDataAtStart=true
步骤九:重启Nacos Server后便能加载到实现的Nacos-CMDB插件
从而让Nacos获取到CMDB里的数据。
6.Nacos基于CMDB来实现多机房就近访问
Nacos在拿到CMDB的数据后,就可以运用CMDB数据的强大威力来实现多种灵活的负载均衡策略了。
下面举例说明如何使用CMDB数据和Selector来实现就近访问。假设目前Nacos已经通过CMDB拿到了一些IP的机房信息,且它们对应的标签信息如下:
makefile
11.11.11.11site:x11
22.22.22.22site:x12
33.33.33.33site:x11
44.44.44.44site:x12
55.55.55.55site:x13
11.11.11.11、22.22.22.22、33.33.33.33、44.44.44.44和55.55.55.55.55都包含了标签site,
且它们对应的值分别为x11、x12、x11、x12、x13;
先注册一个服务,下面挂载IP为11.11.11.11和22.22.22.22两个服务实例。然后修改服务的"服务路由类型",并配置为基于同site优先的服务路由:
也就是将服务路由类型选择为标签,然后输入如下的标签表达式,这个表达式的格式和Nacos的Selector机制有关。
ini
CONSUMER.label.site = PROVIDER.label.site
所谓的Selector机制其实就是,任何一个如下格式的表达式,Nacos都能够实现基于同labelName优先的负载均衡策略。
ini
CONSUMER.label.labelName = PROVIDER.label.labelName
假设服务消费者的IP分别为33.33.33.33、44.44.44.44和55.55.55.55,它们在使用如下接口查询服务实例列表:
arduino
naming.selectInstances("nacos.test.1", true)
那么不同的消费者,将获取到不同的实例列表。33.33.33.33获取到IP为11.11.11.11的实例,44.44.44.44获取到IP为22.22.22.22的实例,而55.55.55.55将同时获取到IP为11.11.11.11和22.22.22.22两个实例。
这样,Nacos便基于Selector机制(标签路由),实现了就近访问。
7.Nacos生产集群Prometheus + Grafana监控
(1)Nacos生产集群可视化配置
shell
#*************** 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
(2)官网介绍的结合prometheus和grafana实现监控Nacos
bash
https://nacos.io/zh-cn/docs/v2/guide/admin/monitor-guide.html
8.Nacos生产集群的其他一些配置参数
(1)Nacos生产集群安全认证核心参数
(2)Nacos生产集群服务器寻址参数
(3)Nacos生产集群Distro和Raft协议核心参数
(1)Nacos生产集群安全认证核心参数
ini
#*************** 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-ui/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**
### The auth system to use, currently only 'nacos' and 'ldap' is supported:
nacos.core.auth.system.type=nacos
### If turn on auth system:
nacos.core.auth.enabled=false
### 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
### Since 1.4.1, Turn on/off white auth for user-agent: nacos-server, only for upgrade from old version.
nacos.core.auth.enable.userAgentAuthWhite=false
### Since 1.4.1, worked when nacos.core.auth.enabled=true and nacos.core.auth.enable.userAgentAuthWhite=false.
### The two properties is the white list for auth and used by identity the request from other server.
nacos.core.auth.server.identity.key=serverIdentity
nacos.core.auth.server.identity.value=security
### worked when nacos.core.auth.system.type=nacos
### The token expiration in seconds:
nacos.core.auth.plugin.nacos.token.expire.seconds=18000
### The default token:
nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
### worked when nacos.core.auth.system.type=ldap,{0} is Placeholder,replace login username
#nacos.core.auth.ldap.url=ldap://localhost:389
#nacos.core.auth.ldap.basedc=dc=example,dc=org
#nacos.core.auth.ldap.userDn=cn=admin,${nacos.core.auth.ldap.basedc}
#nacos.core.auth.ldap.password=admin
#nacos.core.auth.ldap.userdn=cn={0},dc=example,dc=org
#nacos.core.auth.ldap.filter.prefix=uid
(2)Nacos生产集群服务器寻址参数
shell
### MemberLookup
### Addressing pattern category, If set, the priority is highest
# nacos.core.member.lookup.type=[file,address-server]
## 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 AddressServerMemberLookup
# Maximum number of retries to query the address server upon initialization
# nacos.core.address-server.retry=5
## Server domain name address of [address-server] mode
# address.server.domain=jmenv.tbsite.net
## Server port of [address-server] mode
# address.server.port=8080
## Request address of [address-server] mode
# address.server.url=/nacos/serverlist
(3)Nacos生产集群Distro和Raft协议核心参数
shell
#*************** 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
### 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. Safe linear reads are used by default, that is, the Leader tenure is confirmed by heartbeat
# 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
#*************** Distro Related Configurations ***************#
### Distro data sync delay time, when sync task delayed, task will be merged for same data key. Default 1 second.
# nacos.core.protocol.distro.data.sync.delayMs=1000
### Distro data sync timeout for one sync data, default 3 seconds.
# nacos.core.protocol.distro.data.sync.timeoutMs=3000
### Distro data sync retry delay time when sync data failed or timeout, same behavior with delayMs, default 3 seconds.
# nacos.core.protocol.distro.data.sync.retryDelayMs=3000
### Distro data verify interval time, verify synced data whether expired for a interval. Default 5 seconds.
# nacos.core.protocol.distro.data.verify.intervalMs=5000
### Distro data verify timeout for one verify, default 3 seconds.
# nacos.core.protocol.distro.data.verify.timeoutMs=3000
### Distro data load retry delay when load snapshot data failed, default 30 seconds.
# nacos.core.protocol.distro.data.load.retryDelayMs=30000