Nginx使用教程(七):使用Nginx缓存之proxy cache

定义缓存目录

使用您喜欢的文本编辑器打开/etc/nginx/nginx.conf,并在http {区域加入:

  1. proxy_cache_path  /var/www/cache levels=1:2 keys_zone=my-cache:8m max_size=1000m inactive=600m;
  2.  
  3. proxy_temp_path /var/www/cache/tmp;
  4.  
  5. real_ip_header X-Forwarded-For;

前2行创建一个缓存目录。 真正的X-Forwarded-For头指示Nginx将原始IP地址转发到后端(端口8080),否则所有流量似乎都来自127.0.0.1。

应用缓存

接下来,我们需要在/etc/nginx/sites-available/website下创建虚拟主机

  1. server {
  2.         listen 80;
  3.         server_name _;
  4.         server_tokens off;
  5.         location / {
  6.                 proxy_pass              http://127.0.0.1:8080/;
  7.                 proxy_set_header        Host                    $host;
  8.                 proxy_set_header        X-Real-IP               $remote_addr;
  9.                 proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
  10.                 proxy_cache  my-cache;
  11.                 proxy_cache_valid 3s;
  12.                 proxy_no_cache $cookie_PHPSESSID;
  13.                 proxy_cache_bypass $cookie_PHPSESSID;
  14.                 proxy_cache_key         "$scheme$host$request_uri";
  15.                 add_header X-Cache $upstream_cache_status;
  16.         }
  17. }
  18.  
  19. server {
  20.         listen   8080;
  21.         server_name _;
  22.         root /var/www/your_document_root/;
  23.         index index.php index.html index.htm;
  24.         server_tokens off;
  25.         location ~ .php$ {
  26.                 try_files $uri /index.php;
  27.                 fastcgi_pass 127.0.0.1:9000;
  28.                 fastcgi_index index.php;
  29.                 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  30.                 include /etc/nginx/fastcgi_params;
  31.         }
  32.         location ~ /.ht {
  33.                 deny all;
  34.         }
  35. }

然后通过执行以下操作启用它:

  1. cd
  2. ln -s /etc/nginx/sites-available/website /etc/nginx/sites-enabled/website
  3. /etc/init.d/nginx restart

第一个服务器定义是在端口80上运行的反向缓存代理。
第二个服务器定义用于后端(典型的nginx配置,端口8080,而不是80)。

proxy相关指令介绍

proxy_pass http://127.0.0.1:8080/将流量转发到端口8080,Nginx后端位于该端口
proxy_cache my-cache定义要使用的高速缓存,这里是my-cache,我们之前在nginx.conf中添加的
proxy_cache_valid 3s将缓存时间设置为3秒。 在确定缓存到期之前的秒数(清除缓存)。 此数字可以根据您网站上的内容的新鲜度而增加或减少。
proxy_no_cache $ cookie_PHPSESSID禁止反向缓存代理缓存具有PHPSESSID Cookie的请求。 否则,您的登录用户页面将被缓存并显示给其他人。 如果您使用的Cookie框架使用Cookie的默认PHPSESSID以外的Cookie名称,请务必替换。
proxy_cache_bypass $ cookie_PHPSESSID指示代理绕过缓存,并且如果传入请求包含PHPSESSID Cookie,则将请求转发到后端。 否则,你最终会显示登录的用户,登出的版本(从缓存提供)。
proxy_cache_key “$scheme$host$request_uri”定义用于缓存的键。 以下使用$ request_uri,它适合于根据url存储不同版本的页面(不同的GET参数,不同的内容)。
add_header X-Cache $ upstream_cache_status可用于调试,返回HIT,BYPASS或EXPIRED,具体取决于请求是从高速缓存(HIT)提供还是从后端(MISS)提供.EXPIRED表示在高速缓存中找到缓存,但它已过期,并已转发到后端。

Nginx使用教程(六):使用Nginx缓存之FastCGI缓存

启用FastCGI缓存

编辑必须启用缓存的虚拟主机配置文件。

  1. nano /etc/nginx/sites-enabled/vhost

将以下行添加到server{}指令之外的文件顶部:

  1. fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=60m;
  2. fastcgi_cache_key "$scheme$request_method$host$request_uri";

“fastcgi_cache_path”指令指定缓存(/etc/nginx/cache)的位置,其大小(100m),内存区域名称(MYAPP),子目录级别和非活动定时器。
位置可以在硬盘上的任何地方; 但是,大小必须小于您的服务器的RAM +交换,否则你会收到一个错误,“无法分配内存”。 如果缓存在“inactive”选项指定的特定时间内没有被访问(这里为60分钟),Nginx将删除它。
“fastcgi_cache_key”指令指定如何哈希缓存文件名。 Nginx基于此指令使用MD5加密访问的文件。
在location ~ .php$ { }里添加如下行:

  1. fastcgi_cache MYAPP;
  2. fastcgi_cache_valid 200 60m;

“fastcgi_cache”指令引用我们在“fastcgicache_path”指令中指定的内存区域名称,并将缓存存储在此区域中。
默认情况下,Nginx根据这些响应头里指定的时间决定存储缓存对象的时间:X-Accel-Expires / Expires / Cache-Control。
如果缺少这些头,“fastcgi_cache_valid”指令用于指定默认缓存生命周期。 在上面输入的语句中,只缓存状态代码为200的响应。 也可以指定其他响应代码。
测试配置:

  1. service nginx configtest

重载Nginx:

  1. service nginx reload

完整的vhost配置文件如下:

  1. fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=60m;
  2. fastcgi_cache_key "$scheme$request_method$host$request_uri";
  3.  
  4. server {
  5.     listen   80;
  6.  
  7.     root /usr/share/nginx/html;
  8.     index index.php index.html index.htm;
  9.  
  10.     server_name example.com;
  11.  
  12.     location / {
  13.         try_files $uri $uri/ /index.html;
  14.     }
  15.  
  16.     location ~ .php$ {
  17.         try_files $uri =404;
  18.         fastcgi_pass unix:/var/run/php5-fpm.sock;
  19.         fastcgi_index index.php;
  20.         include fastcgi_params;
  21.         fastcgi_cache MYAPP;
  22.         fastcgi_cache_valid 200 60m;
  23.     }
  24. }

测试FastCGI缓存是否生效

创建/usr/share/nginx/html/time.php,内容如下:

  1. <?php
  2. echo time();
  3. ?>

使用curl或您的Web浏览器多次请求此文件。

  1. root@droplet:~# curl http://localhost/time.php;echo
  2. 1382986152
  3. root@droplet:~# curl http://localhost/time.php;echo
  4. 1382986152
  5. root@droplet:~# curl http://localhost/time.php;echo
  6. 1382986152

如果缓存工作正常,您应该在缓存响应时在所有请求上看到相同的时间戳。
执行缓存位置的递归列表以查找此请求的缓存。
root@droplet:~# ls -lR /etc/nginx/cache/
/etc/nginx/cache/:
total 0
drwx—— 3 www-data www-data 60 Oct 28 18:53 e

/etc/nginx/cache/e:
total 0
drwx—— 2 www-data www-data 60 Oct 28 18:53 18

/etc/nginx/cache/e/18:
total 4
-rw——- 1 www-data www-data 117 Oct 28 18:53 b777c8adab3ec92cd43756226caf618e
我们还可以使Nginx为响应添加一个“X-Cache”头,指示缓存是否被丢失或命中。
在server{}指令上面添加以下内容:

  1. add_header X-Cache $upstream_cache_status;

重新加载Nginx服务,并使用curl执行详细请求以查看新标题。
root@droplet:~# curl -v http://localhost/time.php
* About to connect() to localhost port 80 (#0)
* Trying 127.0.0.1…
* connected
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /time.php HTTP/1.1
> User-Agent: curl/7.26.0
> Host: localhost
> Accept: */*
>
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 200 OK
< Server: nginx
< Date: Tue, 29 Oct 2013 11:24:04 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Cache: HIT
<
* Connection #0 to host localhost left intact
1383045828* Closing connection #0

不需要缓存的页面

某些动态内容(例如认证所需页面)不应缓存。 可以基于诸如“requesturi”,“requestmethod”和“http_cookie”的服务器变量来排除这样的内容被高速缓存。
如下例子:

  1. #Cache everything by default
  2. set $no_cache 0;
  3.  
  4. #Don’t cache POST requests
  5. if ($request_method = POST)
  6. {
  7.     set $no_cache 1;
  8. }
  9.  
  10. #Don’t cache if the URL contains a query string
  11. if ($query_string != "")
  12. {
  13.     set $no_cache 1;
  14. }
  15.  
  16. #Don’t cache the following URLs
  17. if ($request_uri ~* "/(administrator/|login.php)")
  18. {
  19.     set $no_cache 1;
  20. }
  21.  
  22. #Don’t cache if there is a cookie called PHPSESSID
  23. if ($http_cookie = "PHPSESSID")
  24. {
  25.     set $no_cache 1;
  26. }

要将“$no_cache”变量应用到相应的指令,请将以下行放在location〜.php $ {}中,

  1. fastcgi_cache_bypass $no_cache;
  2. fastcgi_no_cache $no_cache;

“fasctcgicachebypass”指令忽略之前由我们设置的条件相关的请求的现有缓存。 如果满足指定的条件,“fastcginocache”指令不缓存请求。

清除缓存

缓存的命名约定基于我们为“fastcgicachekey”指令设置的变量。

  1. fastcgi_cache_key "$scheme$request_method$host$request_uri";

根据这些变量,当我们请求“http//localhost/time.php”时,以下是实际值:

  1. fastcgi_cache_key "httpGETlocalhost/time.php";

将此字符串传递到MD5哈希将输出以下字符串:
b777c8adab3ec92cd43756226caf618e
这就是高速缓存的文件名,就像我们输入的“levels = 1:2”子目录。 因此,目录的第一级将从这个MD5字符串的最后一个字符命名为1个字符,即e; 第二级将具有在第一级之后的最后2个字符,即18.因此,该高速缓存的整个目录结构如下:
/etc/nginx/cache/e/18/b777c8adab3ec92cd43756226caf618e
基于这种缓存命名格式,您可以用您最喜欢的语言开发一个清除脚本。 对于本教程,我将提供一个简单的PHP脚本,它清除POSTed URL的缓存。
/usr/share/nginx/html/purge.php:

  1. <?php
  2. $cache_path = ‘/etc/nginx/cache/’;
  3. $url = parse_url($_POST[‘url’]);
  4. if(!$url)
  5. {
  6.     echo ‘Invalid URL entered’;
  7.     die();
  8. }
  9. $scheme = $url[‘scheme’];
  10. $host = $url[‘host’];
  11. $requesturi = $url[‘path’];
  12. $hash = md5($scheme.’GET’.$host.$requesturi);
  13. var_dump(unlink($cache_path . substr($hash, -1) . ‘/’ . substr($hash,-3,2) . ‘/’ . $hash));
  14. ?>

向此文件发送带需要清除的URL的POST请求。

  1. curl -d ‘url=http://www.example.com/time.php’ http://localhost/purge.php

该脚本将根据是否清除缓存而输出true或false。 请确保从高速缓存中排除此脚本,并限制访问。

Nginx使用教程(五):使用Nginx缓存之缓存静态内容

NGINX虽然已经对静态内容做过优化。 但在高流量网站的情况下,仍然可以使用open_file_cache进一步提高性能。 NGINX缓存将最近使用的文件描述符和相关元数据(如修改时间,大小等)存储在缓存中。 缓存不会存储所请求文件的内容。

open_file_cache

启用此指令将存储以下信息的缓存:
打开的文件描述符和相关元数据,如大小,修改时间等
文件和目录的存在
与查找相关的任何错误,例如“权限被拒绝”,“文件未找到”等
缓存定义固定大小,并且在溢出期间,它移除最近最少使用(LRU)元素。 缓存在一段时间不活动之后逐出元素。 默认情况下禁用该指令。 如下例子:

  1. http{
  2.    open_file_cache max=1000 inactive=20s;
  3.    }

在上述配置中,为1,000个元素定义了一个缓存。 inactive参数配置到期时间为20秒。 没有必要为该指令设置非活动时间段,默认情况下,非活动时间段为60秒。
NGINX还定义了一些相关的指令,可用于在错误和有效性检查期间配置open_file_cache的行为。

open_file_cache_valid

NGINX的open_file_cache保存信息的快照。 由于信息在源处更改,快照可能在一段时间后无效。 open_file_ cache_valid指令定义时间段(以秒为单位),之后将重新验证open_file_cache中的元素。 如下例子:

  1. http{
  2.    open_file_cache_valid 30s;
  3.    }

默认情况下,60秒后重新检查元素。

open_file_cache_min_uses

NGINX将在非活动时间段之后从高速缓存中清除元素。 此指令可用于配置最小访问次数以将元素标记为活动使用。 默认情况下,最小访问次数设置为1次或更多次。如下例子

  1. http{
  2.    open_file_cache_min_uses 4;
  3.    }

open_file_cache_errors

如前所述,NGINX可以缓存在文件访问期间发生的错误。 但是这需要通过设置open_file_cache_errors指令来启用。 如果启用错误缓存,则在访问资源(不查找资源)时,NGINX会报告相同的错误。

  1. http{
  2.    open_file_cache_errors on;
  3.    }

默认情况下,错误缓存设置为关闭。

Nginx使用教程(四):提高Nginx网络吞吐量之buffers优化

请求缓冲区在NGINX请求处理中起着重要作用。 在接收到请求时,NGINX将其写入这些缓冲区。 这些缓冲区中的数据可作为NGINX变量使用,例如$request_body。 如果缓冲区与请求大小相比较小,则数据将写入磁盘上的文件,因此将涉及I/O操作。 NGINX提供了可以改变请求缓冲区的各种指令。

client_body_buffer_size

此指令设置用于请求主体的缓冲区大小。 如果主体超过缓冲区大小,则完整主体或其一部分将写入临时文件。 如果NGINX配置为使用文件而不是内存缓冲区,则该指令会被忽略。 默认情况下,该指令为32位系统设置一个8k缓冲区,为64位系统设置一个16k缓冲区。 该指令在NGINX配置的http,server和location区块使用。如下:

  1. server{
  2.       client_body_buffer_size 8k;
  3. }

client_max_body_size

此指令设置NGINX能处理的最大请求主体大小。 如果请求大于指定的大小,则NGINX发回HTTP 413(Request Entity too large)错误。 如果服务器处理大文件上传,则该指令非常重要。

默认情况下,该指令值为1m。 如下:

  1. server{
  2.       client_max_body_size 2m;
  3. }

client_body_in_file_only

此指令禁用NGINX缓冲区并将请求体存储在临时文件中。 文件包含纯文本数据。 该指令在NGINX配置的http,server和location区块使用。 可选值有:
off:该值将禁用文件写入
clean:请求body将被写入文件。 该文件将在处理请求后删除。
on: 请求正文将被写入文件。 处理请求后,将不会删除该文件。
默认情况下,指令值为关闭。 如下:

  1. http{
  2.       client_body_in_file_only clean;
  3. }

client_body_in_single_buffer

该指令设置NGINX将完整的请求主体存储在单个缓冲区中。 默认情况下,指令值为off。 如果启用,它将优化读取$request_body变量时涉及的I/O操作。如下例子:

  1. server{
  2.       client_body_in_single_buffer on;
  3. }

client_body_temp_path

此指令指定存储请求正文的临时文件的位置。 除了位置之外,指令还可以指定文件是否需要最多三个级别的文件夹层次结构。 级别指定为用于生成文件夹的位数。
默认情况下,NGINX在NGINX安装路径下的client_body_temp文件夹创建临时文件。 如下例子:

  1. server{
  2.       client_body_temp_pathtemp_files 1 2;
  3.       }

该指令生成的文件路径如temp_files/1/05/0000003051。

client_header_buffer_size

此指令与client_body_buffer_size类似。 它为请求头分配一个缓冲区。 如果请求头大小大于指定的缓冲区,则使用large_client_header_buffers指令分配更大的缓冲区。如下例子:

  1. http{
  2.       client_header_buffer_size 1m;
  3.       }

large_client_header_buffers

此指令规定了用于读取大型客户端请求头的缓冲区的最大数量和大小。 这些缓冲区仅在缺省缓冲区不足时按需分配。 当处理请求或连接转换到保持活动状态时,释放缓冲区。如下例子:

  1. http{
  2.       large_client_header_buffers 4 8k;
  3.       }

Nginx使用教程(三):Nginx配置性能优化之I/O和TCP配置

配置Nginx I/O

Sendfile

当应用程序传输文件时,内核首先缓冲数据,然后将数据发送到应用程序缓冲区。 应用程序反过来将数据发送到目的地。 Sendfile方法是一种改进的数据传输方法,其中数据在操作系统内核空间内的文件描述符之间复制,而不将数据传输到应用程序缓冲区。 这使操作系统资源的利用率提高。
可以使用sendfile指令启用该方法。 该指令可用于http,server和location代码块:

  1. http{
  2.      sendfile on;
  3. }

此指令默认为off。

直接I/O

操作系统内核通常尝试优化和缓存任何读/写请求。 由于数据在内核中缓存,对同一位置的任何后续读取请求将更快,因为不需要再从磁盘读取信息。
直接I/O是文件系统的一个功能,其从应用程序到磁盘直接读取和写入,从而绕过所有操作系统缓存。 这使得更好地利用CPU周期和提高缓存效率。
该方法用于数据具有较差命中率的地方。 这样的数据不需要在任何高速缓存中,并且可以在需要时加载。 它可以用于提供大文件。 directio指令启用该功能。 该指令可用于http,server和location区块:

  1. location /video/ {
  2.      directio 4m;
  3. }

任何大于指令中指定的文件将由直接I/O加载。 其它情况下禁用此参数。
直接I/O取决于执行数据传输时的块大小。 NGINX有directio_alignment指令来设置块大小。 该指令可用于http,server和location区块:

  1. location /video/ {
  2.      directio 4m;
  3.      directio_alignment 512;
  4. }

除了XFS文件系统,默认值512字节在所有Linux版本运行良好。在此文件系统下,大小应增加到4 KB。

异步I/O

异步I/O允许进程进行不受阻塞或不需要等待I/O完成的I/O操作。
aio命令可在NGINX配置的http,server和location区块下使用。 根据在指令所在区块,该指令将为匹配的请求执行异步I/O。 该参数适用于Linux内核2.6.22+和FreeBSD 4.3。 如下代码:

  1. location /data {
  2.      aio on;
  3. }

默认情况下,该参数设置为off。 在Linux上,aio需要启用direction,而在FreeBSD上,sendfile需要禁用以使aio生效。
该指令具有特殊的线程值,可以为发送和读操作启用多线程。 多线程支持仅在Linux平台上可用,并且只能与处理请求的epoll,kqueue或eventport方法一起使用。
为了使用线程值,在编译Nginx时使用–with-threads选项配置多线程支持。 在NGINX全局上下文中使用thread_pool指令添加一个线程池。 在aio配置中使用该线程池:

  1. thread_pool io_pool threads=16;
  2.    http{
  3.    ……..
  4.       location /data{
  5.         sendfile    on;
  6.         aio        threads=io_pool;
  7. } }

配置Nginx TCP

HTTP是一种基于应用的协议,它使用TCP作为传输层。 在TCP中,数据以称为TCP分组的块的形式传送。 NGINX提供了改变底层TCP栈的行为的指令。 这些参数更改了单个套接字连接的属性。

TCP_NODELAY

TCP/IP网络存在“小包”问题,其中单字符消息可能在高负载网络上导致网络拥塞。 例如分组大小为41字节,其中40字节用于TCP报头,只有1字节是有用信息。 这些小包占用了大约4000%的巨大开销并且使得网络饱和。
ohn Nagle通过不立即发送小包来解决问题(Nagle的算法)。 所有这样的分组被收集一定量的时间,然后作为单个分组一次发送。 这改进了底层网络的的效率。 因此,典型的TCP/IP协议栈在将数据包发送到客户端之前需要等待200毫秒。
在打开套接字时可以使用TCP_NODELAY选项来禁用Nagle的缓冲算法,并在数据可用时立即发送。 NGINX提供了tcp_nodelay指令来启用此选项。 该指令可用于http,server和location区块:

  1. http{
  2.      tcp_nodelay on;
  3. }

该指令默认情况下启用。

TCP_CORK

作为Nagle算法的替代方案,Linux提供了TCP_CORK选项。 该选项告诉TCP堆栈附加数据包,并在它们已满或当应用程序通过显式删除TCP_CORK指示发送数据包时发送它们。 这使得发送的数据分组是最优量,并且因此提高了网络的效率。
NGINX提供了tcp_nopush指令,在连接套接字时启用TCP_CORK。 该指令可用于http,server和location区块:

  1. http{
  2.      tcp_nopush on;
  3. }

该指令默认情况下禁用。

Nginx使用教程(二):Nginx配置性能优化之worker配置

配置Nginx workers

NGINX根据指定的配置运行固定数量的工作进程。 这些工作进程负责处理所有处理。 在下面的章节中,我们将调整NGINX worker参数。 这些参数是NGINX全局上下文的一部分。

worker_processes

worker_processes指令控制工作进程数:

  1. worker_processes 1;

其默认值为1,这意味着NGINX只运行一个worker。 该值应根据可用内核数,磁盘,网络子系统,服务器负载等更改为最佳值。
我们可以将值设置为可用的核心数。 使用lscpu确定可用的核心数:

  1. $ lscpu
  2. Architecture:  x86_64
  3. CPU op-mode(s):  32-bit, 64-bit
  4. Byte Order:  Little Endian
  5. CPU(s):        4

同样可以通过grep cpuinfo得到:

  1. $ cat /proc/cpuinfo | grep ‘processor’ | wc -l

现在我们设置worker数为4:

  1. # One worker per CPU-core.
  2.    worker_processes 4;

或者,可以将其设置为auto。 这样nginx会自动根据核心数为生成对应数量的worker进程。

accept_mutex

由于我们在NGINX中配置了多个workers,因此我们还应配置影响worker的相关指令。 events区域下accept_mutex参数将使每个可用的worker进程逐个接受新连接。 默认情况下,该标志设置为on。 如:

  1. events {
  2.      accept_mutex on;
  3. }

如果accept_mutex为off,所有可用的worker将从等待状态唤醒,但只有一个worker处理连接。 这导致惊群现象,每秒重复多次。 这种现象导致服务器性能下降,因为所有被唤醒的worker都在占用CPU时间。 这导致增加了非生产性CPU周期和未使用的上下文切换。

accept_mutex_delay

当启用accept_mutex时,只有一个具有互斥锁的worker程序接受连接,而其他工作程序则轮流等待。 accept_mutex_delay对应于worker等待的时间帧,然后它尝试获取互斥锁并开始接受新的连接。 默认值为500毫秒

  1. events{
  2.      accept_mutex_delay 500ms;
  3.  }

worker_connections

下一个要查看的配置是worker_connections,默认值为512.该指令设置worker进程最大打开的连接数:

  1. events{
  2.       worker_connections 512;
  3. }

将worker_connections增加到1024或更高的值,以允许同时处理更多连接。

worker_rlimit_nofile

同时连接的数量受限于系统上可用的文件描述符的数量,因为每个套接字将打开一个文件描述符。 如果NGINX尝试打开比可用文件描述符更多的套接字,会发现error.log中出现Too many opened files的信息。
使用ulimit检查文件描述符的数量:

  1. $ ulimit -n

现在,将此值增加到大于worker_processes * worker_connections的值。 应该是增加当前worker运行用户的最大文件打开数值。
NGINX提供了worker_rlimit_nofile指令,这是除了ulimit的一种设置可用的描述符的方式。 该指令与使用ulimit对用户的设置是同样的效果。此指令的值将覆盖ulimit的值,如:

  1. worker_rlimit_nofile 20960;

multi_accept

multi_accept指令使得NGINX worker能够在获得新连接的通知时尽可能多的接受连接。 此指令的作用是立即接受所有连接放到监听队列中。 如果指令被禁用,worker进程将逐个接受连接。

  1. events{
  2.       multi_accept on;
  3. }

添加Nginx为系统服务(设置开机启动)

在本节中,我们将创建一个脚本,将Nginx守护进程转换为实际的系统服务。 这有两个作用:守护程序可以使用标准命令控制,更重要的是,它可以在系统启动时自动启动,并在系统关闭时停止。

System V scripts

大多数基于Linux的操作系统使用System-V风格的init守护进程。 换句话说,他们的启动过程由一个称为init的守护进程管理。
这个守护进程基于运行级别的原理运行,它代表计算机的状态。 这里是一个表表示各种运行级别:

运行级别 状态
0 系统关闭
1 单用户模式(救援模式)
2 多用户模式,不支持NFS
3 完全多用户模式
4 未使用
5 图形界面模式
6 系统重新启动

关于init脚本

init脚本(也称为服务启动脚本或甚至sysv脚本)是一个符合某种标准的shell脚本。 该脚本通过诸如开始,停止和其他等命令来控制守护进程应用程序。首先,当计算机启动时,init守护程序将使用start参数运行脚本。 另一种可能性是通过从shell手动执行脚本:

  1. [[email protected] ~]# service nginx start

或者如果您的系统没有service命令:

  1. [[email protected] ~]# /etc/init.d/nginx start

Nginx init脚本

/etc/init.d/nginx:
基于Debian的发行版本

  1. #! /bin/sh
  2.  
  3. ### BEGIN INIT INFO
  4. # Provides:          nginx
  5. # Required-Start:    $all
  6. # Required-Stop:     $all
  7. # Default-Start:     2 3 4 5
  8. # Default-Stop:      0 1 6
  9. # Short-Description: starts the nginx web server
  10. # Description:       starts nginx using start-stop-daemon
  11. ### END INIT INFO
  12.  
  13. PATH=/opt/bin:/opt/sbin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
  14. DAEMON=/opt/sbin/nginx
  15. NAME=nginx
  16. DESC=nginx
  17.  
  18. test -x $DAEMON || exit 0
  19.  
  20. # Include nginx defaults if available
  21. if [ -f /etc/default/nginx ] ; then
  22.         . /etc/default/nginx
  23. fi
  24.  
  25. set -e
  26.  
  27. case "$1" in
  28.   start)
  29.         echo -n "Starting $DESC: "
  30.         start-stop-daemon –start –quiet –pidfile /var/run/nginx.pid
  31.                 –exec $DAEMON — $DAEMON_OPTS
  32.         echo "$NAME."
  33.         ;;
  34.   stop)
  35.         echo -n "Stopping $DESC: "
  36.         start-stop-daemon –stop –quiet –pidfile /var/run/nginx.pid
  37.                 –exec $DAEMON
  38.         echo "$NAME."
  39.         ;;
  40.   restart|force-reload)
  41.         echo -n "Restarting $DESC: "
  42.         start-stop-daemon –stop –quiet –pidfile
  43.                 /var/run/nginx.pid –exec $DAEMON
  44.         sleep 1
  45.         start-stop-daemon –start –quiet –pidfile
  46.                 /var/run/nginx.pid –exec $DAEMON — $DAEMON_OPTS
  47.         echo "$NAME."
  48.         ;;
  49.   reload)
  50.       echo -n "Reloading $DESC configuration: "
  51.       start-stop-daemon –stop –signal HUP –quiet –pidfile /var/run/nginx.pid
  52.           –exec $DAEMON
  53.       echo "$NAME."
  54.       ;;
  55.   *)
  56.         N=/etc/init.d/$NAME
  57.         echo "Usage: $N {start|stop|restart|force-reload}" >&2
  58.         exit 1
  59.         ;;
  60. esac
  61.  
  62. exit 0

基于Red Hat的发行版本

  1. #!/bin/sh
  2. #
  3. # nginx – this script starts and stops the nginx daemon
  4. #
  5. # chkconfig:   – 85 15
  6. # description:  NGINX is an HTTP(S) server, HTTP(S) reverse
  7. #               proxy and IMAP/POP3 proxy server
  8. # processname: nginx
  9. # config:      /etc/nginx/nginx.conf
  10. # config:      /etc/sysconfig/nginx
  11. # pidfile:     /var/run/nginx.pid
  12.  
  13. # Source function library.
  14. . /etc/rc.d/init.d/functions
  15.  
  16. # Source networking configuration.
  17. . /etc/sysconfig/network
  18.  
  19. # Check that networking is up.
  20. [ "$NETWORKING" = "no" ] && exit 0
  21.  
  22. nginx="/usr/sbin/nginx"
  23. prog=$(basename $nginx)
  24.  
  25. NGINX_CONF_FILE="/etc/nginx/nginx.conf"
  26.  
  27. [ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
  28.  
  29. lockfile=/var/lock/subsys/nginx
  30.  
  31. make_dirs() {
  32.    # make required directories
  33.    user=`$nginx -V 2>&1 | grep "configure arguments:" | sed ‘s/[^*]*–user=([^ ]*).*/1/g’ -`
  34.    if [ -z "`grep $user /etc/passwd`" ]; then
  35.        useradd -M -s /bin/nologin $user
  36.    fi
  37.    options=`$nginx -V 2>&1 | grep ‘configure arguments:’`
  38.    for opt in $options; do
  39.        if [ `echo $opt | grep ‘.*-temp-path’` ]; then
  40.            value=`echo $opt | cut -d "=" -f 2`
  41.            if [ ! -d "$value" ]; then
  42.                # echo "creating" $value
  43.                mkdir -p $value && chown -R $user $value
  44.            fi
  45.        fi
  46.    done
  47. }
  48.  
  49. start() {
  50.     [ -x $nginx ] || exit 5
  51.     [ -f $NGINX_CONF_FILE ] || exit 6
  52.     make_dirs
  53.     echo -n $"Starting $prog: "
  54.     daemon $nginx -c $NGINX_CONF_FILE
  55.     retval=$?
  56.     echo
  57.     [ $retval -eq 0 ] && touch $lockfile
  58.     return $retval
  59. }
  60.  
  61. stop() {
  62.     echo -n $"Stopping $prog: "
  63.     killproc $prog -QUIT
  64.     retval=$?
  65.     echo
  66.     [ $retval -eq 0 ] && rm -f $lockfile
  67.     return $retval
  68. }
  69.  
  70. restart() {
  71.     configtest || return $?
  72.     stop
  73.     sleep 1
  74.     start
  75. }
  76.  
  77. reload() {
  78.     configtest || return $?
  79.     echo -n $"Reloading $prog: "
  80.     killproc $nginx -HUP
  81.     RETVAL=$?
  82.     echo
  83. }
  84.  
  85. force_reload() {
  86.     restart
  87. }
  88.  
  89. configtest() {
  90.   $nginx -t -c $NGINX_CONF_FILE
  91. }
  92.  
  93. rh_status() {
  94.     status $prog
  95. }
  96.  
  97. rh_status_q() {
  98.     rh_status >/dev/null 2>&1
  99. }
  100.  
  101. case "$1" in
  102.     start)
  103.         rh_status_q && exit 0
  104.         $1
  105.         ;;
  106.     stop)
  107.         rh_status_q || exit 0
  108.         $1
  109.         ;;
  110.     restart|configtest)
  111.         $1
  112.         ;;
  113.     reload)
  114.         rh_status_q || exit 7
  115.         $1
  116.         ;;
  117.     force-reload)
  118.         force_reload
  119.         ;;
  120.     status)
  121.         rh_status
  122.         ;;
  123.     condrestart|try-restart)
  124.         rh_status_q || exit 0
  125.             ;;
  126.     *)
  127.         echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
  128.         exit 2
  129. esac

注意修改脚本中的路径。

安装Nginx init脚本

添加执行权限:

  1. [[email protected] ~]# chmod +x /etc/init.d/nginx

Debian-based发行版本:

  1. [[email protected] ~]# update-rc.d -f nginx defaults

Red Hat–based发行版本:

  1. [[email protected] ~]# chkconfig nginx on

Nginx主程序使用介绍

守护进程和服务

在首次运行Nginx之前,了解此应用程序的性质很重要。 有两种类型的计算机应用程序 – 那些需要用户输入,因此在前台运行,另一种在后台运行。 Nginx是后一种类型,通常称为守护进程。 守护进程名称通常带有尾随的“d”,这里可以提到几个例子 – httpd,HTTP服务器守护进程,是几个Linux发行版下给Apache的名称; named,域名解析服务器守护进程; 或crond任务调度器 – 当Nginx从命令行启动时,守护进程立即返回终端,并且在大多数情况下,甚至不会输出任何数据到终端。

用户和组

了解Nginx的进程架构,特别是其各种进程运行的用户和组是非常重要的。由于用户或组的错误配置 ,可能导致Nginx出现权限之类的错误,你最终会得到403 Forbidden HTTP错误,Nginx不能访问请求的文件。
有两个级别的进程,可能具有不同的权限集:
Nginx主进程:这应该以root身份启动。 在大多数类Unix系统中,使用root帐户启动的进程允许在任何端口上打开TCP套接字,而其他用户只能在1024以上的端口上打开侦听套接字。如果您不以root身份启动Nginx,则标准端口 80或443将无法访问。
Nginx工作进程:这些由主进程在您配置文件中使用user指令指定的帐户下自动生成。 配置设置优先于您在编译时指定的配置选项。 如果您没有指定任何这些,工作进程将作为用户nobody和组nobody(或nogroup,取决于您的操作系统)启动。

Nginx命令行选项

Nginx二进制接受命令行参数以执行各种操作,包括控制后台进程。 要获取完整的命令列表,可以使用以下命令输出帮助信息:

  1. [[email protected] ~]$ cd /usr/local/nginx/sbin
  2. [[email protected] sbin]$ ./nginx -h

启动和停止Nginx进程

你可以不用指令任何参数来启动Nginx。 如果守护程序已在运行,将显示一条消息,套接字已在侦听端口上侦听:
[emerg]: bind() to 0.0.0.0:80 failed (98: Address already in use) […]
[emerg]: still could not bind().
除此之外,您可以通过停止,重新启动守护程序或简单地重新加载它的配置来控制守护程序。 通过使用nginx -s命令向进程发送信号来控制进程。
nginx –s stop:立即停止守护进程(使用TERM信号)。
nginx –s quit:正常停止守护程序(使用QUIT信号)。
nginx –s reopen:重新打开日志文件。
nginx –s reload:重新加载配置。
在以上命令无法停止nginx的情况下,终止进程的另一种方法是使用具有root权限的kill vs killall命令:

  1. [[email protected] ~]# killall nginx

测试配置文件

测试Nginx配置文件的命令为:

  1. [[email protected] ~]$ /usr/local/nginx/sbin/nginx –t

也可以测试指定的配置文件:

  1. [[email protected] sbin]$ ./nginx –t –c /home/alex/test.conf

Nginx编译参数详解

从源代码编译应用程序时通常有三个步骤:配置,编译和安装。 配置步骤允许您选择一些在程序编译后无法编辑的选项,因为它对程序二进制文件有直接影响。 因此,这是一个非常重要的阶段,你需要仔细选择,如果你想避免后面的麻烦,如缺乏一个特定的模块或配置文件位于一个随机文件夹等。

简单安装

如果由于某种原因,您不想使安装这么麻烦(例如用于测试目的或仅仅因为您以后会重新编译程序),则可以直接使用不带参数的configure命令。 执行以下三个命令来编译和安装Nginx的工作版本,从configure命令开始:

  1. [[email protected] nginx-1.8.0]# ./configure

运行此命令需要比较长的时间来进行验证过程,以确保您的系统包含所有必需的组件。 如果配置过程失败,请再次检查安装依赖部分,因为它是错误的最常见原因。 有关命令失败原因的信息,您还可以参考objs/autoconf.err文件,其中提供了更详细的报告。 make命令将编译应用程序。 只要配置正确,此步骤不应出现任何错误。

  1. [[email protected] nginx-1.8.0]# make
  2. [[email protected] nginx-1.8.0]# make install

这最后一步将编译文件以及其他资源复制到安装目录,默认是/usr/local/nginx。

Path选项

参数 用途 默认值
–prefix=… Nginx安装的基础目录 /usr/local/nginx
–sbin-path=… Nginx二进制安装目录 /sbin/nginx.
–conf-path=… 主配置文件安装位置 /conf/nginx.conf.
–error-log-path=… 错误日志位置 /logs/error.log.
–pid-path=… Nginx pid文件路径,可以在配置文件指定 /logs/nginx.pid.
–lock-path=… 锁文件位置 /logs/nginx.lock.
–with-perl_
modules_path=…
Perl模块位置
–with-perl=… Perl二进制文件路径
–http-log-
path=…
访问日志路径,可以在配置文件指定 /logs/access.log.
–http-client-
body-temp-path=…
存放由客户端请求生成的临时文件路径 /client_body_temp.
–http-proxy-
temp-path=…
proxy产生的临时文件路径 /proxy_temp.
–http-fastcgi-
temp-path=…
–http-uwsgi-
temp-path=…
–http-scgi-
temp-path=…
由HTTP,FastCGI, uWSGI和SCGI模块产生的临时文件路径 / fastcgi_temp,
/uwsgi_temp, and /scgi_temp.

依赖选项

依赖以库和二进制文件的形式出现。 现在,它们应该已经全部安装在您的系统上了。 但是,即使它们存在于您的系统上,也有可能出现配置脚本无法找到它们的情况。 原因可能有所不同,例如,如果它们安装在非标准目录中。
为了解决这些问题,您可以使用以下选项来指定依赖的路径(其他依赖相关选项已组合在一起):

编译选项 描述
–with-cc=… 指定C编译器的备用位置。
–with-cpp=… 指定C预处理器的备用位置。
–with-cc-opt=… 定义要传递到C编译器命令行的其他选项。
–with-ld-opt=… 定义要传递到C链接器命令行的其他选项。
–with-cpu-opt=… 在以下值中指定不同的目标处理器体系结构:pentium,pentiumpro,pentium3,pentium4,athlon,opteron,sparc32,sparc64和ppc64。
PCRE选项 描述
–without-pcre 禁用PCRE库的使用。 不建议使用此设置,因为它将删除对正则表达式的支持,从而禁用Rewrite模块。
–with-pcre 强制使用PCRE库。
–with-pcre=… 允许您指定PCRE库源代码的路径。
–with-pcre-opt=… 构建PCRE库的其他选项。
–with-pcre-jit=… 构建PCRE与JIT编译的支持。
MD5选项 描述
–with-md5=… 指定MD5库源的路径。
–with-md5-opt=… 用于构建MD5库的其他选项。
–with-md5-asm 为MD5库指定汇编源。
SHA1选项 描述
–with-sha1=… 指定SHA1库源的路径。
–with-sha1-opt=… 构建SHA1库的其他选项。
–with-sha1-asm 为SHA1库指定汇编器源。
zlib选项 描述
–with-zlib=… 指定zlib library源的路径。
–with-zlib-opt=… 用于构建zlib库的其他选项。
–with-zlib-asm=… 为zlib库指定汇编器源。
OpenSSL选项 描述
–with-openssl=… 指定OpenSSL库源的路径。
–with-openssl-opt=… 用于构建OpenSSL库的其他选项。

模块选项

在编译程序之前,需要指定要安装的模块。 有些是默认启用的,有些需要手动启用,如下表所示。

默认启用的模块

以下参数允许您禁用默认情况下启用的模块:
–without-http_charset_module
–without-http_gzip_module
–without-http_ssi_module
–without-http_userid_module
–without-http_access_module
–without-http_access_module
–without-http_autoindex_module
–without-http_geo_module
–without-http_map_module
–without-http_referer_module
–without-http_rewrite_module
–without-http_proxy_module
–without-http_fastcgi_module
–without-http_uwsgi_module
–without-http_scgi_module
–without-http_memcached_module
–without-http_limit_conn_module
–without-http_limit_req_module
–without-http_empty_gif_module
–without-http_browser_module
–without-http_upstream_ip_hash_module
–without-http_upstream_least_conn_module
–without-http_split_clients_module

默认禁用的模块

以下参数允许您启用默认禁用的模块:
–with-http_ssl_module
–with-http_realip_module
–with-http_addition_module
–with-http_xslt_module
–with-http_image_filter_module
–with-http_geoip_module
–with-http_sub_module
–with-http_dav_module
–with-http_flv_module
–with-http_mp4_module
–with-http_gzip_static_module
–with-http_random_index_module
–with-http_secure_link_module
–with-http_stub_status_module
–with-google_perftools_module
–with-http_degradation_module
–with-http_perl_module
–with-http_spdy_module
–with-http_gunzip_module
–with-http_auth_request_module

Nginx使用教程(一):下载并编译安装Nginx

安装依赖

我们已经选择下载程序源代码进行手动编译,而不是使用软件包管理器(如Yum,Aptitude或Yast)进行安装。 这个选择有两个原因。 首先,软件包可能不包含在您的Linux发行版的存储库中。 此外,提供下载和安装Nginx的存储库经常包含比较旧的版本。 更重要的是,你可能需要配置各种各样的编译选项。 由于选择了手动编译,你的系统需要一些工具和库进行编译安装。
根据您在编译时选择的模块,您可能需要不同的依赖。 下面介绍最常见的依赖,如GCC,PCRE,zlib和OpenSSL。

The GNU Compiler Collection

Nginx是用C编写的程序,因此您首先需要在系统上安装一个编译器工具,如GNU编译器集合(GCC)。 GCC可能已经安装在您的系统上,如果没有,必须先安装它。
首先,通过运行以下命令确保系统上尚未安装GCC:
[[email protected] ~]$ gcc
如果您得到以下输出,这意味着GCC已经正确安装在您的系统上了,您可以跳到下一部分:
gcc: no input files
如果收到以下消息,则必须继续安装编译器:
~bash: gcc: command not found
对于CentOS系统:

  1. [[email protected] ~]# yum groupinstall "Development Tools"

对于Ubuntu系统:

  1. [[email protected] ~]# apt-get install build-essentials

PCRE库

需要Perl兼容的正则表达式(PCRE)库来编译Nginx。 Nginx的Rewrite和HTTP核心模块使用PCRE作为其正则表达式的语法,在后面的章节中将会发现。 您将需要安装两个软件包:pcre和pcre-devel。 第一个包提供了编译版本的库,而第二个包提供了开发头文件和源文件来编译项目。
如果使用yum,运行以下命令安装:

  1. [[email protected] ~]# yum install pcre pcre-devel

如果使用apt-get,运行以下命令安装:

  1. [[email protected] ~]# apt-get install libpcre3 libpcre3-dev

zlib库

zlib库为开发人员提供了压缩算法。 在Nginx的各个模块中使用的gzip压缩功能需要zlib库。 同样,您可以使用您的包管理器来安装此组件,因为它默认存在于存储库中。 类似于PCRE,您将需要库及其源进行安装:zlib和zlib-devel。
如果使用yum,运行以下命令安装:

  1. [[email protected] ~]# yum install zlib zlib-devel

如果使用apt-get,运行以下命令安装:

  1. [[email protected] ~]# apt-get install zlib1g zlib1g-dev

OpenSSL

Nginx使用OpenSSL库来提供ssl连接。 因此,我们需要安装openssl库及其开发包。需要安装openssl和openssl-devel:
如果使用yum,运行以下命令安装:

  1. [[email protected] ~]# yum install openssl openssl-devel

如果使用apt-get,运行以下命令安装:

  1. [[email protected] ~]# apt-get install openssl openssl-dev

现在您已经安装了所有依赖条件,可以下载并编译Nginx源代码了。

下载Nginx

一旦您选择了要使用的版本,请打开http://www.nginx.org并找到您要下载的文件的URL。并使用wget下载该文件:

  1. [[email protected] ~]$ mkdir src && cd src
  2. [[email protected] src]$ wget http://nginx.org/download/nginx-1.10.2.tar.gz
  3. [[email protected] src]$ tar zxf nginx-1.10.2.tar.gz

您已成功下载并解压Nginx。 现在,下一步将是配置编译过程。

编译参数

http://devops.webres.wang/2016/10/nginx-configure-parameter/

管理Nginx进程

http://devops.webres.wang/2016/10/nginx-main-program-intro/

添加Nginx到系统服务

http://devops.webres.wang/2016/10/adding-nginx-as-a-system-service/