docker宿主机容器时间分离,linux软件时钟与系统时钟分离

php docker宿主机容器时间分离,linux软件时钟与系统时钟分离

需求

前一段时间用laravel写了个站点,但是客户有一个需求着实难住了我,那就是结算测试。因为在系统里面写的是按每天0点1分以计划任务方式结算前一天的佣金。然后测试的时候需要在一天内模拟很多天的时间点提交订单和自动结算佣金。

场景分析

我最开始想到的是修改源代码以达到效果,但是源代码都已经写好了如果改掉做测试那测完还得还原老版本到生产环境,而这两个就造成了生产环境和测试环境完全是两套代码,那测试还有什么意义?于是我就想起了刚学不久的docker,试想我能不能使用docker安装一个测试环境在docker里面然后使用计划任务隔一段时间[比如一个小时累加一天]自动修改docker沙箱的系统时间?恩,果然还是巨人的肩膀上能看更远!

踩坑

一号坑:于是说干就干,搭建了docker,部署了测试环境,然鹅就在成功的大门离我越来越近的时候,成功我被自己的小聪明坑哭。那就是docker的时间居然是和宿主机共享的。于是各种度娘各种谷歌,一弄就是一整天,终于黄天不负有心人让我找到一个方法。使用github上一位大佬基于C写的假时间插件(具体方法请看下面解决方案)。
二号坑:当我一阵心花路放准备庆幸大功告成的时候,突然发现我写的shell无法全局生效[具体表现就是我的sh文件在计划任务中执行完输出的是假时间,开的命令行时间依然还是宿主机的时间,php获取得到的系统时间也是宿主机的真实时间],心中顿时十万只羊驼奔腾而过。这个问题最终还是通过我的深思熟虑得到答案。
三号坑:解决好时间无法全局生效问题后我以为就可以直接使用了,然鹅,被现实啪啪打脸,我终于承认终究还是我想得太美好了,一切都准备好做最后测试的时候问题又出现了,那就是在php里面时间只能持续跳动10秒,后面又自动获取宿主机时间。这个问题一直困扰了我好几天,一直都一筹莫展。其实针对这个问题网上有很多很多的文章都是转载或则直接复制粘贴某一位大神的一篇文章,最后的10秒无法继续问题最终都没得到解决,最后还是自己想各种办法解决。

解决方案

一号坑解决方案:
在docker容器中使用虚假时间
https://github.com/wolfcw/libfaketime

	git clone https://github.com/wolfcw/libfaketime
	cd libfaketime
	make

按需求我编写了下面的shell文件放到 libfaketime目录【用于计划任务执行】
run.sh


set_date='2020-01-10 10:11:01' #得到一个 add_day天后的时间
#这里的${PWD}最好设置成绝对路径【亲测第一次直接用pwd可以后面居然pwd直接进入到了我的home目录 很尴尬】
export LD_PRELOAD=${PWD}/libfaketime.so.1 
export FAKETIME="@${set_date}" #修改虚拟时间

然鹅当我执行上面这个文件的时候就出现了【二号坑】里面说的问题,使用 . ./ssh.sh或则 source ./ss.sh结果都是php里面获取到的系统时间为宿主机系统时间。

二号坑解决方案:
分析:想了很多解决方案,别人都说shell里面的变量有局限性,建议放到文件中然后再source【这种方法我也试过不知道为什么我这里就是不行】,这不符合我的需求啊因为我的时间是需要每隔一段时间实时变化的,并不能只依赖开机启动。最后灵机一动,既然shell中的变量有局限性,那我能否把需要用到假时间的软件进程放到当前shell中运行?最后在ssh中加上重启php服务,问题迎刃而解。
解决:

#以下命令按自己的php具体情况修改【我这里用的是php开机自启服务文件直接操作】
/etc/init.d/php-fpm-71 restart

解决上面两个坑运行起来,然后php里面能看到假时间,但是持续10秒后又变成了宿主机的真实时间。以下则是这个问题的解决方案。

三号坑解决方案:
这个问题一直困扰了我好几天,一直无解于是又是各种搜索各种试验各种请教大神,甚至还在github的假时间项目里面提交了我的问题,问完我的问题后我抱着看看issues中有没有别人遇到这个问题的时候,有一个人的回答令我眼前一亮虽然和我的需求并不符合但是他解决了我的问题。在这里我把那位大神的解决方法截图贴出来,分享给大家。

github上神的回复

对的你没有看错,把假时间持续时间加大即可。说干就干改一下我的脚本,果然问题迎刃而解。

export FAKETIME_CACHE_DURATION=860000 #假时间持续时间

下面是完整的shell脚本也是我最好几天的劳动成果,在此开源贡献给大家。

set_date='2020-01-10 10:11:01' #得到一个 add_day天后的时间
export FAKETIME_CACHE_DURATION=860000 #假时间持续时间
#这里的${PWD}最好设置成绝对路径【亲测第一次直接用pwd可以后面居然pwd直接进入到了我的home目录 很尴尬】
export LD_PRELOAD=${PWD}/libfaketime.so.1 
export FAKETIME="@${set_date}" #修改虚拟时间
/etc/init.d/php-fpm-71 restart

运行效果
至此完成。

回顾

假时间功能已经解决好2天时间了,今天回首一想,脑海里突然浮现一个观念,那就是这个虚假时间可不可以放宿主机直接做测试,实现方法是安装多个php然后某一个php使用虚假时间做测试,其他的php依然正常运行?答案是坑定的。由于暂时没有这方面需求而且测试次数不够稳定性也不是很好【之前为了实现时间分离玩坏了好几个容器。真机试验风险固然更大,而且没有docker备份方便。】,这里就不做试验了。这里把我的解决方案写出来,如果老铁们有需要就自己折腾折腾把。

总结

挖坑天天有,新手特别多。在学习的长河中问题固然是会层出不穷,但是我们解决问题的那一颗恒心更重要。最好的学习效果,莫过于多年以后遇到一个很难解决的问题。你会想起曾几何时在记忆深处留下过类似的痕迹。然后问题迎刃而解。

最后

如果觉得我的文章对你有帮助,请点个小赞支持支持。也可以留言加我好友我们一起探讨学习。程序人生,如果不是在倒腾那就是在搭建倒腾需要的环境。走在倒腾的道路上你并不孤单。

针对此功能本人有出一个宝塔插件,详情请参阅如下地址
https://blog.youkuaiyun.com/qq_38883889/article/details/106731520

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱折腾的小码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值