nginx

168 阅读32分钟

Http协议和 nginx

跨网络的主机间通讯

套接字Socket是进程间通信IPC的一种实现,允许位于不同主机(或同一主机)上不同进程之间进行通信和数据交换,SocketAPI出现于1983年 BSD 4.2实现在建立通信连接的每一端,进程间的传输要有两个标志:IP地址和端口号,合称为套接字地址 socket address

  • 客户机套接字地址定义了一个唯一的客户进程
  • 服务器套接字地址定义了一个唯一的服务器进程

套接字相关的系统调用:

  • socket() 创建一个套接字
  • bind() 绑定IP和端口
  • listen() 监听
  • accept() 接收请求
  • connect() 请求连接建立
  • write() 发送
  • read() 接收
  • close() 关闭连接

我们可以使用 nc工具来模拟实验

HTTP 超文本传输协议

HTTP 相关概念

互联网:是网络,是所有类型网络的母集。

因特网:世界上最大的互联网网络。即因特网概念从属于互联网概念。习惯上,大家把连接在因特网上的计算机都成为主机。

万维网:WWW(world wide web)万维网并非某种特殊的计算机网络,是一个大规模的、联机式的信息贮藏库,使用链接的方法能非常方便地从因特网上的一个站点访问另一个站点(超链技术),具有提供分布式服务的特点。万维网是一个分布式的超媒体系统,是超文本系统的扩充,基于B/S架构实现

URL:万维网使用统一资源定位符(Uniform Resource Locator)来标志万维网上的各种文档,并使每个文档在整个因特网的范围内具有唯一的标识符URL。

HTTP:为解决"用什么样的网络协议来实现整个因特网上的万维网文档”这一难题,就要使万维网客户程序(以浏览器为主,但不限于浏览器)与万维网服务器程序之间的交互遵守严格的协议,即超文本传送协议(HyperText Transfer Protocol)。HTTP是处于应用层的协议,使用TCP传输层协议进行可靠的传送。因此,需要特别提醒的是,万维网是基于因特网的一种广泛因特网应用系统,且万维网采用的是HTTP(80/TCP)和 HTTPS(443/TCP)的传输协议,但因特网还有其他的网络应用系统(如:FTP、SMTP等等)。

HTML:为了解决"怎样使不同作者创作的不同风格的万维网文档,都能在因特网上的各种主机上显示出来,同时使用户清楚地知道在什么地方存在着链接”这一问题,万维网使用超文本标记语言(HyperText Markup Language),使得万维网页面的设计者可以很方便地用链接从页面的某处链接到因特网的任何一个万维网页面,并且能够在自己的主机品目上将这些页面显示出来。HTML与txt一样,仅仅是是一种文档,不同之处在于,这种文档专供于浏览器上为浏览器用户提供统一的界面呈现的统一规约。且具备结构化的特征,这是txt所不具备的强制规定。

网站的访问量

网站访问量统计的重要指标

  • IP(独立IP):即Internet Protocol,指独立IP数。一天内来自相同客户机IP 地址只计算一次,记录远程客户机IP地址的计算机访问网站的次数,是衡量网站流量的重要指标
  • PV(访问量): 即Page View, 页面浏览量或点击量,用户每次刷新即被计算一次,PV反映的是浏览某网站的页面数,PV与来访者的数量成正比,PV并不是页面的来访者数量,而是网站被访问的页面数量
  • UV(独立访客):即Unique Visitor,访问网站的一台电脑为一个访客。一天内相同的客户端只被计算一次。可以理解成访问某网站的电脑的数量。网站判断来访电脑的身份是通过cookies实现的。如果更换了IP后但不清除cookies,再访问相同网站,该网站的统计中UV数是不变的

网站统计www.alexa.cn/rank/

网站访问量

QPS:request per second,每秒请求数

PV,QPS和并发连接数换算公式

  • QPS= PV * 页面衍生连接次数/ 统计时间(86400)
  • 并发连接数 =QPS * http平均响应时间

峰值时间:每天80%的访问集中在20%的时间里,这20%时间为峰值时间

峰值时间每秒请求数(QPS)=( 总PV数 页面衍生连接次数) 80% ) / ( 每天秒数 * 20% )

提高HTTP连接性能

  • 并行连接:通过多条TCP连接发起并发的HTTP请求
  • 持久连接:keep-alive,重用TCP连接,以消除连接和关闭的时延,以事务个数和时间来决定是否关闭连接
  • 管道化连接:通过共享TCP连接,发起并发的HTTP请求
  • 复用的连接:交替传送请求和响应报文(实验阶段)

I/O 模型相关概念

同步/异步(消息反馈机制):关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知。

  • 同步:synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事情是否处理完成
  • 异步:asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态

阻塞/非阻塞:关注调用者在等待结果返回之前所处的状态

  • 阻塞:blocking,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情。
  • 非阻塞:nonblocking,指IO操作被调用后立即返回给用户一个状态值,而无需等到IO操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。

网络I/O模型

阻塞型、非阻塞型、复用型、信号驱动型、异步

阻塞型 I/O 模型(blocking IO)

阻塞IO模型是最简单的I/O模型,用户线程在内核进行IO操作时被阻塞用户线程通过系统调用read发起I/O读操作,由用户空间转到内核空间。内核等到数据包到达后,然后将接收的数据拷贝到用户空间,完成read操作用户需要等待read将数据读取到buffer后,才继续处理接收的数据。整个I/O请求的过程中,用户线程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够

  • 优点:程序简单,在阻塞等待数据期间进程/线程挂起,基本不会占用 CPU 资源
  • 缺点:每个连接需要独立的进程/线程单独处理,当并发请求量大时为了维护程序,内存、线程切换开销较大,apache 的preforck使用的是这种模式。

同步阻塞:程序向内核发送I/O请求后一直等待内核响应,如果内核处理请求的IO操作不能立即返回,则进程将一直等待并不再接受新的请求,并由进程轮训查看I/O是否完成,完成后进程将I/O结果返回给Client,在IO没有返回期间进程不能接受其他客户的请求,而且是有进程自己去查看I/O是否完成,这种方式简单,但是比较慢,用的比较少。

非阻塞型 I/O 模型 (nonblocking IO)

用户线程发起IO请求时立即返回。但并未读取到任何数据,用户线程需要不断地发起IO请求,直到数据到达后,才真正读取到数据,继续执行。即 “轮询”机制存在两个问题:如果有大量文件描述符都要等,那么就得一个一个的read。这会带来大量的Context Switch(read是系统调用,每调用一次就得在用户态和核心态切换一次)。轮询的时间不好把握。这里是要猜多久之后数据才能到。等待时间设的太长,程序响应延迟就过大;设的太短,就会造成过于频繁的重试,干耗CPU而已,是比较浪费CPU的方式,一般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。

多路复用 I/O 型(I/O multiplexing)

I/O multiplexing 主要包括:select,poll,epoll三种系统调用,select/poll/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。它的基本原理就是select/poll/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。Apache prefork是此模式的select,work是poll模式。

信号驱动式 I/O 模型 (signal-driven IO)

信号驱动I/O的意思就是我们现在不用傻等着了,也不用去轮询。而是让内核在数据就绪时,发送信号通知我们。

调用的步骤是,通过系统调用 sigaction ,并注册一个信号处理的回调函数,该调用会立即返回,然后主程序可以继续向下执行,当有I/O操作准备就绪,即内核数据就绪时,内核会为该进程产生一个SIGIO 信号,并回调注册的信号回调函数,这样就可以在信号回调函数中系统调用 recvfrom 获取数据,将用户进程所需要的数据从内核空间拷贝到用户空间

此模型的优势在于等待数据报到达期间进程不被阻塞。用户主程序可以继续执行,只要等待来自信号处理函数的通知。

在信号驱动式 I/O 模型中,应用程序使用套接口进行信号驱动 I/O,并安装一个信号处理函数,进程继续运行并不阻塞

当数据准备好时,进程会收到一个 SIGIO 信号,可以在信号处理函数中调用 I/O 操作函数处理数据。

  • 优点:线程并没有在等待数据时被阻塞,内核直接返回调用接收信号,不影响进程继续处理其他请求因此可以提高资源的利用率
  • 缺点:信号 I/O 在大量 IO 操作时可能会因为信号队列溢出导致没法通知

异步 I/O 模型 (asynchronous IO)

异步I/O 与 信号驱动I/O最大区别在于,信号驱动是内核通知我们何时开始一个I/O操作,而异步I/O是由内核通知我们I/O操作何时完成,两者有本质区别,相当于不用去饭店场吃饭,直接点个外卖,把等待上菜的时间也给省了。所有事情都交给内核处理。

这五种 I/O 模型中,越往后,阻塞越少,理论上效率也是最优前四种属于同步 I/O,因为其中真正的I/O 操作(recvfrom)将阻塞进程/线程,只有异步 I/O 模型才与 POSIX 定义的异步 I/O 相匹配

Nginx支持在多种不同的操作系统实现不同的事件驱动模型,但是其在不同的操作系统甚至是不同的系统版本上面的实现方式不尽相同

  1. elect: select库是在linux和windows平台都基本支持的 事件驱动模型库,并且在接口的定义也基本相同,只是部 分参数的含义略有差异,最大并发限制1024,是最早期的事件驱动模型。
  2. poll: 在Linux 的基本驱动模型,windows不支持此驱动模型,是select的升级版,取消了最大的并发限制,在编 译nginx的时候可以使用--with-poll_module和--without-poll_module这两个指定是否编译select 库。
  3. epoll: epoll是库是Nginx服务器支持的最高性能的事件驱动库之一,是公认的非常优秀的事件驱动模型,它和 select和poll有很大的区别,epoll是poll的升级版,但是与poll有很大的区别. epoll的处理方式是创建一个待处理的事件列表,然后把这个列表发给内核,返回的时候在去轮训检查这个 表,以判断事件是否发生,epoll支持一个进程打开的最大事件描述符的上限是系统可以打开的文件的最大 数,同时epoll库的I/O效率不随描述符数目增加而线性下降,因为它只会对内核上报的“活跃”的描述符进行 操作。
  4. rtsig: 不是一个常用事件驱动,最大队列1024,不是很常用
  5. kqueue: 用于支持BSD系列平台的高校事件驱动模型,主要用在FreeBSD 4.1及以上版本、OpenBSD 2.0级以上版 本,NetBSD级以上版本及Mac OS X 平台上,该模型也是poll库的变种,因此和epoll没有本质上的区别, 都是通过避免轮训操作提供效率。
  6. /dev/poll: 用于支持unix衍生平台的高效事件驱动模型,主要在Solaris 平台、HP/UX,该模型是sun公司在开发 Solaris系列平台的时候提出的用于完成事件驱动机制的方案,它使用了虚拟的/dev/poll设备,开发人员 将要见识的文件描述符加入这个设备,然后通过ioctl()调用来获取事件通知,因此运行在以上系列平台的时 候请使用/dev/poll事件驱动机制。
  7. eventport: 该方案也是sun公司在开发Solaris的时候提出的事件驱动库,只是Solaris 10以上的版本,该驱动库看防 止内核崩溃等情况的发生。
  8. Iocp: Windows系统上的实现方式,对应第5种(异步I/O)模型

Nginx概述

Nginx 功能介绍

  • 静态的web资源服务器html,图片,js,css,txt等静态资源
  • http/https协议的反向代理 7层
  • 结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求
  • tcp/udp协议的请求转发(反向代理) 4层

基础特性

  • 模块化设计,较好的扩展性
  • 高可靠性
  • 支持热部署:不停机更新配置文件,升级版本,更换日志文件
  • 低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存
  • event-driven,aio,mmap,sendfile

Web 服务相关的功能

  • 虚拟主机(server)
  • 支持 keep-alive 和管道连接(利用一个连接做多次请求)
  • 访问日志(支持基于日志缓冲提高其性能)
  • url rewirte
  • 路径别名
  • 基于IP及用户的访问控制
  • 支持速率限制及并发数限制
  • 重新配置和在线升级而无须中断客户的工作进程

Nginx 进程结构

web请求处理机制

  • 多进程方式:服务器每接收到一个客户端请求就有服务器的主进程生成一个子进程响应客户端,直到用户关闭连接,这样的优势是处理速度快,子进程之间相互独立,但是如果访问过大会导致服务器资源耗尽而无法提供请求。
  • 多线程方式:与多进程方式类似,但是每收到一个客户端请求会有服务进程派生出一个线程来个客户方进行交互,一个线程的开销远远小于一个进程,因此多线程方式在很大程度减轻了web服务器对系统资源的要求,但是多线程也有自己的缺点,即当多个线程位于同一个进程内工作的时候,可以相互访问同样的内存地址空间,所以他们相互影响,一旦主进程挂掉则所有子线程都不能工作了,IIS服务器使用了多线程的方式,需要间隔一段时间就重启一次才能稳定。

主进程(master process)的功能
对外接口:接收外部的操作(信号)
对内转发:根据外部的操作的不同,通过信号管理 Worker
监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程
读取Nginx 配置文件并验证其有效性和正确性
建立、绑定和关闭socket连接
按照配置生成、管理和结束工作进程
接受外界指令,比如重启、升级及退出服务器等指令
不中断服务,实现平滑升级,重启服务并应用新的配置
开启日志文件,获取文件描述符
不中断服务,实现平滑升级,升级失败进行回滚处理
编译和处理perl脚本
工作进程(worker process)的功能
所有 Worker 进程都是平等的
实际处理:网络请求,由 Worker 进程处理
Worker进程数量:一般设置为核心数,充分利用CPU资源,同时避免进程数量过多,导致进程竞争CPU资源, 增加上下文切换的损耗
接受处理客户的请求
将请求依次送入各个功能模块进行处理
I/O调用,获取响应数据
与后端服务器通信,接收后端服务器的处理结果
缓存数据,访问缓存索引,查询和调用缓存数据
发送请求结果,响应客户的请求
接收主程序指令,比如重启、升级和退出等

nginx 模块

  • 核心模块:是 Nginx 服务器正常运行必不可少的模块,提供错误日志记录 、配置文件解析 、事件驱动机制 、进程管理等核心功能
  • 标准HTTP模块:提供 HTTP 协议解析相关的功能,比如: 端口配置 、 网页编码设置 、 HTTP响应头设置 等等
  • 可选HTTP模块:主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,比如:Flash 多媒体传输 、解析 GeoIP 请求、 网络传输压缩 、 安全协议 SSL 支持等
  • 邮件服务模块:主要用于支持 Nginx 的 邮件服务 ,包括对 POP3 协议、 IMAP 协议和 SMTP协议的支持
  • Stream服务模块: 实现反向代理功能,包括TCP协议代理
  • 第三方模块:是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如: Json 支持、 Lua 支持等

nginx高度模块化,但其模块早期不支持DSO机制;1.9.11 版本支持动态装载和卸载
核心模块:core module
标准模块:
HTTP 模块: ngx_http_*
HTTP Core modules   #默认功能
HTTP Optional modules #需编译时指定
Mail 模块: ngx_mail_*
Stream 模块 ngx_stream_*
第三方模块

平滑升级及信号使用

信号

nginx 命令支持向其发送信号,实现不同功能

nginx 当做单独命令使用有以下选项
nginx -h
-v : show version and exit
-V : show version and configure options then exit
-t : test configuration and exit
-T : test configuration, dump it and exit
-q : suppress non-error messages during configuration testing
-s signal : send signal to a master process: stop, quit, reopen, reload
-p prefix : set prefix path (default: /etc/nginx/)
-e filename : set error log file (default: /var/log/nginx/error.log)
-c filename : set configuration file (default: /etc/nginx/nginx.conf)
-g directives : set global directives out of configuration file

显示编译详细情况 模块等信息

nginx -V
nginx version: nginx/1.22.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules- path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log- path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid- path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp- path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http- fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp- path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp -- user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with- http_addition_module --with-http_auth_request_module --with-http_dav_module --with- http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with- http_mp4_module --with-http_random_index_module --with-http_realip_module --with- http_secure_link_module --with-http_slice_module --with-http_ssl_module --with- http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with- mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with- stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 - fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 - mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'

发送信号

kill -l 看信号大全
nginx -h 中可以看到的信号较少
s signal : send signal to a master process: stop, quit, reopen, reload
可以使用man手册来查看详细的信号 如果没安装,去源码包里找到man文件
man 路径/nginx.8 不加路径打不开man帮助
stop SIGTERM 直接停止
quit SIGQUIT 优雅的退出:有人在访问不会结束进程
reopen SIGUSR1 分割日志
reload SIGHUP 重新加载配置文件
SIGHUP Reload configuration, start the new worker process with a new configuration, and
gracefully shut down old worker processes.
SIGQUIT Shut down gracefully. 优雅的关闭:有人在访问不会结束进程
SIGUSR1 Reopen log files. 重新分割日志
SIGUSR2 Upgrade the nginx executable on the fly. 运行中升级
SIGWINCH Shut down worker processes gracefully. 优雅的关闭worker进程,work进程负责处理请求,还有请求不会关闭

升级 nginx1.18 nginx1.20

  1. 将旧Nginx文件换成新Nginx文件(注意备份)
  2. 向master进程发送USR2信号
  3. master进程修改pid文件名,加后缀.oldbin
  4. master进程用新Nginx文件启动新master进程,系统中将有新旧两个Nginx主进程共同提供Web服务
  5. 向旧的Nginx服务进程发送WINCH信号,使旧的Nginx worker进程平滑停止,并删除Nginx.pid.oldbin文件
  6. 向旧master进程发送QUIT信号,关闭老master
  7. 如果发现升级有问题,可以回滚向老master发送HUP,向新master发送QUIT

#ps aux |grep nginx
#先查看是否开启nginx
#vim /apps/nginx/conf/nginx.conf
#开启 两核 #user nobody;
worker_processes 2;
#worker_processes 1 原来是1核
#nginx -s reload
#重新加载配置文件
#wget nginx.org/download/ng… -P /usr/local/src/
#下载安装包到src目录
#cd /usr/local/src/
#tar xf nginx-1.20.2.tar.gz
#cd nginx-1.20.2/
这时需要重新编译安装 ./configur 安装参数基本一致 这时可以使用 nginx -V 查看
nginx -V
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module -- with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with- http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with- stream_realip_module
#./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
#重新编译
#make
注意不要执行 make install
#cd objs
#此文件夹中有新版本的nginx 运行程序
#objs/nginx -v
#查看版本
#mv /apps/nginx/sbin/nginx /apps/nginx/sbin/nginx.bak
#将低版本的nginx主程序改名
#cp objs/nginx /apps/nginx/sbin/
#将新版本 拷入进去
#/apps/nginx/sbin/nginx -t
#检查下语法问题
#kill -USR2 cat /apps/nginx/run/nginx.pid
#发送 2 信号 信号在 man手册中可以看到
#dd if=/dev/zero of=/apps/nginx/html/m.img bs=1G count=10
开启新机器
#wget --limit-rate=1M http://192.168.对应ip地址/m.img
#kill -WINCH cat /apps/nginx/run/nginx.pid.oldbin
#优雅关闭老进程的 worker 进程
#再开启一台服务器测试 是否是新的进程 在下载
测试一段时间无问题 就可以了,如果断掉第一个 下载 ,老的进程就关闭了

配置详细解释

nginx 官方帮助文档:nginx.org/en/docs/

tengine 帮助文档:tengine.taobao.org/nginx_docs/…

Nginx的配置文件的组成部分:
主配置文件:nginx.conf
子配置文件: include conf.d/*.conf

全局配置

nginx 有多种模块

  • 核心模块:是 Nginx 服务器正常运行必不可少的模块,提供错误日志记录 、配置文件解析 、事件驱动机制 、进程管理等核心功能
  • 标准HTTP模块:提供 HTTP 协议解析相关的功能,比如: 端口配置 、 网页编码设置 、 HTTP响应头设置 等等
  • 可选HTTP模块:主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,比如:Flash 多媒体传输 、解析 GeoIP 请求、 网络传输压缩 、 安全协议 SSL 支持等
  • 邮件服务模块:主要用于支持 Nginx 的 邮件服务 ,包括对 POP3 协议、 IMAP 协议和 SMTP协议的支持
  • Stream服务模块: 实现反向代理功能,包括TCP协议代理
  • 第三方模块:是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如: Json 支持、 Lua 支持等

cpu与work进程绑定

将Nginx工作进程绑定到指定的CPU核心,默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进程独占以一核心CPU,但是可以保证此进程不会运行在其他核心上,这就极大减少了nginx的工作进程在不同的cpu核心上的来回跳转,减少了CPU对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务器的性能。 user nginx;
worker_processes auto;
worker_cpu_affinity 00000001 00000010;
#绑定到 第一 和 第二块cpu上
error_log /var/log/nginx/error.log;
#注意 要绑一起绑

调试work进程打开的文件的个数

pid /run/nginx.pid;
worker_priority -20;
worker_rlimit_nofile 65536;
#所有worker进程能打开的文件数量上限,包括:Nginx的所有连接(例如与代理服务器的连接等),而不仅仅是与客户端的连接,另一个考虑因素是实际的并发连接数不能超过系统级别的最大打开文件数的限制.最好与ulimit -n 或者limits.conf的值保持一致, 只要机器性能够多加几个也没问题
例子:
[root@localhost ~]#ps axo pid,cmd,psr,ni|grep nginx|sort -n
18620 nginx: master process /usr/ 0 0
19302 nginx: worker process 0 -20
19303 nginx: worker process 1 -20
19456 grep --color=auto nginx 0 0
#选择其中一个进程 到proc 下去查看 连接状态

[root@localhost ~]#ls /proc/19302/fd
#可以看到打开的连接数
0 1 10 13 14 15 2 4 5 6 7 9

在站点目录下生成大文件big.img
[root@localhost ~]#cd /usr/share/nginx/html/
[root@localhost ~]#dd if=/dev/zero of=big.img bs=100M count=1
可以在 2号机器上安装压力测试的工具写一个压力测试脚本
[root@localhost ~]#yum install httpd-tools -y
#安装压力测试的工具
[root@localhost ~]#while : ;do ab -c 1000 -n 10000 http://192.168.对应IP地址/big.img;sleep 1;done
#写一个压力测试脚本
回到1号机器
[root@localhost ~]#ls /proc/19302/fd
#在2号机压力测试后 就会产生很多 进程文件
0 137 176 214 253 292 330 37 408 447 486 524 563 601 640 68
1 138 177 215 254 293 331 370 409 448 487 525 564 602 641 680
10 139 178 216 255 294 332 371 41 449 488 526 565 603 642 681
100 14 179 217 256 295 333 372 410 45 489 527 566 604 643 69
101 140 18 218 257 296 334 373 411 450 49 528 567 605 644 7

改了后还需要 修改 系统默认项

[root@localhost ~]#ulimit -a
#单个进程能打开的文件是1024
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 7168
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 7168
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited

[root@localhost ~]#ulimit -n 60000
#只修改当前窗口

需要修改pam认证文件
[root@localhost ~]#vim /etc/security/limits.conf
#最后加入
soft core unlimited
hard nproc 1000000
hard core unlimited
soft nproc 1000000
soft nofile 1000000
hard nofile 1000000
soft memlock 32000
hard memlock 32000
soft msgqueue 8192000
hard msgqueue 8192000

#设置完后重启
[root@localhost ~]#ulimit -a

event事件

events {
worker_connections  65536;  #设置单个工作进程的最大并发连接数
use epoll;
#使用epoll事件驱动,Nginx支持众多的事件驱动,比如:select、poll、epoll,只能设置在events模块中设置。
accept_mutex on;
#on为同一时刻一个请求轮流由work进程处理,而防止被同时唤醒所有worker,避免多个睡眠进程被唤醒的设置,默认为off,新请求会唤醒所有worker进程,此过程也称为"惊群",因此nginx刚安装完以后要进行适当的优化。建议设置为on
multi_accept on;
#ON时Nginx服务器的每个工作进程可以同时接受多个新的网络连接,此指令默认为off,即默认为一个工作进程只能一次接受一个新的网络连接,打开后几个同时接受多个。建议设置为on
}

http设置

http 是一个大的语句块,包含若干个小的语句块(比如server语句块)

alias 别名

server {
listen 80;
server_name www.666.com;
location /nwes {
root /data/nginx/html/pc/;
#相当于追加 将 文件夹news追加到/data/nginx/html/pc/news
}
location /study{
alias /mnt/nginx/sports/;
#相当于替换 你访问 study 就是访问/mnt/nginx/sports
}
}

location

在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;ngnix会根据用户请求的URI来检查定义的所有location,按一定的优化级找出一个最佳匹配,而后应用其配置在没有使用正则表达式的时候,nginx会先在server中的多个location选取匹配度最高的一个uri,uri是用户请求的字符串,即域名后面的web文件路径,然后使用该location模块中的正则url和字符串,如果匹配成功就结束搜索,并使用此location处理此请求。

location 官方帮助:
nginx.org/en/docs/htt…
#语法规则:
location [ = | ~ | * | ^ ] uri { ... }

= #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立即处理请求
^~ #用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头,对URI的最左边部分做匹配检查,不区分字符大小写
~ #用于标准uri前,表示包含正则表达式,并且区分大小写
~* #用于标准uri前,表示包含正则表达式,并且不区分大写
不带符号 #匹配起始于此uri的所有的uri
\ #用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号

#匹配优先级从高到低:
=, ^~, ~/*, 不带符号

location = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* .(gif|jpg|jpeg)$ {
[ configuration E ]
}

验证模块

配置
server {
listen 80;
server_name www.kgc.com;
location / {
root /data/nginx/html/pc;
}
location /admin{
root /data/nginx/html/pc;
auth_basic "admin site";
#提示信息,不是所有浏览器都有用
auth_basic_user_file /apps/nginx/conf.d/.httpuser;
#密码文件存放位置
}
}

重写功能

Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求,此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库,rewrite是nginx服务器的重要功能之

一,用于实现URL的重写,URL的重写是非常有用的功能,比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为访问,另外还可以在一定程度上提高网站的安全性。

6.1 ngx_http_rewrite_module模块指令

官方文档: nginx.org/en/docs/htt…

6.1.1 if指令

官方文档:nginx.org/en/docs/htt…
用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中进行配置,Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断,用法如下:
if (条件匹配) {
action
}
使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间使用以下符号链接:
= #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false
!=  #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false
~ #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假
~ * #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真

-f 和 !-f #判断请求的文件是否存在和是否不存在
-d 和 !-d #判断请求的目录是否存在和是否不存在
-x 和 !-x #判断文件是否可执行和是否不可执行
-e 和 !-e #判断请求的文件或目录是否存在和是否不存在 (包括文件,目录,软链接)
#注意:
#如果变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。 #nginx 1.0.1之前变量的值如果以0开头的任意字符串会返回false
#示例:
www.baidu.com

3字打头重定向
301 永久重定向 将缓存记录在浏览器中
302 临时重定向 没有缓存 每次都要重定向

location /main {
index index.html;
default_type text/html;
if ( $scheme = http ){

      echo "if-----> $scheme";
}

    if ( $scheme = https ){

     echo "if ----> $scheme";

  }

    if (!-e $request_filename) {

       echo "$request_filename is not exist";

       #return ;

  }
}

rewrite 指令

通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配,rewrite主要是针对用户请求的URL或者是URI做具体处理
官方文档:nginx.org/en/docs/htt…
rewrite可以配置在 server、location、if
语法格式 :
rewrite可以配置在 server、location、if
语法格式 :
rewrite regex replacement [flag];
正则匹配原始访问url 替代你想让客户访问的标志
rewrite将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URI

注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向 301
正则表达式格式
. #匹配除换行符以外的任意字符
\w #匹配字母或数字或下划线或汉字
\s #匹配任意的空白符
\d #匹配数字
\b #匹配单词的开始或结束
^ #匹配字付串的开始
$ #匹配字符串的结束

  • #匹配重复零次或更多次
  • #匹配重复一次或更多次
    ? #匹配重复零次或一次
    (n) #匹配重复n次
    {n,} #匹配重复n次或更多次
    {n,m} #匹配重复n到m次
    *? #匹配重复任意次,但尽可能少重复
    +? #匹配重复1次或更多次,但尽可能少重复
    ?? #匹配重复0次或1次,但尽可能少重复
    {n,m}? #匹配重复n到m次,但尽可能少重复
    {n,}? #匹配重复n次以上,但尽可能少重复
    \W  #匹配任意不是字母,数字,下划线,汉字的字符
    \S #匹配任意不是空白符的字符
    \D #匹配任意非数字的字符
    \B #匹配不是单词开头或结束的位置
    [^x] #匹配除了x以外的任意字符
    [^kgc] #匹配除了kgc 这几个字母以外的任意字符

rewrite flag 使用介绍

利用nginx的rewrite的指令,可以实现url的重新跳转,rewrtie有四种不同的flag,分别是redirect(临时重定向302)、permanent(永久重定向301)、break和last。其中前两种是跳转型的flag,后两种是代理型

  • 跳转型指由客户端浏览器重新对新地址进行请求
  • 代理型是在WEB服务器内部实现跳转

rewrite 格式
Syntax: rewrite regex replacement [flag]; #通过正则表达式处理用户请求并返回替换后的数据包。
Default: —
Context: server, location, if
redirect;302
#临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302
permanent;301 www.bj.com www.beijing.com
#重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求,状态码:301
break; www.bj.com
#重写完成后,停止对当前URL在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环,建议在location中使用
#适用于一个URL一次重写
last;
#重写完成后,停止对当前URI在当前location中后续的其它重写操作,而后对新的URL启动新一轮重写检查,不建议在location中使用
#适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户301
http转https
server {
listen 443 ssl;
listen 80;
ssl_certificate /apps/nginx/certs/www.666.org.crt;
ssl_certificate_key /apps/nginx/certs/www.666.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.666.org;
location / {    #针对全站跳转
root /data/nginx/html/pc;
index index.html;
if (scheme = http ){  #如果没有加条件判断,会导致死循环   rewrite / https://host redirect;
}   www.666.com www.666.com
}
location /login {     #针对特定的URL进行跳转https
if (scheme = http ){  #如果没有加条件判断,会导致死循环   rewrite / https://host/login redirect;
}
}
}

防盗链

防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名,正常的referer信息有以下几种:
none:#请求报文首部没有referer首部,比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
blocked:#请求报文有referer首部,但无有效值,比如为空。
server_names:#referer首部中包含本主机名及即nginx 监听的server_name。
arbitrary_string:#自定义指定字符串,但可使用* 作通配符。示例: .kgc.org www.666.
regular expression:#被指定的正则表达式模式匹配到的字符串,要使用~ 开 头,例如:~.*.kgc.com

实现盗链
yum install nginx
cd /usr/share/nginx/html
vim test.html

systemctl start nginx
~* .(jpg|gif|swf)¥(美金符) :这段正则表达式表示匹配不区分大小写,以.jpg 或.gif 或.swf 结尾的文件
Valid_referers:设置信任的网站,可以正常使用图片。
None :浏览器中 referer 为空的情况,就是直接在浏览器访问图片。
Blocked :referer 不为空的情况 ,但是值被代理或防火墙删除了,这些值不以 http://或https://开头。
后面的网址或者域名:referer 中包含相关字符串的网址。
If 语句:如果链接的来源域名不在 valid_referers 所列出的列表中,$invalid_referer 为1,则执行后面的操作,即进行重写或返回 403 页面。

反向代理

反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式。

Nginx 除了可以在企业提供高性能的web服务之外,另外还可以将 nginx 本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主要在不同的场景使用以下模块实现不同的功能
ngx_http_proxy_module: #将客户端的请求以http协议转发至指定服务器进行处理
ngx_http_upstream_module #用于定义为proxy_pass,fastcgi_pass,uwsgi_pass等指令引用的后端服务器分组 ngx_stream_proxy_module:#将客户端的请求以tcp协议转发至指定服务器处理
ngx_http_fastcgi_module:#将客户端对php的请求以fastcgi协议转发至指定服务器助理
ngx_http_uwsgi_module: #将客户端对Python的请求以uwsgi协议转发至指定服务器处理