持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情
一、Nacos集群环境的搭建
1-1、基础环境准备
- jdk1.8+
- maven 3.3+
- nginx 作为负载均衡
- mysql 5.7+
集群部署架构图
1-2、nacos部署
上篇文章已经在linux里面部署了nacos,为了方便就在一台虚拟机上部署三个nacos并分配不同的端口,暂定部署三个节点,分别为: nacos8848、nacos8849、nacos8850
1-2-1、配置数据库
单机nacos的时候数据存储在内存中,但是如果要配置集群就需要配合数据库来使用了,假如不适用数据库,多个nacos启动就会启动相对应的进程,数据就会存储在各自的内存中,就无法保证数据一致性了。
修改conf\application.properties的配置,使用外置数据源 要使用mysql5.7+(包括)
#使用外置mysql数据源 spring.datasource.platform=mysql
### Count of DB: db.num=1
### Connect URL of DB:
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=root
db.password.0=root
配置数据库需要注意的是,一定要在数据库中创建nacos数据库,并执行一下conf/下的nacos-mysql.sql脚本,完成数据库初始化操作。
最终数据库生成的表如下:
1-2-2、修改节点
将conf\cluster.conf.example改为cluster.conf,添加节点配置
192.168.253.131:8848
192.168.253.131:8849
192.168.253.131:8850
nacos8849,nacos8850 按同样的方式配置。
1-2-3、修改启动文件
可以在bin/startup.sh文件中修改相关配置如:启动模式、内存等
1-2-3-1、启动模式
默认安装的是集群模式,如果是单机模式,可以改为 standalone。
这样单机启动命令startup.sh -m standalone改为 startup.sh
现在搭建集群模式,这个地方就不需要修改了
1-2-3-2、修改内存
如果出现内存不足:同样修改启动脚本(bin\startup.sh)的jvm参数,如下图:
因为我这边是安装在虚拟机中,内存比较小,因此需要将集群的内存改小一些,可以按照单机的内存修改,如果后面还是内存不够,可以再修改小一点。
JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m -Xmn256m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128m"
1-2-4、启动
启动一些刚刚配置的8848看下能否启动成功
浏览器访问一下:http://192.168.253.131:8848/nacos
看下集群中的节点列表,可以看到8848已经是UP状态
启动没问题,可以将8848的配置复制到8849和8850
一定要记得改端口号
最终可以看到三个节点已经都全部启动成功
1-3、nginx的安装和配置
1-3-1、添加官方源仓库
yum install -y yum-utils
yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
1-3-2、安装openresty
安装openresty集成包
yum install -y openresty
cd /usr/local/openresty/
ls
1-3-3、配置nginx
编辑nginx.conf配置文件
vim nginx/conf/nginx.conf
然后添加如下内容
upstream nacoscluster {
server 127.0.0.1:8848;
server 127.0.0.1:8849;
server 127.0.0.1:8850;
}
server {
listen 8851;
server_name localhost;
location /nacos/{
proxy_pass http://nacoscluster/nacos/;
}
}
可以看到通过访问:http://192.168.253.131:8851/nacos
就可以访问nacos服务了,这样就完成了nginx复制服务了。
二、程序配置nginx服务调用nacos
2-1、修改程序连接nginx负载地址
首先修改stock服务的配置文件
再次修改order服务的配置文件
可以看到两个服务豆浆nacos的地址改为了nginx的服务地址,如果nginx中配置了域名,这两个服务就可以直接配置域名了。
2-2、nacos2.0版本gRPC通信的额外两个端口
启动服务,发现报如下错误:
通过查阅资料发现:
Nacos2.0版本相比1.X新增了gRPC的通信方式,因此需要增加2个端口。新增端口是在配置的主端口(server.port)基础上,进行一定偏移量自动生成。
比如nacos设置8848端口,同时也会占用9848以及9849
| 端口 | 与主端口的偏移量 | 描述 |
|---|---|---|
| 9848 | 1000 | 客户端gRPC请求服务端端口,用于客户端向服务端发起连接和请求 |
| 9849 | 1001 | 服务端gRPC请求服务端端口,用于服务间同步等 |
而上面配置集群一共配置了三个端口分别为8848/8849/8850,那么对应占用的端口为:
8848:9848+9849
8849:9849+9850
8850:9850+9851
看到了吗:9849被重复占用了,这样就会导致集群中的8849服务虽然启动成功,但是一会就会报错,提示端口被占用,具体错误我就不截图了,如果你按照我上面配置的一步步来,相信会看到这个错误
因此需要修改我们nacos集群三个节点的端口,分别修改为:8848/8858/8868三个节点,对应占用的端口为:
8848:9848+9849
8858:9858+9859
8868:9868+9869
这样就会报端口被占用了,修改端口需要同时修改各个节点下的application.prpperties和cluster.conf下的端口。
还有记得修改nginx下的nacos三个节点端口
然后记得重启nginx:
访问nginx地址端口
2-3、Spring Cloud Alibaba2.2.7和nacos2.0.3不兼容问题
在文章最上面还特意提示要按照官方给的版本对照表来进行搭建,到了此步nginx负载三个nacos是没问题的,但是在用程序注册服务的时候就会报如下错误:
com.alibaba.nacos.api.exception.NacosException: Request nacos server failed:
at com.alibaba.nacos.client.naming.remote.gprc.NamingGrpcClientProxy.requestToServer(NamingGrpcClientProxy.java:279) ~[nacos-client-2.0.3.jar:na]
at com.alibaba.nacos.client.naming.remote.gprc.NamingGrpcClientProxy.doSubscribe(NamingGrpcClientProxy.java:227) ~[nacos-client-2.0.3.jar:na]
at com.alibaba.nacos.client.naming.remote.gprc.NamingGrpcClientProxy.subscribe(NamingGrpcClientProxy.java:212) ~[nacos-client-2.0.3.jar:na]
at com.alibaba.nacos.client.naming.remote.NamingClientProxyDelegate.subscribe(NamingClientProxyDelegate.java:147) ~[nacos-client-2.0.3.jar:na]
at com.alibaba.nacos.client.naming.NacosNamingService.subscribe(NacosNamingService.java:393) ~[nacos-client-2.0.3.jar:na]
at com.alibaba.cloud.nacos.discovery.NacosWatch.start(NacosWatch.java:134) ~[spring-cloud-starter-alibaba-nacos-discovery-2.2.7.RELEASE.jar:2.2.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:182) [spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:53) [spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:360) [spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:158) [spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:122) [spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:895) [spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:554) [spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:755) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:402) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1247) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1236) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE]
at com.jony.OrderApplication.main(OrderApplication.java:16) [classes/:na]
Caused by: com.alibaba.nacos.api.exception.NacosException: Client not connected,current status:STARTING
at com.alibaba.nacos.common.remote.client.RpcClient.request(RpcClient.java:655) ~[nacos-client-2.0.3.jar:na]
at com.alibaba.nacos.common.remote.client.RpcClient.request(RpcClient.java:635) ~[nacos-client-2.0.3.jar:na]
at com.alibaba.nacos.client.naming.remote.gprc.NamingGrpcClientProxy.requestToServer(NamingGrpcClientProxy.java:269) ~[nacos-client-2.0.3.jar:na]
... 20 common frames omitted
一开始还是认为环境问题,然后各种排查,查找问题,结果偶然发现一片博文,指出还是由于Spring Cloud Alibaba 2.2.7.RELEASE 和Nacos 2.0.3不兼容,需要将Spring Cloud Alibaba 降级到2.2.6.RELEASE。结果尝试了一下,还真是这个问题。
可以看到降级之后,服务就可以正常注册了。
2-4、nacos集群日志的查看
在集群目录页面会默认生成一个logs文件夹和work文件夹,在logs文件夹中会生成access_logs文件,里面记录了nacos的访问日志,如下
里面就有心跳的请求监测。
可以去Nacos文档里面去看下
这样就可以看到所有的api信息了