博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用docker容器运行golang应用以及热更新
阅读量:3986 次
发布时间:2019-05-24

本文共 2236 字,大约阅读时间需要 7 分钟。

golang程序我们一般是先编译好可执行文件,然后发布出去运行,所以在创建docker镜像的时候,我们也使用这种方式,所以golang程序使用容器来运行实在使太方便了。

common项目是使用gin写的API接口服务,配合endless实现了 graceful restart。

目录结构如下:

在这里插入图片描述
编译

go build common.go

启动命令,前台运行

./common serve

启动命令,后台运行

./common serve -d 或者/bin/man start

平滑重启命令

/bin/man restart

默认情况下,我们的编译 go build xxx 是通过动态链接的方式去调用其他依赖的,生成的可执行文件如果放到别的地方运行的话实际上还是需要系统来提供这些依赖。否则无法运行,所以使用静态链接的方式来编译,这样编译的文件会稍微大一些,但是几乎不会依赖外部环境了。

静态编译方式:

CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo common.go

其实主要的是使用 CGO_ENABLED=0 ,关闭cgo

其次选择一个最小的基础镜像:alpine;或者不以任何镜像为基础:scratch

如果基础镜像不存在,会从远程下载 docker.io/library/alpine 。

Dockerfile文件内容

FROM alpineADD common /data/www/ADD conf/app.ini /data/www/conf/ADD bin/man /data/www/bin/EXPOSE 8001/tcpWORKDIR /data/wwwCMD cd /data/www/ && ./common serve

容器中服务的启动不要使用daemon方式,因此不加 -d 参数。

创建镜像

docker build -t common .docker images

启动容器

docker run --name common --network host -d common或者docker run --name common -p 8001:8001 -d common docker ps netstat -lntp

测试

curl http://localhost:8001/common/Stats

如果想进入容器,使用如下命令

docker exec -it common sh

关于前台运行 or 后台运行的问题

容器中要求 pid=1 的程序必须是前台运行的,否则容器立即退出。
具体参考 https://blog.csdn.net/raoxiaoya/article/details/109194514
然而 endless 的 graceful restart 会启动新的进程来提供服务,在试验过程中的确发现容器立即就退出了,针对这个情况可以写一个几乎不消耗性能的程序来作为pid=1,或者使用 top 命令。

于是 Dockerfile 中的 CMD 要改成:

CMD cd /data/www/ && ./common serve -d && top

关于服务的热更新

在更新了代码并重新编译之后,现在需要发布到线上,可以这样操作:

1、将编译好的可执行文件传到服务器。
2、使用 docker cp common common:/data/www命令将可执行文件传入容器。
3、执行服务重启命令 docker exec -it common sh bin/man restart
4、可以将以上步骤集成到jenkins等自动化部署工具上。

注意

最后注意一点,在查到进程Id的时候,id所在的位置不一样。

在宿主机上

ps -ef |grep 'common serve' |grep -v greproot     15286     1  0 Sep28 ?        00:34:57 ./voteapi serveps -ef |grep 'common serve' |grep -v grep | awk '{print $2}'15286

但是在容器内部

ps -ef |grep 'common serve' |grep -v grep1 root      0:00 ./common serveps -ef |grep 'common serve' |grep -v grep | awk '{print $1}'1

所以 bin/man 这个shell程序需要修改一下。

容器内部的 kill 命令

kill -l 1) HUP 2) INT 3) QUIT 4) ILL 5) TRAP 6) ABRT 7) BUS 8) FPE 9) KILL10) USR111) SEGV12) USR213) PIPE14) ALRM15) TERM16) STKFLT17) CHLD18) CONT19) STOP20) TSTP21) TTIN22) TTOU23) URG24) XCPU25) XFSZ26) VTALRM27) PROF28) WINCH29) POLL30) PWR31) SYS35) RTMIN64) RTMAX

但是

kill -HUP 41

或者

kill -SIGHUP 41

都可以

你可能感兴趣的文章
Linux usb设备驱动(2)---> usbmouse.c 源码分析
查看>>
USB芯片
查看>>
ajax工作原理
查看>>
理解Sharding jdbc原理,看这一篇就够了
查看>>
XiaoMi面试题记录
查看>>
解决跨网场景下,CAS重定向无法登录的问题(无需修改现有代码)
查看>>
java反编译命令
查看>>
activemq依赖包获取
查看>>
版本号中Snapshot的含义
查看>>
JAVA 成员访问权限修饰符
查看>>
Centos下Mysql密码忘记解决办法
查看>>
概念区别
查看>>
关于静态块、静态属性、构造块、构造方法的执行顺序
查看>>
final 的作用
查看>>
在Idea中使用Eclipse编译器
查看>>
idea讲web项目部署到tomcat,热部署
查看>>
centos 防火墙关闭/开启
查看>>
HASHMAP 深入解析
查看>>
HASHMAP原理解析,不错的文章
查看>>
优化IDEA启动速度,快了好多。后面有什么优化点,会继续往里面添加
查看>>