遇到的问题

最近在做一个在客户端进行mongodb数据集选择,然后重写Nginx配置文件,最后重启Nginx的小工具。遇到最大的问题是,现在生成了Nginx配置文件,但是没法重启Nginx,使生成的配置文件即刻生效。 于是想到了一个办法,在服务器上写一个重启Nginx的脚本,使用php来运行这个脚本,客户端通过http访问php来完成Nginx的重启。

Nginx重启脚本

按照上边的思路,第一步要做的就是先搞一个管理Nginx的脚本:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemin
#
# chkconfig:   - 85 15 
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /usr/local/nginx/conf/nginx.conf
# pidfile:     /usr/local/nginx/logs/nginx.pid

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)

NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"

lockfile=/var/lock/subsys/nginx

start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    configtest || return $?
    stop
    start
}

reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}

force_reload() {
    restart
}

configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}

rh_status() {
    status $prog
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac

可以把这个脚本放在指定的位置,比如说/etc/init.d/。

php运行Nginx控制脚本

现在管理Nginx的脚本有了,写几行php代码,运行这个脚本就好了。

1
2
3
4
<?php
	$result2 = exec("/usr/bin/sudo /etc/init.d/nginx reload",$result);
	echo $result2;
?>

写好把这个文件命名为reload.php丢在/usr/local/nginx/html/里边,在浏览器里边输入 http://127.0.0.1/reload.php 就好啦。 但是,好像没有什么反应对吧。原因就是,运行php-fpm工作进程的用户,并没有运行Nginx控制脚本的权限

给php-fpm提权限

更改工作进程用户

首先,要看一下php-fpm的工作进程用户是谁:

1
ps -ef | grep php-fpm

返回结果:

1
2
3
4
5
root       2665      1  0 14:08 ?        00:00:00 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)
nobody     2666   2665  0 14:08 ?        00:00:00 php-fpm: pool www
nobody     2667   2665  0 14:08 ?        00:00:00 php-fpm: pool www
root       4933   4371  0 14:49 pts/2    00:00:00 grep --color=auto php-fpm

很清楚的看到,当前php-fpm运行的master进程是由root启动的,而工作进程则是默认的nobody运行。得到这些信息就可以修改php-fpm的工作进行用户。 添加用户组和用户:

1
2
groupadd reload
adduser -g reload reload

打开/usr/local/php/etc/php-fpm.conf文件,进行配置。修改其中的user和group为reload,重启php。可以看到php-fpm的工作进程用户改变了。

1
2
3
4
5
6
7
ps -ef | grep php-fpm

root       5326      1  0 15:00 ?        00:00:00 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)
reload     5327   5326  0 15:00 ?        00:00:00 php-fpm: pool www
reload     5328   5326  0 15:00 ?        00:00:00 php-fpm: pool www
root       5473   3935  0 15:03 pts/0    00:00:00 grep --color=auto php-fpm

更改/etc/sudoers文件

在更改了php工作进程用户之后,需要做的就给这个用户赋予操作Nginx控制脚本的权限。 步骤如下: 默认情况下,/etc/sudoers文件是不可写的,使用root权限修改文件的操作权限:

1
chmod u+w /etc/sudoers

用文本编辑器打开sudoers文件,在末尾行增加一条:

1
reload   ALL=(root)      NOPASSWD: /etc/init.d/nginx

并且需要把sudoers文件中的“Defaults requiretty”一行前增加#,将其屏蔽。 修改完成,保存文件,修改sudoers文件操作权限。

1
chmod u-w /etc/sudoers

完成重启

至此,需要做的已经完成,在浏览器里边输入http://127.0.0.1/reload.php 就可以正常重启Nginx了。