一、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
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 环境配置正常。