自动reload nginx解决nginx对动态域名不重新解析的问题

屌丝买不起服务器,用家里闲置的两台破笔记本电脑装了个linux为我的小站爱分享读书(www.ishareread.com) 通过nginx+tomcat做了个集群。两台笔记本分别装了tomcat,通过nginx反向代理提供访问。nginx是放在阿里云上的,通过域名映射到nginx上。nginx代理家里的两台笔记本。由于家里的网络通过电信光纤上网,没有固定IP是通过DDNS动态域名解析访问的。问题来了,这个IP经常变。IP一但变了后nginx不再对动态域名进行解析了,访问的还是老IP地址。导致网站访问不了。必须得重启nginx或重新reload nginx。有没有办法让IP变了nginx重新解析动态域名呢?上网找了很久,没有什么好办法。包括改用了淘宝的tengine, 通过ngx_http_upstream_dynamic_module该模块提供了在运行时动态解析upstream中server域名的功能,然而并没有什么卵用。所以想了一个笨办法,就是写一个shell 脚本。定时判断DDNS的域名绑定的IP地址,如果IP地址和上次比较有变化就通过nginx  -s reload将nginx重载配置。实践证明效果还不错。


由于动态域名解析的IP地址经常变化。nginx缓存的还是老的IP地址信息,导致IP地址变化以后nginx无法正常访问到反向代理的机器。


首先是通过域名获取IP地址的代码,代码如下:

getip.sh

#!/bin/sh
if [ $# -lt 1 ]; then
    echo $0 need a parameter
    exit 0
fi

ADDR=$1
TMPSTR=`ping ${ADDR} -s 1 -c 1 | grep ${ADDR} | head -n 1`
echo ${TMPSTR} | cut -d'(' -f 2 | cut -d')' -f1

然后是将IP写到文件,定时获取动态域名的IP,并将IP与文件中的IP比较如果不一致则reload nginx。代码如下:

reloadnginx.sh

#!/bin/bash
echo '...begin...'
if [ $# -lt 1 ]; then
    echo $0 need a host parameter
    exit 0
fi
if [ ! -n "$2" ] ;then
   sleeptime=10
else
   sleeptime=$2
fi

echo '...refreshtime='${sleeptime}'s'
host=$1
ipfile="ip.ini"

while [ true ]; do

  runlogfile="run."`date "+%Y-%m-%d"`".log"
  reloadlogfile="reload."`date "+%Y-%m-%d"`".log"
  echo `date`'...read ip.ini...'>>"$runlogfile" >&1
  if [ ! -f "$ipfile" ]; then
    #touch "$ipfile"
    sh getip.sh "$host" > "$ipfile"
  fi

  oldIpAddress=`cat ip.ini |head -n 1`
  curIpAddress=`sh getip.sh "$host"`
  echo `date`'...oldIpAddress='${oldIpAddress} >>"$runlogfile"
  echo `date`'...curIpAddress='${curIpAddress} >>"$runlogfile"

  if [ "$oldIpAddress" != "$curIpAddress" ];then
     echo '..oldIpAddress:'${oldIpAddress}'!=curIpAddress:'${curIpAddress}'.......' >>"$runlogfile"
     /usr/local/tengine/sbin/nginx -s reload
     echo '...nginx -s reload....' >>"$runlogfile"
     sh getip.sh "$host" > "$ipfile"
     echo `date`'...ipchanged..oldIpAddress:'${oldIpAddress}'!=curIpAddress:'${curIpAddress}'...nginx -s reload!' >>"$reloadlogfile"
  fi
 
  /bin/sleep "$sleeptime"
done

echo '...end .....'

然后写一个run.sh运行脚本,可以让脚本在后台运行,并输出日志。

写一个终止stop.sh脚本,可以让脚本停止运行。

开始测试。


当动态域名的IP发生变化时nginx 自动重载。


这样,不管是你的动态域名IP发生了变化,还是由于路由器重启导致IP发生了变化,nginx都可以自动重载。nginx访问动态域名都是解析的正确的IP地址。

脚本文件列表如下:


运行的时候带上需要刷新的动态域名及刷新的时间作为参数

如 ./run.sh xiejava.jios.org 30  脚本就会每30秒去检测一下xiejava.jios.org这个动态域名的IP地址是否有变化,如果有变化则自动reload nginx.


注意:请确认ping 命令能够正常ping 通域名。

如不能ping通域名,需要检查是否DNS设置不正确。

# cat /etc/resolv.conf

检查DNS的配置是否正确。


具体的代码和脚本下载

posted @ 2017-01-07 17:32  xiejava  阅读(496)  评论(0编辑  收藏  举报