WHCSRL 技术网

nginx详解

Nginx详解

Nginx介绍

nginx是一个开源且高性能的HTTP服务器,可靠的HTTP中间件,代理服务。

Nginx应用场景(可以做什么)

HTTP服务

虚拟目录

反向代理

负载均衡

动静分离

资源缓存

Nginx 模型

单 nginx 官方统计并发量最高 5W

单 apache 官方统计并发量最高 2W

nginx 这得益于 I/O 模型

I/O 介绍

输入 输出 写 读

就好似磁盘 你往里放数据,是 I (输入)

你看磁盘里的电影就是 O (输出)

每次I/O,都要经由两个阶段

第一步:将数据从磁盘文件先加载至内核空间(缓冲区),等待数据准备完成,时间较长。

第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短。

image-20210925151810047

认识个单词 kernel 内核

同步

调用者等待被调用者返回消息,才能继续执行

例如: 老板布置你任务,一直向你询问 有没有完成,完成了老板做下一件事,这种通信机制成为同步。

异步

被调用者通知状态,通知或者回调机制主动通知被调用者的运行状态

例如:老板分配你任务,任务进度状态你会向老板汇报,老板做自己的事情,不会向你问询结果。

同步/异步 关注是被调用者消息通信机制

同步和异步的区别:
     同步:被调用者不会返回任务的状态,需要调用者不停的询问
     异步:被调用者会向调用者返回任务的状态,不需要调用者不停的询问
  • 1
  • 2
  • 3
  • 4
  • 5
阻塞 Blocking

指 IO 操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起

例如:手洗衣服,没戏完之前你都是被占用的状态。

非阻塞 nobloking

指 IO 操作被调用后立刻返回一个用户状态,无需等IO操作彻底完成,最终的调用结果返回之前,调用者不会被挂起

例如:全自动洗衣机,不需要占用你时间,洗完会通知你,在期间你没有因为洗衣服被占用时间。

阻塞/非阻塞:关注调用者在等待结果返回之前的状态
  • 1
IO模型
同步阻塞型

即用户进程通过系统调用拿资源,因不确定是否拿到数据,所以会一次次的询问结果,这个过程是同步。

将数据从磁盘拷贝到内核空间,再将内核中的数据复制到应用的用户空间,这个过程进程不能做其他事,即阻塞。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HqtASmIb-1634528106847)(C:UsersyycAppDataRoamingTypora ypora-user-imagesimage-20210925163939591.png)]

同步非阻塞

即用户进程通过系统调用拿资源,因不确定是否拿到数据,所以会一次次的询问结果,这个过程是同步。

将数据从磁盘拷贝到内核空间,再将内核中的数据复制到应用的用户空间,这个过程进程可以做其他事,即非阻塞。

这个较同步阻塞没有改善,看似非阻塞,进程可以干其他事,但由于是同步,进程依旧在不断问询结果,反而更消耗资源。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ay3qKRd2-1634528106849)(C:UsersyycAppDataRoamingTypora ypora-user-imagesimage-20210925164015624.png)]

IO多路复用(select)异步阻塞

用户进程找一个代理select,而不直接与内核打交道,系统调用交于select进行处理。

用户进程收到资源从磁盘写入内核缓冲区信息后,将内核缓冲区内容复制到用户空间。

select接待用户进程不是一对一的方式,而是一对多。用户进程依旧阻塞于select调用。这个有点像吃饭,客人和服务员之间的关系,>客人不会和后厨打交道,交由服务员完成。

IO多路复用只能成为异步阻塞模型,因阻塞在IO调用那里,但一个select可以检测多个IO模型,相比与同步阻塞只能检测一个提高了cpu的利用率。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p4y2Advo-1634528106850)(C:UsersyycAppDataRoamingTypora ypora-user-imagesimage-20210925164119445.png)]

信号驱动型 (异步半阻塞)

即用户进程建立SIGIO的信号处理程序,复制数据从磁盘到内核空间,等处理完递交SIGIO告知用户进程,这个过程是不阻塞的状态。

用户进程从内核空间复制到用户应用空间,这个过程是阻塞的。

信号驱动并未完全解决问题,只是做到了一部分不阻塞,一部分阻塞。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aASysISR-1634528106853)(C:UsersyycAppDataRoamingTypora ypora-user-imagesimage-20210925164143938.png)]

异步IO模型 (异步非阻塞) (epoll)

用户进程不受阻塞,所有的请求,拿数据拷贝到应用空间都由内核完成,用户进程可以接收更多的用户请求。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KPp0dCg8-1634528106854)(C:UsersyycAppDataRoamingTypora ypora-user-imagesimage-20210925164218273.png)]

nginx高并发原理

nginx高并发使用的是epoll的方式,提供给用户访问,复制数据的一些操作交由内核完成。自身做的事情越少接待的用户请求就越多。

epoll在linux2.6中增加了内存拷贝mmap机制,加速与内核空间的消息传递,即内存映射。

内存映射机制:磁盘中有数据,数据有对应的inode,在内存中映射一个相同的inode,大小也相同,下次拿数据不需要遍历inode,分析路径了。这样提高了效率。

例如:好似学使用字典的,你先查找它是什么音,查到后直接找对应的字。

为什么nginx比apache高效?

Nginx采用的epoll 异步非阻塞模型,有内存映射机制;apache用的是select 同步阻塞模型,线性遍历inode号,效率低下。

假设你在大学读书,住的宿舍楼有很多间房间,你的朋友要来找你。
select版宿管大妈就会带着你的朋友挨个房间去找,直到找到你为止。 
而epoll版宿管大妈会先记下每位同学的房间号, 你的朋友来时,只需告诉你的朋友你住在哪个房间即可,不用亲自带着你的朋友满大楼找人。 
如果来了10000个人,都要找自己住这栋楼的同学时,select版和epoll版宿管大妈,谁的效率更高,不言自明。 
同理,在高并发服务器中,轮询I/O是最耗时间的操作之一,select和epoll的性能谁的性能更高,同样十分明了。
  • 1
  • 2
  • 3
  • 4
  • 5

Nginx 配置文件

#运行用户
user www-data;    
#启动进程,通常设置成和cpu的数量相等
worker_processes  1;

#全局错误日志及PID文件
error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

#工作模式及连接数上限
events {
    use   epoll;             #epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,可以大大提高nginx的性能
    worker_connections  1024;#单个后台worker process进程的最大并发链接数
    # multi_accept on;
}

#设定http服务器,利用它的反向代理功能提供负载均衡支持
http {
     #设定mime类型,类型由mime.type文件定义
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    #设定日志格式
    access_log    /var/log/nginx/access.log;

    #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用,
    #必须设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度,降低系统的uptime. (零拷贝)
    sendfile        on;
    #tcp_nopush     on;

    #连接超时时间
    #keepalive_timeout  0;
    keepalive_timeout  65;
    tcp_nodelay        on;
    
    #开启gzip压缩
    gzip  on;
    gzip_disable "MSIE [1-6].(?!.*SV1)";

    #设定请求缓冲
    client_header_buffer_size    1k;
    large_client_header_buffers  4 4k;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

    #设定负载均衡的服务器列表
     upstream mysvr {
    #weigth参数表示权值,权值越高被分配到的几率越大
    #本机上的Squid开启3128端口
    server 192.168.8.1:3128 weight=5;
    server 192.168.8.2:80  weight=1;
    server 192.168.8.3:80  weight=6;
    }


   server {
    #侦听80端口
        listen       80;
        #定义使用www.xx.com访问
        server_name  www.xx.com;

        #设定本虚拟主机的访问日志
        access_log  logs/www.xx.com.access.log  main;

    #默认请求
    location / {
          root   /root;      #定义服务器的默认网站根目录位置
          index index.php index.html index.htm;   #定义首页索引文件的名称

          fastcgi_pass  www.xx.com;
         fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
          include /etc/nginx/fastcgi_params;
        }

    # 定义错误提示页面
    error_page   500 502 503 504 /50x.html;  
        location = /50x.html {
        root   /root;
    }

    #静态文件,nginx自己处理
    location ~ ^/(images|javascript|js|css|flash|media|static)/ {
        root /var/www/virtual/htdocs;
        #过期30天,静态文件不怎么更新,过期可以设大一点,如果频繁更新,则可以设置得小一点。
        expires 30d;
    }
    #PHP 脚本请求全部转发到 FastCGI处理. 使用FastCGI默认配置.
    location ~ .php$ {
        root /root;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /home/www/www$fastcgi_script_name;
        include fastcgi_params;
    }
    #设定查看Nginx状态的地址
    location /NginxStatus {
        stub_status            on;
        access_log              on;
        auth_basic              "NginxStatus";
        auth_basic_user_file  conf/htpasswd;
    }
    #禁止访问 .htxxx 文件
    location ~ /.ht {
        deny all;
    }
     
     }
}

以上是一些基本的配置,使用Nginx最大的好处就是负载均衡

如果要使用负载均衡的话,可以修改配置http节点如下:

#设定http服务器,利用它的反向代理功能提供负载均衡支持
http {
     #设定mime类型,类型由mime.type文件定义
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    #设定日志格式
    access_log    /var/log/nginx/access.log;

    #省略上文有的一些配置节点

    #。。。。。。。。。。

    #设定负载均衡的服务器列表
     upstream mysvr {
    #weigth参数表示权值,权值越高被分配到的几率越大
    server 192.168.8.1x:3128 weight=5;#本机上的Squid开启3128端口
    server 192.168.8.2x:80  weight=1;
    server 192.168.8.3x:80  weight=6;
    }

   upstream mysvr2 {
    #weigth参数表示权值,权值越高被分配到的几率越大

    server 192.168.8.x:80  weight=1;
    server 192.168.8.x:80  weight=6;
    }

   #第一个虚拟服务器
   server {
    #侦听192.168.8.x的80端口
        listen       80;
        server_name  192.168.8.x;

      #对aspx后缀的进行负载均衡请求
    location ~ .*.aspx$ {

         root   /root;      #定义服务器的默认网站根目录位置
          index index.php index.html index.htm;   #定义首页索引文件的名称

          proxy_pass  http://mysvr ;#请求转向mysvr 定义的服务器列表

          #以下是一些反向代理的配置可删除.

          proxy_redirect off;

          #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          client_max_body_size 10m;    #允许客户端请求的最大单文件字节数
          client_body_buffer_size 128k;  #缓冲区代理缓冲用户端请求的最大字节数,
          proxy_connect_timeout 90;  #nginx跟后端服务器连接超时时间(代理连接超时)
          proxy_send_timeout 90;        #后端服务器数据回传时间(代理发送超时)
          proxy_read_timeout 90;         #连接成功后,后端服务器响应时间(代理接收超时)
          proxy_buffer_size 4k;             #设置代理服务器(nginx)保存用户头信息的缓冲区大小
          proxy_buffers 4 32k;               #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
          proxy_busy_buffers_size 64k;    #高负荷下缓冲大小(proxy_buffers*2)
          proxy_temp_file_write_size 64k;  #设定缓存文件夹大小,大于这个值,将从upstream服务器传

       }

     }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
location

默认是匹配 nginx 请求 URL的

location优先级

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RuodERtR-1634528106856)(C:UsersyycAppDataLocalTempImage.png)]

Break:页面找不到,停止匹配 # 布瑞可

Last: 页面找不到,继续向下匹配 #拉斯特

Nginx 优化

绑定 CPU 最好做自动绑定的

worker_processes auto;
  • 1
为什么要绑定 Nginx 进程到不同的 CPU 上 ?
默认情况下,Nginx 的多个进程有可能跑在某一个 CPU 或 CPU 的某一核上,导致 Nginx 进程使用硬件的资源不均,因此绑定 Nginx 进程到不同的 CPU 上是为了充分利用硬件的多 CPU 多核资源的目的。
  • 1
  • 2

长连接

keepalive 在 http 区块 开启

设置 客户端连接 最长 120秒 一个连接最大请求数目

零拷贝 sendfile

开启

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ugMwANEe-1634528106857)(C:UsersyycAppDataRoamingTypora ypora-user-imagesimage-20210925163557529.png)]

为什么要做 零拷贝?

nginx 默认处理数据 是三层的 本地磁盘 > 内核缓冲区 > 用户缓冲区

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mIvzYyKE-1634528106858)(C:UsersyycAppDataRoamingTypora ypora-user-imagesimage-20210925170406378.png)]

开启零拷贝之后 数据处理就不需要第三层了 大大加快了 处理速度。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O8F0Apk0-1634528106859)(C:UsersyycAppDataRoamingTypora ypora-user-imagesimage-20210925165901922.png)]

防盗链

盗链指的是在⾃⼰的界⾯展示不在⾃⼰服务器上的内容,通过技术⼿段获得他⼈服务器的资源地址,绕过别⼈资源展示页⾯,在⾃⼰页⾯向⽤户提供此内容,从⽽减轻⾃⼰服务器的负担,因为真实的空间和流量来⾃别⼈服务器

gzip 调优

配置文件修改 http区域 开启gzip

访问控制

  1. 做控制访问需要用到 限制连接模块 和 限制请求模块,

  2. 修改 nginx 配置文件 在http区块添加IP地址限制命令,

  3. 比如一分钟限制30个请求,其它的错误返回给客户端。

虚拟目录

1.修改nginx配置文件

2.在http区块 在复制一个server区块 修改一下域名

3.重启nginx服务

资源缓存

通常情况下缓存是⽤来减少后端压⼒, 将压⼒尽可能的往前推, 减少后端压⼒,提⾼⽹站并发延时。

客户端 ---- nginx -<<- 服务器

**做缓存的优点:**降低网络带宽加快客户端访问速度减轻后端的压力

缓存方式

代理缓存, 获取服务端内容进⾏缓存

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ck8Qs5EV-1634528106860)(C:UsersyycAppDataLocalTempImage.png)]

Nginx 代理缓存原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YSgXkz7s-1634528106860)(C:UsersyycAppDataLocalTempImage.png)]

检查⽇志命令情况

tail -10 /usr/local/nginx/logs/access.log

Nginx rewrite 地址重写

rewirte 主要实现 URL地址重写 以及重定向。

Nginx 代理

1.降低网络带宽

2.加快客户端访问速度

3.减轻后端的压力

代理的分类

正向代理(内部上) 客户端<–>代理->服务端客户端知道代理服务器的存在一般用于公司客户端上网

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WZhSQFaC-1634528106861)(C:UsersyycAppDataLocalTempImage.png)]

反向代理 客户端->代理<–>服务端客户端不知道代理的存在代理一般是由服务端设置,加快客户端的访问速度的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zG1q0WAP-1634528106861)(C:UsersyycAppDataLocalTempImage.png)]

正向和反向代理区别

区别在于代理的对象不⼀样

正向代理代理的对象是客户端

反向代理代理的对象是服务端

proxy_pass 代理模块

Nginx负载均衡

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vlD3kXSD-1634528106862)(C:UsersyycAppDataLocalTempImage.png)]

Nginx 是⼀个典型的七层 SLB

Nginx 负载均衡模块upstream 需要跟nginx反向代理模块proxy_pass结合起来使用

Nginx 实现负载均衡⽤到了 proxy_pass 代理模块核⼼配置, 将客户端请求代理转发⾄⼀ 组 upstream 虚拟服务池

客户端访问nginx nginx反向代理给后端服务器,至于分给谁,看upstream 的负载均衡算法,

Nginx动静分离

动静分离

过中间件将动态请求和静态请求进⾏分离, 分离资源, 减少不必要的请求消耗, 减少请求延时。

好处: 动静分离后, 即使动态服务不可⽤, 但静态资源不会受到影响通过中间件将动态请求和静态请求分离

动静分离模块 upstream 和 proxy_pass

客户端访问 网站 ,访问网站访问动态页面就反向代理给 tomcat 访问静态页面,就反向代理给 nginx。

推荐阅读