Nginx 学习纲要

一、Nginx 简介

Nginx是一个高性能的 HTTP 和反向代理 web 服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点开发的,第一个公开版本0.1.0发布于2004年10月4日。

其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。

其特点是占有内存少,并发能力强,事实上 nginx 的并发能力确实在同类型的网页服务器中表现较好,目前已经是最主要的 web 服务器软件。

nginx 有一个主进程和几个 worker 进程。主进程的作用是读取并执行配置,并维护 worker 进程。worker 进程是实际处理请求的进程。

nginx 采用事件驱动模型和基于系统的一些机制来高效分发请求给多个 worker 进程。worker 进程的数量可以在配置文件中配置。

二、Nginx 的特点

  • 模块化设计,较好的扩展性。
  • 高可靠性。
  • 支持热部署:不停机更新配置文件,升级版本,更换日志文件。
  • 低内存消耗:10000 个 keep-alive 连接模式下的非活动连接,仅需要 2.5M 内存。

三、Nginx 能用来做什么?

  • 静态资源的web服务器。
  • FastCGI(lnmp),uWSGI(python)等协议 :web 服务器,fastcgi 配合 php-fpm 实现 php web 服务。
  • http 协议反向代理服务器。
  • pop3/imap4协议反向代理服务器。

四、Nginx与web服务相关的功能

  • 虚拟主机(server)
  • 支持 keep-alive 和管道连接
  • 访问日志(支持基于日志缓冲提高其性能)
  • url rewirte 路径别名
  • 基于 IP 及用户的访问控制
  • 支持速率限制及并发数限制
  • 重新配置和在线升级而无须中断客户的工作进程
  • SSL 支持
  • gzip 支持
  • cache 支持

五、Nginx 如何安装?

  • 包安装:apt-get,yum,用于安装系统默认支持的版本。
  • 编译安装:用于安装指定的版本。

六、Nginx 配置文件详解

nginx 配置文件是分层配置的,从外到内,main > http > server > location

nginx 配置文件

6.1 段

6.1.1 main 段

nginx 在运行时与具体业务功能无关的一些参数,比如工作进程数,运行的身份等。

woker_processes 2

在配置文件的顶级main部分,worker角色的工作进程的个数,master进程是接收并分配请求给worker处理。

这个数值简单一点可以设置为cpu的核数, 也是 auto 值,如果开启了 ssl 和 gzip 更应该设置成与逻辑 CPU 数量一样甚至为 2倍,可以减少I/O操作, 如果nginx服务器还有其它服务,可以考虑适当减少。

worker_cpu_affinity

在高并发情况下,通过设置cpu粘性来降低由于多CPU核切换造成的寄存器等现场重建带来的性能损耗。如

worker_cpu_affinity 0001 0010 0100 1000; (四核)。
worker_rlimit_nofile 10240

可以限制为操作系统最大的限制 65535。

6.1.2 events 段

worker_connections 2048

每一个 worker 进程能并发处理(发起)的最大连接数(包含与客户端或后端被代理服务器间等所有连接数)。

nginx作为反向代理服务器,计算公式最大连接数 = worker_processes * worker_connections / 4,不能超过worker_rlimit_nofile。当 nginx 作为 http 服务器时,计算公式里面是除以 2。

use epoll

在Linux操作系统下,nginx默认使用epoll事件模型,得益于此,nginx在Linux操作系统下效率相当高。同时Nginx在OpenBSD或FreeBSD操作系统上采用类似于epoll的高效事件模型kqueue。

6.1.3 http 段

与提供http服务相关的一些配置参数。例如:是否使用keepalive啊,是否使用gzip进行压缩等。

sendfile on
开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,减少用户空间到内核空间的上下文切换。对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。

keepalive_timeout 65 : 长连接超时时间,单位是秒,这个参数很敏感,涉及浏览器的种类、后端服务器的超时设置、操作系统的设置,可以另外起一片文章了。长连接请求大量小文件的时候,可以减少重建连接的开销,但假如有大文件上传,65s内没上传完成会导致失败。如果设置时间过长,用户又多,长时间保持连接会占用大量资源。

send_timeout : 用于指定响应客户端的超时时间。这个超时仅限于两个连接活动之间的时间,如果超过这个时间,客户端没有任何活动,Nginx将会关闭连接。

client_max_body_size 10m
允许客户端请求的最大单文件字节数。如果有上传较大文件,请设置它的限制值

client_body_buffer_size 128k
缓冲区代理缓冲用户端请求的最大字节数
模块http_proxy:
这个模块实现的是nginx作为反向代理服务器的功能,包括缓存功能(另见文章)

proxy_connect_timeout 60
nginx跟后端服务器连接超时时间(代理连接超时)
proxy_read_timeout 60
连接成功后,与后端服务器两个成功的响应操作之间超时时间(代理接收超时)

proxy_buffer_size 4k
设置代理服务器(nginx)从后端realserver读取并保存用户头信息的缓冲区大小,默认与proxy_buffers大小相同,其实可以将这个指令值设的小一点

proxy_buffers 4 32k
proxy_buffers缓冲区,nginx针对单个连接缓存来自后端realserver的响应,网页平均在32k以下的话,这样设置

proxy_busy_buffers_size 64k
高负荷下缓冲大小(proxy_buffers*2)

proxy_max_temp_file_size
当 proxy_buffers 放不下后端服务器的响应内容时,会将一部分保存到硬盘的临时文件中,这个值用来设置最大临时文件大小,默认1024M,它与 proxy_cache 没有关系。大于这个值,将从upstream服务器传回。设置为0禁用。

proxy_temp_file_write_size 64k
当缓存被代理的服务器响应到临时文件时,这个选项限制每次写临时文件的大小。proxy_temp_path(可以在编译的时候)指定写到哪那个目录。

proxy_pass,proxy_redirect见 location 部分。

模块http_gzip:

gzip on : 开启gzip压缩输出,减少网络传输。
gzip_min_length 1k : 设置允许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。默认值是20。建议设置成大于1k的字节数,小于1k可能会越压越大。
gzip_buffers 4 16k : 设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。4 16k代表以16k为单位,安装原始数据大小以16k为单位的4倍申请内存。
gzip_http_version 1.0 : 用于识别 http 协议的版本,早期的浏览器不支持 Gzip 压缩,用户就会看到乱码,所以为了支持前期版本加上了这个选项,如果你用了 Nginx 的反向代理并期望也启用 Gzip 压缩的话,由于末端通信是 http/1.0,故请设置为 1.0。
gzip_comp_level 6 : gzip压缩比,1压缩比最小处理速度最快,9压缩比最大但处理速度最慢(传输快但比较消耗cpu)
gzip_types :匹配mime类型进行压缩,无论是否指定,”text/html”类型总是会被压缩的。
gzip_proxied any : Nginx作为反向代理的时候启用,决定开启或者关闭后端服务器返回的结果是否压缩,匹配的前提是后端服务器必须要返回包含”Via”的 header头。
gzip_vary on : 和http头有关系,会在响应头加个 Vary: Accept-Encoding ,可以让前端的缓存服务器缓存经过gzip压缩的页面,例如,用Squid缓存经过Nginx压缩的数据。。

    fastcgi_connect_timeout 3000s;
    fastcgi_send_timeout 6000s;
    fastcgi_read_timeout 6000s;
    fastcgi_buffer_size 128k;
    fastcgi_buffers 8 128k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_intercept_errors on;

    client_header_timeout 3000s;
    client_body_timeout 3000s;
    client_max_body_size    20m;
    client_body_buffer_size 256k;

6.1.4 server 段

典型的 server 段配置文件

server {
    # 监听 HTTP 协议默认的 [80] 端口。
    listen 80;
    # 绑定主机名 [example.com]。
    server_name example.com;
    # 服务器站点根目录 [/example.com/public]。
    root /example.com/public;

    # 添加几条有关安全的响应头;与 Google+ 的配置类似,详情参见文末。
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    # 站点默认页面;可指定多个,将顺序查找。
    # 例如,访问 http://example.com/ Nginx 将首先尝试「站点根目录/index.html」是否存在,不存在则继续尝试「站点根目录/index.htm」,以此类推...
    index index.html index.htm index.php;

    # 指定字符集为 UTF-8
    charset utf-8;

    # Laravel 默认重写规则;删除将导致 Laravel 路由失效且 Nginx 响应 404。
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # 关闭 [/favicon.ico] 和 [/robots.txt] 的访问日志。
    # 并且即使它们不存在,也不写入错误日志。
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    # 将 [404] 错误交给 [/index.php] 处理,表示由 Laravel 渲染美观的错误页面。
    error_page 404 /index.php;

    # URI 符合正则表达式 [\.php$] 的请求将进入此段配置
    location ~ \.php$ {
        # 配置 FastCGI 服务地址,可以为 IP:端口,也可以为 Unix socket。
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        # 配置 FastCGI 的主页为 index.php。
        fastcgi_index index.php;
        # 配置 FastCGI 参数 SCRIPT_FILENAME 为 $realpath_root$fastcgi_script_name。
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        # 引用更多默认的 FastCGI 参数。
        include fastcgi_params;
    }
    # 通俗地说,以上配置将所有 URI 以 .php 结尾的请求,全部交给 PHP-FPM 处理。

    # 除符合正则表达式 [/\.(?!well-known).*] 之外的 URI,全部拒绝访问
    # 也就是说,拒绝公开以 [.] 开头的目录,[.well-known] 除外
    location ~ /\.(?!well-known).* {
        deny all;
    }
}

6.1.5 location 段

6.2 重定向

6.3 邪恶的 if

其他

  • gzip
  • http code
  • try
  • access log
  • error log
  • proxy
  • ssl
  • map

七、Nginx 高级使用

openresty

  • access control
  • 复杂的重定向
  • 缓存管理

八、测试相关

8.1 搭建一个最小的测试单元

其实,当你的 nginx 跑起来之后,你访问 127.0.0.1 就可以看到一个 nginx 的默认页面了。

你看到这个页面,说明你的 nginx 服务已经正常在运行,默认的页面是 nginx 的默认 server 段在执行,如果感兴趣的话,可以了解下默认 server 的配置文件。

搭建自己的 web 站点,你需要做以下几件事情:

8.1.1 dns 解析:

这个 dns 解析可以是真实的域名增加 A 记录,也可以是修改自己的 hosts 表,比如:

127.0.0.1 abc.test # test 域名 chrome 会识别,其他后缀的测试域名,可能会有问题。

当做好域名解析之后,你就可以在 nginx 的 vhosts 目录下增加虚拟主机了。

8.1.2 设置站点目录:

遵照习惯,我们设定 web 的根目录为 /srv/www
在这个目录下,我们建立 abc.test 目录。
在 abc.test 目录下,我们新建一个 index.html 文件,敲入如下代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p> hello, world! </p>
</body>
</html>

在 abc.test 目录下,新建 phpinfo.php, 敲入如下代码:

<?php

echo phpinfo();

?>

8.1.3 增加虚拟主机:

server {
    listen       80;
    server_name  abc.test;
    index index.html index.php;
    root  /srv/www/abc.test;

    # logs
    error_log  /var/log/nginx/abc_error.log error;
    access_log /var/log/nginx/abc_access.log;

    # rewrite
    location / {
        try_files $uri $uri/ @rewrite;
    }

    # static cache
    location ~* .(js|css|png|jpg|gif|ico)$ {
        expires 7d;
    }


    if ( $fastcgi_script_name ~ ..*/.*php ) {
        return 403;
    }

    location @rewrite {
        rewrite ^(.*)$ /index.php$1;
    }

    location ~ \.php($|/) {
        fastcgi_pass unix:/var/run/php/php5.6-fpm.sock;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include  fastcgi.conf;
    }
}

8.1.4 重启 nginx,并访问 abc.test, 以查看效果。

  • 访问 abc.test
  • 访问 abc.test/index.html
  • 访问 abc.test/phpinfo.php

如果以上访问都正常,说明 nginx 环境配置正常, php 环境配置正常。

相关

添加新评论