Nginx的原理、常用配置和生产案例应用

目录

Nginx的概念

Nginx的系统架构 

Nginx的服务过程

Nginx.conf配置讲解

自定义日志格式 

Location语法

Nginx的具体应用

一、Nginx+Lua实现动态黑名单

二、基于Nginx 的静态缓存

三、基于Nginx 图片防盗链

四、子域名展示

五、多个config配置

六、动静态分离解决跨域

附录1:Nginx 日志格式变量说明

附录2:Nginx的安装

附录3:添加nginx服务


Nginx的概念

正向代理代理的是客户端
反向代理代理的是服务端

Nginx是一个高性能的HTTP和反向代理服务器,单台Nginx服务器最多能够支持高达50000的并发请求,所以一般情况下,会将Nginx作为静态资源的访问服务器或者作为访问流量分流的服务器
主要特点:占用内存少,并发能力强,扩展容易

 

Nginx的系统架构 

nginx配置use epoll后,以异步非阻塞方式工作,能够轻松处理百万级的并发连接

nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程

Nginx的原理、常用配置和生产案例应用_第1张图片

Nginx的服务过程

从功能上来分有三种:
handlers 处理器模块
filter
proxies 

Nginx的原理、常用配置和生产案例应用_第2张图片

Nginx.conf配置讲解

# 指定nginx 用户及用户组  user xx xx
#user  nobody;
# 指定nginx 工作进程 根据硬件调整 通常等于cpu 核数
worker_processes  1;
# 全局错误信息(warn)
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
# PID(进程标识符) 存储目录
#pid        logs/nginx.pid;



gzip on;
gzip_disable "msie6";#为指定的客户端禁用gzip功能
gzip_proxied any;#压缩所有的请求
gzip_min_length 1000;#数据启用压缩的最少字节数
gzip_comp_level 4;#设置数据的压缩等级

#设置需要压缩的数据格式
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss tex

#负载均衡
upstream demo {
        server 127.0.0.1:8080    weight=1;#权重,值越高,分配到的几率越高
        server 127.0.0.2:8081    down;#down表示这台机器不参与
        server 127.0.0.2:8081    backup;

 }
upstream moblie {
        server 192.168.80.123:8080;
        server 192.168.80.124:8080;
}
    
upstream img {
        server 192.168.80.123:8080;
        server 192.168.80.124:8080;
}




events {
    #连接上限 
    worker_connections  1024;
}

设定http服务器
http {
    # 文件扩展名与文件类型映射
    include       mime.types;
    # 默认文件类型
    default_type  application/octet-stream;
    # 设定日志格式
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    # 设置access log
    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    # 设定虚拟主机
    server {
        listen       80; # 监听端口号
        server_name  localhost; 域名 可以有多个 用空格隔开

        #charset koi8-r;
        # 设定虚拟主机访问的日志
        #access_log  logs/host.access.log  main;

        #手机站点与PC站点分离
        set $mobile_rewrite 1;

        if ($http_user_agent ~* "(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino") {
            set $mobile_rewrite 0;
        }
        
        if ($http_user_agent ~* "^(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-)") {
            set $mobile_rewrite 0;
        }

        location / {
            #proxy_pass http://demo;
            if ($mobile_rewrite = 0) {
                proxy_pass http://moblie;
            }
            proxy_pass http://demo;
            index  index.html index.htm;
        }

        #动静分离  **.do **.aciton  js css jpg gif html
         location ~ .*\.(jpg|gif)$ {
            root http://img;
        }
   }
    server {
        listen    80;
        server_name    www.demo.com;
        access_log    logs/dome.access.log;

        location / {
            proxy_pass http://demo;
            index index.html;
            root html;
        }
    }
    

}

 

自定义日志格式 

使用系统默认处理起来非常的复杂,而且生成的日志格式字段可能我并不全需要或者不满足我现在要求。怎么解决?自定义日志格式

# 1、去掉下面2部分注释
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

 access_log  logs/access.log  main;


# 2、添加自定义日志格式
log_format bf_log '$remote_addr^A$http_host^A$msec^A$request_uri';(分号必不可少)

# 3、 开启日志目录
    location =/bf.gif{
        default_type image;(分号必不可少)
        access_log logs/bf.log bf_log;(分号必不可少)
    }

# 4、生成的日志格式
172.16.100.35^Abigdata-spark04.ibeifeng.com^A1479985996.537^A/bf.gif

Location语法

配置语法
location [= | ~* | ^~ ] /uri/ {...}


配置规则
location = /uri 精准匹配
location ^~ /uri 前缀匹配
location ~ /uri
location / 通用匹配


规则的优先级

1 location = /
2 location = /index
3 location ^~ /article/
4 location ^~ /article/files/
5 location ~ \.(gif|png|js|css)$
6 location /
 

http://192.168.11.154/
http://192.168.11.154/index ->2
http://192.168.11.154/article/files/1.txt ->4
http://192.168.11.154/mic.png ->5


1. 精准匹配是优先级最高
2. 普通匹配(最长的匹配)
3. 正则匹配


实际使用建议
location =/ {

location / {

location ~* \.(gif|....)${
}

Nginx的具体应用

一、Nginx+Lua实现动态黑名单

1.安装Redis

wget http://download.redis.io/redis-stable.tar.gz

进入redis根目录执行 make PREFIX=/usr/local/redis  install

mv redis.conf /usr/local/redis/etc

vi /usr/local/redis/etc/redis.conf //将daemonize no 改成daemonize yes

设置开机启动:/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf

2.安装LuaJIT(可不安装)

LuaJIT 和 Lua 的一个区别是,LuaJIT 的运行速度比标准 Lua 快数十倍,可以说是一个 Lua 的高效率版本。

cd /usr/local/src 
wget http://luajit.org/download/LuaJIT-2.1.0-beta2.tar.gz 
tar zxf LuaJIT-2.1.0-beta2.tar.gz 
cd LuaJIT-2.1.0-beta2 
make PREFIX=/usr/local/luajit 
make install PREFIX=/usr/local/luajit

配置lua的环境变量

export LUAJIT_LIB=/usr/local/luajit/lib
export LUAJIT_INC=/usr/local/luajit/include/luajit-2.1

3.下载lua-nginx-module 模块

yum -y update nss #nss版本过于陈旧,升级即可

cd /usr/local   

git clone https://github.com/chaoslawful/lua-nginx-module.git  

4.下载ngx_devel_kit(NDK) 

cd /usr/local

wget https://github.com/simpl/ngx_devel_kit/archive/v0.2.19.tar.gz

tar -xzvf v0.2.19

5.安装lua-redis-parser,lua-resty-redis是openresty(1.9.15.1)的一个组件,简单来说,它提供一个lua语言版的redis API,使用socket(lua sock)和redis通信 

git clone https://github.com/openresty/lua-resty-redis.git

mv lua-resty-redis /usr/local/nginx/lua/lua-resty-redis


6.进入之前安装nginx的解压目录,重新编译安装(引入LuaJIT并加入ngx_devel_kit-0.2.19和lua-nginx-module的目录) 

sudo ./configure --with-ld-opt="-Wl,-rpath,/usr/local/luajit/lib" --add-module=/usr/local/ngx_devel_kit-0.2.19 --add-module=/usr/local/lua-nginx-module-0.10.2 

编译安装

sudo make -j2

make  install

7.nginx.conf的配置

http {

    lua_package_path "/usr/local/nginx/lua/lua-resty-redis/lib/?.lua;;";

    #由 Nginx 进程分配一块 1M 大小的共享内存空间,用来缓存 IP 黑名单
    lua_shared_dict ip_blacklist 1m;
    
    server {
        listen       8081;
        server_name  hadoop.senior02;

        location ~ .*(BfImg)\.(gif)$ {
          default_type image/gif;
          access_log /home/hadoop/access.log log_format;
          root /usr/local/nginx/conf/www/source; 
            }
        
         location = /ipblacklist {
                 access_by_lua_file conf/lua/ip_blacklist.lua;
                 default_type text/html;
                    content_by_lua 'ngx.say("

hello, lua

")';
             }
    }

}

ip_blacklist.lua文件

local redis = require("resty.redis")
local ngx_log = ngx.log
local ngx_ERR = ngx.ERR
local ngx_INFO = ngx.INFO
local ngx_exit = ngx.exit
local ngx_var = ngx.var

-- 黑名单缓存60秒
local cache_idle = 60
local forbidden_list = ngx.shared.forbidden_list


local function close_redis(red)
    if not red then
        return
    end
    -- 释放连接(连接池实现)
    local pool_max_idle_time = 100000 -- 毫秒
    local pool_size = 100  -- 连接池大小
    local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
    
    if not ok then
        ngx_log(ngx_ERR, "set redis keepalive error : ", err)
    end
end

-- 从redis获取ip黑名单列表
local function get_forbidden_list()
    local red = redis:new()
    red:set_timeout(10000)
    local ip = "192.168.226.4"
    local port = 6379
    --local password = ""
    local ok, err = red:connect(ip, port)
    if not ok then
        ngx_log(ngx_ERR, "connect to redis error : ", err)
        close_redis(red)
        return
    end
    
    --local res, err = red:auth(password)
    --if not res then
    --    ngx_log(ngx_ERR, "failed to authenticate: ", err)
    --    close_redis(red)
    --   return
    --end
    
    local resp, err = red:smembers("forbidden_list")
    if not resp then
        ngx_log(ngx_ERR, "get redis connect error : ", err)
        close_redis(red)
        return
    end
    -- 得到的数据为空处理
    if resp == ngx.null then
        resp = nil
    end
    close_redis(red)
    
    return resp
end

-- 刷新黑名单
local function reflush_forbidden_list()
    local current_time = ngx.now()
    local last_update_time = forbidden_list:get("last_update_time");
    
    if last_update_time == nil or last_update_time < (current_time - cache_idle) then
        local new_forbidden_list = get_forbidden_list();
        if not new_forbidden_list then
            return
        end
        
        forbidden_list:flush_all()
        for i, forbidden_ip in ipairs(new_forbidden_list) do
            forbidden_list:set(forbidden_ip, true);
        end
        forbidden_list:set("last_update_time", current_time);
    end
end


reflush_forbidden_list()
local ip = ngx_var.remote_addr
if forbidden_list:get(ip) then
    ngx_log(ngx_INFO, "forbidden ip refused access : ", ip)
    return ngx_exit(ngx.HTTP_FORBIDDEN)
end
 

8.效果演示

redis-cli

#添加黑名单

SADD forbidden_list "127.0.0.1"

#移除黑名单

SREM forbidden_list "127.0.0.1"

访问http://hadoop.senior02:8081/ipblacklist

二、基于Nginx 的静态缓存

某电商平台商品详情页需要实现 700+ QPS,如何着手去做?

问题:当达到500QPS 的时候很难继续压测上去。
分析原因:一个详情页html 主体达平均150 kb 那么在500QPS 已接近局域网宽带极限。必须减少内网通信。

 

解决方案:

一、在http元素下添加缓存区声明。
proxy_cache_path /data/nginx/cache_item levels=1:1:2 keys_zone=cache_item:500m
inactive=30d max_size=10g;
二、为指定location 设定缓存策略。
proxy_cache cache_item;
proxy_cache_key $host$uri$is_args$args;#以全路径md5值做做为Key
proxy_cache_valid 200 304 12h; #对不同的HTTP状态码设置不同的缓存时间
expires 7d; #总体缓存时间

 

Nginx的原理、常用配置和生产案例应用_第3张图片

Nginx的原理、常用配置和生产案例应用_第4张图片

缓存的清除:
该功能可以采用第三方模块 ngx_cache_purge 实现。

为nginx 添加 ngx_cache_purge 模块
#下载ngx_cache_purge 模块包 ,这⾥nginx 版本为1.6.2 purge 对应2.0版
wget http://labs.frickle.com/files/ngx_cache_purge-2.0.tar.gz#查看已安装模块
./sbin/nginx -V

#进⼊nginx安装包⽬录 重新安装 --add-module为模块解压的全路径
./configure --prefix=/root/svr/nginx --with-http_stub_status_module --with-http_ssl_module --
add-module=/root/svr/nginx/models/ngx_cache_purge-2.0

#重新编译
make

#拷⻉ 安装⽬录/objs/nginx ⽂件⽤于替换原nginx ⽂件
#检测查看安装是否成功
nginx -t

清除配置:
location ~ /purge(/.*) {
   #允许访问的IP
   allow 127.0.0.1;
   allow 192.168.0.193;
   #禁⽌访问的IP
   deny all;
   #配置清除指定缓存区和路径(与proxy_cache_key⼀⾄)
   proxy_cache_purge cache_item $host$1$is_args$args;
}

三、基于Nginx 图片防盗链

什么是图片防盗链?意思是指本站内图片、CSS等资源只有本站点可以访问,不允许其它站点打开。该功能如果用JAVA如何实现?很单简单,只要判断一下 请求头当中的referer 属性是否为 指定域名即可。Nginx原理类似。
防盗链配置:
location ~* \.(gif|png|jpg|swf|flv)$ {
   root html;
   valid_referers none *.tl.com;
   if ($invalid_referer) {
       rewrite ^/ http://www.tl.com/image/403.png;
       #return 404;
    }
}
 
说明:如果 valid_referers 条件判断未通过,nginx 则会赋值 invalid_referer 为true
语法: valid_referers none | blocked | server_names | string ...;
参数说明:

none                   不允许 “Referer” 来源头部为空的情况
blocked               不允许“Referer”值为空情况,有可能Referer的值被代理或者防火墙删除
server_names    “Referer”来源头部包必须含当前的server_names (当前域名)可以多个

四、子域名展示

有时会有这样的需求,每个子域名对应一个静态站点(类似58到家、有赞商城等)。如果每天增加一个域名会相当麻烦。在nginx 当中可直接基于$host 连接到对应目录。具体配置实现如下:
server {
  listen 80;
  server_name *.tl.com;
  root /data/www/$host;
  access_log logs/$host.access.log;
   location / {
            index index.html;
     }
}

 

五、多个config配置

在我们的一台服务器上,一个nginx服务器下面可能跑着许多许多的项目;那么就需要配置多个对应的配置 端口号 已经文件入库目录等等那么项目多了以后,把这些项目都写到一个文件里 到后期难以查看与管理我们只需要新建一个文件夹,下面全部存放 我们的子配置 然后在主配置中把这个子目录引入即可

 

include /etc/nginx/default.conf;     
include /etc/nginx/upstream/*.conf;     
include /etc/nginx/conf.d/*.conf; // 这里就是引入的子配置文件夹

一个范例 子配置的conf 

server {
    listen       832; // 端口号
    server_name localhost; // 域名
    index index.html index.htm index.php;
    root  /home/www/ai/crm/web/public; //项目的入口文件夹

    location ~ /.svn/ {
        deny all;
    }


    location / {
        rewrite ^/$ /index.php last;
        rewrite ^/(?!index\.php|index\.html|layui|css|js|bootstrap|robots\.txt)(.*)$ /index.php/$1 last;
    }

    location ~/uploads/.*\.(php|php5)?$ {
        deny all;
    }
    location ~/public/.*\.(php|php5)?$ {
        deny all;
    }

   location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
      expires      30d;
    }

    location ~ .*\.(js|css)?$ {
      expires      8d;
    }
    #access_log  /www/logs/access.log  main;

  }

 

六、动静态分离解决跨域

后端,用户通过 http://www.javaboy.org/jinlu/** 格式的地址就可以访问到我服务端的接口。

upstream zqq.com{
server 127.0.0.1:9999 weight=2;
}

location /jinlu/ {
proxy_pass http://zqq.com;
tcp_nodelay on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

前端 ,用户通过 http://www.javaboy.org/jinlu-admin/**格式的请求就可以访问到前端资源了。

location /jinlu-admin/ {
root /usr/local/nginx/html/jinlu-admin/;#所有静态文件直接读取硬盘
expires 30d; #缓存30天
}

备注:生产一般不用

https://mp.weixin.qq.com/s/okKU5VmBxwyht09TGTNdBQ

 

附录1:Nginx 日志格式变量说明

变量名称            变量描述                                 举例说明
$remote_addr         客户端地址                                113.140.15.90
$remote_user        客户端用户名称          
$time_local             访问时间和时区                             18/Jul/2012:17:00:01 +0800
$request_time        请求的URI和HTTP协议                        “GET /pa/img/home/logo-alipay-t.png HTTP/1.1″
$http_host             请求地址,即浏览器中你
输入的地址(IP或名)                   
 img.alipay.com  10.253.70.103
$status                    HTTP请求状态          200
$upstream_status   upstream状态            200
$body_bytes_sent   发送给客户端文件内容大小                  547
$http_referer          跳转来源     “https://cashier.alipay.com…/”

 

$http_user_agent     

用户终端代理 “Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SV1; GTB7.0; .NET4.0C;
$ssl_protocol         SSL协议版本              TLSv1
$ssl_cipher                       交换数据中的算法             RC4-SHA

$upstream_addr      

 

 


 

 后upstream的地址, 即真正提供服务的主机地址                     10.228.35.247:80
$request_time                  整个请求的总时间                0.205
$upstream_response_time     请求过程中upstream响应时间          0.002
$msec                  日志写入时间。单位为秒,精度是毫秒。  
$request_uri           从客户端发送来的原生请求URI,包括参数它不可以进行修改                       "/foo/bar.php?arg=baz"
$uri                   变量指当前的请求URI,不包括任何参数          "/foo/bar.php" 

 

附录2:Nginx的安装

yum install gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl
openssl-devel
1)wget 官网下载地址
2)tar zxvf 源码包
3)cd /解压的nginx目录下
4)./configure  生成编译的makefile   ./configure --prefix=...
5)make &&make install

     /server/nginx/sbin/nginx nginx 启动
    ./nginx -v   #可查看版本
        nginx version: nginx/1.10.3
        
    ./nginx -V    #可查看编译情况
        built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) 
        configure arguments: --prefix=/server/nginx
    ./nginx -t    
        nginx: the configuration file /server/nginx/conf/nginx.conf syntax is ok
        nginx: configuration file /server/nginx/conf/nginx.conf test is successful
    ./nginx -s reload 重新加载配置文件
        配置文件修改了,一定要重新启动
    ./nginx -c filename     用户指定启动时使用的其他配置文件    
    Nginx的停止方式:
        快速停止,平滑停止
        kill -TERM pid  快速停止,服务还没有停止,进程就已经停止(kill -9 pid)
        kill -QUIT  pid 平滑停止     把请求关掉之后,再把进程关掉(/nginx -s stop
     
    Nginx的升级
        nginx可以实现平滑升级,既不影响现在的服务前提下实现升级
        前提条件:新的安装路径和旧的安装路径保持一致,最好备份旧的服务器
        1)安装新的服务器
        2)发送USR2信号实现平滑升级
            kill -USR2 pid 或者 /server/nginx/logs/nginx.pid
        3)发送平滑停止旧的服务器信号
            kill -WHICH pid信号 /nginx/logs/nginx.pid
        -rw-r--r-- 1 root root 2656 Feb 24 16:30 nginx.conf
        -rw-r--r-- 1 root root 2656 Feb 24 16:30 nginx.conf.default  ##备份文件
        

附录3:添加nginx服务

1)在/etc/init.d目录下 touch nginx 创建一个nginx脚本文件,文件内容拷贝下面这个nginx.txt文件(注意不要直接将下面这个文件上传到/etc/init.d目录下,另外该文件里面指定的Nginx安装路径要改为实际安装路径)

2)chmod 755 /etc/init.d/nginx

3) 设置开机自启动 chkconfig nginx on && chkconfig --list | grep nginx

nginx.txt内容

#!/bin/bash
#
# chkconfig: - 85 15
# description: nginx is a World Wide Web server. It is used to serve
# 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"
 
#[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
 
lockfile=/var/lock/subsys/nginx
 
#make_dirs() {
#   # make required directories
#   user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
#   options=`$nginx -V 2>&1 | grep 'configure arguments:'`
#   for opt in $options; do
#       if [ `echo $opt | grep '.*-temp-path'` ]; then
#           value=`echo $opt | cut -d "=" -f 2`
#           if [ ! -d "$value" ]; then
#               # echo "creating" $value
#               mkdir -p $value && chown -R $user $value
#           fi
#       fi
#   done
#}
 
start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
#    make_dirs
    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
    sleep 1
    start
}
 
reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
#  -HUP是nginx平滑重启参数  
    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

 

你可能感兴趣的:(Nginx的原理、常用配置和生产案例应用)