文章目录

  • 一、什么是 Nacos
    • 1.1 Nacos 架构
    • 1.2 Nacos Server部署
      • 1.2.1 单机模式
      • 1.2.2 集群模式
        • 1.2.2.1 nginx反向代理配置
        • 1.2.2.2 nacos+nginx启动总结
    • 1.3 prometheus+grafana监控Nacos
      • 1.3.1 配置application.properties文件,暴露metrics数据
      • 1.3.2 搭建prometheus采集Nacos metrics数据
    • 1.4 搭建grafana图形化展示metrics数据
  • 二、.Nacos注册中心实战
    • 2.1 注册中心演变及其设计思想
    • 2.2 Nacos注册中心架构
    • 2.3 核心功能
    • 2.4 服务注册表结构
    • 2.5 服务领域模型
    • 2.6 配置领域模型
  • 三、Spring Cloud Alibaba Nacos快速开始
    • 3.1 Spring Cloud Alibaba版本选型
    • 3.2 搭建Nacos-client服务

一、什么是 Nacos

官方文档: https://nacos.io/zh-cn/docs/what-is-nacos.html

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

Nacos的关键特性包括:

  • 服务发现和服务健康监测
  • 动态配置服务
  • 动态 DNS 服务
  • 服务及其元数据管理

主流的注册中心对比:

1.1 Nacos 架构


NamingService: 命名服务,注册中心核心接口
ConfigService:配置服务,配置中心核心接口


OpenAPI文档:https://nacos.io/zh-cn/docs/open-api.html
nacos版本: v1.1.4 升级到v1.4.1

1.2 Nacos Server部署

你可以通过源码和发行包两种方式来获取 Nacos。

下载源码编译:
源码下载地址:https://github.com/alibaba/nacos/ | 可以用迅雷下载

cd nacos/
mvn -Prelease-nacos clean install -U

下载安装包:
下载地址:https://github.com/alibaba/Nacos/releases

当前推荐的稳定版本是2.0.3。


这次学习,我们暂时使用v1.4.1版本…

下载好nacos-server-1.4.1.tar.gz之后,我们将其上传到linux服务器上。

1.2.1 单机模式

官方文档: https://nacos.io/zh-cn/docs/deployment.html

解压:

tar -axvf nacos-server-1.4.1.tar.gz

然后进入nacos目录:

单机启动nacos,执行命令

sh ./bin/startup.sh -m standalone


查看服务是否启动

ps -ef | grep nacos

在nacos的启动脚本startup.sh中可以看到,默认的启动方式为集群方式。

我们可以修改默认启动方式:

访问nocas的管理端:http://192.168.131.172:8848/nacos ,默认的用户名密码是 nocas/nocas 。


成功启动!成功访问!很棒!!!

1.2.2 集群模式

官网文档: https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html

集群部署架构图:

1、单机搭建伪集群,复制nacos安装包,修改为nacos8849,nacos8850,nacos8851

2、创建mysql数据库,sql文件位置:conf\nacos-mysql.sql

注意,nacos1.4.1版本搭配mysql5.x版本的时候,启动总是报错说数据库连接错误!后来换成mysql8.x之后成功解决这个错误!!!

注意: 使用内置数据源时,无需进行任何配置。使用外置数据源,生产使用建议至少主备模式,或者采用高可用数据库。

我们此时是要使用外部数据源,所以要配置。我们创建一个名为nacos的数据库,并执行一下sql脚本!

/** 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.*//******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info   */
/******************************************/
CREATE TABLE `config_info` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',`data_id` varchar(255) NOT NULL COMMENT 'data_id',`group_id` varchar(255) DEFAULT NULL,`content` longtext NOT NULL COMMENT 'content',`md5` varchar(32) DEFAULT NULL COMMENT 'md5',`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',`src_user` text COMMENT 'source user',`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',`app_name` varchar(128) DEFAULT NULL,`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',`c_desc` varchar(256) DEFAULT NULL,`c_use` varchar(64) DEFAULT NULL,`effect` varchar(64) DEFAULT NULL,`type` varchar(64) DEFAULT NULL,`c_schema` text,PRIMARY KEY (`id`),UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_aggr   */
/******************************************/
CREATE TABLE `config_info_aggr` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',`data_id` varchar(255) NOT NULL COMMENT 'data_id',`group_id` varchar(255) NOT NULL COMMENT 'group_id',`datum_id` varchar(255) NOT NULL COMMENT 'datum_id',`content` longtext NOT NULL COMMENT '内容',`gmt_modified` datetime NOT NULL COMMENT '修改时间',`app_name` varchar(128) DEFAULT NULL,`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',PRIMARY KEY (`id`),UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段';/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_beta   */
/******************************************/
CREATE TABLE `config_info_beta` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',`data_id` varchar(255) NOT NULL COMMENT 'data_id',`group_id` varchar(128) NOT NULL COMMENT 'group_id',`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',`content` longtext NOT NULL COMMENT 'content',`beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps',`md5` varchar(32) DEFAULT NULL COMMENT 'md5',`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',`src_user` text COMMENT 'source user',`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',PRIMARY KEY (`id`),UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_tag   */
/******************************************/
CREATE TABLE `config_info_tag` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',`data_id` varchar(255) NOT NULL COMMENT 'data_id',`group_id` varchar(128) NOT NULL COMMENT 'group_id',`tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',`tag_id` varchar(128) NOT NULL COMMENT 'tag_id',`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',`content` longtext NOT NULL COMMENT 'content',`md5` varchar(32) DEFAULT NULL COMMENT 'md5',`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',`src_user` text COMMENT 'source user',`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',PRIMARY KEY (`id`),UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_tags_relation   */
/******************************************/
CREATE TABLE `config_tags_relation` (`id` bigint(20) NOT NULL COMMENT 'id',`tag_name` varchar(128) NOT NULL COMMENT 'tag_name',`tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type',`data_id` varchar(255) NOT NULL COMMENT 'data_id',`group_id` varchar(128) NOT NULL COMMENT 'group_id',`tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',`nid` bigint(20) NOT NULL AUTO_INCREMENT,PRIMARY KEY (`nid`),UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = group_capacity   */
/******************************************/
CREATE TABLE `group_capacity` (`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',`group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',PRIMARY KEY (`id`),UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = his_config_info   */
/******************************************/
CREATE TABLE `his_config_info` (`id` bigint(64) unsigned NOT NULL,`nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,`data_id` varchar(255) NOT NULL,`group_id` varchar(128) NOT NULL,`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',`content` longtext NOT NULL,`md5` varchar(32) DEFAULT NULL,`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,`src_user` text,`src_ip` varchar(50) DEFAULT NULL,`op_type` char(10) DEFAULT NULL,`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',PRIMARY KEY (`nid`),KEY `idx_gmt_create` (`gmt_create`),KEY `idx_gmt_modified` (`gmt_modified`),KEY `idx_did` (`data_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = tenant_capacity   */
/******************************************/
CREATE TABLE `tenant_capacity` (`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',`tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID',`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',PRIMARY KEY (`id`),UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';CREATE TABLE `tenant_info` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',`kp` varchar(128) NOT NULL COMMENT 'kp',`tenant_id` varchar(128) default '' COMMENT 'tenant_id',`tenant_name` varchar(128) default '' COMMENT 'tenant_name',`tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc',`create_source` varchar(32) DEFAULT NULL COMMENT 'create_source',`gmt_create` bigint(20) NOT NULL COMMENT '创建时间',`gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',PRIMARY KEY (`id`),UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';CREATE TABLE `users` (`username` varchar(50) NOT NULL PRIMARY KEY,`password` varchar(500) NOT NULL,`enabled` boolean NOT NULL
);CREATE TABLE `roles` (`username` varchar(50) NOT NULL,`role` varchar(50) NOT NULL,UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
);CREATE TABLE `permissions` (`role` varchar(50) NOT NULL,`resource` varchar(255) NOT NULL,`action` varchar(8) NOT NULL,UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
);INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');

在数据库创建一个名为nacos数据库并执行以上sql脚本得到结果如下:

3、以nacos8849为例,进入nacos8849目录

3.1)修改conf\application.properties的配置,使用外置数据源

#修改端口号
server.port=8849#使用外置mysql数据源
spring.datasource.platform=mysql ### Count of DB:
db.num=1### Connect URL of DB:
db.url.0=jdbc:mysql://192.168.131.172:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=123456

注意填写正确的数据库连接用户名和密码。我的密码是123456。

3.2)将conf\cluster.conf.example文件copy一份改为cluster.conf,并添加节点配置。请每行配置成ip:port。(请配置3个或3个以上节点)

cp ./cluster.conf.example ./cluster.confvim cluster.conf
# 192.168.131.172:8849 注意,本服务的IP:端口不用自己配置,启动的时候刽自动生成,只需要配置其他集群节点的信息!
192.168.131.172:8850
192.168.131.172:8851

nacos8850,nacos8851 按同样的方式配置(端口分别改为8850,8851)。

4、修改启动脚本(bin\startup.sh)的jvm参数(nacos8850,nacos8851 按同样的方式配置JVM参数)

注意,我们此时是集群模式,应该修改else分支下的JVM参数!!!

5、别启动nacos8849,nacos8850,nacos8851

使用内置数据源
sh startup.sh -p embedded

使用外置数据源
sh startup.sh

以nacos8849为例,进入nacos8849目录,启动nacos

bin/startup.sh

然后分别启动nacos8850,nacos8851服务。

然后我们再来访问http://192.168.131.172:8849/nacos,登录后查看集群信息:

可以看到,集群已经成功启动!!!

注意,nacos默认启动方式就是集群模式!

1.2.2.1 nginx反向代理配置

修改/conf/nginx.conf配置文件,添加反向代理配置:

upstream nacoscluster {server 192.168.131.172:8849;server 192.168.131.172:8850;server 192.168.131.172:8851;
}server {listen        8847;server_name   192.168.131.172;location /nacos/ {proxy_pass http://nacoscluster/nacos/;}
}

访问: http://192.168.131.172:8847/nacos


即,此时我们客户端要使用nacos集群服务的时候,只需要配置这个nginx代理的地值http://192.168.131.172:8847地址即可,并且nginx端已经帮我们处理好了负载均衡,默认为轮训算法,可以配置权重,一致hash等其他算法。

server:port: 8045spring:application:name: mall-order# 配置nacos注册中心地址
cloud:nacos:discovery:server-addr: 192.168.131.172:8847

1.2.2.2 nacos+nginx启动总结

1、启动nginx(记得nginx中配置好nacos反向代理)

# 默认编译的nginx路径为这个,也可以使用whereid nginx 查看地址
/usr/local/nginx/sbin/nginx

2、分别启动nacos8849,nacos8850,nacos8851服务

# 分别在集群服务的bin目录下启动
sh startup.sh


3、使用nginx中配置的nacos地址在浏览器中访问测试集群是否成功:

http://192.168.131.172:8847/nacos

1.3 prometheus+grafana监控Nacos

官方监控文档地址:https://nacos.io/zh-cn/docs/monitor-guide.html

Nacos 0.8.0版本完善了监控系统,支持通过暴露metrics数据接入第三方监控系统监控Nacos运行状态,目前支持prometheus、elastic search和influxdb,下面结合prometheus和grafana如何监控Nacos,官网grafana监控页面。与elastic search和influxdb结合可自己查找相关资料。

下面我们开始配置。(为了简单测试,这里我们暂时使用nacos单机模式实战吧… 妥协了)

1.3.1 配置application.properties文件,暴露metrics数据

management.endpoints.web.exposure.include=*

注:上面的这个配置原来是注释掉的,现在去掉注释,放开。(集群中每个都要修改)


访问{ip}:8848/nacos/actuator/prometheus,看是否能访问到metrics数据。

1.3.2 搭建prometheus采集Nacos metrics数据

下载你想安装的prometheus版本,地址为: https://prometheus.io/download/

我们使用linux Centos7,所以下载linux版本:

上传后解压prometheus压缩包:

tar -zxvf prometheus-2.31.1.linux-amd64.tar.gz

修改配置文件prometheus.yml采集Nacos metrics数据:

添加如下配置:

- job_name: "nacos"metrics_path: '/nacos/actuator/prometheus'static_configs:# 这里配置nacos服务地址,可以看到这里可以配置一个集合,即集群信息可以配置在这里# - targets: ['192.168.131.172:8849','192.168.131.172:8850','192.168.131.172:8851']# 如果是单机模式,集合中只配置一个元素即可- targets: ['192.168.131.172:8848']

注意yml中空格不要多写,格式一定要严格对齐!否则启动可能会报错说配置文件出错!

启动prometheus服务:

./prometheus --config.file="prometheus.yml"

通过访问http://{ip}:9090/graph可以看到prometheus的采集数据,在搜索栏搜索nacos_monitor可以搜索到Nacos数据说明采集数据成功。

查看nacos(集群)状态:


配制采集nacos metrics数据:
如下图,进入Graph这个tab后,输入nacos,选中nacos_monitor :

点"Execute",有数据显示,就说明采集到数据成功:


可以看到,此时数据已经采集成功。但是这样可能显示还不是很直观,接下来我们再集成grafana来展示数据。

1.4 搭建grafana图形化展示metrics数据

和prometheus在同一台机器上安装grafana,使用 yum 安装grafana。

下载grafana
本地下载地址:https://dl.grafana.com/oss/release/grafana-7.3.4.linux-amd64.tar.gz

linux推荐使用yum安装:

sudo yum install https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.2.4-1.x86_64.rpm

如果下载太慢,使用国内镜像:https://www.newbe.pro/Mirrors/Mirrors-Grafana/

注意要下载第五个,这个大小为51.8M的,其他的无法使用…

下载后解压:

ar -zxvf grafana-5.2.4.linux-amd64.tar.gz


进入查看结构,有bin目录证明是正确的。

启动服务:

# 直接启动并在直接输入日志
./bin/grafana-server


也可以静默启动,将日志输入到指定的文件中:

nohup ./bin/grafana-server >> nuhup.log 2>&1 &

访问grafana: http://{ip}:3000:

可以到此页面说明启动成功!默认用户名和密码都是admin。登录之后可以会要求修改密码,可以选择skip跳过:
然后会进入主页面:

配置prometheus数据源:

点"Add data source":

Name:prometheus
类型选择Prometheus:

URL填写prometheus的地址(注意:http要写上,最后地址后的’/'也最好加上,即完整地址为:http://192.168.131.172:9090/),http method选择get方法,其他不用填写,然后点"Save & Test":

接下来我们需要引入nacos监控展示模板:

github模板下载链接:https://github.com/nacos-group/nacos-template/blob/master/nacos-grafana.json

如果网速慢,可以使用gitee,gitee模板下载连接:https://gitee.com/jakhyd/nacos-template

点“Upload JSON file”上传模板文件,然后点"Load"


然后再点击"import"按钮:

然后就可以看到监控数据了:

Nacos监控分为三个模块:

  • nacos monitor展示核心监控项

  • nacos detail展示指标的变化曲线

  • nacos alert为告警项

配置grafana告警:

当Nacos运行出现问题时,需要grafana告警通知相关负责人。grafana支持多种告警方式,常用的有邮件,钉钉和webhook方式。

具体配置连接:https://nacos.io/zh-cn/docs/monitor-guide.html

二、.Nacos注册中心实战

2.1 注册中心演变及其设计思想

2.2 Nacos注册中心架构

2.3 核心功能

服务注册:Nacos Client会通过发送REST请求的方式向Nacos Server注册自己的服务,提供自身的元数据,比如ip地址、端口等信息。Nacos Server接收到注册请求后,就会把这些元数据信息存储在一个双层的内存Map中。

服务心跳:在服务注册后,Nacos Client会维护一个定时心跳来持续通知Nacos Server,说明服务一直处于可用状态,防止被剔除。默认5s发送一次心跳。

服务同步:Nacos Server集群之间会互相同步服务实例,用来保证服务信息的一致性。 leader raft

服务发现:服务消费者(Nacos Client)在调用服务提供者的服务时,会发送一个REST请求给Nacos Server,获取上面注册的服务清单,并且缓存在Nacos Client本地,同时会在Nacos Client本地开启一个定时任务定时拉取服务端最新的注册表信息更新到本地缓存。

服务健康检查:Nacos Server会开启一个定时任务用来检查注册服务实例的健康情况,对于超过15s没有收到客户端心跳的实例会将它的healthy属性置为false(客户端服务发现时不会发现),如果某个实例超过30秒没有收到心跳,直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册) 。

2.4 服务注册表结构


官方图:

nacos可以以namespace来隔离服务,我们可以为不同的环境创建不同的命名空间。注意,不同命名空间中的服务是无法相互调用的。

再往下划分,还有group::serviceName、ClusterName等划分。

#配置nacos注册中心地址
cloud:nacos:discovery:server-addr: 192.168.131.172:8848namespace: 39e1e969-15f9-46d2-832d-fa052da55377group: mall-usercluster-name: Shanghai

总结:
NameSpace可以用来区分不同的环境,如dev、qa、prod等。所以说一套nacos可以支持多个环境的服务注册。

Group用来区分不同的微服务组,如交易微服务、仓储微服务组等。不同的微服务可以属于一个微服务组。

Service对应一个具体的服务,如订单服务、支付服务。而一个具体的服务中还可以进行区分:Cluster。Cluster可以用来描述一个服务的异地多机房部署。比如一个订单服务,可能在北京有部署,也可能在上海有部署。

2.5 服务领域模型

2.6 配置领域模型

围绕配置,主要有两个关联的实体,一个是配置变更历史,一个是服务标签(用于打标分类,方便索引),由 ID 关联。

三、Spring Cloud Alibaba Nacos快速开始

3.1 Spring Cloud Alibaba版本选型


3.2 搭建Nacos-client服务

1、引入依赖

父Pom中支持spring cloud&spring cloud alibaba, 引入依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><modules><module>mall-order</module><module>mall-common</module></modules><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>org.jihu.mall</groupId><artifactId>spring-cloud-alibaba-mall</artifactId><version>1.0-SNAPSHOT</version><name>spring-cloud-alibaba-mall</name><packaging>pom</packaging><description>Demo project for Spring Cloud Alibaba</description><properties><java.version>1.8</java.version><spring-cloud.version>Hoxton.SR8</spring-cloud.version><spring-cloud-alibaba.version>2.2.5.RELEASE</spring-cloud-alibaba.version></properties><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></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement></project>

当前项目orderpom中引入依赖:

<!-- nacos服务注册与发现 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

完整pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>vip-spring-cloud-alibaba</artifactId><groupId>com.tuling.mall</groupId><version>0.0.1-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>mall-user-consumer-demo</artifactId><dependencies><dependency><groupId>com.tuling.mall</groupId><artifactId>mall-common</artifactId><version>0.0.1-SNAPSHOT</version></dependency><!-- nacos服务注册与发现 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency></dependencies>
</project>

2、application.yml中配置

server:port: 8046spring:application:name: mall-order# 配置nacos注册中心地址cloud:nacos:discovery:server-addr: 192.168.131.172:8848# 配置是否为持久化实例#ephemeral: false

更多配置连接:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-discovery


3、启动springboot应用,nacos管理端界面查看是否成功注册

// 由于common模块中引入了数据库相关的,所以这里暂时排除相关自动化配置
// @EnableDiscoveryClient 该注解可以不写,springCloudAlibaba已经完成了配置
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DruidDataSourceAutoConfigure.class})
public class MallOrderApplication {public static void main(String[] args) {SpringApplication.run(MallOrderApplication.class, args);}
}

启动成功之后,登录nacos去查看服务列表:
http://192.168.131.172:8848/nacos

4、测试是否可用

使用RestTemplate进行服务调用,可以使用微服务名称 (spring.application.name)。

我们之前使用RestTemplate调用的时候必须写ip:port或者hostname:port,此时我们已经使用nacos完成了服务mall-order的注册,思考是否可以直接使用服务名称来调用。

// 之前url;String url = "http://localhost:8040/order/findOrderByUserId/"+id;// 现在url:
String url = "http://mall-order/order/findOrderByUserId/"+id;

我们使用另一个服务mall-user中的如下controller方法来测试,该方法中使用RestTemplate调用mall-order服务,但是此时url地址中写的是服务名称,而并不是具体的ip:port。

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate RestTemplate restTemplate;@RequestMapping(value = "/findOrderByUserId/{id}")public Result findOrderByUserId(@PathVariable("id") Integer id) {log.info("根据userId {} 查询订单信息", id);String url = "http://mall-order/order/findOrderByUserId/"+id;Result result = restTemplate.getForObject(url, Result.class);return result;}
}

打开浏览器,我们来访问mall-user服务中的:http://localhost:8040/user/findOrderByUserId/1,以此来触发restTemplate去调用mall-order中的方法。

但是结果却是报错了:

-11-08 11:31:07.218 ERROR 14448 --- [nio-8040-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://mall-order/order/findOrderByUserId/1": mall-order; nested exception is java.net.UnknownHostException: mall-order] with root causejava.net.UnknownHostException: mall-order

什么意思呢?不知道的主机名mall-order

分析,依旧是说我们此时调用的是普通的restTemplate服务,虽然我们将服务已经注册到nacos中了,但是restTemplate并不认识这个服务名称,自然就无法通过服务名称解析具体的ip:port了。


所以说,此时要有一个组件,能够去动态的从nacos中读取服务列表,并且选择其中一个获得其ip:port,并将mall-order服务名转化为ip:port真实地址之后再使用restTemplate去调用服务。

其实Spring中的httpClient中提供有一个扩展点拦截器:ClientHttpRequestInterceptor。而其中负载均衡器组件Ribbon就实现了这个拦截器:

public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {private LoadBalancerClient loadBalancer;private LoadBalancerRequestFactory requestFactory;public LoadBalancerInterceptor(LoadBalancerClient loadBalancer, LoadBalancerRequestFactory requestFactory) {this.loadBalancer = loadBalancer;this.requestFactory = requestFactory;}public LoadBalancerInterceptor(LoadBalancerClient loadBalancer) {this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer));}public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {URI originalUri = request.getURI();// 获取url中的服务名称,比如mall-orderString serviceName = originalUri.getHost();Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);// 调用execute,我们跟进去看看这个方法是如何解析服务名的return (ClientHttpResponse)this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));}
}


我们进入到这个RibbonLoadBalancerClient是实现类中对应的这个方法中:

// serviceId就是serverName
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException {return this.execute(serviceId, (LoadBalancerRequest)request, (Object)null);
}// 继续跟进去
public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint) throws IOException {// 根据服务名称从Map<String, AnnotationConfigApplicationContext> contexts = new ConcurrentHashMap();// 中获取一个服务的instanceILoadBalancer loadBalancer = this.getLoadBalancer(serviceId);// 获取到具体的serverServer server = this.getServer(loadBalancer, hint);if (server == null) {throw new IllegalStateException("No instances available for " + serviceId);} else {RibbonLoadBalancerClient.RibbonServer ribbonServer = new RibbonLoadBalancerClient.RibbonServer(serviceId, server, this.isSecure(server, serviceId), this.serverIntrospector(serviceId).getMetadata(server));return this.execute(serviceId, (ServiceInstance)ribbonServer, (LoadBalancerRequest)request);}
}// --------
protected Server getServer(ILoadBalancer loadBalancer, Object hint) {// 根据不同的算法选择一个serverreturn loadBalancer == null ? null : loadBalancer.chooseServer(hint != null ? hint : "default");
}

Ps:Ribbon的源码我们后面会仔细研究,现在只是大概了解一下。

总结来说,就是此时我们其实可以使用Ribbon负载均衡器来实现服务选择,它默认实现了如上的功能,即拉取服务列表并通过算法选择其中一个服务来进行调用。

mall-order(localhost:8040, localhost:8041, localhost:8042) — 选择一个并替换mall-order名称—> localhost:8040 -------> 最终服务调用

所以说我们此时要给我们的RestTemplate配置这个负载均衡器,让其可以自动实现这个功能。

那么该如何配置呢?其实RestTemplate中是可以设置拦截器的:

@Configuration
public class RestTemplateConfig {@AutowiredLoadBalancerClient loadBalancerClientl;@Beanpublic RestTemplate restTemplate() {RestTemplate restTemplate = new RestTemplate();// 构造方法需要一个List<LoadBalancerClient>参数, 此时LoadBalancerClient在spring容器中是已经存在的restTemplate.setInterceptors(Collections.singletonList(new LoadBalancerInterceptor(loadBalancerClientl)));return restTemplate;}
}

配置好重启项目之后,我们再来测试:http://localhost:8040/user/findOrderByUserId/1

可以看到,此时已经restTemplate已经可以成功通过服务名mall-order来访问了。

优化:
在我们实际的使用中,其实可以不用手动的给restTemplate设置这个拦截器,可以直接使用Ribbon提供的注解 @LoadBalence 来完成拦截器的设置!

@Configuration
public class RestTemplateConfig {@AutowiredLoadBalancerClient loadBalancerClientl;@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
}

这样也可以实现如上功能。

Alibaba微服务组件Nacos单机+集群配置 prometheus+grafana监控配置及注册中心实战【收获满满】相关推荐

  1. 2:Alibaba微服务组件Nacos注册中心

    Spring Cloud Alibaba系列目录 提示:这里是第二章:Alibaba微服务组件Nacos注册中心 微服务和Spring Cloud Alibaba介绍 Alibaba微服务组件Naco ...

  2. Alibaba微服务组件Nacos注册中心

    目录 什么是 Nacos 官方: Nacos 的关键特性 Nacos注册中心 注册中心演变及其设计思想 核心功能 主流的注册中心 Nacos Server部署 下载源码编译 下载安装包 单机模式 集群 ...

  3. Spring Cloud Alibaba入门教程-05【Alibaba微服务组件Nacos配置中心】

    1. Nacos配置中心使用 官方文档: https://github.com/alibaba/spring­cloud­alibaba/wiki/Nacos­config Nacos 提供用于存储配 ...

  4. Alibaba微服务组件Sentinel

    Alibaba微服务组件Sentinel 1.分布式系统遇到的问题 服务的可用性问题 ​ 提供系统可用性的关键是在相关组件失效情况下,系统能多快恢复并继续正确提供服务.当服务器挂掉的时候首先想到什么原 ...

  5. Windows安装Nacos单机集群

    Windows安装Nacos单机&集群 下载地址: https://github.com/alibaba/nacos/releases 创建nacos配置库,并运行下面的sql脚本 然后修改配 ...

  6. 从单机架构------》到现在复杂的微服务,分布式,集群,云平台途中是遇到了什么问题,又如何解决的?

    本文转载地址服务端高并发分布式架构演进之路  写的很清楚,全面,顺序的话,肯定不是完全正确,如Docker,redis 等 但不重要,过程就是这莫个过程,根据公司业务不同,架构演变自然不同.转载记录一 ...

  7. Spring Cloud Alibaba微服务组件快速上手

    文章目录 Nacos 什么是Nacos Nacos的启动 将项目注册到Nacos 项目pom依赖 yaml配置 Nacos心跳机制 Dubbo 什么是RPC 什么是Dubbo Dubbo服务的注册与发 ...

  8. Nacos 单机集群搭建及常用生产环境配置 | Spring Cloud 3

    一.Nacos 概览 Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现.配置管理 ...

  9. Spring Cloud Alibaba基础教程:Nacos的集群部署

    点击蓝色"程序猿DD"关注我哟 <Spring Cloud Alibaba基础教程>连载中,关注我一起学习!前情回顾: <使用Nacos实现服务注册与发现> ...

  10. dubbo k8s 服务发现_将Dubbo微服务迁移到k8s集群环境中前的思考与落地

    将Dubbo微服务迁移到k8s中的思考与落地 说到容器化,不得不提kubernetes这个集群编排系统,它是一个开源系统,用于容器化应用的自动部署.扩缩和管理. Kubernetes 将构成应用的容器 ...

最新文章

  1. 中国移动领取买卖将在2016年破万亿
  2. 010-映射诊断环境
  3. 计算机专业读mba,计算机专业的学生适合读MBA吗MBA考试_MBA-教育宝
  4. 交换机和路由器上流量限制
  5. mybatis写当天 当月的数据 时间段数据https://www.cnblogs.com/xzjf/p/7600533.html
  6. 2019手卫生定义_2021年卫生资格考试部分科目大纲和教材变化归总!
  7. Exchange 技巧(1) Exchange2010 邮件收发统计
  8. C++进阶教程之信号处理
  9. php检测php.ini是否配制正确
  10. SONY α系列(A6000A7)数码微单相机APP破解免付费安装教程
  11. typecho插件编写教程6 - 调用接口
  12. Java网络 1.3 开发工具介绍
  13. wsl 2 中安装docker
  14. php获取h5视频直链,一种H5播放实时视频的方法与系统与流程
  15. 小程序获取头像昵称最新版本
  16. 想知道有哪些缩小视频大小的软件?这几个压缩软件你该知道
  17. iptables匹配功能length
  18. 拿来就用的脚本案例(三)
  19. phpcms 点赞_php+js实现点赞功能的示例详解
  20. 程序员的自我修养 --- 热爱、分享与梦(本人简历及开源社区贡献)

热门文章

  1. VMware使用技巧之“快照”+“克隆”
  2. 最小二乘法为什么使用误差平方和
  3. 数学计算机学具制作,《 用计算器计算》四年级数学
  4. pageSize不生效
  5. python爬虫,爬取贝壳网数据简单案例
  6. mac键盘锁住了怎么解决 苹果电脑键盘锁住了解决方法
  7. 树莓派B+安装简单版魔镜MagicMirror
  8. tp6 导入excel表格
  9. openwrt官方固件怎么中继网络
  10. MATLAB的semilogy函数的理解