Nginux的配置文件是ngiux.conf
全局配置参数:
1、运行用户
user nobody
2、启动的进程数,与CPU数量设置相同
worker_processes 1;
3、错误日志和PID文件
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
4、输出日志格式
log_format access '$remote_addr -
time_local] “KaTeX parse error: Double superscript at position 15: request" ' '̲status
http_referer” ’ ‘“
http_x_forwarded_for”’;
Nginux内置参数含义
5、工作模式和连接数限制
events{
use epoll;
worker_connections 20000; //每个进程的连接数
}
Nginx支持如下处理连接的方法(I/O复用方法),这些方法可以通过use指令指定。
select – 标准方法。 如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数 –with-select_module 和 –without-select_module 来启用或禁用这个模块。
poll – 标准方法。 如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数 –with-poll_module 和 –without-poll_module 来启用或禁用这个模块。
kqueue – 高效的方法,使用于 FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X. 使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。
epoll – 高效的方法,使用于Linux内核2.6版本及以后的系统。在某些发行版本中,如SuSE 8.2, 有让2.4版本的内核支持epoll的补丁。
rtsig – 可执行的实时信号,使用于Linux内核版本2.2.19以后的系统。默认情况下整个系统中不能出现大于1024个POSIX实时(排队)信号。这种情况 对于高负载的服务器来说是低效的;所以有必要通过调节内核参数 /proc/sys/kernel/rtsig-max 来增加队列的大小。可是从Linux内核版本2.6.6-mm2开始, 这个参数就不再使用了,并且对于每个进程有一个独立的信号队列,这个队列的大小可以用 RLIMIT_SIGPENDING 参数调节。当这个队列过于拥塞,nginx就放弃它并且开始使用 poll 方法来处理连接直到恢复正常。
/dev/poll – 高效的方法,使用于 Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+.
eventport – 高效的方法,使用于 Solaris 10. 为了防止出现内核崩溃的问题, 有必要安装 这个 安全补丁。
epoll的优点
支持一个进程打开大数目的socket描述符(FD)
select 最不能忍受的是一个进程所打开的FD是有一定限制的,由FD_SETSIZE设置,默认值是2048。对于那些需要支持的上万连接数目的IM服务器来说显 然太少了。这时候你一是可以选择修改这个宏然后重新编译内核,不过资料也同时指出这样会带来网络效率的下降,二是可以选择多进程的解决方案(传统的 Apache方案),不过虽然linux上面创建进程的代价比较小,但仍旧是不可忽视的,加上进程间数据同步远比不上线程间同步的高效,所以也不是一种完 美的方案。不过 epoll则没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左 右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。
IO效率不随FD数目增加而线性下降
传 统的select/poll另一个致命弱点就是当你拥有一个很大的socket集合,不过由于网络延时,任一时间只有部分的socket是”活跃”的,但 是select/poll每次调用都会线性扫描全部的集合,导致效率呈现线性下降。但是epoll不存在这个问题,它只会对”活跃”的socket进行操 作—这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的。那么,只有”活跃”的socket才会主动的去调用 callback函数,其他idle状态socket则不会,在这点上,epoll实现了一个”伪”AIO,因为这时候推动力在os内核。在一些 benchmark中,如果所有的socket基本上都是活跃的—比如一个高速LAN环境,epoll并不比select/poll有什么效率,相 反,如果过多使用epoll_ctl,效率相比还有稍微的下降。但是一旦使用idle connections模拟WAN环境,epoll的效率就远在select/poll之上了。
使用mmap加速内核与用户空间的消息传递。
这 点实际上涉及到epoll的具体实现了。无论是select,poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很 重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。而如果你想我一样从2.5内核就关注epoll的话,一定不会忘记手工 mmap这一步的。
内核微调
这一点其实不算epoll的优点了,而是整个linux平台的优点。也许你可以怀疑linux平台,但是你无法回避linux平台赋予你微调内核的能力。比如,内核TCP/IP协 议栈使用内存池管理sk_buff结构,那么可以在运行时期动态调整这个内存pool(skb_head_pool)的大小— 通过echo XXXX>/proc/sys/net/core/hot_list_length完成。再比如listen函数的第2个参数(TCP完成3次握手 的数据包队列长度),也可以根据你平台内存大小动态调整。更甚至在一个数据包面数目巨大但同时每个数据包本身大小却很小的特殊系统上尝试最新的NAPI网卡驱动架构。
6、设定Http服务器,利用反向代理实现负载均衡
http{
#设置mime类型
include /etc/nginx/mime.types;
default_type application/octet-stream;
#设定日志格式
access_log /usr/local/nginx/logs/access.log’
#sendfile: 设置为on表示启动高效传输文件的模式。sendfile可以让Nginx在传输文件时直接在磁#盘和tcp socket之间传输数据。如果这个参数不开启,会先在用户空间(Nginx进程空间)申请##一个buffer,用read函数把数据从磁盘读到cache,再从cache读取到用户空间的buffer,再用#write函数把数据从用户空间的buffer写入到内核的buffer,最后到tcp socket。开启这个参数后#可以让数据不用经过用户buffer
sendfile on;
#连接超时配置
keepalive_timeout 60;
#开启gzip压缩
gzip on;
#负载均衡列表
upstream test.com{
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:9090 weight=2;
}
#虚拟机设置
server {
listen 80;
server_name rabbitmq1; #匹配主机名
#charset koi8-r;
#access_log logs/host.access.log main;
#配置所有请求
location / {
proxy_pass http://127.0.0.1:8080/examples/;
proxy_redirect default;
}
#error_page 404 /404.html;
redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
#配置50开头的网页
location = /50x.html {
root html;
}
}
#第二个虚拟机
server {
listen 80;
server_name rabbitmq1.com rabbitmq1.net;#匹配主机名
#匹配所有请求
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_redirect default;
}
}
}
Location匹配规则
1.=,精确匹配
location = /index.html {
#规则
}
# 则匹配到 `http://mytest.com/index.html` 这种请求。
2.~,大小写敏感
location ~ /GuFang/ {
#规则
}
#请求示例
#http://mytest.com/GuFang/ [成功]
#http://mytest.com/gufang/ [失败]
3.~*,大小写忽略
location ~* /GuFang/ {
#规则
}
# 则会忽略 uri 部分的大小写
#http://mytest.com/GuFang/ [成功]
#http://mytest.com/gufang/ [成功]
4.^~,只匹配以 uri 开头
location ^~ /images/ {
#规则
}
#以 /images/ 开头的请求,都会匹配上
#http://mytest.com/images/a.jpg [成功]
#http://mytest.com/images/b.mp4 [成功]
5.@,nginx内部跳转
location /video/ {
error_page 404 @video_err;
}
location @video_err {
# 规则
}
#以 /video/ 开头的请求,如果链接的状态为 404。则会匹配到 @img_err 这条规则上。
Rewrite
rewrite的组要功能是实现RUL地址的重定向。Nginx的rewrite功能需要PCRE软件的支持,即通过perl兼容正则表达式语句进行规则匹配的。默认参数编译nginx就会支持rewrite的模块,但是也必须要PCRE的支持
rewrite是实现URL重写的关键指令,根据regex(正则表达式)部分内容,重定向到replacement,结尾是flag标记。
rewrite语法格式及参数语法说明如下:
关键字 正则 替代内容 flag标记
rewrite [flag];
关键字:其中关键字rewrite不能改变
正则:perl兼容正则表达式语句进行规则匹配
替代内容:将正则匹配的内容替换成replacement
flag标记:rewrite支持的flag标记
flag标记说明:
last #本条规则匹配完成后,继续向下匹配新的location URI规则
break #本条规则匹配完成即终止,不再匹配后面的任何规则
redirect #返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
rewrite参数的标签段位置:
server,location,if
regex 常用正则表达式说明
\
将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如“\n”匹配一个换行符,而“\$”则匹配“$”
^
匹配输入字符串的起始位置
$
匹配输入字符串的结束位置
*
匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll”
+
匹配前面的字符一次或多次。如“ol+”能匹配“ol”及“oll”、“oll”,但不能匹配“o”
?
匹配前面的字符零次或一次,例如“do(es)?”能匹配“do”或者“does”,"?"等效于"{0,1}"
.
匹配除“\n”之外的任何单个字符,若要匹配包括“\n”在内的任意字符,请使用诸如“[.\n]”之类的模式。
(pattern)
匹配括号内pattern并可以在后面获取对应的匹配,常用$0...$9属性获取小括号中的匹配内容,要匹配圆括号字符需要\(Content\)
例程
server {
listen 80;
server_name mytest.com;
rewrite ^/(.*) http://myexample.com/$1 permanent;
location =/index.html {
root /usr/local/nginx/mydir;
}
location ~ /Example/{
root /usr/local/nginx/mydir;
index index.html;
}
location ~* /Example/{
root /usr/local/nginx/mydir;
index index.html;
}
location ^~ /image/ {
root /usr/local/nginx/html;
}
location /img/ {
error_page 404 @img404;
}
location @img404 {
root /usr/local/nginx/html;
index 50x.html;
}
}
server {
listen 80;
server_name myexample.com;
}
Nginx中的upstream轮询机制
1、轮询(weight=1)
默认选项,当weight不指定时,各服务器weight相同, 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
upstream bakend {
server 192.168.1.10;
server 192.168.1.11;
}
2、weight
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
如果后端服务器down掉,能自动剔除。
比如下面配置,则1.11服务器的访问量为1.10服务器的两倍。
upstream bakend {
server 192.168.1.10 weight=1;
server 192.168.1.11 weight=2;
}
3、ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session不能跨服务器的问题。
如果后端服务器down掉,要手工down掉。
upstream resinserver{
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
4、fair(第三方插件)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream resinserver{
server 192.168.1.10:8080;
server 192.168.1.11:8080;
fair;
}
5、url_hash(第三方插件)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存服务器时比较有效。
在upstream中加入hash语句,hash_method是使用的hash算法
upstream resinserver{
server 192.168.1.10:8080;
server 192.168.1.11:8080;
hash $request_uri;
hash_method crc32;
}