一种监听机制实现容器服务间正常顺序启动的方法
文献发布时间:2023-06-19 19:30:30
技术领域
本发明涉及计算机软件领域,具体涉及容器化部署。
背景技术
在互联网飞速发展的当下,后端服务架构从传统的单体服务往微服务进阶,若测试、部署依然用传统方式,无疑会带来巨大的工作量和问题。
开发人员与部署人员之间的矛盾,不能保证开发人员提供的代码即应用,可能存在环境问题和繁琐配置问题,导致开发环境部署一切正常,而在生产环境却出现各种意想不到的问题。
运维人员人肉部署的体力问题,在当今高并发的互联网环境中,服务应用需要支持秒级容灾、扩容缩容的能力,传统形式运维人员只能加班通过人肉方式去挨个扩容部署,枯燥且容易出错。
容器化部署技术应运而生,如Docker,它实现了Linux容器化技术,提供了解决方案——可以轻量级进行系统平滑移植,安装软件的时候,把软件需要的原始环境一模一样复制过来,保证软件哪里安装都能跑,不受宿主环境的影响。但是对于多个相互依赖的容器化服务进行容器化部署时,目前市面上还不存在完整解决方案,如docker-compose会存在如下不足,虽然能确定先后关联的服务,并保证容器间的网络通畅,但是无法保证服务正常启动后,其依赖的服务才能启动。
目前docker环境下还未有现成的方式可以获取到其他容器服务的运行状态。假设使用面向过程的思想,如将容器服务A启动后将状态记录到容器A或者宿主机某个文件内,依赖A容器服务的其他容器服务B根据这个文件的内容判断容器服务A是否启动完成。
方式一:如容器服务A将启动结果存在在A容器内,容器服务B需要获取到容器A的文件,因为容器文件是隔离的,这个没法实现;
方式二:如将容器服务A将启动结果挂载在宿主机,容器服务B也使用文件挂载的方式获取到容器服务A的启动结果,启动容器服务B定时获取容器服务A的运行结果文件,根据结果判断容器服务A是否启动完成。
方式一实现不了,方式二理论是可以的,但是会带来额外的依赖,如需要容器服务A将文件存储在宿主机,然后容器服务B通过文件挂载获取容器A的运行结果文件,甚至还需要在原始容器A和容器B中增加脚本。
使用面向过程的方式对存在依赖的容器存在侵入性,耦合性高。而使用心条监听机制的方式是单方面去监听目标容器,无需更改容器本身的信息,无侵入性,耦合性低。
发明内容
本发明为克服上述的不足之处,本发明提供一种监听机制实现容器服务间正常顺序启动的方法,在时间间隔内,尝试对依赖服务发起心跳,直到依赖服务能回应心跳时,当前服务才开始启动,从而保证服务间是正常先后启动。
心跳检查监听机制,场景多用于判断目标对象是否正常运行,定时发送简易的通信包,在特定时间内未接受到对方响应,则判断对方状态异常,然后做相应处理。使用docker-compose容器编排时,多个存在相互依赖关系的容器服务进行编排时存在不足,如容器B依赖容器A,无法保证容器B在容器A启动完成后再启动。使用心跳检测技术可实现容器B在容器A启动后有序启动。
一种监听机制实现容器服务间正常顺序启动的方法,包括:
步骤一,设置若干容器服务,每一个容器服务都是基于其镜像创建;
步骤二,将心跳检测脚本拷贝到镜像出的容器服务内;
步骤三,使用docker-compose进行编排容器间启动顺序;
步骤四,使用指令启动所有容器服务;
步骤五,每一个容器服务根据其由步骤二和步骤三设置的心跳检测脚本判断是否启动,直到所有容器服务均启动完毕。
作为优选,所述的心跳检测脚本基于socket连接建立心跳监听;基于bash的/dev/tcp/ip/port实现网络请求。
作为优选,所述的心跳检测脚本设置最大监听时间1000s,设置监听间隔1s,监听时间内监听到上一级信号则启动本级容器服务,超过最大监听时间则发送启动失败信号。
本发明的实质性特点在与:本方案基于心跳机制,无侵入性,耦合性低,可以单方面去监听被依赖的服务。前提是依赖的服务前提准备好脚本,启动时依赖服务时监听被依赖服务的运行状态。相互依赖的容器化服务启动时,能确保被依赖服务正常启动后,后者才开始启动,避免后者启动失败,提升了容器化部署的成功率。多容器服务编排时,多个服务同时启动会使得宿主服务器的CPU在启动过程中达到过高的占用率,影响宿主机器稳定性。而使用心跳监听机制,可以编排容器服务的启动顺序,使容器服务先后有序启动完成,且能够降低启动过程中宿主机CPU占用过高的问题。
具体实施方式
下面结合具体实施实例对本发明进行进一步描述,但本发明的保护范围并不仅限于此。
以简单的docker-compose示例。容器服务serverA,基于镜像image-a创建,容器服务serverB,基于镜像image-b创建,容器服务serverC,基于镜像image-c创建。
针对容器启动过程做描述主要流程如下。使用docker-compose启动容器时,会基于所有容器创建对应的容器服务并执行所有服务文件中command的指令,容器服务serverA首先会被启动,其次serverB对应的command使用了心跳监听脚本,将会等待serverA启动完成后执行,监听1000s,每1s监听1次,如果1000s内启动serverA正常继续启动服务serverB,此后继续根据容器服务serverB启动结果再启动容器服务serverC;如果1000s后容器服务serverA未启动或者启动失败了,容器serverB将超时退出,容器serverC也将超时退出。
实施例1
两个容器化服务,irms-server和mysql,前者服务依赖后者服务的正常启动。
准备好心跳监听shell脚本:wait-for-it.sh
编写irms-server的dockerfile,将wait-for-it.sh打进镜像中并生成镜像
#基于基础镜像
#FROM adoptopenjdk/openjdk8
FROM classmethod/openjdk-alpine-git:latest
MAINTAINER wys
#替换源地址,国外地址比较慢
RUN sed-i's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/'
/etc/apk/repositories
RUN apk add--no-cache bash
RUN apk add curl
RUN apk add gnupg
RUN mkdir-p/app/config
ADD application-prod.yml/app/application-prod.yml
COPY logback.xml/app/logback.xml
ADD biap4Server.jar/app/biap4Server.jar
#将wait-for-it.sh打进镜像中
ADD wait-for-it.sh/app/wait-for-it.sh
COPY docker-entrypoint.sh/app/docker-entrypoint.sh
RUN chmod+x/app/wait-for-it.sh
RUN chmod+x/app/docker-entrypoint.sh
ENTRYPOINT["/app/docker-entrypoint.sh"]
同理编写mysql的dockerfile,并生成镜像
#基于基础镜像
FROM mysql:oracle
MAINTAINER wys
ENV TEMPLATE_PATH/tempdata
ENV FILE_1 3.dyd_irms_data.sqlCOPY./1.dyd_irms_init.sql/docker-entrypoint-initdb.d/
COPY./2.dyd_prod_map_data.sql/docker-entrypoint-initdb.d/2.dyd_prod_map_data.sql
ADD$FILE_1$TEMPLATE_PATH/
RUN chown mysql:mysql$TEMPLATE_PATH
ADD run_dynmaic_sql.sh/docker-entrypoint-initdb.d/run_dynmaic_sql.sh
RUN chmod+x/docker-entrypoint-initdb.d/run_dynmaic_sql.sh
使用docker-compose编写docker-compose-test.yml进行容器化服务编排,irms-server服务依赖于mysql服务,需要写明irms-server服务通过发明的心跳监听机制去监听mysql服务,再去启动。
/>
最后都过docker-compose批量容器化启动即可
docker-compose-f docker-compose-test.yml up-d
以上的所述乃是本发明的具体实施例及所运用的技术原理,若依本发明的构想所作的改变,其所产生的功能作用仍未超出说明书所涵盖的精神时,仍应属本发明的保护范围。