Docker 下的 Nacos 环境开发
欢迎访问我的 GitHub
这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本文是《Docker下,两分钟极速体验Nacos》的续篇,前文我们极速体验了 Nacos 注册中心、服务提供者、服务消费者,这些应用都对应着不同的 Docker 容器,今天就来细说这些 Docker 容器的镜像。
回顾上一章的业务流程
先来回顾一下上一章,整个 Docker 环境中有哪些容器,提供了什么服务,如下图,请顺着橙色提示框的数字顺序来看请整个流程::
系列文章链接
下面是《Spring Cloud Alibaba 实战系列》的所有文章地址:
Nacos 环境背后对应的 Docker 技术
在 Docker 下搭建一个包含 Nacos 注册中心、服务提供者、服务消费者的环境,总的来说需要做下面这些事情:
制作 Nacos 镜像;
制作服务提供者镜像;
制作服务消费者镜像;
制作 docker-compose.yml 文件,将容器编排在一起,然后一次性启动;
接下来我们逐个开发上面提到的内容;
源码下载
如果您不打算写代码,也可以从 GitHub 上下载本次实战的源码,地址和链接信息如下表所示:
这个 git 项目中有多个文件夹,本章的应用在 nacosdemo 文件夹下,如下图所示:
制作 Nacos 镜像
对 Nacos 镜像的功能要求有以下三点:
包含 Nacos server 应用;
暴露 web 管理服务的端口;
容器启动时,Nacos 服务能够自动启动;
为了满足以上要求,除了编写 Dockerfile 文件,还要编写 docker-entrypoint.sh 文件,在容器创建时执行该文件用于启动 Nacos 服务;
首先是 Dockerfile 文件,该文件用于制作 Nacos 镜像:
从 Dockerfile 内容中可见,先去 nacos 的 github 下载安装包,然后解压,再复制 docker-entrypoint.sh 到镜像中,最后将 nacos 的 8848 端口暴露出来;再来看看 docker-entrypoint.sh 文件的内容,该文件在容器启动时会被执行,内容很简单,就是进入 nacos 的 bin 目录,执行启动文件,再将 start.out 输出到控制台:
有两个重要信息需要注意:
nacos 的官方参考启动命令是 ./startup.sh -m standalone ,这个命令会将 jvm 的输出重定向到 start.out 文件,也就是说 nacos 的 JVM 进程是在后台运行的,不会占用控制台(相比之下,spring boot 应用使用 java -jar 启动时会占用控制台),对于 docker 来说,容器内的进程如果不占用控制台,docker 就认为该容器已经结束工作,就会停止该容器,所以,为了避免 nacos 在 docker 刚刚启动就退出,需要用 tail -f start.out 来占领控制台;
用 tail -f start.out 来占领控制台可以避免容器刚刚启动就退出,但也有个弊端,就是容器中有了多个进程,并且 nacos 进程的 PID 不是 1,所以在执行 docker stop 命令时,结束进程的信号量不会到 nacos 进程,而是去了 PID 等于 1 的进程,所以 nacos 进程不会立即退出,只能等到 30 秒后被强制 kill,这个问题最好的解法是修改 nacos 的 startup.sh ,让 nacos 进程始终保持在控制台,不要重定向到后台,但这样就导致 Dockerfile 不好处理了,每次下载和解压了 nacos 安装包后,都要用本地的 startup.sh 去替换原有的,这样做的话,如果 nacos 升级版本,这边本地的 startup.sh 也要随之更新,很是麻烦...
构建镜像
Dockerfile 和 docker-entrypoint.sh 文件准备好之后放在同一个目录,执行以下命令构建镜像:
如果您在 hub.docker.com 已经注册,可以执行以下命令将本地镜像上传到 hub.docker.com ,这样任何人都可以下载使用该镜像了:
Nacos 镜像的制作已经完成,接下来制作一个 java 应用的镜像:服务提供者;
java 应用的父工程
接下来要开发的 simple-provider 和 simple-consumer 两个应用都是 java 应用,为了管理方便,做一个基于 maven 的父工程,再将 simple-provider 和 simple-consumer 以 module 的形式加入到这个父工程中;
基于 maven 创建父工程,名为 nacosdemo,其 pom.xml 内容如下:
可见这是个普通的父工程,里面对 spring cloud 和 spring cloud alibaba 的版本做了控制,避免子工程还要各种指定版本的繁琐操作;
制作服务提供者镜像
simple-provider 是个 java web 应用,使用了 spring cloud alibaba 的依赖库之后可以使用 Nacos 的注册发现服务,整个工程的开发步骤如下:
基于 maven 创建工程,其 pom.xml 内容如下:
上述内容有两点需要注意:a. 依赖 spring-cloud-starter-alibaba-nacos-discovery,这样可以用上 spring cloud nacos 的服务;b. 使用了 maven 插件 jib-maven-plugin,用于将应用构建成 docker 镜像,此插件相关的详情请参考《Docker与Jib(maven插件版)实战》;
配置文件 application.properties,配置应用名称和 nacos 地址,注意这里 nacos 地址配置的是 nacoshost ,对应的是后面 docker-compose.yml 中的 link 参数:
应用启动类 SimpleProviderApplication ,配置了注解 EnableDiscoveryClient,用于启动注册发现服务:
增加一个提供 http 服务的 controller 类 ProviderController:
以上就是 simple-provider 的所有源码了,在 pom.xml 所在目录执行以下命令,即可构建 docker 镜像,存入本地仓库:
制作服务消费者镜像
simple-consumer 是个 java web 应用,启动后对外提供 http 服务,响应的时候,通过 nacos 取得 simple-provider 的地址,然后向 simple-provider 发请求,将响应返回给浏览器:
基于 maven 创建工程,其 pom.xml 内容如下:
配置文件 application.properties,配置应用名称和 nacos 地址,注意这里 nacos 地址配置的是 nacoshost ,对应的是后面 docker-compose.yml 中的 link 参数:
应用启动类 SimpleConsumerApplication,配置了注解 EnableDiscoveryClient,用于启动注册发现服务:
增加一个提供 http 服务的 controller 类 ConsumerController,通过 LoadBalancerClient 取得 simple-provider 的服务地址,然后发请求过去 :
以上就是 simple-consumer 的所有源码了,在 pom.xml 所在目录执行以下命令,即可构建 docker 镜像,存入本地仓库:
编写 docker-compose.yml
三个镜像都准备好了,接下来是做容器编排,docker-compose.yml 内容如下:
上述编排文件,有几点需要注意:a. 可以用 container_name 设置容器的名字,但是不要给 provider 的容器设置名字,因为按照规划 provider 会启动多个容器,指定名字会导致第二个容器启动时报名字冲突的错误;b. provider 和 consumer 通过 depends_on 参数,将自己的启动时间放在了 nacos 后面;c. links 的作用是将 nacos 的 IP 地址,写入 provider 和 consumer 的/etc/hosts 文件中,这样这两个容器内容的应用可以通过 nacoshost 来访问 nacos 了;
启动多个容器
在 docker-compose.yml 所在目录执行以下命令,即可启动所有容器,并且 provider 容器会启动 6 个:
至此,整个 nacos 的 docker 环境搭建过程已经回顾完毕,在您搭建自己的容器环境时,希望本文能给您一些参考;
欢迎关注 InfoQ:程序员欣宸
版权声明: 本文为 InfoQ 作者【程序员欣宸】的原创文章。
原文链接:【http://xie.infoq.cn/article/63b0649f67045194681cc2ed3】。文章转载请联系作者。
评论