Nginx看这一篇文章就够了!

2,627 阅读6分钟

1. Nginx进程模型

Nginx是Master-Worker进程模型。
Master进程:主进程,监视worker进程。
Worker进程:工作进程,做相应的工作。
可以通过配置文件进行配置worker进程数量,默认配置为1,如下图所示。

下图为Master与Worker进程的工作流程示意图。

2. Worker进程工作原理

2.1 Worker进程抢占机制

如下图所示,假设我们配置文件中,配置了三个worker进程,那么启动nginx时,matser会fork出三个worker进程,如果现在客户端发起一个请求,那么三个work进程会进行争锁(accept_mutex锁),谁抢到是谁的。

2.2 异步非阻塞特性

Nginx是异步非阻塞
在 Linux 下,Nginx 使用 epoll 的 I/O 多路复用模型,每个worker可以同时处理多个client请求
默认conf文件

events {
   # 默认使用epoll
   use epoll;
   # 每个worker允许连接的最大数
   worker_connections  1024;
}

3. nginx.conf配置详解

3.1 nginx.conf配置结构

3.2 nginx.conf核心配置

  1. 设置worker进程的用户,指的linux中的用户,会涉及到nginx操作目录或文件的一些权限,默认为nobody。

    若修改为root,修改后进入nginx下的sbin目录使用 ./nginx -s reload命令重启,发现如下worker进行用户由nobody变为root。

  2. worker进程工作数设置,一般来说CPU核数有几个,就设置几个,或者设置为N-1也行。

  3. nginx 日志级别debug | info | notice | warn | error | crit | alert | emerg ,错误级别从左到右越来越大

  4. 设置nginx进程 pid
    以上3及4在我们进行安装nginx的时候已经指定了具体的路径。 juejin.cn/post/690453…

  5. 设置工作模式

events {
# 默认使用epoll
use epoll;
# 每个worker允许连接的客户端最大连接数
worker_connections 10240;
}
  1. http 是指令块,针对http网络传输的一些指令配置
http {
}
  1. include 引入外部配置,提高可读性,避免单个配置文件过大
include mime.types;
  1. 设定日志格式, main 为定义的格式名称,如此 access_log 就可以直接使用这个变量了,同样access.log在我们安装nginx的时候已经指定了具体的路径,这里我们使用nginx的默认配置。

  2. sendfile 使用高效文件传输,提升传输性能。启用后才能使用tcp_nopush ,是指当数据表累积一定大小后才发送,提高了效率。

  3. keepalive_timeout 设置客户端与服务端请求的超时时间,保证客户端多次请 求的时候不会重复建立的连接,节约资源损耗,单位 s。

  4. gzip on 开启html css js等文件的压缩,体积变小,提高传输效率,但是也会消耗服务器性能。

  5. server模块-虚拟主机,可配置多个

补充:
进入sbin目录下,使用命令 ./nginx -t可以检查配置文件正确性。
总结图

4. nginx.pid打开失败及失效的解决方案

1、打开失败 2、无效的PID

5. Nginx常用命令介绍

    nginx -s quit       优雅停止nginx,有连接时会等连接请求完成再杀死worker进程  

    nginx -s reload     优雅重启,并重新载入配置文件nginx.conf

    nginx -s reopen     重新打开日志文件,一般用于切割日志

    nginx -v            查看版本  
    
    nginx -V            详细版本信息,包括编译参数 

    nginx -t            检查nginx的配置文件

    nginx -h            查看帮助信息

    nginx  -c filename  指定配置文件

6. Nginx日志切割

6.1 手动日志切割

现有的日志都存在了/var/log/nginx/ 目录下,这在我们安装的时候已经指定了相应的位置,包括两个日志 /var/log/nginx/error.log /var/log/nginx/access.log ,但是随着时间的推移,日志文件会越来越多,体积会越来越大,不便于运维人员查看,所以我们可以通过把这个大的日志切割成多个不同的小文件作为日志,切割规则可以以天为单位,如果每天有几百个G或者几T的文件的话,则可以按半天或小时进行切割。
具体步骤如下:
1、创建一个shell可执行文件:cut_my_log.sh,内容如下: 注意以下脚本是按照分钟进行切割的,在工作中可以按照实际场景进行修改, 按天切割:RECORD_TIME=$(date -d "yesterday" +%Y-%m-%d)

#!/bin/bash
LOG_PATH="/var/log/nginx"
RECORD_TIME=$(date -d "yesterday" +%Y-%m-%d+%H:%M)
PID=/var/run/nginx/nginx.pid
mv ${LOG_PATH}/access.log ${LOG_PATH}/access.${RECORD_TIME}.log
mv ${LOG_PATH}/error.log ${LOG_PATH}/error.${RECORD_TIME}.log
# 向nginx主进程发送信号,用于重新打开日志
kill -USR1 `cat $PID`                         

2、为cut_my_log.sh添加可执行的权限

chmod +x cut_my_log.sh

3、测试日志切割后的结果

./cut_my_log.sh

6.2 定时日志切割

1、安装定时任务

yum install crontabs

2、crontab -e 编辑并且添加一行新的任务

*/1 * * * * /usr/local/nginx/sbin/cut_my_log.sh

3、重启定时任务

service crond restart

总结

7. 使用Nginx做静态资源服务器

7.1 HTML,CSS,JS等路由

在nginx中新增虚拟主机配置,即server配置,这里可以直接在nginx做相关配置,也可以使用新建一个配置用include命令导入,比如这里新建一个imooc.conf,在nginx.conf中导入外挂的conf配置。
nginx.conf配置如下:

imooc.conf配置如下:

这里的location是路由规则,相应的配置意思是,如果我们访问/目录,则会路由到服务器下的/home/foodie-shop/目录下,首页是index.html, 也就是如果我们访问服务器ip:90端口,就会路由到foodie-shop项目下的index.html上。

7.2 图片、音频等路由

对于其他非html,js,css等资源,也可以部署在nginx上,这里我们做如下示范。我们依旧以90端口为路由,在同一个server里面加一个location, 但是要注意这里不能再是/ 因为会与上面的 location / 重复, 这里的包括图片,音频视频等资源我们都放在/home/imooc文件夹下,在配置location时,我们做如下配置。

这时访问/imooc会自动拼接 /home,最后得到正确的路径。 浏览器访问ip+90+/imooc/+资源名称即可访问。
当然我们可以进一步采用别名的形式。如下:

这里访问/static就会从/home/imooc下寻找资源。

7.3 Location的匹配规则简介

1、空格:默认匹配,普通匹配

location / {
	root /home;
}

2、= : 精准匹配

location = /imooc/img/face1.png {
     root /home;
}

3、~* : 匹配正则表达式,不区分大小写

# 符合图片的显示
location ~* \.(GIF|jpg|png|jpeg) {
 	root /home;
}

4、~ : 匹配正则表达式,区分大小写

# GIF必须大写才能匹配到,只要访问/home目录下的静态资源,就能路由到相应的文件,
# 比如home目录下有一个static文件夹,里面放着图片,那么访问ip+端口/static/1.jpg就可以访问到
location ~ \.(GIF|jpg|png|jpeg) {
 	root /home;
}

5、^~ : 以某个字符路径开头

// 只能访问/imooc/img下的资源
location ^~ /imooc/img {
 	root /home;
}

8. 使用Gzip压缩提升请求效率

   # 开启gzip压缩,目的:提高传输效率,节约带宽
    gzip  on;
   # 限制最小压缩,小于1字节文件不会压缩
    gzip_min_length 1;
   # 定义压缩的级别(压缩比,文件越大,压缩越多,但是cpu使用会越多)
    gzip_comp_level 3;
   # 定义压缩文件的类型
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png applicatio
n/json;

9. Nginx跨域配置

注意:nginx跨域和以前讲的springboot跨越配置都可以解决跨域问题,只需配置一个就行。 juejin.cn/post/688292…

跨域配置:

    #允许跨域请求的域,*代表所有
    add_header 'Access-Control-Allow-Origin' *;
    #允许带上cookie请求
    add_header 'Access-Control-Allow-Credentials' 'true';
    #允许请求的方法,比如GET/POST/PUT/DELETE
    add_header 'Access-Control-Allow-Headers' *;
    #允许请求的header
    add_header 'Access-Control-Allow-Methods' *; 

详细配置如下:

#进程, 可更具cpu数量调整
worker_processes  1;
events {
    #连接数
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    #连接超时时间,服务器会在这个时间过后关闭连接。
    keepalive_timeout  10;

    # gizp压缩
    gzip  on;

    # 直接请求nginx也是会报跨域错误的这里设置允许跨域
    # 如果代理地址已经允许跨域则不需要这些, 否则报错(虽然这样nginx跨域就没意义了)
    
    #允许跨域请求的域,*代表所有
    add_header 'Access-Control-Allow-Origin' *;
    #允许带上cookie请求
    add_header 'Access-Control-Allow-Credentials' 'true';
    #允许请求的方法,比如GET/POST/PUT/DELETE
    add_header 'Access-Control-Allow-Headers' *;
    #允许请求的header
    add_header 'Access-Control-Allow-Methods' *; 
    
    # srever模块配置是http模块中的一个子模块,用来定义一个虚拟访问主机
    server {
        listen       80;
        server_name  localhost;
        
        # 根路径指到index.html
        location / {
            root   html;
            index  index.html index.htm;
        }

        # 重定向错误页面到/50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

}

10. Nginx中静态资源防盗链配置

防止其他站点跨域后盗取图片链接。
在nginx.conf中添加如下配置。

#对源站点验证
valid_referers *.chen.com;
#非法引入会进入下方判断
if ($invalid_referer) { 
    return 404;
}

11. Nginx做反向代理

示例如下:

upstream tomcats {
   server 123.89.195.81:8080;
   server 123.89.195.82:8080;
   server 123.89.195.83:8080;
}

server {
        listen       80;
        server_name  123.89.195.79;
        location / {
            proxy_pass http://tomcats;
        }
}

此时,访问nginx所在ip+80端口号,就会被路由到后面的三台tomcat服务器上。

12. Nginx负载均衡策略

  • 轮询(默认)
    根据Nginx配置文件中的顺序,依次把客户端的Web请求分发到不同的后端服务器。
#默认配置就是轮询策略
upstream server_group {
   server backend1.example.com;
   server backend2.example.com;
}
  • 权重
upstream server_group {
    server backend1.example.com weight=5;
    #默认为不配置权重为1
    server backend2.example.com;
}
  • ip_hash
hash(ip)%node_counts = index

ip_hash 可以保证用户访问可以请求到上游服务中的固定的服务器,前提是用户ip没有发生更改。
使用ip_hash的注意点:
不能把后台服务器直接移除,只能标记down 。

upstream tomcats {
    ip_hash;
    server 192.168.1.173:8080;
    server 192.168.1.174:8080 down;
    server 192.168.1.175:8080;
}
  • url_hash 根据每次请求的url地址,hash后访问到固定的服务器节点。
upstream tomcats {
    # url hash
    hash $request_uri;
    server 192.168.1.173:8080;
    server 192.168.1.174:8080;
    server 192.168.1.175:8080;
}
server {
    listen 80;
    server_name www.tomcats.com;
    location / {
    proxy_pass http://tomcats;
}
  • least_conn 最少连接数请求,请求会分配到连接数最少的server上。
upstream tomcats {
    # 最少连接数
    least_conn
    server 192.168.1.173:8080;
    server 192.168.1.174:8080;
    server 192.168.1.175:8080;
}
server {
    listen 80;
    server_name www.tomcats.com;
    location / {
    proxy_pass http://tomcats;
}

13. upstream指令参数记录

  • max_conns 节点的最大连接数
upstream tomcats {
    server 192.168.1.173:8080 max_conns=2;
}
  • slow_start 缓慢启动时间。使得服务器慢慢地加入集群中,该参数不能使用在hash和random load balancing中,如果在upstream中只有一台server,则该参数失效。
upstream tomcats {
    server 192.168.1.173:8080 weight=6 slow_start=60s;
    server 192.168.1.174:8080 weight=2;
    server 192.168.1.175:8080 weight=2;
}
  • down 节点下线,表示当前的server暂时不参与负载,服务器节点不可用
upstream tomcats {
    server 192.168.1.173:8080 down;
    server 192.168.1.174:8080 weight=1;
    server 192.168.1.175:8080 weight=1;
}
  • backup 备用节点,只有等其他服务器都宕机后,它才会上线,加入到集群中,backup参数不能使用在hash和random load balancing中。
upstream tomcats {
    server 192.168.1.173:8080 backup;
    server 192.168.1.174:8080 weight=1;
    server 192.168.1.175:8080 weight=1;
}
  • max_fails 允许的最大失败数
  • fail_timeout 超过最大失败数后的等待时间
max_fails=2 fail_timeout=15s

代表在15秒内请求某一server失败达到2次后,则认为该server已经挂了或者宕机了,随后再过15秒,这15秒内不会有新的请求到达刚刚挂掉的节点上,而是会打到运作的server,15秒后会再有新请求尝试连接挂掉的server,如果还是失败,重复上一过程,直到恢复。

14. 使用keepalive配置提高性能

keepalive : 设置长连接处理的数量
proxy_http_version :设置长连接http版本为1.1
proxy_set_header :清除connection header 信息

具体案例:
upstream tomcats {
    server 192.168.1.190:8080;
    keepalive 32;
}
  server {
      listen 80;
      server_name www.tomcats.com;
      location / {
      proxy_pass http://tomcats;
      proxy_http_version 1.1;
      proxy_set_header Connection "";
  }

15. 案例

这里记录下,在一台阿里云服务器上,部署nginx,静态资源及后台代码都部署在这台服务器上,后台代码部署在了tomcat上。

upstream tomcats {
        server 121.**.195.81:8088;

}
server {
          listen       81;
          server_name  yun.j*-**-***.cn;
          location / {
              proxy_pass http://tomcats;
          }
        }            
server {
            listen       81;
            server_name  shop.j*-**-***.cn;、
            location / {
                root /home/website/foodie-shop;
                index index.html;
            }
        }
server {
            listen       81;
            server_name  center.j*-**-***.cn;
            location / {
                root /home/website/foodie-center;
                index index.html;
            }
        }

一台服务器对应了三个不同的三级域名,这里端口设置为81,是因为域名还没备案,默认不能访问80端口,此时,我们访问不同的域名就会打到不同的服务上,nginx在这里对后台tomcat部署的接口服务实现了反向代理,并且实现了动静分离。