欢迎来到 Purvisの部落格.|

兰purvis

园龄:7年10个月粉丝:12关注:42

2022-08-21 22:29阅读: 502评论: 0推荐: 0

Nginx 介绍、部署及性能优化

本文主要内容:

1、Nginx 简介

2、Nginx 搭建及生产环境配置

3、Nginx 性能调优

 

一、Nginx 简介

正向代理和反向代理

正向代理: 客户端非常明确要访问的服务器地址,它代理客户 端,替客户端发出请求。比如:FQ (警告⚠️:FQ操作违反相关法律规定,本篇文章仅供 学习参考,切勿盲目FQ)。

 

反向代理: 均衡分工,控制流量,避免出现局部节点负载过大。 反向代理隐藏了服务器的信息,它代理的是服务器端, 代其接收请求。 换句话说,反向代理的过程中,客户端并不知道具体是 哪台服务器处理了自己的请求。如此一来,既提高了访 问速度,又为安全性提供了保证。

什么是 Nginx ?

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好。

注:Nginx 实际代表的是 engine-x,其音标为:/'endʒɪneks/ 

Nginx 与Apache性能对比

160 million 个站点在 NGINX 上运行

51% 前 10,000 个访问量最大的网站Nginx 占比

36% 的亚马逊网络服务运行着Nginx

 

二、Nginx 搭建及生产环境配置

Nginx 编译安装

复制代码
$ yum -y install gcc gcc-c++                              # 下载gcc编译器
$ yum -y install pcre-devel openssl-devel                 # 下载PCRE
$ wget http://nginx.org/download/nginx-1.21.1.zip         # 下载nginx,官方网站是 http://nginx.org ,自己
                                                          # 找到需要的版本,右键复制下载链接
$ tar -zxvf nginx-1.19.2.tar.gz                           # 解压
$ cd nginx-1.19.2
$ ./configure --prefix=/opt/nginx \                       # 生成makefile
    --with-http_stub_status_module \                      # 使用./configure --help查看各个模块的使用情况
    --with-http_ssl_module                                # 使用--with-http_perl_modules方式安装需要的模块
$ make && make install                                    # 编译安装
$ cd /opt/nginx                                           # 进入到安装目录
$ ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/      # 将 /usr/local/nginx/sbin/nginx 软连接
                                                          # 到 /usr/local/sbin 下,就可以在任意地方使用nginx命令
复制代码

Nginx 系统服务配置

复制代码
cat > /usr/lib/systemd/system/nginx.service << NGINX_CONF
[Unit]
Description=The NGINX HTTP and reverse proxy server
Documentation=http://nginx.org/en/docs/
Wants=network-online.target

[Service]
Type=forking
PIDFile=${nginx_dir}/logs/nginx.pid
ExecStartPre=${nginx_dir}/sbin/nginx -t
ExecStart=${nginx_dir}/sbin/nginx
ExecReload=${nginx_dir}/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT \$MAINPID

[Install]
WantedBy=multi-user.target
NGINX_CONF
复制代码
# Nginx system 配置
$ systemctl daemon
-reload $ systemctl enable nginx $ systemctl stop nginx $ systemctl start nginx $ systemctl reload nginx

Nginx 动态负载配置

Nginx 动态负载及高可用

Nginx高并发处理原理

进程模型采用Master/Worker 方式。当 nginx 启动的时候,会创建一个 Master 进程,Master进程会根据nginx.conf配置文件中相应的配置项来fork出多个worker子进程去处理请求(怎么处理也是根据配置文件中相应的配置文件)。

​ Master进程负责管理Worker进程的生命周期、处理网络事件、接收外界信号等。由于Master进程可以fork出多个Worker进程,所以说Nginx是多进程的。

 

 

 

 

 

 

 

 

 



 

 

     

 

 

 

 

   

        异步处理模式是指nginx处理请求的时候是采用I/O多路复用技术(select | poll | epoll 模型),即多个 I/O 可以复用一个进程。当 worker 进程接收到客户端的请求后,会调用服务端对其请求进行处理,如果没有立即得到响应结果, worker 进程没有阻塞,而是去处理其他请求,知道有请求被服务端处理完成并返回响应结果。
​        这里的 worker 进程默认就是采用 epoll 多路复用机制来对服务端进行处理的。当服务端返回响应结果时,回调 epoll 多路复用器,epoll 告知 worker 进程,worker 会挂起当前正在处理的线程,去获取响应结果返回客户端,完成后再去执行被挂起的线程。整个过程中不会出现等待的情况,所以理论上Ngnix的一个进程就可以处理无限数量的连接,而且无需轮询。

​注:worker 进程接收客户端请求不是采用的 epoll 模型,而是互斥锁机制;只有对服务端的请求和响应采用的是 epoll 模型。

Nginx的特点 – 高并发

复制代码
$ ulimit –a                             # 查看当前会话中的linux核心配置,只需要关注open file
$ ulimit –n                             # 查看系统的“进程最大可打开文件数的设置”,默认时1024
vim /etc/security/limit.conf            # 修改“进程最大可打开文件数的设置”
#添加下面两行
    soft nofile 65535                   # 应用软件级别限制的最大可打开文件数的限制
    hard nofile 65535                   # 操作系统级别限制的最大可打开文件数的限制
$ ulimit -n 65535                       # 文件保存后不会马上生效,所以还得更改当前会话级别的配置
# 修改nginx配置文件(下面两行) 
$ vim /src/local/nginx/conf/nginx.conf
worker_rlimit_nofile 65535;             # 这行,看这里看这里
events {
    use epoll;
    worker_connections 65535;           # 这行,看这里看这里
}
$ nginx -s reload                       # 热部署重新加载配置文件
复制代码

要知道,在linux的世界里,一切皆文件.因此要实现大的并发量的第一步,修改linux系统的文件标识符限制数,,也就是文件打开数量的限制

Nginx的特点 – 热部署

$ nginx -s reload

1、当上面的命令一执行,如果发现配置文件已更改,会创建一个新的主进程
2、当前所有的worker进程不会再接收新的请求并把当前正在处理的请求执行完就关闭
3、master主进程会创建新的worker进程来接收并处理新的请求

Nginx的特点 – 模块化

复制代码
$ git clone https://github.com/agentzh/echo-nginx-module 
#放入指定位置
$ mv echo-nginx-module-master /opt/nginx/echo-nginx-module
$ ./configure                                                   #就用这个命令生成新的makefile
    --prefix=/opt/nginx \
    --with-http_stub_status_module \
    --with-http_ssl_module \
    --add-module=/opt/nginx/echo-nginx-module
$ make                                                          # 编译(这里只需要make,一定不要执行make install,
                                                                # 不然会被覆盖)
$ cp /opt/nginx/sbin/nginx /opt/nginx/sbin/nginx.bak            #备份原文件
$ cp /opt/nginx/objs/nginx /opt/nginx/sbin/nginx
$ ln -s /opt/nginx/sbin/nginx /opt/bin/nginx                    #重新建立软连接,检测配置文件并平滑启动
$ nginx -t
$ nginx -s reload
复制代码

Nginx的特点

 

低消耗

一万个非活跃性链接,消耗内存仅暂用2.5M

高可用

woker都一个一个的进程,就算其中某个进程挂掉了,也对其他的进程没得影响,而且其他的进程会接替出问题的进程。

Nginx 的整体结构

 

 

 

 

 

  

全局块

配置影响nginx的全局指令。包括:

  • 配置运行nginx的服务器用户组
  • worker process数
  • nginx进程
  • pid存放路径
  • 错误日志存放路径
  • 配置文件的引入

events块

配置影响nginx服务器或与用户的网络连接。包括:

  • 设置网络连接的序列化(惊群)
  • 是否允许同时接收多个网络连接
  • 选择事件驱动模型
  • 设置最大连接数

http块

可以嵌套多个server模块,配置代理、缓存、日志定义等和第三方模块的配置。包括:

  • 定义MIMI-Type
  • 自定义服务日志格式
  • 允许sendfile方式传输文件
  • 连接超时时间
  • 单连接请求数上限

server块

配置虚拟主机相关参数。包括:

  • 配置网络监听
  • 配置基于名称的虚拟主机
  • 配置基于IP的虚拟主机

location块

配置请求的路由,以及页面和其他静态资源的处理。包括:

  • Location配置
  • 请求根目录配置更改
  • URL
  • 网站默认首页配置

Nginx Location 匹配

 

 

匹配顺序:

1. 首先精确匹配 =

2. 其次最佳匹配 ^~

3. 其次是按文件中顺序的正则匹配

4. 然后匹配不带任何修饰的前缀匹配

5. 最后是交给 / 通用匹配

6. 当有匹配成功时候,停止匹配,按当前匹配规则处理请求

注意:前缀匹配,如果有包含关系时,按最大匹配原则进行匹配。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

访问根目录 /,比如 http://localhost/ 将匹配 规则A

访问 http://localhost/login 将匹配 规则B,http://localhost/register 则匹配 规则F

访问 http://localhost/static/a.html 将匹配 规则C

访问 http://localhost/static/files/a.exe 将匹配 规则X,虽然 规则C 也能匹配到,但因为最大匹配原则,最终选中了 规则X。你可以测试下,去掉规则 X ,则当前 URL 会匹配上 规则C。

访问 http://localhost/a.gif, http://localhost/b.jpg 将匹配 规则D 和 规则 E ,但是 规则 D 顺序优先,规则 E 不起作用,而 http://localhost/static/c.png 则优先匹配到 规则 C

访问 http://localhost/a.PNG 则匹配 规则 E ,而不会匹配 规则 D ,因为 规则 E 不区分大小写。

访问 http://localhost/img/a.gif 会匹配上 规则D,虽然 规则Y 也可以匹配上,但是因为正则匹配优先,而忽略了 规则Y。

访问 http://localhost/img/a.tiff 会匹配上 规则Y。

访问 http://localhost/category/id/1111 则最终匹配到规则 F ,因为以上规则都不匹配,这个时候应该是 Nginx 转发请求给后端应用服务器,比如 FastCGI(php),tomcat(jsp),Nginx 作为反向代理服务器存在。

 

三、Nginx 性能调优

全局模块下的 调优

max_clients = worker_processes * worker_connections;

$ vim /opt/nginx/conf/nginx.conf

worker_processes auto;              # 设置进程数
worker_cpu_affinity 01 10;          # 设置内核数量以及进程使用内核情况
worker_rlimit_nofile 65535;         # 可打开最大文件数

worker_processes
​worker的进程数,该值一般设置为CPU内核数,或者内核的整倍数。不仅仅取决于CPU内核数,也与磁盘数量和负载均衡模式有关系,在不知道怎么做的时候可以设置为auto。
worker_cpu_affinity
​将worker进程与cpu内核进行绑定,该配置是以多位二进制数进行设置。
worker_rlimit_nofile
设置一个worker进程最大能打开的文件数。默认值与当前linux系统的设置的最大能打开的文件描述符一致。

events模块下的调优

I/O 多路复用

select vs. poll vs. epoll/kqueue

其中select和poll都是标准的工作模式,

kqueue和epoll是高效的工作模式,
不同的是epoll用在Linux平台上,kqueue用在BSD系统中。

对于Linux系统Linux2.6+的内核,推荐选择epoll工作模式,这是高性能高并发的设置

https://programmer.help/blogs/introduction-to-select-poll-epoll-i-o-multiplexing.html
https://nima101.github.io/io_multiplexing

$ vim /opt/nginx/conf/nginx.conf
events {
    use epoll;                          # 设置worker进程与客户端的连接方式(事件驱动模型)
    worker_connections  1024;           # 设置worker进程最大的连接数,默认为512
    accept_mutex on;                    # 设置网路连接序列化,防止惊群现象发生,默认为on
    accept_mutex_delay 500ms;
    multi_accept on;                    # 设置一个进程是否同时接受多个网络连接,默认为off
}

https 模块下的调优

复制代码
http {
    ...
    sendfile    on;                      # 开启高效文件传输模式
    tcp_nopush     on;                   # 防止网络阻塞
    tcp_nodelay     on;                  # 设置数据发送缓存
    client_max_body_size 10m;            # 最大允许上传的文件大小根据业务需求来设置
    keepalive_timeout  65;               # 设置客户端与Nginx间所建立的长连接
                                         # 的生命超时时间,时间到达,
                                         # 则连接将自动关闭。单位秒
    keepalive_requests  2000;            # 设置一个长连接发出最多的请求数
    ...
}
复制代码

Sendfile
参数用于开启文件的高效传输模式。同时将tcp_nopush和tcp_nodelay两个指令设置为on,可防止网络及磁盘I/O阻塞,提升Nginx工作效率。
tcp_nopush
设置是否将nginx的响应头单独发送,如果开启:则会以单独的形式发送nginx的响应头,而真实的响应体数据会在单独以数据包的形式发送;如果关闭:则会将nginx的响应头和真实的响应体数据一起发送,每个响应都会包含。
tcp_nodelay
设置数据发送缓存,如果开启:不设置数据发送缓存,适合传输小数据;如果关闭:开启数据发送缓存,如果传输图片等大文件,建议设置为 off。
client_body_timeout
设置客户端获取响应的超时时间。如果超时了 ,则认为请求失败。可根据此值得设置来做接口的简单小压测,并且 可设置一个合理的值,保证请求响应的最优。
keepalive_timeout
设置连接活跃时间,如果超时则断开连接。若设置为0,则表示禁止keepalive连接。如果传输的数据量小,且系统运算量很小,则可以将该值设置小一些;反之。
keepalive_requests
​设置一个长连接发送请求的最大数。如果当前系统并发量大,而如果 该值 设置很小,则会导致keepalive_timeout 时间还未到,但是keepalive_requests上限已经到了。故我们需要根据真实系统并发量和连接活跃时间来设置该值。

 

复制代码
http {
    ...
    # 将当前目录(conf 目录)中的 mime.types 文件包含进来
    include       mime.types;
    include /opt/nginx/vhost.d/*.conf;
    server {
        ...
        include /opt/nginx/upstream/*.conf;
        ...
        upstream {
            ...
            include /opt/nginx/upstream/xxx.1hai.cn.conf;
            ...
        }
        ...
    }
复制代码
复制代码
http {
    ...

    charset utf-8;      # 设置请求与响应的字符编码

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    log_format  postdata  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                                          ' $request_body'
                      '"$http_user_agent" "$http_x_forwarded_for"';
    # 开启访问日志,存放路径为logs/access.log,以log_format  main格式存放
    access_log  logs/access.log  main;
    ...
}
复制代码

Nginx 日志切割

复制代码
$ cat /etc/logrotate-daily
/opt/nginx/logs/*.log
{
    rotate 4
    daily
    dateext
    dateformat .%Y%m%d
    compress
    missingok
    notifempty
    copytruncate
    sharedscripts
}
复制代码

为什么要做日志切割?

因为随时系统访问量的增长,访问日志里会出现越来越多的数据,如果不去按照时间去做合理的日志切割,访问日志里的数据多到无法打开的地步,所以需要做日志切割。

logrotate的行为也是受crontab控制,在/etc/cron.daily目录下。

而crontab任务是受anacron控制,在/etc/anacron文件中配置。

Nginx Gzip 压缩

复制代码
http {
    ...
    gzip  on;     # 开启gzip压缩
    # 用来指定压缩的类型
    gzip_types application/atom+xml
        application/javascript
        application/json
        application/ld+json
        application/manifest+json
        application/rss+xml
        xxx...;

    gzip_comp_level 2;
    ...
}
复制代码

gzip_comp_level

压缩比率。
用来指定gzip压缩比,1压缩比最小,处理速度最快;
9压缩比最大,传输速度快,但处理最慢,也比较消耗CPU资源

Nginx gzip压缩功能介绍
Nginx gzip压缩模块提供了压缩文件内容的功能,用户请求的内容在发送到用户客户端之前,Nginx服务器会根据一些具体的策略实施压缩策略,以节约网站出口带宽,同时加快数据传输效率,来提升用户访问体验。
Nginx gzip压缩的优点
提升网站用户体验:发送给用户的内容小了,用户访问单位大小的页面就加快了,用户体验提升了,网站口碑就好了
节约网站带宽成本:数据是压缩传输的,因此节省了网站的带宽流量成本,不过压缩时会稍微消耗一些CPU资源,这个一般可以忽略不计
需要和不需要压缩的对象
纯文本内容压缩比很高,因此,纯文本的内容最好进行压缩,例如:html、css、js、xml、shtml等格式的文件
被压缩的纯文本文件必须大于1KB,由于压缩算法的特殊原因,极小的文件压缩后可能反而变大
图片、视频(流媒体)等文件尽量不要压缩,因为这些文件大多都是经过压缩的,如果再压缩很可能不会减小或减小很少,或者可能增大,同事压缩时还会消耗大量的CPU、内存资源

Nginx 提供两种限流方式

一、是控制速率

复制代码
http {
    ...
    limit_req_zone $binary_remote_addr 
                            zone=myRateLimit:10m rate=10r/s;
    server {
        location / {
            limit_req zone=myRateLimit;
            proxy_pass http://my_upstream;
        }
    }
    ...
}
复制代码

key:定义限流对象,binary_remote_addr 是一种key,表示基于 remote_addr(客户端IP) 来做限流,binary_ 的目的是压缩内存占用量。
zone:定义共享内存区来存储访问信息, myRateLimit:10m 表示一个大小为10M,名字为myRateLimit的内存区域。1M能存储16000 IP地址的访问信息,10M可以存储16W IP地址访问信息。
rate:用于设置最大访问速率,rate=10r/s 表示每秒最多处理10个请求。Nginx 实际上以毫秒为粒度来跟踪请求信息,因此 10r/s 实际上是限制:每100毫秒处理一个请求。这意味着,自上一个请求处理完后,若后续100毫秒内又有请求到达,将拒绝处理该请求。

复制代码
http {
    ...
    limit_req_zone $binary_remote_addr 
                            zone=myRateLimit:10m rate=10r/s;
    server {
        location / {
            # limit_req zone=myRateLimit burst=20;
            limit_req zone=myRateLimit burst=20 nodelay;
            proxy_pass http://my_upstream;
        }
    }
    ...
}
复制代码

burst 译为突发、爆发,表示在超过设定的处理速率后能额外处理的请求数。当 rate=10r/s 时,将1s拆成10份,即每100ms可处理1个请求。
此处,burst=20 ,若同时有21个请求到达,Nginx 会处理第一个请求,剩余20个请求将放入队列,然后每隔100ms从队列中获取一个请求进行处理。若请求数大于21,将拒绝处理多余的请求,直接返回503.
不过,单独使用 burst 参数并不实用。假设 burst=50 ,rate依然为10r/s,排队中的50个请求虽然每100ms会处理一个,但第50个请求却需要等待 50 * 100ms即 5s,这么长的处理时间自然难以接受。
nodelay 针对的是 burst 参数,burst=20 nodelay 表示这20个请求立马处理,不能延迟,相当于特事特办。不过,即使这20个突发请求立马处理结束,后续来了请求也不会立马处理。burst=20 相当于缓存队列中占了20个坑,即使请求被处理了,这20个位置这只能按 100ms一个来释放。
这就达到了速率稳定,但突然流量也能正常处理的效果。

二、是控制并发连接数

复制代码
http {
    ...
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;

    server {
        ...
        limit_conn perip 10;
        limit_conn perserver 100;
    }
    ...
}
复制代码

设置白名单

复制代码
http {
    ...
    geo $limit {
        default 1;
        10.0.0.0/8 0;
        192.168.0.0/24 0;
        172.20.0.35 0;
    }
    map $limit $limit_key {
        0 "";
        1 $binary_remote_addr;
    }
    limit_req_zone $limit_key zone=myRateLimit:10m rate=10r/s;
    ...
}
复制代码

geo 对于白名单(子网或IP都可以) 将返回0,其他IP将返回1。

map 将 limitlimit_key,如果是 $limit 是0(白名单),则返回空字符串;如果是1,则返回客户端实际IP。

limit_req_zone 限流的key不再使用 binaryremoteaddrlimit_key 来动态获取值。
如果是白名单,limit_req_zone 的限流key则为空字符串,将不会限流;
若不是白名单,将会对客户端真实IP进行限流。

设置黑名单

复制代码
$ cat blockip.conf
deny 165.91.122.67;
deny 180.169.22.135;                     #在nginx的安装目录下面,新建屏蔽ip文件,命名为blockip.conf
deny 219.220.141.2;
$ vim nginx.conf
http{
    ...
    include blocksip.conf;               #nginx.conf文件将该配置加入http{}标签末尾
    ...
}
$ nginx -s reload
$ cat blockip.conf                       #如果你想实现这样的应用,除了几个IP外,其他全部拒绝,那需要你在blockip.conf中这样写
allow 1.1.1.1;
allow 1.1.1.2;
deny all;
复制代码

限制数据传输速度

复制代码
http {
    ...
    location /flv/ {
        flv;
        limit_rate_after 20m;
        limit_rate       100k;
    }
    ...
}
复制代码

除限流外,ngx_http_core_module 还提供了限制数据传输速度的能力(即常说的下载速度)。

这个限制是针对每个请求的,
表示客户端下载前20M时不限速,后续限制100kb/s。

本文作者:兰purvis

本文链接:https://www.cnblogs.com/purvis/p/16611144.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   兰purvis  阅读(502)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.

作曲 : Reol

作词 : Reol

fade away...do over again...

fade away...do over again...

歌い始めの一文字目 いつも迷ってる

歌い始めの一文字目 いつも迷ってる

どうせとりとめのないことだけど

伝わらなきゃもっと意味がない

どうしたってこんなに複雑なのに

どうしたってこんなに複雑なのに

噛み砕いてやらなきゃ伝わらない

ほら結局歌詞なんかどうだっていい

僕の音楽なんかこの世になくたっていいんだよ

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

僕は気にしない 君は気付かない

何処にももういないいない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

忘れていく 忘れられていく

We don't know,We don't know.

目の前 広がる現実世界がまた歪んだ

目の前 広がる現実世界がまた歪んだ

何度リセットしても

僕は僕以外の誰かには生まれ変われない

「そんなの知ってるよ」

気になるあの子の噂話も

シニカル標的は次の速報

麻痺しちゃってるこっからエスケープ

麻痺しちゃってるこっからエスケープ

遠く遠くまで行けるよ

安定なんてない 不安定な世界

安定なんてない 不安定な世界

安定なんてない きっと明日には忘れるよ

fade away...do over again...

fade away...do over again...

そうだ世界はどこかがいつも嘘くさい

そうだ世界はどこかがいつも嘘くさい

綺麗事だけじゃ大事な人たちすら守れない

くだらない 僕らみんなどこか狂ってるみたい

本当のことなんか全部神様も知らない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

僕は気にしない 君は気付かない

何処にももういないいない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

忘れていく 忘れられていく

We don't know,We don't know.