一、前言

Nginx 是一个高性能的 Web 和反向代理服务器, 它具有有很多非常优越的特性。

# 1.1 作为 Web 服务器

相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率。能够支持高达 50,000 个并发连接数的响应,其使用 epoll and kqueue 作为开发模型。

# 1.2 作为负载均衡服务器

Nginx 既可以在内部直接支持 Rails 和 PHP,也可以支持作为 HTTP代理服务器 对外进行服务。Nginx 用 C 编写, 不论是系统资源开销还是 CPU 使用效率都比 Perlbal 要好的多。

Nginx 安装非常的简单,配置文件 非常简洁(还能够支持perl语法),Bugs 非常少的服务器: Nginx 启动特别容易,并且几乎可以做到 7*24 不间断运行,即使运行数个月也不需要重新启动。

二、安装

# 2.1 添加仓库资源

  1. vim /etc/yum.repos.d/nginx.repo

添加如下内容:

  1. [nginx]
  2. name=nginx repo
  3. baseurl=http://nginx.org/packages/centos/7/$basearch/
  4. gpgcheck=0
  5. enabled=1

注意 baseurl=http://nginx.org/packages/OS/OSRELEASE/$basearch/ 中 OS/OSRELEASE 表示系统和版本号,根据自己情况而定。

# 2.2 查看 yum 资源列表

  1. yum list | grep nginx

# 2.3 安装

  1. yum install nginx

# 2.4 查看版本

  1. nginx -v # 使用 -V 可以查看 nginx 安装时依赖的模块

# 2.5 常用命令

  1. # 启动 nginx 服务
  2. nginx
  3. # 重启 nginx 服务
  4. nginx -s reload
  5. # 关闭 nginx 服务
  6. nginx -s quit
  7. # 测试 nginx.conf 配置文件合法性
  8. nginx -t

# 2.6 信号量

  1. # 重新加载配置文件
  2. kill HUP `cat /var/run/nginx.pid`
  3. # 重读日志文件
  4. kill USR1 `cat /var/run/nginx.pid`

下图为启动 nginx 服务的默认首页:

三、目录/文件介绍

# 3.1 目录介绍

日志相关

  1. /etc/logrotate.d/nginx # Nginx 日志轮转,用于 logrotate 服务的日志切割
  2. /var/log/nginx # 存放请求日志和错误日志

服务配置相关

  1. /etc/nginx/nginx.conf # 主配置文件
  2. /etc/nginx/conf.d/default.conf # 默认加载配置文件

编码相关

  1. /etc/nginx/koi-utf
  2. /etc/nginx/koi-win
  3. /etc/nginx/win-utf

请求类型相关

  1. /etc/nginx/mime.types # 设置 http 协议的 Content-Type 与扩展名对应关系

守护进程相关

  1. /usr/lib/systemd/system/nginx-debug.service
  2. /usr/lib/systemd/system/nginx.service
  3. /etc/sysconfig/nginx
  4. /etc/sysconfig/nginx-debug

模块相关

  1. /usr/lib64/nginx/modules
  2. /etc/nginx/modules

命令相关

  1. /usr/sbin/nginx
  2. /usr/sbin/nginx-debug

帮助文档

  1. /usr/share/doc/nginx-1.12.1

缓存相关

  1. /var/cache/nginx

# 3.2 配置文件介绍

以下是主配置文件内容(/etc/nginx/nginx.conf 和 /etc/nginx/conf.d/default.conf),下文介绍的内容基本上都是在配置文件中进行配置。

其中,/etc/nginx/nginx.conf 引用了 /etc/nginx/conf.d/default.conf 内容。

  1. #运行用户
  2. user nginx;
  3. #启动进程,通常设置成和cpu的数量相等
  4. worker_processes 1;
  5. #全局错误日志及PID文件
  6. error_log /var/log/nginx/error.log warn;
  7. pid /var/run/nginx.pid;
  8. #工作模式及连接数上限
  9. events {
  10. #epoll是多路复用IO(I/O Multiplexing)中的一种方式,
  11. #仅用于linux2.6以上内核,可以大大提高nginx的性能
  12. use epoll;
  13. #单个后台worker process进程的最大并发链接数
  14. worker_connections 1024;
  15. }
  16. http {
  17. #设定mime类型,类型由mime.type文件定义
  18. include /etc/nginx/mime.types;
  19. default_type application/octet-stream;
  20. #设定日志格式
  21. log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  22. '$status $body_bytes_sent "$http_referer" '
  23. '"$http_user_agent" "$http_x_forwarded_for"';
  24. access_log /var/log/nginx/access.log main;
  25. #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
  26. #对于普通应用,必须设为 on,
  27. #如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
  28. #以平衡磁盘与网络I/O处理速度,降低系统的uptime.
  29. sendfile on;
  30. #tcp_nopush on;
  31. #连接超时时间
  32. keepalive_timeout 65;
  33. tcp_nodelay on;
  34. #开启gzip压缩
  35. gzip on;
  36. gzip_disable "MSIE [1-6].";
  37. #设定请求缓冲
  38. client_header_buffer_size 128k;
  39. large_client_header_buffers 4 128k;
  40. #设定虚拟主机配置
  41. server {
  42. #侦听80端口
  43. listen 80;
  44. #定义使用 www.extlight.com访问
  45. server_name www.extlight.com;
  46. #设定本虚拟主机的访问日志
  47. access_log logs/nginx.access.log main;
  48. #默认请求
  49. location / {
  50. #定义服务器的默认网站根目录位置
  51. root /usr/share/nginx/html;
  52. #定义首页索引文件的名称
  53. index index.html index.htm;
  54. }
  55. # 定义错误提示页面
  56. error_page 500 502 503 504 /50x.html;
  57. location = /50x.html {
  58. root /usr/share/nginx/html;
  59. }
  60. }
  61. }

四、location 讲解

location 用于匹配客户端发送的 url ,从而定位请求资源。

匹配方式大致分成 3 类:

  1. location = xxx {} # 精准匹配
  2. location pattern {} # 一般匹配
  3. location ~ pattern {} # 正则表达式匹配

# 4.1 案例分析

假设 Nginx 配置文件中有如下配置:

  1. location = / {
  2. [ 配置 A ]
  3. }
  4. location / {
  5. [ 配置 B ]
  6. }
  7. location /documents/ {
  8. [ 配置 C ]
  9. }
  10. location ^~ /images/ {
  11. [ 配置 D ]
  12. }
  13. location ~* \.(gif|jpg|jpeg)$ {
  14. [ 配置 E ]
  15. }

当请求 http://192.168.2.25/ 时,会定位到配置 A;

当请求 http://192.168.2.25/index.html 时,会定位到配置 B;

当请求 http://192.168.2.25/documents/document.html 时,会定位到配置 C;

当请求 http://192.168.2.25/images/1.gif 时,会定位到配置 D;

当请求 http://192.168.2.25/documents/1.jpg 时,会定位到配置 E。

五、rewrite 重写

使用 Nginx 提供的全局变量或自己设置的变量,结合正则表达式和标志位实现 url 重写以及重定向。

rewrite 使用范围:在 server、location 和 if 中。

rewrite 与 location 的区别:rewrite 是在同一域名内更改获取资源的路径,而 location 是对一类路径做控制访问或反向代理。

# 5.1 rewrite 语法

  1. rewrite regex replacement [flag]

语法说明:

  1. regex:正则表达式
  2. replacement :重定向位置
  3. flag:标志位
  4. last : 相当于Apache的[L]标记,表示完成rewrite
  5. break : 停止执行当前虚拟主机的后续rewrite指令集
  6. redirect : 返回302临时重定向,地址栏会显示跳转后的地址
  7. permanent : 返回301永久重定向,地址栏会显示跳转后的地址

# 5.2 if 语法

如果在 if 中执行 rewrite 操作,需要了解如下判断规则:

  1. if(condition){...}

判断规则:

  1. 当表达式只是一个变量时,如果值为空或任何以 0 开头的字符串都会当做 false
  2. 直接比较变量和内容时,使用 = 或 !=
  3. ~ 正则表达式匹配,~*不区分大小写的匹配,!~ 区分大小写的不匹配
  4. -f 和 !-f 用来判断是否存在文件
  5. -d 和 !-d 用来判断是否存在目录
  6. -e 和 !-e 用来判断是否存在文件或目录
  7. -x 和 !-x 用来判断文件是否可执行

# 5.3 案例介绍

  1. if ($http_user_agent ~ MSIE) {
  2. rewrite ^(.*)$ /msie/$1 break; # 如果UA包含"MSIE",rewrite请求到/msie/目录下
  3. }
  4. if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
  5. set $id $1; # 如果cookie匹配正则,设置变量$id等于正则引用部分
  6. }
  7. if ($request_method = POST) {
  8. return 405; # 如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302
  9. }
  10. if ($slow) {
  11. limit_rate 10k; # 限速,$slow可以通过 set 指令设置
  12. }
  13. if (!-f $request_filename){
  14. break;
  15. proxy_pass http://127.0.0.1; # 如果请求的文件名不存在,则反向代理到 localhost 。这里的break也是停止rewrite检查
  16. }
  17. if ($args ~ post=140){
  18. rewrite ^ http://example.com/ permanent; # 如果query string中包含"post=140",永久重定向到 example.com
  19. }

常用变量如下:

  1. $args # 这个变量等于请求行中的参数,同 $query_string
  2. $content_length # 请求头中的 Content-length 字段。
  3. $content_type # 请求头中的 Content-Type 字段。
  4. $document_root # 当前请求在 root 指令中指定的值。
  5. $host # 请求主机头字段,否则为服务器名称。
  6. $http_user_agent # 客户端 agent 信息
  7. $http_cookie # 客户端 cookie 信息
  8. $limit_rate # 这个变量可以限制连接速率。
  9. $request_method # 客户端请求的动作,通常为 GET 或 POST。
  10. $remote_addr # 客户端的IP地址。
  11. $remote_port # 客户端的端口。
  12. $remote_user # 已经经过 Auth Basic Module 验证的用户名。
  13. $request_filename # 当前请求的文件路径,由 root 或 alias 指令与 URI 请求生成。
  14. $scheme # HTTP 方法(如http,https)。
  15. $server_protocol # 请求使用的协议,通常是 HTTP/1.0 或 HTTP/1.1。
  16. $server_addr # 服务器地址,在完成一次系统调用后可以确定这个值。
  17. $server_name # 服务器名称。
  18. $server_port # 请求到达服务器的端口号。
  19. $request_uri # 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
  20. $uri # 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
  21. $document_uri # 与 $uri 相同。

六、访问控制

依赖 ngx_http_access_module 模块。

在 /etc/nginx/nginx.conf 文件末尾中,有一行 include /etc/nginx/conf.d/*.conf; 设置,表示该文件会引入 /etc/nginx/conf.d/ 下的 .conf 结尾的文件。

在 /etc/nginx/conf.d/ 下有一个 default.conf 文件,我们修改其部分内容:

  1. server_name access;
  2. location / {
  3. root /usr/share/nginx/html;
  4. deny 192.168.2.2;
  5. allow all;
  6. index index.html index.htm;
  7. }

在 location 中配置了 deny 和 allow,表示除了 192.168.2.2 的 ip,允许其他 ip 访问 nginx。其中,192.168.2.2 为宿主机 ip 地址。

七、文件压缩

依赖 ngx_http_gzip_module 模块。

  1. location ~* \.(jpg|gif|png|txt|xml)$ {
  2. gzip on;
  3. gzip_http_version 1.1;
  4. gzip_comp_level 6;
  5. gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif image/png
  6. ;
  7. root /opt/test;
  8. }

压缩 /opt/test 目录下的资源。可通过浏览器调试工具查看请求返回加载资源文件的大小。

常用配置说明:

  1. gzip on|off; # 是否开启 gzip,默认值为 off。
  2. gzip_buffers 32 4k|16 8k; # 缓冲,压缩在内存中缓存分成几块,每块大小
  3. gzip_comp_level [1~9]; # 指定 gzip 压缩程度。推荐使用 6。压缩级别越高,越浪费 cpu 计算资源
  4. gzip_disable MSIE [4-6]\.; # 响应 IE4~IE6 浏览器的请求时,不使用 gzip。
  5. gzip_min_length 200; # 大于 200 字节就进行文件压缩
  6. gzip_http_version 1.0|1.1; # 使用 http/1.1 协议才进行文件压缩,默认值为 1.1。
  7. gzip_types mime-type ...; # 设置需要压缩文件的类型,如:text/plain text/css
  8. gzip_vary on|off; # 是否传输 gzip 压缩标识,默认值为 off。

八、静态资源缓存

依赖 ngx_http_headers_module 模块。

  1. location ~* \.(jpg|gif|png|txt|xml)$ {
  2. expires 24h;
  3. root /opt/test;
  4. }

向响应头中添加 Cache-Control,设置缓存时间为 24 小时。

语法:

  1. expires 60s; # 60 秒
  2. expires 10m; # 10 分钟
  3. expires 2h; # 2 小时
  4. expires 30d; # 30 天

九、跨域

依赖 ngx_http_headers_module 模块。

  1. location ~* \.(jpg|gif|png|txt|xml)$ {
  2. gzip on;
  3. gzip_http_version 1.1;
  4. gzip_comp_level 2;
  5. gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif image/png
  6. ;
  7. # 设置允许跨域请求
  8. add_header 'Access-Control-Allow-Origin' '*';
  9. add_header 'Access-Control-Allow-Credentials' 'true';
  10. add_header 'Access-Control-Allow-Methods' 'GET, POST,PUT,DELETE, OPTIONS';
  11. root /opt/test;
  12. }

十、防盗链

依赖 ngx_http_referer_module 模块。

  1. location ~* \.(jpg|gif|png|txt|xml)$ {
  2. valid_referers none blocked 192.168.2.25;
  3. if ($invalid_referer) {
  4. return 403;
  5. }
  6. }

只允许 192.168.2.25 的服务器请求资源。

十一、反向代理

依赖 ngx_http_proxy_module 模块。

  1. listen 80;
  2. location / {
  3. proxy_pass http://192.168.2.25:8080;
  4. proxy_set_header Host $http_host;
  5. proxy_set_header X-Real-IP $remote_addr;
  6. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  7. proxy_connect_timeout 30;
  8. proxy_send_timeout 30;
  9. proxy_read_timeout 30;
  10. proxy_buffering on;
  11. proxy_buffer_size 32k;
  12. proxy_buffers 4 128k;
  13. proxy_busy_buffers_size 256k;
  14. proxy_temp_file_write_size 128k;
  15. proxy_max_temp_file_size 256k;
  16. }

8080 端口为 tomcat 启动端口。浏览器访问 http://192.168.2.25 后会看到 tomcat 首页。

常用配置说明:

  1. proxy_pass url; # 被代理服务器地址。如:http://127.0.0.1:8080。
  2. proxy_set_header xx xx; # 更改 Nginx 服务器接收的客户端请求的头信息,然后将新请求头发给后端服务器。
  3. proxy_connect_timeout 30; # Nginx 与后端服务器建立连接超时时间
  4. proxy_send_timeout 30; # Nginx 向后端服务器发送 write 请求后,等待响应的超时时间。
  5. proxy_read_timeout 30; # Nginx 向后端服务器发送 read 请求后,等待响应的超时时间。
  6. proxy_buffering on|off; # 是否开启 Proxy Buffer
  7. proxy_buffer_size 32k; # 缓冲区大小
  8. proxy_buffers 4 128k; # 缓冲区数量和大小
  9. proxy_busy_buffers_size 256k; # 设置系统很忙时可以使用的 proxy_buffers的大小,官方推荐位 proxy_buffers * 2
  10. proxy_temp_file_write_size 128k; # 当后端服务器的响应过大时 Nginx 一次性写入临时文件的数据大小
  11. proxy_max_temp_file_size 256k; # 每个请求能用磁盘上临时文件最大大小

十二、负载均衡

依赖 ngx_http_upstream_module 模块。

  1. upstream mytomcat {
  2. server 192.168.2.25:8081;
  3. server 192.168.2.25:8082;
  4. server 192.168.2.25:8083;
  5. }
  6. server {
  7. location / {
  8. proxy_pass http://mytomcat;
  9. }
  10. }

启动 3 个 tomcat 服务。浏览器访问 http://192.168.2.25,nginx 默认通过轮询方式将请求转发给 3 个 tomcat 服务。

均衡策略补充:

策略一:轮询(默认),即上述配置。

策略二:最少链接,客户端请求会被转发到连接数最少的服务器上。

  1. upstream mytomcat {
  2. least_conn;
  3. server 192.168.2.25:8081;
  4. server 192.168.2.25:8082;
  5. server 192.168.2.25:8083;
  6. }

策略三:weight 权重,指定轮询几率,权重越大,请求转发到的几率越大。

  1. upstream mytomcat {
  2. server 192.168.2.25:8081 weight=3;
  3. server 192.168.2.25:8082 weight=2;
  4. server 192.168.2.25:8083;
  5. }

策略四:ip_hash,每个请求按访问 ip 的 hash 值分配。

  1. upstream mytomcat {
  2. ip_hash;
  3. server 192.168.2.25:8081;
  4. server 192.168.2.25:8082;
  5. server 192.168.2.25:8083;
  6. }

策略五:url_hash(第三方),需要安装 url_hash 模块,按访问 url 的 hash 结果来分配请求。

  1. upstream mytomcat {
  2. hash $request_uri;
  3. server 192.168.2.25:8081;
  4. server 192.168.2.25:8082;
  5. server 192.168.2.25:8083;
  6. }

策略六:fair(第三方),需要安装 nginx-upstream-fair 模块,按后端服务器的响应时间来分配请求,响应时间短的优先分配。

  1. upstream mytomcat {
  2. fair;
  3. server 192.168.2.25:8081;
  4. server 192.168.2.25:8082;
  5. server 192.168.2.25:8083;
  6. }

十三、代理缓存

依赖 ngx_http_proxy_module 模块。

  1. upstream mytomcat {
  2. server 192.168.2.25:8081;
  3. server 192.168.2.25:8082;
  4. server 192.168.2.25:8083;
  5. }
  6. proxy_cache_path /usr/proxy/cache level=1:2 keys_zone=light_cache:10m max_size=10g inactive=60m use_temp_path=off;
  7. server {
  8. location / {
  9. proxy_pass http://mytomcat;
  10. proxy_buffering on;
  11. proxy_cache light_cache;
  12. proxy_cache_valid 200 304 12h;
  13. proxy_cache_valid any 10m;
  14. proxy_cache_key $host$uri$is_args$args;
  15. add_header Nginx-Cache "$upstream_cache_status";
  16. }
  17. }

Proxy Cache 机制依赖于 Proxy Buffer 机制,因此,只有当 Proxy Buffer 开启时,Proxy Cache 的配置才发挥作用。

常用配置说明:

  1. proxy_cache_path xx xx .. # 设置 Nginx 服务器存储缓存数据路径以及缓存索引相关内容
  2. proxy_cache name|off; # name 表示存放缓存索引的内存区域名称,off 表示关闭 Proxy Cache
  3. proxy_cache_valid 200 304 12h; # 针对不同的 HTTP 响应状态设置不同的缓存时间
  4. proxy_cache_key xxx; # 设置 Nginx 服务器在内存中为缓存数据建立索引时使用的关键字

十四、配置 HTTPS

依赖 ngx_http_ssl_module 模块。

需要开发者购买 CA 证书。

  1. server {
  2. listen 443;
  3. ssl on;
  4. ssl_certificate /etc/nginx/cert/xxx.pem;
  5. ssl_certificate_key /etc/nginx/cert/xxx.key;
  6. ssl_session_cache shared:SSL:10m;
  7. ssl_session_timeout 10m;
  8. }

十五、参考资料