设为首页 收藏本站
查看: 525|回复: 0

[经验分享] I/O模型与Nginx详细配置、优化

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-5-25 09:47:01 | 显示全部楼层 |阅读模式
I/O:
I/O类型:
同步和异步:synchronous, asyncronous
关注的是消息通知机制,即被调用者如何把消息通知给调用者

同步:调用发出之后不会立即返回消息,但一旦返回,则返回即是最终结果;
异步:调用发出之后,被调用方立即返回消息,但返回的并非最终结果;被调用者通过状态、通知机制等来通知调用者,或通过回调函数来处理结果;

阻塞和非阻塞:block, nonblock
关注的是调用者等待被调用者返回调用结果时的状态

阻塞:调用结果返回之前,调用者会被挂起;调用者只有在得到返回结果之后才能继续;
非阻塞:调用者在结果返回之前,不会被挂起,即调用不会阻塞调用者;

I/O模型:
例如:一次读请求操作
(1) 等待数据准备好:从磁盘到内核内存;
(2) 从内核内存复制到进程内存;

blocking IO:阻塞式IO
调用者发送请求后,就被挂起,等待数据从磁盘到内核内存,并等待从内核内存复制到进程内存,最后返回数据,完成一次I/O;
nonblocking IO:非阻塞IO
调用者发送请求后,不被挂起,但需要不断的想内核询问,直到数据从磁盘到内核内存;但在等待从内核内存复制到进程内存时,被挂起,直到返回数据,完成一次I/O
IO multiplexing:复用型IO
select(),poll()
调用者发送请求后,就被挂起,等待在数据从磁盘到内核内存,但是阻塞在select上,而不是内核上,select还可以接收其他I/O请求;但第二阶段还是阻塞的,阻塞在自己的调用上,而不是select上
signal driven IO:事件驱动式IO
通知:
水平触发:多次通知;
边缘触发:只通知一次;
调用者发送请求后,不会被挂起,而数据从磁盘到内核内存完成后会通知调用者;但第二阶段还是阻塞的
asynchronous IO:异步IO
调用者发送请求后,不会被挂起,而是在所有阶段都已完成后会通知调用者
web服务器要处理两路I/O:网络I/O [ 通过内核接收用户请求 ]和磁盘I/O [ 通过内核向磁盘发出请求 ]

Nginx:
Nginx:engine X
Tengine  nginx淘宝的二次开发版

Nginx特性:
模块化设计、较好的扩展性;
nginx不支持动态装卸载而Tengine支持
高可靠
使用主控进程master+工作进程worker组成,master不负责处理用户请求而是启动一个worker,并将用户请求交个一个worker去处理
低内存消耗
一个线程响应多个请求
10000个keep-alive模式下的connection,仅需要2.5MB的内存;
支持热部署
不停机而更新配置文件、日志文件滚动、升级程序版本;

支持事件驱动event、异步I/O[AIO]、内存映射[mmap];

基本功能:
静态资源的web服务器,能缓存打开的文件描述符;
http、smtp、pop3协议的反向代理服务器;
缓存加速、负载均衡;
支持FastCGI(fpm, LNMP), uWSGI(Python)等;
模块化(非DSO机制)、过滤器zip、SSI及图像的大小调整;
支持SSL;

扩展功能:
基于名称和IP的虚拟主机;
支持keepalive
支持平滑升级
定制访问日志、支持使用日志缓冲区提供日志存储性能;
支持url rewrite
支持路径别名
支持基于IP及用户的访问控制
支持速率限制,支持并发数限制

Nginx的基本架构:
一个master进程,生成一个或多个worker进程;
事件驱动:epoll(默认使用边缘触发)
I/O复用器支持:select,poll, rt signal
支持sendfile, sendfile64:磁盘从内核空间直接构建响应报文发送,而不再经过用户空间。
支持异步I/O [ AIO ]
支持内存映射[mmap]

nginx的工作模式:非阻塞、事件驱动、由一个master进程生成多个worker线程,每个worker响应n个请求;
支持的并发连接数:worker* n,但是受限于套接字数量[65535]限制

模块类型:
核心模块
Standard HTTP modules 标准的HTTP协议模块
Optional HTTP modules 可选的HTTP协议模块
Mail modules 邮件模块
3rd party modules 第三方模块

安装方法:
源码:编译安装
制作好的程序包:rpm包,在epel源中

编译安装:
#useradd -r nginx
#./configure --prefix=/usr/local/nginx --conf-path=/etc/nginx/nginx.conf--user=nginx --group=nginx --error-log-path=/var/log/nginx/error.log--http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx/nginx.pid--lock-path=/var/lock/nginx.lock --with-http_ssl_module--with-http_stub_status_module --with-http_gzip_static_module--with-http_flv_module --with-http_mp4_module--http-client-body-temp-path=/var/tmp/nginx/client--http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fastcgi--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi
#make && make install
#mkdir -pv /var/tmp/nginx/{client,proxy,fastcgi,uwsgi}


--prefix=/usr/local/nginx
指定安装路径
--conf-path=/etc/nginx/nginx.conf
指定配置文件生成路径
--user=nginx
指定运行时以哪个用户的身份运行
--group=nginx
设置工作组
--error-log-path=/var/log/nginx/error.log
设置错误日志位置
--http-log-path=/var/log/nginx/access.log
设置访问日志位置
--pid-path=/var/run/nginx/nginx.pid
设置pid文件位置
--lock-path=/var/lock/nginx.lock
设置锁文件位置
--with-http_ssl_module
支持https
--with-http_stub_status_module
支持server-status状态页查看
--with-http_gzip_static_module
支持gzip压缩
--with-http_flv_module
支持流媒体
--with-http_mp4_module
支持MP4
--http-client-body-temp-path=/var/tmp/nginx/client
指定客户端临时的body目录
--http-proxy-temp-path=/var/tmp/nginx/proxy
指定临时的proxy目录
--http-fastcgi-temp-path=/var/tmp/nginx/fastcgi
指定临时的fastcgi目录
--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi
指定临时的uwsgi目录
--with-debug
支持调试模式

设置环境变量
#vim /etc/profile.d/nginx.sh
exportPATH='/usr/local/nginx/sbin':$PATH
#. /etc/profile.d/nginx.sh

启动:nginx
  若设置环境变量就用这种启动/usr/local/nginx/sbin/nginx
新改动配置生效的方式:nginx -s reload
支持的参数
nginx -s reload | stop| quit |reopen


配置文件:

main配置段:全局配置段
event{}: 定义event模型工作特性
http {} : 定义http协议相关的配置

配置指令:要以分号结尾,语法格式:
directivevalue1 [value2...]

支持使用变量:
内置变量
自定义变量:
setvar_name value

主配置段的指令:
用于调试、定位问题
正常运行必备的配置
优化性能的配置
事件相关的配置


main主配置段的指令:
正常运行的必备配置:

1、user USERNAME[GROUPNAME];
指定运行worker进程的用户和组;若在编译安装时指定,会被注释用默认指定的用户
usernginx nginx;

2、pid/path/to/pid_file;
指定nginx守护进程的pid文件;
pid/var/run/nginx/nginx.pid;

3、worker_rlimit_nofile#;
指定所有worker进程所能够打开的最大文件数;需要手动添加这一行一般设为51200,

性能优化相关的配置:

1、worker_processes #;
worker进程的个数;通常应该略少于CPU物理核心数;总核心数-1或-2

2、worker_cpu_affinity   cpumask ...;
将工作进程绑定到cpu的设置
优点:提升缓存的命中率;
cpumask:
假设一共有四颗cpu,表示方法,超过8颗使用更多的位数
cpu1:0000 0001
cpu2:0000 0010
cpu3:0000 0100
cpu4:0000 1000

worker_cpu_affinity00000001 00000010 00000100;

3、timer_resolution
计时器解析度;若对时间解析度要求不高应降低此值,可减少gettimeofday()系统调用的次数;此值越高,精准度越高,消耗的资源越高;反之,越低
timer_resolution 100ms

4、worker_priority number
指明worker进程的优先级,使用的是nice值;
-20,19
worker_priority number -10

事件相关的配置:
1、accept_mutex{off|on};
master调度用户请求至各worker进程时使用的负载均衡锁;on表示能让多个worker轮流地、序列化地去响应新请求;
应启用:accept_mutex on;

2、lock_file file;
accept_mutex互斥锁用到的锁文件路径;

3、use[epoll|rtsig|select|poll];
指明使用的事件模型;建议让Nginx自行选择;

4、worker_connections #;
设定单个worker进程所能够处理的最大并发连接数量;
一般设为:worker_connections 51200;

所能接收的并发数为worker_connections * work_processes,若这个值大于65535就不会有效了

用户于调试、定位问题:
必须编译时--with-debug才可以使用
1、daemon{on|off};
是否以守护进程方式运行nginx;调试时应该设置为Off,就会把调试信息输出到前台;

2、master_process{on|off};
是否以master/worker模型来运行nginx; 调试时可以设置为off;

3、error_log file| stderr | syslog:server=address[,parameter=value] | memory:size [debug | info| notice | warn | error | crit | alert | emerg];
error_log 位置 级别;        级别可以省略,使用默认级别
error_log /var/log/nginx/err.log
若要使用debug级别,需要在编译nginx时使用了--with-debug选项;

总结:常需要进行调整的参数
worker_processes,worker_connections, worker_cpu_affinity, worker_priority


Nginx作为web服务器时使用的配置:
http {}:由ngx_http_core_module模块所引入;

配置框架:
http{
upstream{
...
}

server{
location  URL {
root"/path/to/somedir";
...
}
# 类似于httpd中的<Location>,用于定义URL与本地文件系统的映射关系;
locationURL {
if... {
...
}
}
}
# 每个server类似于httpd中的一个<VirtualHost>;
server{
...
}

}

注意:与http相关的指令仅能够放置于http、server、location、upstream、if上下文,但有些指令仅应用于这5种上下文中的某些种;

配置指令:
1、server {}
定义一个虚拟主机;

    server {
//监听IP和端口,ip可以省略listen 80
        listen 172.16.37.10:80;
//主机名称
        server_name www.lixin.com;
//设置访问日志位置 和 日志格式
        access_log/var/log/nginx/access.log combined;

        location /{
//设置html页面存放位置
root /web;
//设置默认首页文件,从左到右,若找不到index.html就去找index.htm
index index.html index.htm
        }
     }                                

2、server_name NAME [...];
后可跟多个主机;名称还可以使用正则表达式(~)或通配符;

(1) 先做精确匹配检查;
(2) 左侧通配符匹配检查:*.lixin.com
(3) 右侧通配符匹配检查:如mail.*
(4) 正则表达式匹配检查:如 ~^.*\.lixin\.com$
(5) default_server;


server{
server_name www.lixin.com;
}

server{
server_name *.lixin.com;
}

server{
server_namemail.*
}

3、location [ = | ~ | ~* |^~ ] uri { ... }
功能:允许根据用户请求的URI来匹配定义的各location;匹配到时,此请求将被相应的location配置块中的配置所处理,例如做访问控制等功能;

=:精确匹配检查;
^~:URI的前半部分匹配,不支持正则表达式;
~: 正则表达式模式匹配检查,区分字符大小写;
~*: 正则表达式模块匹配检查,不区分字符大小写;

匹配的优先级:精确匹配(=)、^~、~、~*、不带任何符号的location;

server{
listen80;
server_name www.lixin.com;
location/ {
root"/vhosts/web1";
}

location/bbs/ {
             root   /;
             index  index.html index.htm;
}

location ~*/bbs {
root"/";
}
}

http://www.lixin.com/index.html   -->  /vhosts/web1/index.html
http://www.lixin.com/bbs/index.html  --> /bbs/index.html 匹配到第3个location,以表示把http://www.lixin.com/bbs/ 当做 /


4、alias path;
用于location配置段,定义路径别名

location/images/ {
root"/vhosts/web1";
}
http://www.lixin.com/images/a.jpg -->/vhosts/web1/images/a.jpg

location/images/ {
alias"/www/pictures";
}
http://www.lixin.com/images/a.jpg -->/www/picuter/a.jpg

注意:root表示指明路径为对应的location "/" URL; alias表示路径映射,即location指令后定义的URL是相对于alias所指明的路径而言;

5、error_page code [...][=code] URI | @name
根据http响应状态码来指明特用的错误页面;

error_page404 /404_customed.html

[=code]:以指定的响应码进行响应,而不是默认的原来的响应;默认表示以新资源的响应码为其响应码;

6、基于IP的访问控制
allowIP/Network;
denyIP/Network;
例:
allow172.16.0.0/16;
denyall;
7、基于用户的访问控制
auth_basic "显示提示信息";
auth_basic_user_file "/PATH/TO/PASSWORD_FILE";
账号密码文件建议使用htpasswd来创建;
例:
auth_basic"Input passwd";
auth_basic_user_file /usr/local/nginx/.htpasswd;
htpasswd -c /usr/local/nginx/.htpasswd lx

8、https服务

生成私钥,生成证书签署请求,并获得证书;

    server {
        listen       443 ssl;
        server_name  www.lixin.com;

        ssl_certificate      /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key  /etc/nginx/ssl/nginx.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   /vhosts/web1;
            index  index.html index.htm;
        }
   }                                       

9、stub_status {on|off};
开启状态页
仅能用于location上下文;

        location /status {
            stub_status on;
            allow 172.16.0.0/16;
            deny all;
        }

结果示例:               
Active connections: 6   # 当前所有处于打开状态的连接数;
serveraccepts handled requests
241 241 431
(1) 已经接受过的连接数
(2) 已经处理过的连接数
(3) 已经处理过的请求数;在“保持连接”模式下,请求数量可能会多于连接数量;
Reading:0 Writing: 1 Waiting: 5         
Reading:正处于接收请求状态的连接数;
Writing: 请求已经接收完成,正处于处理请求或发送响应的过程中的连接数;
Waiting:保持连接模式,且处于活动状态的连接数;

10、URL重写
语法:rewrite 正则表达式 替换 flag;
例如:
...
rewrite^/images/(.*\.jpg)$ /imgs/$1 break;
rewrite^/imgs/(.*\.jpg)$ /images/$1 break;
....


flag:
last:一旦此rewrite规则重写完成后,就不再被后面其它的rewrite规则进行处理;而是由User Agent重新对重写后的URL再一次发起请求,并从头开始执行类似的过程
break:一旦此rewrite规则重写完成后,由User Agent对新的URL重新发起请求,且不再会被当前locatrion内的任何rewrite规则所检查;
redirect:以302响应码(临时重定向)返回新的URL;
permanent:以301响应码(永久重定向)返回新的URL;

11、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/$1 break;
}

12、防盗链
location~* \.(jpg|gif|jpeg|png)$ {
# 允许www.lixin.com这个网站对这些种类图片的引用是合法的
valid_referer none blocked www.lixin.com;     
# $invalid_referer表示除了上面定义的合法的引用,其他都被归为$invalid_refere这个不合法的引用
if($invalid_referer) {
}
}

13、自定义访问日志格式
    log_format main  '$remote_addr - $remote_user[$time_local] "$request" '
                      '$status $body_bytes_sent"$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"';

    access_log logs/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选项;

5、client_header_timeout#;
读取http请求报文首部的超时时长;

6、client_body_timeout#;
读取http请求报文body部分的超时时长;

7、send_timeout #;
发送响应报文的超时时长;

fastcgi的相关配置:
LNMP:php启用fpm模型;
location~ \.php$ {
    root           /var/www/html;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME /var/www/html$fastcgi_scri    pt_name;
   # fastcgi_params在/etc/nginx/下  ,若编译时没指定配置文件则在/usr/local/nginx/conf/下
    include        fastcgi_params;   
}



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-70371-1-1.html 上篇帖子: nginx基础及其相关配置 下篇帖子: 配置nginx作为web server 模型
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表