文章目录
Nacos
Nacos简介
为什么叫 Nacos
前面四个字母分别表示 Naming 和 Configuration 的前两个字母, 最后一个s 为 Service
Nacos是什么?
- 一个更易于构建云原生运用的动态服务发现、配置管理和服务管理平台
- Nacos: Dynamic Naming and Configuration Service(动态命名和配置服务)
Nacos 就是注册中心+ 配置中心,等价于Eureka + Config + Bus
Nacos = Eureka + Config + Bus
Nacos能做什么?
- 替代 Eureka 做服务注册中心
- 替代 Config 做服务配置中心
- 服务注册,就是将提供某个服务的模块信息(通常是这个服务的ip和端口)注册到1个公共的组件上去。
- 服务发现,就是新注册的这个服务模块能够及时的被其他调用者发现。不管是服务新增和服务删减都能实现自动发现
核心功能
- 服务注册:Nacos Client会通过发送REST请求的方式向Nacos Server注册自己的服务,提供自身的元数据,比如ip地址、端口等信息。Nacos Server接收到注册请求后,就会把这些元数据信息存储在一个双层的内存Map中。
服务心跳:在服务注册后,Nacos Client会维护一个定时心跳来持续通知Nacos Server,说明服务一直处于可用状态,防止被剔除。默认5s发送一次心跳。 - 服务同步:Nacos Server集群之间会互相同步服务实例,用来保证服务信息的一致性。
- 服务发现:服务消费者(Nacos Client)在调用服务提供者的服务时,会发送一个REST请求给Nacos Server,获取上面注册的服务清单,并且缓存在Nacos Client本地,同时会在Nacos Client本地开启一个定时任务定时拉取服务端最新的注册表信息更新到本地缓存
- 服务健康检查:Nacos Server会开启一个定时任务用来检查注册服务实例的健康情况,对于超过15s没有收到客户端心跳的实例会将它的healthy属性置为false(客户端服务发现时不会发现),如果某个实例超过30秒没有收到心跳,直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册)
Nacos单机使用
服务搭建
- 可以根据自己的系统去官网下载对应的压缩包安装,这里不再说明
- 启动
windows版本解压完后,直接运行bin/startup.cmd
即可,但在运行前,还需要改一些配置文件
- config/application.properties
去生成一个大于32位字符的字符串,高版本不给这个值赋值启动会报错
nacos.core.auth.plugin.nacos.token.secret.key 字段说明地址
- windows单机启动修改startup.cmd(linux启动时直接加 -m standalone即可,不用修改)
windows单机启动
set MODE=“standalone”
- pom依赖
对应版本要找和SpringCloud适配的,可以去上面的版本选择超链接里查看版本对应
<!--nacos服务注册与发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
- yml配置文件
spring:
application:
name: mall-user #微服务名称
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #这里推荐使用主机名访问,在hosts文件中配置ip名称的映射
- 启动类注解
@EnableDiscoveryClient 可加可不加,但为了规范最好还是加上,然后启动项目,观察日志控制台打印是否有以下日志
nacos registry, DEFAULT_GROUP mall-user 192.168.45.1:8001 register finished
- 页面查看
既然现在已经实现了服务的注册,那么接下来就是服务的调用,一般会使用负载均衡器去调用服务(Spring Cloud Ribbon、OpenFeign等),这里不再细说,会在单个学习中介绍(低版本的nacos可能集成了Ribbon)
这里说一下spring-cloud-loadbalancer
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-loadbalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
服务隔离相关配置
NameSpace隔离设计
命名空间经常用于用户粒度的隔离,常用场景之一是不同环境的隔离;例如开发测试环境和生产环境的隔离、开发人员和开发人员间的隔离
- 创建命名空间
- 项目中使用
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #这里推荐使用主机名访问,在hosts文件中配置ip名称的映射
namespace: 59d55e51-216c-4551-95ed-c2b999e1f587 #指定命名空间的id,那么就只能注册/调用此命名空间下的服务
group服务分组
不同的服务可以归类到同一分组,group也可以起到服务隔离的作用。yml中可以通过spring.cloud.nacos.discovery.group
参数配置,更多应用场景是配置分组(比如ABC都属于支付服务,但A是付款服务,B是退款服务,C是红包服务,那么就可以将ABC分到一个group下)
集群分组
spring.cloud.nacos.discovery.cluster-name
指定集群的名字,相同集群名间的服务优先调用
比如我现在有上海和北京的集群服务,那我肯定是北京各服务间的调用尽量访问北京的服务器,上海服务间的的调用访问上海的服务器,可以通过这个配置来实现(对应的nacos页面也会以集群名分开存储)
NacosRule源码中获取服务实例
public class NacosRule extends AbstractLoadBalancerRule {
public Server choose(Object key) {
try {
String clusterName = this.nacosDiscoveryProperties.getClusterName();
DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer();
String name = loadBalancer.getName();
//获取服务实例
NamingService namingService = nacosDiscoveryProperties
.namingServiceInstance();
List<Instance> instances = namingService.selectInstances(name, true);
if (CollectionUtils.isEmpty(instances)) {
LOGGER.warn("no instance in service {}", name);
return null;
}
List<Instance> instancesToChoose = instances;
//如果clusterName不为空,就获取和clusterName相同的服务实例
if (StringUtils.isNotBlank(clusterName)) {
List<Instance> sameClusterInstances = instances.stream()
.filter(instance -> Objects.equals(clusterName,
instance.getClusterName()))
.collect(Collectors.toList());
if (!CollectionUtils.isEmpty(sameClusterInstances)) {
instancesToChoose = sameClusterInstances;
}
else {
LOGGER.warn(
"A cross-cluster call occurs,name = {}, clusterName = {}, instance = {}",
name, clusterName, instances);
}
}
//负载均衡返回一个服务实例,也跟权重等有关系
Instance instance = ExtendBalancer.getHostByRandomWeight2(instancesToChoose);
return new NacosServer(instance);
}
catch (Exception e) {
LOGGER.warn("NacosRule error", e);
return null;
}
}
}
临时实例和持久化实例(了解)
Nacos鉴权开启
主要就是修改application.properties配置文件中的3个配置
nacos.core.auth.enabled=false #开启鉴权
#配置自定义身份识别的key和value(不可为空)
nacos.core.auth.server.identity.key=authKey
nacos.core.auth.server.identity.value=authValue
项目的yml文件中指定nacos登录的用户名和密码
spring.cloud.nacos.discovery.username =nacos
spring.cloud.nacos.discovery.password =nacos
Nacos集群搭建
nacos集群搭建,如果在一台服务器上装nacos集群时,web端口不要设置为连续的几个端口,防止端口冲突
;仔细来说,nacos2.X版本比1.X版本增了gRPC的通信方式,需要增加端口,新增的端口是在主端口上,进行一定偏移量自动生成的(所以搭建时,主端口间隔尽量大些)
集群方式:
- http://ip1:port/openAPI 直连ip模式,机器挂则需要修改ip才可以使用。
- http://SLB:port/openAPI 挂载SLB模式(内网SLB,不可暴露到公网,以免带来安全风险),直连SLB即可,下面挂server真实ip,可读性不好。
- http://nacos.com:port/openAPI 域名 + SLB模式(内网SLB,不可暴露到公网,以免带来安全风险),可读性好,而且换ip方便,推荐模式(此次搭建用这种方式)
环境准备
3台机器,nacos安装包
修改配置文件
在nacos的解压目录下, conf文件夹下,修改配置文件cluster.conf.example文件(去掉example后缀),添加3行 ip:port
多网卡时,需要指定一下用那个网卡,否则启动可能出问题或者去nacos页面看节点时,发现节点不止3个节点
多网卡还有其他一些可配置参数,了解下就行了
鉴权开启(生产环境都会有,自己搭建就可省略)
配置外置数据源
-
初始化mysql数据库
需要执行的sql -
修改application.properties文件
-
分别启动3个nacos节点
bin/startup.sh
访问nacos页面,这时在集群管理菜单下就可以看到3个nacos节点
代码中引入nacos集群
yml配置文件
spring:
application:
name: mall-user #微服务名称
#配置nacos注册中心地址
cloud:
nacos:
discovery:
server-addr: 192.168.65.174:8848,192.168.65.192:8848,192.168.65.204:8848
username: nacos
password: nacos
其实到这里就可以了,但后面还可以引入Nginx配置负载均衡
引入nignx
使用VIP/nginx请求时,需要配置成TCP转发,不能配置http2转发,否则连接会被nginx断开。 9849和7848端口为服务端之间的通信端口,请勿暴露到外部网络环境和客户端测。
引入nignx做负载均衡,也可以理解为:如果nacos集群变更了,我只需改nignx配置中的nacos节点,而无需更改代码中和nacos相关的配置
准备nginx环境
- 如果安装了nginx,先检查nginx是否有stream模块,输出中包含:–with-stream
nginx -V
- 安装nginx
#安装依赖包
yum -y install gcc gcc-c++ autoconf automake
yum -y install zlib zlib-devel openssl openssl-devel pcre-devel
# 下载nginx
wget https://nginx.org/download/nginx-1.18.0.tar.gz
tar -zxvf nginx-1.18.0.tar.gz
cd nginx-1.18.0
#编译nginx 如果使用 nginx 的 stream 功能,在编译时一定要加上 “--with-stream”
./configure --with-stream
make && make install
#安装后nginx默认路径/usr/local/nginx
- 配置http模块
在nginx的http下面配置http协议相关的地址和端口:
http {
# nacos服务器http相关地址和端口
upstream nacos-server {
server 192.168.65.174:8848;
server 192.168.65.192:8848;
server 192.168.65.204:8848;
}
server {
listen 8848;
location / {
proxy_pass http://nacos-server/;
}
}
}
- 配置grpc,需要nginx有stream模块支持
# nacos服务器grpc相关地址和端口,需要nginx已经有stream模块
# stream块用于做TCP转发
stream {
upstream nacos-server-grpc {
server 192.168.65.174:9848;
server 192.168.65.192:9848;
server 192.168.65.204:9848;
}
server {
listen 9848;
proxy_pass nacos-server-grpc;
}
}
- 启动nginx,然后就可以正常使用了。
sbin/nginx -c conf/nginx.conf
yml中配置
spring:
application:
name: mall-user #微服务名称
#配置nacos注册中心地址
cloud:
nacos:
discovery:
server-addr: nacos.mall.com:8848 #nacos.mall.com nginx服务器ip的域名映射
username: nacos
password: nacos