用户工具

站点工具


jaysnote:htpdate

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

jaysnote:htpdate [2018/11/09 15:43] (当前版本)
jaylee 创建
行 1: 行 1:
 +<​markdown>​
  
 +# htpdate
 +
 +标签 :GAC-350 ​ htpdate
 +
 +GAC-350 放弃ntpdate采用htpdate,通过`/​etc/​default/​htpdate`配置为deamon模式,并且尝试从多个门户网站同步时间。但是测试反馈从开机无网络到网络恢复的时候同步时间未及时恢复,​需要等待一段时间。
 +
 +```bash
 +HTP_SERVERS="​baidu.com youku.com taobao.com"​
 +HTP_OPTIONS="​-D -d -s -t"
 +```
 +
 +初步怀疑第一次未正常获取到时间后,默认轮询周期过大,导致未及时同步,在`man htpdate`找到轮询周期的描述,从这里看这里默认的轮询周期在30分钟至32小时。
 +
 +```bash
 +-m -M  These options specify the minimum (-m) and maximum (-M) polling intervals for HTP requests, in seconds. The default range is between 30 minutes and 32 hours. Htpdate calcu‐
 +              lates the optimal polling frequency between minimum and maximum values. Only applicable when running in daemon mode.
 +```
 +
 +
 +
 +## code review
 +
 +https://​salsa.debian.org/​debian/​htpdate
 +
 +```bash
 +sudo apt-get source htpdate ​           #​htpdate-1.1.0
 +```
 +
 +仔细走读了代码,发现这里的最小时间和最大时间有很多规则,理顺完整原理后再详细介绍这里的规则。
 +
 +* htpdate 区分deamon 模式,在deamon模式会周期同步时间,否则只同步一次;
 +* 从服务器http文件头多次获取时间,如果存在多个服务器,多次获取;
 +* 计算多个服务器获取时间平均值,并且计算本地误差然后更改时间;
 +
 +而对于轮询时间和异常处理,如下规则:
 +
 +* 多个服务器,某一个服务器获取时间失败,休眠,时间设置最小时间除以/​服务器数量;​
 +
 +  ```c
 +  //htpdate.c Line.726
 +  /* Sleep for a while, unless we detected a time offset */
 +  if ( daemonize && !offsetdetect )
 +  sleep( sleeptime / numservers );
 +  ```
 +
 +* 成功获取时间(任一服务器),如果存在误差,立即同步,休眠30分钟(固定时间)最小延时值设置为最小时间;
 +
 +  ```c
 +  //htpdate.c Line.796
 +  /* Decrease polling interval to minimum */
 +  sleeptime = minsleep;
 +  ​
 +  /* Sleep for 30 minutes after a time adjust or set */
 +  sleep( DEFAULT_MIN_SLEEP );
 +  ```
 +
 +* 多个服务器获取时间均失败,最小时间睡眠;
 +
 +  ```c
 +  //htpdate.c Line.750
 +  if ( goodtimes ) {
 +  } else {
 +      printlog( 1, "No server suitable for synchronization found" );
 +      /* Sleep for minsleep to avoid flooding */
 +      if ( daemonize )
 +          sleep( minsleep );
 +  ```
 +
 +* 获取成功,但是不存在时间误差;睡眠时间*2,直到最大时间;
 +
 +  ```c
 +  //htpdate.c Line.750
 +  /* Increase polling interval */
 +  if ( sleeptime < maxsleep )
 +      sleeptime <<= 1;
 +  ```
 +
 +综上,如果未通过-m 或者 -M 默认最小轮询时间为30(DEFAULT_MIN_SLEEP)分钟,开机无网络,如果在半个小时内恢复网络,最多等待10分钟(最小时间30/​服务器数量3),如果在30分钟后恢复网络,最多等待30分钟(默认最小时间);
 +
 +如果同步时间,30分钟后再次又存在误差,如果误差在于秒级别,调整时间,如果误差大于秒级别调整时间会失败,参考[通过date -s 修改时间未及时同步](#​Troubleshooting/​通过date -s 修改时间未及时同步)。
 +
 +同步时间后不存在误差,时间按照-m传递时间默认(30分钟)递增,直到-M传递的最大值,默认32小时;
 +
 +## modify
 +
 +如果只是修改开机网络恢复未及时同步的情景,直接尝试修改`/​etc/​default/​htpdate`,增加-m 和-M 设置最小和最下时间即可。
 +
 +```
 +HTP_OPTIONS="​-D -d -s -t -m 60 -M 65"
 +```
 +
 +查看日志
 +
 +```bash
 +sudo  cat /​var/​log/​syslog |grep htpdate
 +```
 +
 +> **提示**:需要通过`-d`启用debug模式;
 +
 +
 +
 +## Troubleshooting
 +
 +### 通过date -s 修改时间未及时同步
 +
 +> **注意**:如果上一次成功同步时间,则默认需要等待30分钟(DEFAULT_MIN_SLEEP)
 +
 +```bash
 +$sudo  cat /​var/​log/​syslog |grep htpdate
 +Nov  5 20:18:33 mxj-zbcs-310 htpdate: Adjusting 252461173.667 seconds
 +```
 +
 +如果成功设置(`-s`)一次时间后,修改时间模式设置为调整模式(`-a`),该模式下主要是调整小误差延时,出现在过大时间会直接设置失败。
 +
 +```c
 +//htpdate.c Line.311
 +case 1:                     /* Adjust time smoothly */
 +    timeofday.tv_sec ​ = (long)timedelta;​
 +    timeofday.tv_usec = (long)((timedelta - timeofday.tv_sec) * 1000000);
 +
 +    printlog( 0, "​Adjusting %.3f seconds",​ timedelta );
 +
 +    /* Become root */
 +    if ( seteuid(0) ) {
 +        printlog( 1, "​seteuid()"​ );
 +        exit(1);
 +    } else {
 +        return( adjtime(&​timeofday,​ NULL) );       
 +    }
 +```
 +
 +> **PS**: 最新版本1.2.0-2现象一致,说明htpdate deamon 模式为考虑此问题,如果要解决此问题可能只有在非deamon模式,每次通过`-s`模式设置时间;
 +
 +```bash
 +sudo htpdate -s -t  baidu.com youku.com taobao.com
 +```
 +
 +
 +
 +</​markdown>​
jaysnote/htpdate.txt · 最后更改: 2018/11/09 15:43 由 jaylee