摘要:开源项目Zheng的部署环境十分复杂,虽然官方提到只需要10分钟就可以完成部署,但是涉及到多达6种依赖服务的安装和配置,十分繁琐。所以本文将使用docker对该项目的环境进行配置。目前第一部是将环境Docker化,第二步就是将应用本身也要Docker化。通过Docker基本实现一键部署,无需繁琐配置。下面就开始介绍是如何一步一步将zheng的环境进行Docker化。
项目介绍
基于Spring+SpringMVC+Mybatis分布式敏捷开发系统架构,提供整套公共微服务服务模块:集中权限管理(单点登录)、内容管理、支付中心、用户管理(支持第三方登录)、微信平台、存储系统、配置中心、日志分析、任务和通知等,支持服务治理、监控和追踪,努力为中小型企业打造全方位J2EE企业级开发解决方案。
参考资料
官方项目oschina
官方项目GitHub
开源项目【zheng】环境搭建指南
Docker 技术介绍
Docker 是一种容器技术,并且在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。
Docker 和传统虚拟化方式不同。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
优势
所以对于复杂的环境的部署使用Docker有得天独厚的优势:
更高效的利用系统资源
由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。
更快速的启动时间
传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
一致的运行环境
开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。
持续交付和部署
对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。
使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment) 系统进行自动部署。
而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。
更轻松的迁移
由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
更轻松的维护和扩展
Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
Docker Compose
Compose
项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。 。
Compose
定位是 「定义和运行多个 Docker 容器的应用(Defining and running multi-container Docker applications)」,其前身是开源项目 Fig。
通过第一部分中的介绍,我们知道使用一个 Dockerfile
模板文件,可以让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。
Compose
恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml
模板文件(YAML
格式)来定义一组相关联的应用容器为一个项目(project)。
Compose
中有两个重要的概念:
服务 (service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
项目 (project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml
文件中定义。
Compose
的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。
主要服务介绍
根据zheng官方指导,我们知道目前系统主要依赖6个服务,分别是 mysql
,redis
,zookeeper
,activemq
,nginx
,dubbo
。我们分别介绍其配置。
概述
我们参考了 JHipster
项目的风格,将不同的服务 compose
配置独立出来,然后在项目配置文件中通过 extends
关键字进行配置。比如我们有xxx-service.yml
,然后在项目配置文件中app.yml
使用如下语句配置:
1 | xxx-service: |
MySQL
首先我们介绍数据库服务,官方给出了使用 MySQL
,并且提供了初始化脚本 zheng.sql
和 zheng-ucenter.sql
。实际上我们的数据服务可以选用MySQL
或 MariaDB
,这里使用MySQL
的官方镜像,为了保证服务的一致性,我们没有使用 latest
,而是使用具体标签5.7.22
。如果使用最新的版本8,可能需要解决授权插件的问题,相关参考1,2。
代码: mysql.yml
1 | version: '2' |
执行初始化脚本
我们希望在 MySQL 服务启动时自动根据项目提供的脚本创建数据,这里我们使用 MySQL
Docker镜像的初始化机制,也就是在 MySQL
启动时,会执行/docker-entrypoint-initdb.d
目录下的sql
脚本。所以我们只需要将我们的脚本映射到该目录就可以,所以这里使用了一个 Volume
的配置就是完成这个操作的。
1 | - ./script/zheng.sql:/docker-entrypoint-initdb.d/zheng.sql |
这里需要注意,一开始在导入的时候,总是中文乱码,在反复检查编码确认都为 UTF8
后才通过该 issue 注意到,乱码的产生原来是 Docker 镜像在执行初始化命令的时候的 Terminal
编码配置的问题,因为脚本中有中文,而命令行窗口默认不是 UTF8
,所以实际上所执行的脚本本身就是乱码,就不能怪MySQL
了。解决办法很简单,指定 Docker 的默认编码方式:
1 | - LANG=C.UTF-8 |
环境变量
除了前面介绍的编码方式,这里环境变量还配置了用户名,密码和初始创建的数据库名称。这里的密码使用的项目默认的密码,这个密码在配置文件中(比如 \zheng\zheng-upms\zheng-upms-rpc-service\src\main\resources\profiles\dev.properties
)的datasource.master.jdbc.password=rWd3Hb+AzNg3IXF1b5vD+g==
。大家需要注意这个配置是经过AES
加密过了,具体加密方式参考该工具类(\zheng\zheng-common\src\main\java\com\zheng\common\util\AESUtil.java
),直接运行 main
1 | key | AESEncode | AESDecode |
也就是说如果配置文件中是 FNFl9F2O2Skb8yoKM0jhHA==
,说明配置的就是空字符串。 如果配置文件中是rWd3Hb+AzNg3IXF1b5vD+g==
,说明配置就是123456。为了让大家不需要修改项目配置,所以这里一律使用和默认密码相匹配的配置。
- MySQL: 123456
- redis:空字符串
命令行参数和端口
端口暴露默认端口 3306
命令行执行:
1 | mysqld --skip-ssl --character_set_server=utf8mb4 --sql_mode="" |
这里指定了 --sql_mode
表示不对脚本做任何限制。因为在一开始参考其他的配置,将NO_ZERO_DATE
配置到了 sql_mode
中,导致出错(ERROR 1067 (42000) at line 517: Invalid default value for 'last_login_time'
)。因为项目脚本有一个 last_login_time
配置成了0,所以这里不能开启这个选项。参考
单独测试
这样 MySQL
就配置好了,可以单独启动使用工具链接进行测试了,首先确认当前目录为项目的根目录,确保能够找到正确的 yaml
配置文件。
1 | 启动 |
由于我们映射了MySQL
数据到本地Volume,所以这时候会在 \docker\data\mysql\data
中创建数据。这个数据会一直保留,就是将服务停止,如果想更新数据,只需要删除所有数据在重新启动就可以了。
redis
Redis 的配置相对简单,这里由于官方镜像不支持各种配置,所以我们选用了bitnami/redis
,版本为4.0,这是该镜像的优势,主要是可以支持各种配置同时是官方源码自动编译的,品质也是可靠的。
配置文件如下:
1 | version: '2' |
使用默认端口:6379。
这里只需要一个配置就是,设置为空密码
1 | # - REDIS_PASSWORD= |
如果你希望配置不同的密码,使用REDIS_PASSWORD
指定密码。
zookeeper
配置简单,使用默认端口:2128
1 | version: '2' |
activemq
使用了一个第三方的镜像,配置简单
1 | version: '2' |
nginx
nginx 的配置由于项目中的配置文件应该是给windows使用的,这里进行一定的修改,基本包含了原有的配置,并修改了路径为相对路径。但是这里可能有些问题,主要是前端抽离的项目感觉并不完整,项目打包后也会在 webapp 中生成前端项目,不知道有何区别。
1 | version: '2' |
dubbo
由于 dubbo这个项目不再获取,也没有官方镜像,这里我自己根据官网的源码制作了一个镜像。注意这个服务依赖于zookeeper。
1 | version: '2' |
dubbo 的配置包含了指定 zookeeper
的地址,这里使用 docker-compse 的网络别名。
整体项目配置
有了单独的服务后,我们就可以配置整体的环境了,配置十分简单,就是把服务的配置链接到外部的文件即可:
1 | version: '2' |
依赖环境服务相关操作
至此整个环境部署完成
实现zheng环境的docker化,通过配置好的docker-compose,一键启动所有依赖服务,并且和目前项目的默认配置匹配,项目无需进行任何更改就可以立即运行。该配置参考JHipster,将不同的服务配置成不同的 yaml 文件,然后在同一的 app.yaml 中引用所有的服务。
整个docker-compose 由6个服务构成
- mysql
- redis
- nginx
- zookeeper
- activemq
- dubbo
单独测试独立服务
确保当前命令行当前路径为项目根路径
1 | docker-compose -f docker/mysql.yml up -d |
测试dubbo
由于 dubbo 依赖于 zookeepr,所以单独有一个 dubbo 的 yaml 用来测试:
1 | docker-compose -f docker/dubbo.yml up -d |
一键启动所有的服务
1 | docker-compose -f docker/app.yml up -d |
一键关闭所有的服务
该操作会保留所有数据,因为数据会被存放在 Volume 中, 注意这些文件不会被 git 管理,请自行管理。
1 | docker-compose -f docker/app.yml down |
查看指定服务的log
其中 -f
表示 follow,会持续显示最新的log
1 | docker-compose -f docker/app.yml logs -f <service_name> |
For example:1
2docker-compose -f docker/app.yml logs -f zheng-mysql
docker-compose -f docker/app.yml logs -f <service_name>
重新 build 某个服务
如果对某个服务的 yaml 文件进行了更改,可以通过该命令进行重新build
1 | docker-compose -f docker/app.yml up -d --no-deps --build <service_name> |
For example
1 | docker-compose -f docker/app.yml up -d --no-deps --build zheng-mysql |
项目应用运行
分享了5个 Intellij 的执行配置文件,文件在 .idea\runConfigurations
下面,(.gitignore 排除了这些文件)
可以直接点击这些配置运行对应项目,按照要求应该依次启动:
- ZhengUpmsRpcServiceApplication.xml
- zheng_upms_server.xml
- ZhengCmsRpcServiceApplication.xml
- zheng_cms_admin.xml
- zheng_cms_web.xml
希望这些能够帮助面对复杂配置望而却步的开发者快速体验。