背景
最近在尝试将本博客后端升级为微服务架构,使用了nacos作为服务商,部署采用Docker容器,编写docker-compose.yml一键运行容器,在容器中连接nacos时遇到了Client not connected, current status:STARTING错误。直接访问domain:port/nacos/index.html是可以访问的,说明nacos启动和数据库链接是没有问题的,后查询文献发现是nacos v2.*.*版本增加了9848端口,需要添加映射。
一、 运行环境
nacos版本:2.2.3
mysql版本:5.7
采用了mysql作为持久化的数据库,docker作为运行的环境
二、启动nacos
采用 docker 的形式运行 mysql 和 nacos
起初运行 nacos 的 docker 命令:
docker run -d
-e MODE=standalone
-e PREFER_HOST_MODE=hostname
-e SPRING_DATASOURCE_PLATFORM=mysql
-e MYSQL_SERVICE_HOST=本机地址
-e MYSQL_SERVICE_PORT=3306
-e MYSQL_SERVICE_USER=root
-e MYSQL_SERVICE_PASSWORD=123456
-e MYSQL_SERVICE_DB_NAME=nacos-config
-p 8848:8848
--name nacos
--restart=always nacos/nacos-server:latest
命令解释:
docker run:这是Docker的一个命令,用于从Docker镜像创建并启动一个容器。
-d:这个选项告诉Docker在后台运行容器,并返回容器ID。
-e:这个选项用于设置环境变量。例如,-e MODE=standalone 设置了环境变量MODE的值为’standalone’。
-p:这个选项用于端口映射,例如 -p 8848:8848 将主机的8848端口映射到容器的8848端口。
–name:这个选项用于给容器命名,此处的名字为’nacos’。
–restart=always:这是一个策略,表明如果容器退出,Docker应该总是尝试重新启动它。
nacos/nacos-server:latest:这是要运行的Docker镜像的名称,其中’nacos/nacos-server’是镜像的仓库和名称,'latest’是标签,表示要使用的是最新的版本。
nacos可以正常启动,然后也可以访问web控制台。但是事情还没完。
注: 为了更方便理解,这里给出的是docker运行语句,而非docker-compose写法。
二、出现问题
然后我启动项目连接 nacos 的时候报错:Client not connected,current status:STARTING,StatusRuntimeException。以及无法连接到127.0.0.1:8848
经过多方查找,发现 nacos 2.x.x 需要在启动的时候多映射两个端口:9848,9849
官方解释如下:
Nacos2.0版本相比1.X新增了gRPC的通信方式,因此需要增加2个端口。新增端口是在配置的主端口(server.port)基础上,进行一定偏移量自动生成。
端口 | 与主端口的偏移量 | 描述 |
---|---|---|
9848 | 1000 | 客户端gRPC请求服务端端口,用于客户端向服务端发起连接和请求 |
9849 | 1001 | 服务端gRPC请求服务端端口,用于服务间同步等 |
更多解释移步官网查看:https://nacos.io/zh-cn/docs/v2/upgrading/2.0.0-compatibility.html |
所以修改后的 docker 启动命令应该是:
docker run -d
-e MODE=standalone
-e PREFER_HOST_MODE=hostname
-e SPRING_DATASOURCE_PLATFORM=mysql
-e MYSQL_SERVICE_HOST=本机地址
-e MYSQL_SERVICE_PORT=3306
-e MYSQL_SERVICE_USER=root
-e MYSQL_SERVICE_PASSWORD=123456
-e MYSQL_SERVICE_DB_NAME=nacos-config
-p 8848:8848 -p 9848:9848 -p 9849:9849
--name nacos
--restart=always nacos/nacos-server:latest
最后提醒:在不同容器中一般不能使用127.0.0.1作为ip来连接,每个容器都是独立个体,可以理解为一个单独的虚拟机。如果要容器间通信,可以使用公网ip;如果容器在同一个网段(同一主机部署),可以使用容器名作为域名进行通信,例如mysql的容器名是cxblog-mysql
,则MYSQL_SERVICE_HOST=cxblog-mysql
,或在配置文件里面将连接url改为db.url.0=jdbc:mysql://cxblog-mysql:3306/nacos-config