五种IO机制,Nginx web重点基础详解
Nginx
1.高并发链接:官方测试能够支持5W并发连接,在实际生产环境中跑到2~3万并发连接数。
2.内存消耗少:在3W并发链接下,开启的10个Nginx进程才消耗150M内存
3.配置文件非常简单:风格跟程序一样通俗易懂。
4.陈本低廉:Nginx为开源软件,可以免费使用。而购买F5 BIG-IP NetScaler等硬件负载均衡交换机则需要十多万至几十万人民币。
5.支持Rewrite重写规则:能够根据域名,URL的不同,将HTTP请求分到不同的后端服务器群组。
6.内置的健康检查功能:如果Nginx Proxy后端的某台Web服务器宕机了,不会影响前端访问。
7.节省带宽:支持GZIP压缩,可以添加浏览器本地缓存的Header头,可以设置压缩级别。
8.稳定性高:用于反向代理,宕机的概率微乎其微,master,worker。
9.模块化设计:模块可以动态编译,不耦合,灵活组建性非常好!
10.外围支持好:文档全,二次开发和模块较多
11.支持热部署:可以不停机重载配置文件
12.支持事件驱动,AIO,mmap等性能优化
理解要点:异步IO,mmap
HEADER
通用首部
请求首部:
If-Modified-Since , If-None-Match
响应首部
实体首部
扩展首部
Pv:page view 页面整个一次的浏览量
Uv:user view 独立IP
Web页面
1.加速
缓存加速
基于任何浏览器对单个域名访问的多线程是有限的,在站点上做加速时,比如在同一主页面上的资源,按照资源类型划分,分别对应多个域名,那么就能起到很高的页面加速效果。
2.认证
基于IP认证:
基于用户认证:
basic
digest
3.资源认证:
Alias
DocumentRoot
I/O类型
同步和异步:synchronous,asynchronous
关注的是消息通知机制
同步:调用发出之后不会立即返回,但一旦返回,则返回即使最终结果。
异步:调用发出之后,被调用方立即返回消息,但返回的并非最终结;被调用者通过状态,通知机制等,来通知调用者,或通过回调函数来处理结果。
阻塞和非阻塞:block,nonblack
关注的是调用者等待被调用者返回调用结果时的状态
阻塞:调用结果返回之前,调用者会被挂起;调用者只有在得到返回结果之后才能继续;
非阻塞:调用者在结果返回之前,不会被挂起,即调用不会阻塞调用者;
I/O模型
blocking IO(阻塞式IO)
nonblocking IO(非阻塞式IO)
IO multiplexing(复用型IO)
select() poll()
signal driven IO(事件驱动型IO)
通知:
水平触发:多次通知
边缘触发:只通知一次,但可以回调
asynchronous IO(异步IO)
例如:一次read操作:
主要的两步:(1)内核进程将磁盘中的内容读到内核内存
(2)用户进程将内核内存中的内容copy一份到用户内存
而IO操作即主要为(2)
1.阻塞性IO
在内核进行(1)(2)步骤时,进程被‘不可中断式挂起’,什么事都做不了,一直在等待。
一个进程通常情况下,只能处理单路IO,例如这个用户请求,起码经过网络IO和磁盘IO两种IO方式。
2.非阻塞式IO
第(1)步是忙等待状态,第(2)步还是阻塞模式,所有非阻塞模式并不比阻塞式高多少
阻塞式IO和非阻塞式IO都是古老的单进程模型,一个进程响应一个任务,都是串行模式。
3.复用型IO(多路IO)
在用户请求与内核处理之间有一个内核中的select(),poll(),
select()最多承载1024
这种多路模式就相当于在内核中加了一个助理,能把请求分发给内核中不同的功能去处理,但是实际也是阻塞的,阻塞在select上,并没阻塞在用户进程上,所以还可以进行别的IO请求。
4.事件驱动型IO
第(1)步,不用进行忙等,完成了内核会通知。第(2)部还是阻塞式的
不用阻塞,不用忙等,这样的话一个进程可以处理多个响应请求(这是真正的实现一个响应多个请求),虽然这点有了进步,但是第(2)步仍然是阻塞的,所以性能的提高不会非常大。这种处理方式即为callback处理方式。
引入了两种通知机制:水平触发(多次通知,直到你拿到)
边缘触发(只通知一次,但我会把资源发在某处,你来了问我取就行(回调方法))
5.异步IO
第(1)(2)阶段都不用阻塞,用户请求之后,进程将资源扔给内核,内核处理完毕,直接将数据返回给进程,进程直接打包发走,实现了真正的1对n,所以非常优秀
Nginx支持异步IO,还更支持mmap机制,所以它的性能优秀
五种IO的比较图
有通知机制的notification叫做异步IO
Nginx
Nginx: engine X,Tengine ,Registry
libevent:高性能的网络库epoll():nginx就继承了其的epoll()这种事件驱动方法。
Nginx特性:
模块化设计,较好的扩展性,淘宝改进的tengine支持动态模块可装载
高可靠
master–> worker
低内存消耗
10000个keep-alive模式下的connection,仅需要2.5MB的内存
支持热部署
不停机而更新配置文件,日志文件滚动,升级程序版本;
支持事件驱动机制,异步IO,mmap内存映射;
基本功能:
静态资源的web服务器,能缓存打开的文件描述符;
http,smtp,pop3协议的反向代理服务器
缓存,负载均衡机制:
支持FastCGI(fpm,LNMP),uWSGI(python)等;
模块化(非DSO机制),过滤器zip,SSI及图像的大小调整;
扩展功能:
基于名称和IP的虚拟主机;
支持keepalive
支持平滑升级
定制访问日志,支持使用日志缓冲区提供日志存储性能;
支持url rewrite
支持路径别名
支持基于IP及用户的访问控制
支持速率限制,支持并发数限制
Nginx的基本运行图
Nginx的基本架构:
1. 一个master进程,生成一个或多个worker进程(线程)
它支持sendfile机制:
磁盘通过内核的指令进行操作,然后内核将操作的结果直接打包成数据报文,通过网卡发送,其中省略了多次返回到用户进程的状态,这样提高 了效率。
2. 基于事件驱动:linux系统epoll(边缘出发),BSD系统kqueue(),/dev/poll
nginx都支持以上不同系统的事件驱动机制
IO复用:复用器:select,poll,rt signal
支持sendfile(该方式下发送内容大小有限,一般为几k),sendfile64(相比sendfile,每次发送的内容更大一点)
支持AIO
支持mmap
Nginx的工作模式:非阻塞,事件驱动,由一个master进程生成多个worker线程,每个worker响应n个请求:
作为web服务器而言,总体支持的最大请求书为worker* n,但是套接字最多为65535个,最多5w左右,但是在反向代理模式下会更少一些
模块类型:
核心模块
Standard HTTP modules 标准HTTP模块
Optional HTTP modules 可选的HTTP模块
Mail modules 邮件模块
3rd party modules 第三方模块(在源码编译时,需要手动添加编译)
安装方法:
1. 源码安装
2. 制作好的程序包:rpm包,
1. 源码安装Niginx
a) 步骤
groupadd –r nginx
useradd –g nginx –r nginx
b) 常用第三方模块
i. --with-http_ssl_module开启https方式
c) 安装命令
./configure --prefix=/home/hxl/Test_nginx --user=nginx --group=nginx--error-log-path=/home/hxl/Test_nginx/logs/error.log--http-log-path=/home/hxl/logs/access.log--pid-path=/home/hxl/log/nginx/nginx.pid --lock-path=/home/hxl/Test_nginx/lock/nginx.lock--with-http_ssl_module --with-http_stub_status_module--with-http_gzip_static_module --with-http_flv_module--http-client-body-temp-path=/home/hxl/Test_nginx/clinet--http-proxy-temp-path=/home/hxl/Test_nginx/proxy--http-fastcgi-temp-path=/home/hxl/Test_nginx/fastcgi--http-uwsgi-temp-path=/home/hxl/Test_nginx/uwsgi
make && make install
修改nginx.conf第一行为user root;
找到nginx启动命令启动nginx
测试访问
d) 配置文件
main配置段: 全局配置段
event { }: 定义event模型工作特性
http { }: 定义http协议相关配置
配置指令:要以分号结尾,语法格式:
directivevalue1 {value2…}
支持使用变量
内置变量:
模块会提供几建变量定义
自定义变量:
setvar_namevalue
主配置段的指令:
用于调试,定位问题
正常运行必备的配置
优化性能的配置
事件相关的配
上述内容回顾
I/O模型,nginx基本安装
e) 主配置段的指令:
正常运行的必备配置:
1. user USERNAME [GROUPNAME];
指定运行worker进程的用户和组;
组名字省略的话,默认使用与用户名相同的组
user nginx nginx;
2. pid /path/to/pid_file;
指定nginx守护进程的pid文件;
pid /home/hxl/log/nginx/nginx.pid
3. worker_rlimit_nofile <number>;
更改rlimit_nofile所有worker进程一共打开的最大文件数()的限制。用于增加限制而不重新启动主进程
4. worker_rlimit_core一般不调整
更改rlimit_core所有worker进程的核心文件()的最大大小的限制
优化性能相关的配置:
1. worker_processes #;
worker进程的个数:通常应该略少于CPU物理核心数;
不过较新版本的都支持auto这种自动判断数量的方式了,可以直接设置为auto
2. worker_cpu_affinitv cpumask …;保证了缓存的有效性,可能会提升缓存的命中率。
设定将worker进程绑定在那些cpu上
context switch会产生CPU的不必要的消耗
cpumask:
0000 0000
0000 0001 一号 cpu
0000 0010 二号 cpu
…
不过较新版本的都支持auto这种自动判断数量的方式了,可以直接设置为auto(很方便,不用再记什么参数了)
3. timer_resolution;
计时器解析度:降低此值,可减少gettimeofday()系统调用次数。默认情况下,gettimeofday()每次接收到内核事件时都会调用它(在生产环境中,并没有设置这个)。
例:
timer_resolution100ms;
4. worker_prioritynumber;
定义worker进程的调度优先级,如通过nice命令完成的;
赋值number表示较高的优先级。允许范围通常在-20到19。
例:
worker_priority -10
f)事件相关的配置
1. accept_mutex{on | off};
如果accept_mutex启用,woker进程将轮流接受新链接。
还有一个_delay,设置等待时间的
2. lock_file file;
accept_mutex 用到的锁文件路径
3. use <method> [epoll|rtsig|select|poll];
指定要使用的连接处理method,通常不需要明确指定它,因为nginx默认使用最有效的方法。
4. woker_connections
设置单个woker进程可以打开的同时连接的最大数量。
g)用户调试,定位问题:
1. daemon { on | off };
是否以守护进程方式运行nginx,调试时应该设置为off;
2. master_process { on | off };
是否以master/worker模型来运行nginx;
3. error_log file [level]
第一个参数定义一个file将存储日志的参数。
第二个参数决定的level记录的,并且可以使以下中的一个:
debug,info,notice,warn,error,crit,alert或emerg。上述日志级别按严重性增加的顺序列出。
若要使用debug级别,需要在编译nginx时使用–with-debug选项;
h) 总结,常需要进行调整的参数
woker_processes,worker_connections,worker_cpu_affinity,worker_priority
i) 新改动配置生效的方式
nginx –s reload
stop,quit,reopen
Nginx作为web服务器时使用的配置:
http{}:由ngx_http_core_module模块所引入:
配置框架:
http {
upstream {
…
}
server {
location {
root “/path/to/somedir”;
} #类似于httpd种的,用于定义URL与本地文件系统的映射关系;
location URL {
if … {
…
}
}
} #每个server类似于httpd中的一个;
server {
…
}
}
注意:与http相关的指令仅能够放置于http,server,location,upstream,if上下文,但有些指令仅应用与这5种上下文种的某些种;
配置指令:
1. server { }
用来定于虚拟主机的
root指定的目录,index所载入的文件都可以放在任意位置
2. listen
指定监听的地址和端口:
listen address[:port];
listen port;
3. server_name NAME […];
后可跟多个主机:名称还可以使用正则表达式(~)或通配符;
(1) 先做精确匹配检查:
(2) 左侧通配符匹配检查:*.magedu.com
(3) 右侧通配符匹配检查:如mail.*
(4) 正则表达式匹配检查:如~^.*\.magedu\.com$
(5) default_server;
server {
server_name www.testnginx.com;
}
server {
server_name *.testnginx.com
}
server {
server_name mail.*
}
4. root path;
设置资源路径映射,用于指明请求的URL所对应的资源所在的文件系统上的起始路径;
5. location [ = | ~ | ~* | ^~ ] uri [ … ]
location @name […]
功能:允许根据用户请求的URI来匹配定义的各location;匹配到时,此请求将被相应的location配置块中的配置所处理,例如做访问控制等功能;
=: 精确匹配检查
~: 正则表达式模式匹配检查,区分字符大小写
~*: 正则表达式模式匹配检查,不区分字符大小写
^~: URI的前半部分匹配,不检查正则表达式
匹配的优先级:精确匹配(=),^~,~,~*,不带任何符号的location;
server {
listen 80;
server_name www.testnginx.com;
location / {
root “/vhosts/web1”;
}
location /images/{
root “/vhosts/images”;
}
location ~*\.php$ {
fcgipass
}
}
http://nginx.org/en/docs/http/ngx_http_core_module.html#location【官方地址,以上所有的配置指令,官方都有明确解释,前提是不被墙】
测试location使用规则,可以手动写一写测试一下,这个规则还是很神奇的(神奇之处(路径的相对性问题),会在root和alias中做了详细分析),里面有一些规则,不好表达,需要自己根据效果感受一下的!
6. alias path
用于location配置段,定义路径别名
说明解释:
location /images/ {
root html;
}
http://127.0.0.1:8080/images/index.html <—— /html/images/index.html (真实地址)
location /images/ {
alias /www/pictures/;
}
http://127.0.0.1:8080/images/index.html <—— /www/pictures/index.html(真实地址)
注意(理解例子,就不用看这么绕来绕去的话了):
root表明指明路径为对用的location“/” URL;
alias表明路径映射,即location指令后定义的URL是相对于alias所指明的路径而言
7. index file;
默认主页面:
index index.php index.html;
8. error_page code […] [=code] URI| @name
根据http响应状态码来指明特用的错误页面;
error_page 404/404_customed.html
[=code]:以指定的响应码进行响应,而不是默认的原来的响应;默认表示以新资源的响应码为其响应码
(还可以更改返回的响应码,这样浏览器会显示你更改过的响应码类型)
9. 基于IP的访问控制
allow IP/IP段
deny IP/IP段/all
可以放在server中,也可以放在location中,作用域不同;
10. 基于用户的访问控制
basic,digest
auth_basic “[说明认证]”
auth_basic_user_file “/PATH/TO/PASSWORD_FILE”
账号密码文件建立使用htpasswd(改名了需下载httpd)来创建:
命令为 htpasswd –c –m [/PATH/TO/PASSWORD_FILE] <name>
11. https服务(普通手动添加方式较多,等接下来详细研究企业购买证书并安装的流程)
生成私钥,生成证书签署请求,并获得证书
在nginx.conf文件中有关于完整版的配置模板
12. stub_status {on|off};
仅能用于location上下文;
状态信息允许IP可以自己设定
浏览器效果图如下
Active connections: 2#当前所有处于打开状态的连接数;
server accepts handled requests
19230 19230 74
(接受过的连接数)(处理过的连接数)(处理的请求,在“保持连接”模式下,请求数量可能会多于连接数量;)
Reading:正处于接受请求状态的连接数;
Writing:请求已经接受完成,正处于处理请求或发送响应的过程中的连接数;
waiting:保持连接模式,且处于活动状态的连接数
13. rewrite [对于URL处理]
rewrite regex replacement flag;
例如:rewrite ^/images/(.*\.jpg)$/imgs/$1 break;
http://www.testnginx.com/images/a/b/1.jpg —(根据设置规则的重定向)—> http://www.testnginx.com/imgs/a/b/1.jpg
flag:
last: 一旦此rewrite规则重写完成后,就不在被后面其它的rewrite规则进行处理,而是由User Agent重新对重写后的URL再一次发起请求,并从头开始执行类似的过程
break: 一旦此rewrite规则重写完成后,由User Agent对新的URL重新发起新请求,且不再会被当前locatrion内的任何rewrite规则所检查
redirect: 以302响应码(临时重定向)返回新URL;
permanent: 以301响应码(永久重定向)返回新URL;
14. if
语法:if (condition){…}
应用环境: server, location
condition:
(1) 变量名:
变量值为空串,或者以“0”开始,则为false,其它的均为true;
(2) 以变量为操作数构成的比较表达式
可以使用=,!=类似的比较操作符进行测试;
(3) 正册表达式的模式匹配操作
~: 区分大小写的模式匹配检查
~*: 不区分大小写的模式匹配检查
!~和!~*: 对上面两种测试取反
(4) 测试文件可用性: -f,!-f
(5) 测试指定路径为目录的可能性:-d,!-d
(6) 测试文件的存在性:-e,!-e
(7) 检查文件是否有执行权限: -x,!-x
例如:
if ($http_user_agent~* MSIE) {
rewrite^(.*)$/msie/$1break;
}
说明:通过$http_user_agent检测用户使用哪种操作系统/版本号等,MSIE是微软推出的网页浏览器,如果检测用户是用微软的这款浏览器的话,它会将URL按照规则重定向个URL。
15. 防盗链
location ~* \.(jpg|gif|jpeg|png)$ {
valid_referer noneblocked www.testnginx.com; #设置允许连接地址
if ($invalid_referer) { #设置发生盗链的重定向地址
rewrite^/http://www.testnginx.com/403.html
}
}
16.定制访问日志格式
log_formatmain '$remote_addr - $remote_user[$time_local] "$request" '
'$status $body_bytes_sent"$http_referer" '
'"$http_user_agent""$http_x_forwarded_for"';
access _loglogs/access.log main;
(格式名)
注意:此处可用变量为nginx各模块内建变量;
网络连接相关的配置:
1. keepalive_timeout #; 长连接的超时时长,默认75s;
2. keepalive_requests #; 在一个长连接上所能够允许请求的最大资源数;
3. keepalive_disable [msie6|safari|none];
为指定类型的User Agent禁用长连接;
4. tcp_nodelayon|off;
是否对长连接使用TCP_nodelay选项;一般设为on,多小都发送;
5. client_header_timeout#;读取http请求报文首部的超时时长;
6. client_body_timeout#;读取http请求报文Body部分的超时时长;
7. send_timeout#;发送响应报文的超时时长;
fastcgi的相关配置:
LNMP:php启用fpm模型;
php模块nginx配置模板中都有,可以看着模板进行编辑测试,原理采用反带方式,测试时注意iptables是否开启了外部网络访问该9000端口的权限。