Nginx之一
libevent :高性能的网络库
epoll()
nginx调用了libevent库中的epoll
Epoll --异步模型
- 支持一个进程打开大数目的socket描述符
- IO效率不随FD数据增加而线性下降
- 使用mmap加速内核与用户空间的消息传递
- 边缘出发和水平触发
Nginx 采用C进行编写,不论是系统资源开销还是CPU使用率都比Perlbal要好很多
优点:
主要应用类别:
- 使用Nginx结合FastCGI运行PHP、JSP、Perl等程序
- 使用Nginx作反向代理、负载均衡、规则过滤
- 使用Nginx运行静态HTML页面、图片
- Nginx与其他新技术的结合应用
基本功能:
静态资源的web服务器,能缓存打开的文件描述符;
http、smtp、pop3协议的反向代理服务器;
缓存加速、负载均衡;
支持FastCGI(fpm、LNMP),uWSGI(Python);
模块化(非DSO机制)、过滤器zip、SSI及图像的大小调整;
支持SSL
扩展功能:
基于名称和IP的虚拟主机;
支持平滑升级,支持url rewrite,支持路径别名;
支持keepalive;
支持基于IP及用户访问控制;
支持速率限制,支持并发数限制
三、Nginx的模块与工作原理
Nginx由内核和模块组成,仅仅通过查找配置文件将客户端请求映射到一个location block(location是nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。
3.1、 Nginx的模块从结构上分为:核心模块、基础模块和第三方模块,
核心模块:HTTP模块、EVENT模块和MAIL模块等;
基本模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块等;
第三方模块:HTTP Upstream 、Request Hash 模块、Notice模块和HTTP Access Key模块等
核心模块--基本功能和指令,如进程管理和安全
事件模块--在Nginx内配置网络使用的能力
配置模块--提供包含机制
http://nginx.org/en/docs/http/ngx_http_core_module.html
3.2、Nginx模块从功能上分为三类。分别是:
Handlers(处理器模块) 此类模块直接处理请求,并进行输出内容和修改headers信息等操作。handlers处理器模块一般只能有一个;
Filters(过滤器模块) 此类模块主要对其它处理器模块输出的内容进行修改操作,最后由Nginx输出;
Proxies(代理类模块)就是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如fastcgi等操作交互,实现服务器代理和负载均衡等功能。
Nginx 的模块直接被编译进Nginx,因此属于静态编译方式。启用Nginx后,Nginx的模块会被自动加载,不像在Apache一样,首先将模块编译为一个so文件,然后在配置文件中指定是否进行加载。在解析配置文件时,Nginx的每个模块都可能去处理某个请求,但是同一个处理请求只能有一个模块来完成
Nginx的模块下一次常规的HTTP请求和相应的过程
NGINX整体架构
NGINX工作模式:非阻塞、事件驱动、由一个master进程生成多个worker线程,每个workerx相应n个请求。
支持sendfile,sendfile64
支持AIO、mmap
事件驱动模型: epoll(边缘触发) kqueue模型 用于FreeBSD 4.1及以上版本 OpenBSD2.9、NetBSD2.0及Mac os X平台上。都是通过避免轮询操作提供效率。该模型同时支持条件触发(也叫水平触发,只要满足条件就触发一个事件)和边缘触发(每个状态变化时,就触发一个事件) /dev/poll 主要用在unix衍生平台的高效事件驱动模型,主要在solaris7 11/99及以上版本 HP/UX11.22以上版本等 eventport 模型,用于支持solaris 10及以上版本平台的高效事件驱动模型。
nginx参数: --prefix=<path> 指向安装目录 --sbin-path=<path> 指向(执行)程序文件(nginx) --conf-path=<path> 指向配置文件(nginx.conf) --error-log-path=<path> 指向错误日志目录 --pid-path=<path> 指向pid文件(nginx.pid) --lock-path=<path> 指向lock文件(nginx.lock)(安装文件锁定,防止安装文件被别人利用,或自己误操作。) --user=<user> 指定程序运行时的非特权用户 --group=<group> 指定程序运行时的非特权用户组 --builddir= 指向编译目录 --with-rtsig_module 启用rtsig模块支持(实时信号) --with-select_module 启用select模块支持(一种轮询模式,不推荐在高载环境下使用)禁用:--without-select_module --with-poll_module 启用poll模块支持(功能与select相同,与select特性相同,为一种轮询模式,不推荐在高载环境下使用) --with-file-aio 启用file aio支持(一种APL文件传输格式) --with-ipv6 启用ipv6支持 --with-http_ssl_module 启用ngx_http_ssl_module支持(使支持https请求,需已安装openssl) --with-http_realip_module 启用ngx_http_realip_module支持(这个模块允许从请求标头更改客户端的IP地址值,默认为关) --with-http_addition_module 启用ngx_http_addition_module支持(作为一个输出过滤器,支持不完全缓冲,分部分响应请求) --with-http_xslt_module 启用ngx_http_xslt_module支持(过滤转换XML请求) --with-http_image_filter_module 启用ngx_http_image_filter_module支持(传输JPEG/GIF/PNG 图片的一个过滤器)(默认为不启用。gd库要用到) --with-http_geoip_module 启用ngx_http_geoip_module支持(该模块创建基于与MaxMind GeoIP二进制文件相配的客户端IP地址的ngx_http_geoip_module变量) --with-http_sub_module 启用ngx_http_sub_module支持(允许用一些其他文本替换nginx响应中的一些文本) --with-http_dav_module 启用ngx_http_dav_module支持(增加PUT,DELETE,MKCOL:创建集合,COPY和MOVE方法)默认情况下为关闭,需编译开启 --with-http_flv_module 启用ngx_http_flv_module支持(提供寻求内存使用基于时间的偏移量文件) --with-http_gzip_static_module 启用ngx_http_gzip_static_module支持(在线实时压缩输出数据流) --with-http_random_index_module 启用ngx_http_random_index_module支持(从目录中随机挑选一个目录索引) --with-http_secure_link_module 启用ngx_http_secure_link_module支持(计算和检查要求所需的安全链接网址) --with-http_degradation_module 启用ngx_http_degradation_module支持(允许在内存不足的情况下返回204或444码) --with-http_stub_status_module 启用ngx_http_stub_status_module支持(获取nginx自上次启动以来的工作状态) --without-http_charset_module 禁用ngx_http_charset_module支持(重新编码web页面,但只能是一个方向--服务器端到客户端,并且只有一个字节的编码可以被重新编码) --with-http_gzip_module 禁用ngx_http_gzip_module支持(该模块同-with-http_gzip_static_module功能一样) --without-http_ssi_module 禁用ngx_http_ssi_module支持(该模块提供了一个在输入端处理处理服务器包含文件(SSI)的过滤器,目前支持SSI命令的列表是不完整的) --without-http_userid_module 禁用ngx_http_userid_module支持(该模块用来处理用来确定客户端后续请求的cookies) --without-http_access_module 禁用ngx_http_access_module支持(该模块提供了一个简单的基于主机的访问控制。允许/拒绝基于ip地址) --without-http_auth_basic_module禁用ngx_http_auth_basic_module(该模块是可以使用用户名和密码基于http基本认证方法来保护你的站点或其部分内容) --without-http_autoindex_module 禁用disable ngx_http_autoindex_module支持(该模块用于自动生成目录列表,只在ngx_http_index_module模块未找到索引文件时发出请求。) --without-http_geo_module 禁用ngx_http_geo_module支持(创建一些变量,其值依赖于客户端的IP地址) --without-http_map_module 禁用ngx_http_map_module支持(使用任意的键/值对设置配置变量) --without-http_split_clients_module 禁用ngx_http_split_clients_module支持(该模块用来基于某些条件划分用户。条件如:ip地址、报头、cookies等等) --without-http_referer_module 禁用disable ngx_http_referer_module支持(该模块用来过滤请求,拒绝报头中Referer值不正确的请求) --without-http_rewrite_module 禁用ngx_http_rewrite_module支持(该模块允许使用正则表达式改变URI,并且根据变量来转向以及选择配置。如果在server级别设置该选项,那么他们将在 location之前生效。如果在location还有更进一步的重写规则,location部分的规则依然会被执行。如果这个URI重写是因为location部分的规则造成的,那么 location部分会再次被执行作为新的URI。 这个循环会执行10次,然后Nginx会返回一个500错误。) --without-http_proxy_module 禁用ngx_http_proxy_module支持(有关代理服务器) --without-http_fastcgi_module 禁用ngx_http_fastcgi_module支持(该模块允许Nginx 与FastCGI 进程交互,并通过传递参数来控制FastCGI 进程工作。 )FastCGI一个常驻型的公共网关接口。 --without-http_uwsgi_module 禁用ngx_http_uwsgi_module支持(该模块用来医用uwsgi协议,uWSGI服务器相关) --without-http_scgi_module 禁用ngx_http_scgi_module支持(该模块用来启用SCGI协议支持,SCGI协议是CGI协议的替代。它是一种应用程序与HTTP服务接口标准。它有些像FastCGI但他的设计 更容易实现。) --without-http_memcached_module 禁用ngx_http_memcached_module支持(该模块用来提供简单的缓存,以提高系统效率) --without-http_limit_zone_module 禁用ngx_http_limit_zone_module支持(该模块可以针对条件,进行会话的并发连接数控制) --without-http_limit_req_module 禁用ngx_http_limit_req_module支持(该模块允许你对于一个地址进行请求数量的限制用一个给定的session或一个特定的事件) --without-http_empty_gif_module 禁用ngx_http_empty_gif_module支持(该模块在内存中常驻了一个1*1的透明GIF图像,可以被非常快速的调用) --without-http_browser_module 禁用ngx_http_browser_module支持(该模块用来创建依赖于请求报头的值。如果浏览器为modern ,则$modern_browser等于modern_browser_value指令分配的值;如 果浏览器为old,则$ancient_browser等于 ancient_browser_value指令分配的值;如果浏览器为 MSIE中的任意版本,则 $msie等于1) --without-http_upstream_ip_hash_module 禁用ngx_http_upstream_ip_hash_module支持(该模块用于简单的负载均衡) --with-http_perl_module 启用ngx_http_perl_module支持(该模块使nginx可以直接使用perl或通过ssi调用perl) --with-perl_modules_path= 设定perl模块路径 --with-perl= 设定perl库文件路径 --http-log-path= 设定access log路径 --http-client-body-temp-path= 设定http客户端请求临时文件路径 --http-proxy-temp-path= 设定http代理临时文件路径 --http-fastcgi-temp-path= 设定http fastcgi临时文件路径 --http-uwsgi-temp-path= 设定http uwsgi临时文件路径 --http-scgi-temp-path= 设定http scgi临时文件路径 --without-http 禁用http server功能 --without-http-cache 禁用http cache功能 --with-mail 启用POP3/IMAP4/SMTP代理模块支持 --with-mail_ssl_module 启用ngx_mail_ssl_module支持 --without-mail_pop3_module 禁用pop3协议(POP3即邮局协议的第3个版本,它是规定个人计算机如何连接到互联网上的邮件服务器进行收发邮件的协议。是因特网电子邮件的第一个离线协议标 准,POP3协议允许用户从服务器上把邮件存储到本地主机上,同时根据客户端的操作删除或保存在邮件服务器上的邮件。POP3协议是TCP/IP协议族中的一员,主要用于 支持使用客户端远程管理在服务器上的电子邮件) --without-mail_imap_module 禁用imap协议(一种邮件获取协议。它的主要作用是邮件客户端可以通过这种协议从邮件服务器上获取邮件的信息,下载邮件等。IMAP协议运行在TCP/IP协议之上, 使用的端口是143。它与POP3协议的主要区别是用户可以不用把所有的邮件全部下载,可以通过客户端直接对服务器上的邮件进行操作。) --without-mail_smtp_module 禁用smtp协议(SMTP即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP协议属于TCP/IP协议族,它帮助每台计算机在发送或中转信件时找到下一个目的地。) --with-google_perftools_module 启用ngx_google_perftools_module支持(调试用,剖析程序性能瓶颈) --with-cpp_test_module 启用ngx_cpp_test_module支持 --add-module= 启用外部模块支持 --with-cc= 指向C编译器路径 --with-cpp= 指向C预处理路径 --with-cc-opt= 设置C编译器参数(PCRE库,需要指定–with-cc-opt=”-I /usr/local/include”,如果使用select()函数则需要同时增加文件描述符数量,可以通过–with-cc- opt=”-D FD_SETSIZE=2048”指定。) --with-ld-opt= 设置连接文件参数。(PCRE库,需要指定–with-ld-opt=”-L /usr/local/lib”。) --with-cpu-opt= 指定编译的CPU,可用的值为: pentium, pentiumpro, pentium3, pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64 --without-pcre 禁用pcre库 --with-pcre 启用pcre库 --with-pcre= 指向pcre库文件目录 --with-pcre-opt= 在编译时为pcre库设置附加参数 --with-md5= 指向md5库文件目录(消息摘要算法第五版,用以提供消息的完整性保护) --with-md5-opt= 在编译时为md5库设置附加参数 --with-md5-asm 使用md5汇编源 --with-sha1= 指向sha1库目录(数字签名算法,主要用于数字签名) --with-sha1-opt= 在编译时为sha1库设置附加参数 --with-sha1-asm 使用sha1汇编源 --with-zlib= 指向zlib库目录 --with-zlib-opt= 在编译时为zlib设置附加参数 --with-zlib-asm= 为指定的CPU使用zlib汇编源进行优化,CPU类型为pentium, pentiumpro --with-libatomic 为原子内存的更新操作的实现提供一个架构 --with-libatomic= 指向libatomic_ops安装目录 --with-openssl= 指向openssl安装目录 --with-openssl-opt 在编译时为openssl设置附加参数 --with-debug 启用debug日志
https://blog.csdn.net/u012271055/article/details/84291170
nginx 常用的模块有 http web模块、mail邮件反向代理模块、stream 4层反向代理模块
编译时,加入---with-http_gzip_static_module --with-http_stub_status_module 常用
--with-http_ssl_module --with-http_gzip_static_module --with-http_stub_status_module --with-pcre=/opt/software/pcre-8.35 --with-zlib=/opt/software/zlib-1.2.8 --with-openssl=/opt/software/openssl-1.0.1i --add-module=/opt/software/nginx-1.8.1/modules/nginx-rtmp-module
安装后增加模块可以先make 手动替换目录下sbin/nginx文件
网络连接相关的配置:
keepalive_timeout #; 长连接的超时时长,默认为75s; keepalive_requests #; 在一个长连接上所能够允许请求的最大资源数; keepalive_disable [msie6|safari|none]; 为指定类型的User Agent禁用长连接; tcp_nodelay on|off; 是否对长连接使用TCP_NODELAY选项; client_header_timeout #; 读取http请求报文首部的超时时长; client_body_timeout #; 读取http请求报文body部分的超时时长; send_timeout; 发送响应报文的超时时长;
stub_status指令获取nginx状态信息
使用ngx_http_stub_status_module模块提供的功能可以获取nginx运行的状态信息。对应的指令只有一个,即stub_status
e.g 还可以明确指定访问该信息不记录日志,且提供访问控制,不让外界人随意获取信息。
location /status { stub_status on; access_log off; allow 192.168.100.0/24; deny all; }
重载配置文件后,只需在浏览器中输入"主机名/status"即可获取信息。
Active connections: 291 server accepts handled requests 16630948 16630948 31070465 Reading: 6 Writing: 179 Waiting: 106
状态信息意义如下:
- 第一行active connections:291表示当前处于活动状态的客户端连接数,包括正处于等待状态的连接。
- 第四行reading数量为6,表示nginx正在读取请求首部的数量,即正在从socket recv buffer中读取数据的数量;
- writing:请求已经接受完成,正处于处理请求或发送响应的过程中的连接数;
- 数量为179表示nginx正在将响应数据写入socket send buffer以返回给客户端的连接数量;
- waiting:保持连接模式,且处于活动状态的连接数
- 等待空闲客户端发起请求的客户端数量,包括长连接状态的连接以及已接入但socket recv buffer还未产生可读事件的连接,其值为active-reading-writing。
- writing:请求已经接受完成,正处于处理请求或发送响应的过程中的连接数;
- 第二行accepts的数量为16630948表示从服务启动开始到现在已经接收进来的总的客户端连接数;
- handled的数量为16630948表示从服务启动以来已经处理过的连接数,(一般handled的值和accepts的值相等,除非作出了连接数限定);
- requests的数量为已经处理过的请求数。一个连接可以有多个请求,所以可以计算出平均每个连接发出多少个请求。
配置web身份认证
需要输入用户名和密码才能访问站点的功能为web身份认证功能。nginx中由ngx_http_auth_basic_module模块提供该功能。指令包括auth_basic和auth_basic_user_file。这两个指令可以在http根段、server段、location段使用。
auth_basic string | off auth_basic_user_file path/to/user_passwd_file # 密码文件使用相对路径时是相对conf目录的
需要注意的是,密码文件不能使用明文密码的方式。该类文件一般使用apache提供的工具htpasswd生成,该工具在httpd-tools包中,具体用法见htpasswd命令。也可以使用openssl passwd生成相关密码然后复制到密码文件中。以下是一个示例:
server { listen 80; server_name www.longshuai.com www1.longshuai.com; location / { root /www/longshuai/; index index.html index.htm; auth_basic "Auth your name"; auth_basic_user_file /usr/local/nginx/htpasswd; } }
然后使用htpasswd生成密码文件/usr/local/nginx/conf/htpasswd。
yum -y install httpd-tools htpasswd -b -c -m /usr/local/nginx/conf/htpasswd Jim 123456 htpasswd -b -m /usr/local/nginx/conf/htpasswd Tom 123456
-b
选项是表示batch模式,不用交互输入密码。
-c
表示创建密码文件,只能为第一个用户使用该选项,否则后面使用会覆盖前面已经创建过的。
-m
表示强制使用md5。Jim和Tom是需要验证的用户名,123456是密码。查看生成的密码文件。
[root@xuexi nginx]# cat htpasswd
Jim:$apr1$URdS8lcY$GyghBlYInlqfkto0ndnH1.
Tom:$apr1$B/orDxHj$1jIWk1X5XabpH3hcFQzoN1
然后重载配置文件,在浏览器中测试。测试时最好不要用IE。
也可以使用openssl passwd生成,下面的"-apr1"(数值1而非字母L的小写)选项是为apache密码做相关支持的。
openssl passwd -apr1 123456 $apr1$rD/3/kFH$L8KYfzAWFtHO8mOiR9dci1 # 或者加点盐 openssl passwd -apr1 -salt 'xyz' 123456 $apr1$xyz$j0n99G44SENB4NmJiwEfJ0
然后将得到的密码复制到密码文件中对应的用户名后面即可。如将得到的"$apr1$xyz$j0n99G44SENB4NmJiwEfJ0"作为"Admin"用户的验证密码。
Admin: $apr1$xyz$j0n99G44SENB4NmJiwEfJ0
转自:https://www.cnblogs.com/f-ck-need-u/p/7683027.html#5-nginx-
URL重写-----if和Rewrite语法
https://www.cnblogs.com/f-ck-need-u/p/7685485.html
rewrite可以写在server段、location段和if段。语法:
rewrite regexp replacement [flag]
如果replacement部分以"http://"或"https://"或"$schema"开头,则直接临时重定向,见下表中的redirect标记。
flag是标记。有4种标记,它们的作用如下表。
last : 一旦此rewrite规则重写完成后,就不再被后面其它的rewrite规则进行处理;而是由User Agent重新对重写后的URL再一次发起请求,并从头开始执行类型的过程 break:一旦此rewrite规则重写完成后,由User Agent对新的URL重新发起请求,且不再会被当前location内的任何rewrite规则所检查
redirect: 返回临时重定向状态码302;当replacement部分不是以"http://"或者"https://"或者"$schema"开头的时候使用,"$schema"变量表示使用的是什么协议
permanent : 返回永久重定向状态码301
例如:
....
rewrite "^/bbs/(.*)/images/(.*)\.jpg$" www.longshuai.com/bbs/$2/images/$1.jpg last;
rewrite "^/bbs/(.*)/images/(.*)\.jpg$" www.longshuai.com/bbs/$2/images/$1.jpg break;
....
假设有N条rerite,用户请求第一个的时候,从头开始匹配,直到匹配到flag为last的时候匹配到了,就会停止往下匹配(不检查了)变成一个新URL(即重定向后的URL),
这个新URL就会重新发给nginx服务器,nginx服务器也会重复刚才的检查过程如果匹配到了,那就会再一次循环。循环循环到不满足条件就跳出循序。
如果使用last标记,nginx默认支持10次循环,然后返回500状态码。而如果使用break标记,则在重写完成后不会再次匹配重写。
last和break用来实现URL改写,此时浏览器中的地址不会改变,但实际上在服务器上访问的资源和路径已经改变了。redirect和permanent用来实现URL跳转,浏览器中的地址会改变为跳转后的地址。在使用proxy_pass指令时要使用break标记
if语法
if (condition) { 语句 }
应用于server标签和location标签
使用if实现根据浏览器分离访问
server { listen 80; server_name 192.9.191.30; location / {
root html;
index index.html index.htm;
if ($http_user_agent ~* "MSIE") #MSIE IE浏览器
{
root /var/www/MSIE;
}
if ($http_user_agent ~* "Firefox") #$匹配firefox浏览器
{
root /var/www/Firefox;
}
if ($http_user_agent ~* "Chrome"){ #匹配chrome谷歌浏览器 return 301; } if ($http_user_agent ~* "iphone"){ #匹配iphone手机 return 302; } if ($http_user_agent ~* "android"){ #匹配安卓手机 return 404; } return 405; #其它浏览器默认访问规则 } } }
//添加主页文件
echo "IE" > /var/www/MSIE/test.html
echo "Firefox" > /var/www/Firefox/test.html
upstream 模块------负载均衡
https://www.cnblogs.com/f-ck-need-u/p/7684732.html#1-3-upstream-
nginx重定向错误---更改nginx.conf在server 区域加入
server
{
listen 80;
server_name www.XXX.com ;
index index.html index.htm index.php;
root /opt/www/;
location ~ .*.(php|php5)?$
{
#fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
error_page 404 502 501 50x @error; locaton @error { root html; }
error_page 500 502 503 504 = /50x.html;
location = /50x.html {
root html;
}
log_format 65 ‘$remote_addr – $remote_user [$time_local] "$request" ‘
‘$status $body_bytes_sent "$http_referer" ‘
‘"$http_user_agent" $http_x_forwarded_for’;
access_log /opt/nginx/logs/65.log 65;
}
注意事项:
1.必须要添加:fastcgi_intercept_errors on; 如果这个选项没有设置,即使创建了404.html和配置了error_page也没有效果。
fastcgi_intercept_errors 语法: fastcgi_intercept_errors on|off
默认:fastcgi_intercept_errors off 添加位置: http, server, location(更改nginx.conf在http定义区域加入:fastcgi_intercept_errors on;)
默认情况下,nginx不支持自定义404错误页面,只有这个指令被设置为on,nginx才支持将404错误重定向。这里需要注意的是,并不是说设置了fastcgi_intercept_errors on,nginx就会将404错误重定向。在nginx中404错误重定向生效的前提是设置了fastcgi_intercept_errors on,并且正确的设置了error_page这个选项(包括语法和对应的404页面)
2.不要出于省事或者提高首页权重的目的将首页指定为404错误页面,也不要用其它方法跳转到首页。
3.自定义的404页面必须大于512字节,否则可能会出现IE默认的404页面。例如,假设自定义了404.html,大小只有11个字节(内容为:404错误)。
三、Nginx平滑增加编译模块
由于需要生产环境的需求,现需要对原nginx增加stream模块功能,虽然过程很简单,但是也做一个记录以备查看。具体操作过程整理如下:
3.1、查看Nginx原编译参数
3.2、添加所需要的模块
我们需要添加模块为stream模块,具体做法是重新编译,并增加--with-stream参数。首先进入nginx解压后的目录,然后运行如下编译指令:
3.3、备份原启动文件
首先停止nginx服务,将原启动文件做一个备份:
3.4、将新文件拷贝到工作目录
做到这一步已经完成了,已经可以看到--with-sream模块已经编译到了nginx里面去了!!