faketime修改docker容器内时间,实现游戏服务器时间的动态修改

docker 修改时间   动态修改程序时间  

应用场景

游戏测试中,服务器经常需要调整时间,比如测活动,要测完整流程需要频繁修改时间 由于我们测试环境使用的是docker环境,也不希望影响宿主机时间,从而影响其他用户开发和测试

实现方案

  • 调整整机时间,这个操作成本太高,会影响到主机的所有用户

  • 直接应用层做虚拟时间,需要调用特定接口,如果有逻辑直接调用了系统接口,那么时间就会不一致

  • 将server组做成docker,直接修改docker的时间,有个副作用,修改docker时间会将宿主机时间也修改

  • 用虚拟机框定server组,可以直接修改时间,单用户单虚拟机,有些门槛,一个策划或者qa会验证n个版本,这样需要n个虚拟机,不好维护

  • faketime,给特定进程隔离的时间定制,可以是一个docker进程,也可以是一组server进程,框定的一个进程范围公用一个时间,隔离性很好

faketime的安装

  • 如果没有指定PREFIX,则缺省安装到/usr/local/ 目录下
git clone https://github.com/wolfcw/libfaketime.git  
cd libfaketime  
make  
make install  
  • 安装完生成两个文件
/usr/local/lib/faketime/libfaketime.so.1
/usr/local/bin/faketime

faketime的使用

  • 方法一 bin/faketime是对libfaketime.so.1的一个wrapper,可以方便使用
/usr/local/bin/faketime 'last friday 5 pm' /bin/date
/usr/local/bin/faketime '2024-09-10 08:15:42' /bin/date
/usr/local/bin/faketime -f '-10d' date
  • 方法二 直接使用libfaketime.so.1
$ LD_PRELOAD=/usr/local/ib/faketime/libfaketime.so.1 FAKETIME="-10d" date
$ LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME="2024-09-10 08:15:42" date
  • 我这里用到的就是方法二
LD_PRELOAD=/usr/lib/lib/faketime.so.1 FAKETIME="2024-09-10 12:00:00"  node mygame.js  

faketime几种时间格式

  • 绝对时间

格式 "YYYY-MM-DD hh:mm:ss"
绝对时间是不会变的,任何时候去取时间都是得到这个值。

$ LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME="2024-01-01 01:01:01" /bin/bash -c 'while [ $SECONDS -lt 5 ]; do date; sleep 1; done'
Wed Jan  1 01:01:01 PST 2024  
Wed Jan  1 01:01:01 PST 2024  
Wed Jan  1 01:01:01 PST 2024  
Wed Jan  1 01:01:01 PST 2024  
Wed Jan  1 01:01:01 PST 2024  
  • 开始时间

格式 "@YYYY-MM-DD hh:mm:ss",和绝对时间相比,多了一个@符号。

$ LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME="@2024-01-01 01:01:01" /bin/bash -c 'while [ $SECONDS -lt 5 ]; do date; sleep 1; done'
Wed Jan  1 01:01:01 PST 2024  
Wed Jan  1 01:01:01 PST 2024  
Wed Jan  1 01:01:01 PST 2024  
Wed Jan  1 01:01:01 PST 2024  
Wed Jan  1 01:01:01 PST 2024  
$ LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME="@2024-01-01 01:01:01" FAKETIME_DONT_RESET=1 /bin/bash -c 'while [ $SECONDS -lt 5 ]; do date; sleep 1; done'
Wed Jan  1 01:01:01 PST 2024  
Wed Jan  1 01:01:02 PST 2024  
Wed Jan  1 01:01:03 PST 2024  
Wed Jan  1 01:01:04 PST 2024  
Wed Jan  1 01:01:05 PST 2024  
  • 相对时间

格式"(+|-)(0-9)+[d|h|m|s|...]"

$ LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME="-1d" /bin/bash -c 'while [ $SECONDS -lt 5 ]; do date; sleep 1; done'
Wed Jun 23 12:11:39 PDT 2024  
Wed Jun 23 12:11:40 PDT 2024  
Wed Jun 23 12:11:41 PDT 2024  
Wed Jun 23 12:11:42 PDT 2024  
Wed Jun 23 12:11:43 PDT 2024  
$ LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME="-1d" FAKETIME_DONT_RESET=1 /bin/bash -c 'while [ $SECONDS -lt 5 ]; do date; sleep 1; done'
Wed Jun 23 12:11:23 PDT 2024  
Wed Jun 23 12:11:24 PDT 2024  
Wed Jun 23 12:11:25 PDT 2024  
Wed Jun 23 12:11:26 PDT 2024  
Wed Jun 23 12:11:27 PDT 2024  
  • 详细文档
https://github.com/wolfcw/libfaketime/