张瑞林 吴学敏

摘要:庞杂而版本升级频繁的互联网后端服务系统,需要一种内部耦合性低的方法来实现灵活开发、便捷部署。该文分析了Docker容器的特点及其核心技术,然后通过实例来说明把一个复杂的后端服务拆分为多个微服务子系统,在Docker官方公布的OpenJDK、MySql等基础镜像之上构建新镜像,并运行这些镜像作为微服务,以此来提供整体后端服务的基本方法,最后总结了本方法的优缺点。

关键词: Docker技术;后端服务;微服务

中图分类号:TP3        文献标识码:A

文章编号:1009-3044(2019)13-0281-02

随着互联网信息技术的发展,一些系统变得更加庞大复杂,后端系统给前端Web或应用程序提供的服务越来越大,功能越来越多。因此,这些臃肿的后端系统带来一系列问题:开发者难以掌握整个大系统全部细节,修BUG或者增加新功能都不容易;无论修改多小的功能都要对整个系统进行更新,带来潜在未知风险;每次版本更新时,重新启动也要耗费较长时间等等。为了解决上述问题,把复杂的后端系统分割为多个微小系统是一个不错的选择,因此本文提出了一种在后端服务中应用Docker容器作为载体来提供微服务的解决方法。

1 Docker容器及其核心技术

Docker技术是dotCloud 公司在2013年发布的基于Go语言实现的云开源项目,与已有的传统虚拟化技术相比,Docker技术有着独特的优势,比如轻量级、自由度更大、启动快等特点,并且Docker技术可以按照所需的服务和应用打包起来建立执行的环境。

Docker有3个核心概念,镜像、容器以及仓库。其中Docker镜像是一个由一层层只读层构成的模板文件。Docker容器使用了Linux操作系统内核的命名空间(Namespace)、控制组(Control Group)、联合文件系统(Union File System)等三个关键技术。Docker容器使用Linux内核的Namespace特性进行各个容器之间的隔离,通过内核的Control Groups进行使用资源的限制和监控,通过高性能分层文件系统Union File System使得镜像可以通过分层实现和继承。图1是Docker容器技术的架构图。

1.1 命名空间Namespace技术

Namespace技术是容器的隔离性的基础,Namespace将容器的进程、网络、消息、文件系统、UTS等系统资源和用户空间隔离开。使用了Namespace之后,进程在Namespace之外展示为一个普通用户,但是在Namespace内则展现为root用户(uid=0)。也就是进程在这个Namespace里拥有root权限,在Namespace外面只有普通用户的权限。通过Namespace特性,每个Docker容器都有自己的独立的命名空间,运行在该Docker中的应用程序和运行中独立的操作系统中类似,这种隔离性保证了容器之间彼此互不影响。

1.2 控制组Control Groups技术

Control Groups技术对进程起了限制资源的作用。这些资源包括CPU,内存,存储,网络等。通过Control Groups还可以实时的监控进程的监控和统计信息。比如在启动Docker容器时,可以指定允许使用的内存大小,Docker 会自动为容器在目录/sys/fs/cgroup/memory/Docker/<容器的完整长ID>中创建相应 Cgroup 配置文件。Control Groups技术为Docker容器限定使用资源提供了技术支持。

1.3 联合文件系统Union File System技术

联合文件系统Union File System是一种轻量级高性能的分层文件系统,能把不同物理位置的目录合并一起挂载到同一个虚拟目录下。Docker容器使用了联合文件系统技术实现了镜像的分层。在该文件系统中,每次修改都可以看作创建了一个新的层Layer,Docker镜像就是由一层或多层这样的Layer所构成。镜像层都是只读的,但是镜像启动成为容器,在容器层是可写的。Docker镜像之间有顺序关系,最下面一层为基础镜像,其他层都会有一个指针指向下一层,上层镜像依赖于下层镜像。

2 使用Docker容器构建后端微服务

2.1 后端服务整体架构

下文以某公司的信息服务后端系统为例,介绍把该后端系统分割为多个微服务子系统,再以Docker容器作为载体创建后端服务的方法。先按照业务逻辑进行划分后端微服务,分为生产部后端应用服务、生产部数据库服务、MQTT消息发送服务、售后后端应用服务、售后数据库服务等5个微服务,这些微服务都以Docker容器的方式独立运行于一个主机里,主机的操作系统是UBUNTU 16.04。图2是以Docker为载体的后端服务系统,Docker1~5分别承载了上面的五个微服务,各个微服务的Docker以“IP:Port”的方式对外提供后端服务,即要访问某个服务,需要知道该服务的IP和端口号。

2.2 Docker容器微服务组建步骤

该后台系统分割为5个Docker微服务后,需要Docker1和Docker4提供JAVA环境来运行JAR包,需要Docker3提供MQTT代理服务器broker(作用是接受发布者发布的所有消息再按订阅规则发给不同的消息订阅者),需要Docker2和Docker5提供MySql数据库服务。下面是这5个Docker容器微服务的组建步骤:

(1)去Docker官方仓库去获取这3种镜像(JAVA运行环境、MQTT代理服务器、MySql数据库环境)。具体地是,安装好Docker后,使用“Docker pull openjdk”命令从仓库里拉取openjdk这个Docker镜像到本地,这镜像提供了JAVA运行环境;使用“Docker pull toke/mosquitto”命令拉mosquitto镜像(MQTT服务镜像);使用“Docker pull mysql”命令拉取MySql镜像。

(2)把生产部后端服务的JAVA JAR包放到JDK镜像后生成新的镜像。具体地是,新建Dockerfile,使用Docker build命令按照Dockerfile里设定的规则来创建Docker镜像。在这个基础镜像之上,把生产部后端服务的JAVA JAR包拷贝到新镜像里,再设定该容器启动时自动运行该JAR包即可。

(3)使用Docker run命令运行第2步生成的镜像来创建Docker容器,以此提供生产部后端微服务,运行时需要指定容器端口和映射到宿主机的端口,因为最终是需要通过“IP:端口”的形式来提供后端服务,每个Docker容器都会自动获取一个内网IP。

(4)把售后后端服务的JAVA JAR包放到JDK镜像后生成新的镜像。这一步的和第2步类似,使用的JAR包换成售后后端的JAR包即可。

(5)运行第4步生成的镜像来创建Docker容器,以此提供售后后端微服务,这一步和第3步类似,注意,指定的宿主机映射端口号要不同。

(6)运行第1步获得的MySql镜像创建生产部数据库容器。运行时也指定容器端口和映射到宿主机的端口。采用数据卷(Volume)的方式把MySql容器内部的数据库目录/var/lib/mysql挂载到宿主机的目录(比如新建一个目录/host/mysql_data/)下,这样,容器内的MySql数据文件就会持久化保存到宿主机,即使容器本身被删除,我们也可以在宿主机上的挂载目录里找到数据库文件。

(7)运行第1步获得的MQTT镜像来提供MQTT代理服务器。运行时要指定映射到宿主机的端口和MQTT的端口。

3 Docker容器作为后端服务载体的优缺点分析

在采用Docker容器作为后端微服务的载体后,主要有下列优点:

(1)Docker容器可以打包了整个运行环境,确保了开发环境、测试环境以及生产环境的一致性。这样就不会出现开发环境运行良好,到生产环境就发生异常等问题。生产环境出现问题,也可以方便地把生产环境的镜像拿到开发环境进行问题重现和调查。

(2)Docker镜像占用硬盘空间比传统虚拟机小,传统虚拟机镜像通常以G字节为单位,Docker镜像通常只有几M到几百M字节。尺寸的减小不仅仅降低了硬盘资源占用,在传输文件时也更加快捷。

(3)Docker容器在对硬件要求较传统虚拟机低,因为Docker容器之间共用了宿主机的操作系统资源。一台主机上可以运行几十、几百甚至更多的Docker容器。

Docker容器作为后端微服务的载体也存在一些不足之处,主要有下面几点:

(1)Docker容器之间跟宿主机共用一些系统资源,隔离性不彻底,会存在安全上的未知风险。

(2)Docker基于64位Linux内核特性,所以在其他操作系统比如windows或MAC上不能直接使用Docker。

(3)在Docker里的程序调用系统服务时会有一些不便,比如,使用系统定时任务crontab,用法和普通的主机里的crontab不一样。

4 结语

Docker官方提供了很多流行应用的镜像文件,比如本文用到OpenJDK、MySql、MQTT等镜像,我们可以在这些基础镜像之上创建自己的应用镜像。采用这些镜像为载体,把复杂的后端系统划分为多个小系统,可以充分利用Docker隔离性、系统资源要求相对低、部署方便等特性,特别适合模块多,版本更新频繁的后端系统,在实际工程应用中已经取得了良好效果。

参考文献:

[1] Sam Newman.微服务设计[M].北京:人民邮电出版社,2016:23-26.

[2] 杨保华.Docker技术入门与实践[M].北京:机械工业出版社2016:165-171.

[3] 谢睿.Docker技术在Web服务中的应用[J].电子技术与软件工程,2018(16):173.

【通联编辑:代影】