一、http相关知识
1.http的请求流程
①:建立tcp连接
②:web浏览器向web服务器发送请求
③:web浏览器发送请求头信息
建立连接后,客户机发送一个请求给服务器,请求方式的格式:URL、version、MIME
④:web服务器响应
响应格式:version status_code、MIME信息、body信息。
⑤:Web服务器向浏览器应答头部信息
⑥:Web服务器向浏览器发送数据
⑦:Web服务器关闭TCP连接
web页面:可能一次页面多个URL和资源请求、可能请求静态资源或动态资源
2.MPM 多路处理模型
①:prefork模型
主进程开启子进程进行响应,每个子进程处理一个请求,子进程根据访问量大小进行调整
②:worker模型
实现设置好开多少进程、每个进程开多少线程
③:event模型
worker模型的变种,把服务进程从连接中分离出来,开启keepalive场合下对worker模式承受更高的并发负载。
流程:客户端到服务端发送浏览器请求,本质上是获取对方的web数据。客户端要发起两次I/O,分别为网络请求I/O、服务器数据I/O(内核到用户据I/O)。首先网络请求I/O,发送TCP请求连接,其次把请求的数据发送到内核空间,内核空间进行预热识别,内核空间的内存就会有所消耗(每次请求就要调用I/O的进程数,无论是MPM哪个模块都会占据内核空间内存数),将内核空间磁盘中的web数据复制到用户空间;第四步:用户空间将数据进行处理,产生新的数据;如果对方请求是put数据,就要把数据copy到内核,然后存储到对应的磁盘中。最后在web服务进程,将处理数据封装成html响应报文,基于tcp套接字连接,返回给客户端。
二、I/O模型详解
1.I/O网络模型
2.Linux的I/O
磁盘 1/O
网络 1/O:一切皆文件,本质为对 socket 文件的读写
磁盘I/O
磁盘I/O是进程向内核发起系统调用,请求磁盘上的某个资源比如是html 文件或者图片,然后内核通过相应的驱动程序将目标文件加载到内核的内存空间,加载完成之后把数据从内核内存再复制给进程内存,如果是比较大的数据也需要等待时间
网络 I/O
网络通信就是网络协议栈到用户空间进程的I/O就是网络I/O
获取请求数据,客户端与服务器建立连接发出请求,服务器接受请求(1-3)
构建响应,当服务器接收完请求,并在用户空间处理客户端的请求,直到构建响应完成(4)
返回数据,服务器将已构建好的响应报文再通过内核空间的网络I/O发还给客户端(5-7)
每次 I/O,都要经由两个阶段:
第一步:将数据从文件先加载至内核内存空间(缓冲区),等待数据准备完成,时间较长
第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短
3.五种I/O模型:
①同步和异步
关注的是消息通知机制
同步:调用资源发出请求不会立即返回,但如果返回肯定是最终结果
异步:调用资源发出,被调用方立即返回消息,但可能不是最终结果
②阻塞和非阻塞
关注的是调用者等待被调用者提供结果时的状态
阻塞:调用结果返回之前,调用者处于挂起状态、只有获取结果后才继续
非阻塞:调用者在结果返回之前,不会被挂起,调用不会阻塞调用者。
③五种I/O模型
阻塞
非阻塞
多路I/O(select 和 poll) 1024以内
事件驱动
异步(AIO)
【注】:Apache是select同步阻塞模型,支持文件描述符太小,默认1024
nginx是epoll(linux)异步非阻塞模型,支持文件描述符最大65535
nginx支持三种I/O,多路I/O、事件驱动、异步非阻塞;默认是事件驱动模型
apache,Tomcat等都用I/O复用
select调用:同步客户到进程之间的映射关系;既同步又阻塞,但有select调用,所有并发高
事件驱动I/O模型:Nginx(异步非阻塞)
前半段(应用进程-内核)是完全非阻塞的,内核空间还是阻塞的
epoll异步模型(事件驱动模型)
①:支持一个进程打开大数目的socket描述符
②:I/O效率不随fd数目增加而线性下降
③:使用mmap加速内核与用户空间的消息传递
④:边缘触发和水平触发
通知机制:水平触发 多次通知;边缘触发 一次通知
poll()
Select()
三、Nginx基本架构
1.Nginx简介
①:是一款开源的轻量级的高性能的静态资源web服务器、同时也是非常优秀反向代理服务器(负载均衡)、缓存服务器、邮件代理服务器。常见CDN:nginx、squid、varnish
②:最早由俄罗斯程序员伊戈尔·赛索耶夫开发,官方主页http://nginx.org
③:理念和apache不一样,占用内存少、并发能力强、在中国大陆绝大部分的网站服务器都在使用。
④:属于web服务器解决方案领域的新贵,市场份额一路飙升。
2.Nginx作为web服务器的优点
在高连接,高并发情况下,Nginx是apache的很不错的替代品理论支持超50000并发。
使用异步非阻塞的epoll模型(已经可以支持AIO),内存消耗很少。
配置文件非常简单
Rewrite重写规则非常强大
内置健康检查功能---> (后端web服务器宕机,不影响前端访问)
节省带宽---> 支持gzip压缩(可定义压缩级别),可以添加浏览器本地缓存
稳定性高 ---> 用于反向代理,宕机几率低
模块化设计:模块可以动态编译,nginx不支持DSO(动态装卸载模块)
热部署:不停机重载配置文件,性能好。
成本低廉(尤其是作为负载均衡)
Nginx二次开发版
淘宝 Tengine
Registry
libevent: 高性能的网络库 epoll()
3.Nginx基本功能:
静态资源的web服务器,缓存打开的文件描述符:
http、smtp、pop3协议的反向代理服务器
缓存加速、负载均衡
支持fastcgi(fpm LNMP),uWSGI(python)等;Python开发框架是django、java:ssm
模块化(非DSO机制)、过滤器zip、SSI及图像的大小调整
支持SSL(TLS)
扩展功能:
基于名称和IP以及端口的虚拟主机:
支持长连接:keepalive
支持平滑升级
定制访问日志、支持使用日志缓冲区,提高日志存储性能
支持URL rewrite
支持路径别名
支持基于IP和用户的访问控制
支持速率限制,支持并发数限制
4.Nginx的基本架构
一个主进程生成多个worker(工作)进程(由CPU核心数来决定)
事件驱动:epoll(边缘触发)
I/O复用器:select,poll, rt signal(实时信号)
支持Sendfile和sendfile64
支持AIO(异步I/O)和nmap(内存映射)
nginx工作模式
复用I/O、事件驱动、AIO 由1个主进程生成多个worker线程,每个worker响应多个请求。
模块类型
核心模块
Standard HTTP modules(标准http模块)
Optional HTTP modules(可选模块) --with
Mail modules (邮件模块)
第三方模块 (第三方模块需要额外编译指定) --add
5.nginx源码编译
安装方法:
源码:编译安装
官方的rpm包(基于epel源)
(1)源码编译安装nginx步骤:
①:安装基于perl的正则表达式,支持URL重写
yum -y install pcre-devel zlib-devel openssl-devel
pcre-devel:正则表达式包、zlib-devel:压缩包、openssl-devel:加密认证
②:建立nginx用户
useradd -r nginx //由于编译安装,需要创建一个程序用户nginx
③:预配置(根据实际情况添加或修改功能)
如需支持https 许支持ssl yum -y install openssl-devel
./configure --prefix=/usr/local/nginx --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/lock/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_dav_module --with-http_stub_status_module --with-threads --with-file-aio && make && make install
--prefix=/usr/local/nginx:程序安装路径
--conf-path=/etc/nginx/nginx.conf:配置文件
--error-log-path=/var/log/nginx/error.log:错误日志
--http-log-path=/var/log/nginx/access.log:支持httpd访问日志路径
--pid-path=/var/run/nginx.pid:支持pid路径
--user=nginx --group=nginx:属主、属主
--with-http_ssl_module:支持https
--with-http_v2_module:支持http2.0
--with-http_stub_status_module:支持状态显示页
--with-http_realip_module:支持记录原始ip的功能模块
--with-pcre:支持正则表达式
--with-stream:支持上游代理功能
cd /usr/local/nginx/
cd sbin (把/etc/nginx/nginx.conf里面的user ***改成user nginx)
编译完毕后为nginx的主程序设置软链接 ln -sv /usr/local/nginx/sbin/nginx /usr/local/sbin/nginx
nginx (启动服务)、 nginx -s reload (重启nginx)、nginx -s stop (停服)
四、Nginx的web配置
1.nginx配置文件讲解
vim /etc/nginx/nginx.conf
main配置段:全局配置段
event:定义event模型工作模型工作特性
http {
}:定义http协议相关的配置
配置指令:不区分大小写,但要以分号结尾。支持使用变量(内置变量和自定义变量)
主配置段(全局)的指令:
用于调试、定位问题
正常运行必备的配置
优化性能的配置
事件相关的配置
正常运行的必备配置:
①:user USERNAME [group user]
指定运行worker进程的用户和组
user nginx nginx;
②:pid /path/to/pid_file;
指定nginx守护进程的PID文件,注释到配置文件中的,就代表编译在哪就在哪;否则需要停服,更改并创建响应目录
③:worker_rlimit_nofile(相当于ulimit -n)
指定一个worker进程所能够打开的最大文件句柄数
把nginx设置为高并发
①vim /etc/sysctl.conf //内核打开最大数量
②vim /etc/security/limits.conf //安全相关的从不同层面,针对硬件和软件打开文件数量
③vim /etc/nginx/nginx.conf
测试是否实现高并发:
性能优化相关的配置:
①:worker_processes #;
worker进程的个数;通常应略少于CPU物理核心数(可设置为auto)
进程切换 context switch会产生CPU不必要的消耗,进程数要少于CPU。
但能提升缓存命中率
②:worker_cpu_affinity [cpu mask] 目的在于将worker进程绑定在某些CPU上
cpumask由八位数的二进制表示
例如:00000001 00000010 00000100;
③:time_resolution
计时器解析度:降低此值,可减少gettimeofday()系统调用的次数。(提升nginx性能)
④:worker_priority NUMBER:
指明worker进程的优先(nice)值
-20-->100,19-->139
检查语法并重启;
nginx -t nginx -s reload ep_pol(事件驱动模型)
事件相关的配置:
①:accept_mutex {off|on};
master调度用户请求至各worker进程时使用的负载均衡锁,on表示能使多个worker进程轮流、序列化的响应新请求。(使CPU核心数非常均匀的调度)
②:lock_file file
accept_mutex用到的锁文件路径
③:use [epoll|select|poll|rtsig]
指明使用的事件模型,建议让nginx自动选择
④:worker_connections #
设定单个worker进程能处理的最大并发连接数量;
例如 worker_connections 10240;
用于用户调试、定位问题:(若使用调试功能,需在编译的时候--with-debug)
①:daemon {on|off};
是否以守护进程方式运行nginx,调试时应该设置为on。
②:master_process {on|off};
是否以master/worker模型来运行nginx,调试时可以设为off。
③:error_log file
错误日志,包括日志位置和级别。(使用debug级别,需要编译时使用--with-debug选项)
经常需要调整的参数:worker_processes,worker_connections,worker_cpu_affinity,worker_priority
五、Nginx网页重写
1.基于nginx实现上传服务器
client _max_body_size 1m;#设置允许客户端上传单个文件的最大值,默认值为1m,上传文件超过此值会出 413 错误
client body_buffer_size size;#用于接收每个客户端请求报文的 body 部分的缓冲区大小;默认 16k;超出此大小时,其将被暂存到磁盘上的由 client body temp_path 指令所定义的位置 client body temp path path [level1 [level2 [level3]]];
#设定存储客户端请求报文的body部分的临时存储路径及子目录结构和数量,目录名为 16 进制的数字,使用 hash 之后的值从后往前截取1位、2 位、2 位作为目录名
client max body size 100m;
client body buffer size 1024k;
client body_temp_path /usr/share/nginx/client body_temp/ 1 2 2;
2.stub_status {onloff} 状态统计页面,仅能用于 location 上下文
例如:
测试:
状态内容详解:
Active connections: 1 ---->当前所有处于活动的连接
server accepts handled requests
276 276 221 ----> 接受的连接、处理过的连接、处理的请求
Reading:0 Writing:1 Waiting: 0 正在接受的请求;请求完成,处于发送响应报文
状态;处于活动状态的连接数
URL重写(用户请求重定向)
编写格式:rewrite regex replacement flag;
xxx.wma xxx.mp3 /aaa/.jpg /bbb/xxx.gif
www.xxhf123.com/hubei
3.URL重写(用户请求重定向)
编写格式:rewrite regex replacement flag;
xxx.wma xxx.mp3 /aaa/.jpg /bbb/xxx.gif
www.xxhf123.com/hubei hebei
URL重写在企业中应用广泛,当域名发生更改和迁移,以及可以方便SEO优化
(1)return:模式比较简单,客户端可以感知
vim /etc/nginx/nginx.conf
测试:(也可以用301)
②实现直接重定向域名中
必须在/etc/hosts/里面做本地名字解析
测试:http://web.xxhf123.top
(2)rewrite
例如
rewrite ^/images/(.*\.jpg)$ /imgs/$1 break;
rewrite ^/aaa/(.*).jpg$ /bbb/$1.gif break;
rewrite /(.*)$ https://www.xxhf123.com/$1 break;
例:
①rewrite ^/aaa/ /bbb //从aaa目录往bbb里面跳
然后在/usr/local/nginx/html 目录下建立bbb目录,在bbb下面建立index.html
测试:
②做精准匹配,访问gif格式的图片,跳转到jpg里,客户端正在访问的是动态的gif
测试:发现访问的是gif格式
③或者可以针对aaa目录大范围做匹配规则
测试:发现访问aaa的时候,也可以看到动图
④实现跳转https访问
在https里面进行设置(跨协议客户端一定会感知)
把/usr/local/nginx的资源,copy 到https目录下的index
测试:http://web.xxhf123.top/gou.jpg
(3)rewrite四大标记为位 flag分类:
①:last rewrite规则重写完成,不再被其他规则处理,由浏览器对新规则发起请求,重头开始执行。(例如定义Alias别名)
②:break:rewrite规则完成,跳出循环。
③:redirect:以302状态响应码返回新URL,属于临时重定向。
④:permanent:以301状态响应码返回新URL,属于永久重定向。
【注】:测试时要把缓存清干净
例如:rewrite ^/discuz/(.*)$ /skyuc/$1 break; 此种方式已经实质上属于访问新位置资源,但URL没有跳转。
例如:rewrite ^/discuz/(.*)$ https://web.xxhf.com/$1 redirect; 此方式属于URL跳转,URL位置已经发生改变
Last和break:让客户端不感知;操作时有个bug,无论break、last都会跳
①break
break,直接打断,不跳转alias;而last会跳转
测试:http://web.xxhf123.top/aaa/
②进行实验last:
在alias里面创建index.html
测试:
③精准匹配aaa/index.html,然后跳转到bbb下
测试:
redirect和permanent:让客户端感知
redirect:
测试:输入192.168.10.100/bbb
把/usr/local/nginx/html/bbb/gou.gif 移到 /alias
测试:
permanent:301重定向
测试:浏览器输入192.168.10.100/aaa/
4.if上下文以及防盗链
(1)if上下文(通常定义在location或server上下文中)
语法:if (condition) {......}
应用环境:server,location
condition:
①变量名 (变量值为空时,或者以“0”开始,即为false,其他的均为true)
②以变量为基础的比较表达式
③可以基于正则表达式模式匹配操作
~:区分大小写模式匹配
~*:不区分大小写的模式匹配检查
!~和!~*:对上面两种测试取反
④测试文件是否存在 -f !-f
⑤测试指定目录是否存在 -d !-d
⑥测试文件是否存在:-e !-e
⑦检查文件是否有执行权:-x !-x
例如:if ($http_user_agent ~* MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
if ($request_method = POST) {
return 405;
}
进行创建msie目录:
测试结果:
定义一个localtion,不用写mise
测试实验结果:
模拟IE浏览器:
常见变量:
例:
标签:web,http,请求,nginx,--,worker,Nginx From: https://blog.csdn.net/m0_51586984/article/details/137065560