Nginx

概述

Nginx(发音同engine x)是一个异步框架的 Web服务器,也可以用作反向代理,负载平衡器 和 HTTP缓存。该软件由 Igor Sysoev 创建,并于2004年首次公开发布。同名公司成立于2011年,以提供支持。

Nginx可以部署在网络上使用FastCGI脚本、SCGI处理程序、WSGI应用服务器或Phusion乘客模块的动态HTTP内容,并可作为软件负载均衡器。

Nginx使用异步事件驱动的方法来处理请求。Nginx的模块化事件驱动架构[11]可以在高负载下提供更可预测的性能。

Nginx是一款面向性能设计的HTTP服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势。与旧版本(<=2.2)的Apache不同,Nginx不采用每客户机一线程的设计模型,而是充分使用异步逻辑从而削减了上下文调度开销,所以并发服务能力更强。整体采用模块化设计,有丰富的模块库和第三方模块库,配置灵活。 在Linux操作系统下,Nginx使用epoll事件模型,得益于此,Nginx在Linux操作系统下效率相当高。同时Nginx在OpenBSD或FreeBSD操作系统上采用类似于epoll的高效事件模型kqueue。

Nginx在官方测试的结果中,能够支持五万个并行连接,而在实际的运作中,可以支持二万至四万个并行连接。

与Apache相比

Nginx 的编写有一个明确目标就是超越 Apache Web 服务器的性能。Nginx 提供开箱即用的静态文件,使用的内存比 Apache 少得多,每秒可以处理大约四倍于 Apache 的请求。低并发下性能与 Apache 相当,有时候还低于,但是在高并发下 Nginx 能保持低资源低消耗高性能。还有高度模块化的设计,模块编写简单。配置文件简洁。

命令行 & 参数

施工中…

nginx.conf配置

施工中…

配置文件导读

events{
use epoll;
multi_accept on;
worker_connections 10240;
}
http{
include /etc/nginx/mime.types; # 设定mime类型
default_type application/octet-stream;
access_log /var/log/nginx/access.log; # 设定日志格式
include upstream-servers.conf; # 建议把upstream设置放在单独的文件


server{ # 虚拟服务器, 可以有多个server
listen 80;
server_name s1.xxx.com;
index index.shtml index.html index.htm;
root /opt/xxx;

# 一些rewrite
rewrite ^/help$ /help/ redirect;

# location定义, 建议顺序: 精确匹配=, 前缀匹配^~, 正则匹配~, 普通匹配
location ~ ^/api/labs {
access_log /opt/logs/nginx/labs_stat.log labs_stat;
proxy_pass http://resin-labs-plugins;
}
location /{
proxy_pass http://resin-admin-vip;
}

}
}

server

@TODO

location

参考 (http://nginx.org/en/docs/http/ngx_http_core_module.html#location)
优先级:

  1. 精确匹配: location = /xxx URL完全匹配”/xxx”
  2. 前缀匹配: location ^~ /xxx URL”/xxx”开头的前缀, 比如”a.com/xxx/1”
  3. 正则匹配: location ~ ^*.php$
  4. 正则(不区分大小写): location ~* ^*.php$
  5. 普通匹配: location / 这样写一般用作其他条件都不符合, 最后的default行为

适用建议:

# 第一个必选规则
#直接匹配网站根, 如果首页访问量很大, 应该首先匹配
location = / {
root /var/www/;
index index.htm index.html;
}

# 第二个必选规则是处理静态文件请求
# 前缀匹配"^~"优先级仅次于精确匹配"=", 可以用来
location ^~ /static/ {
root /webroot/static/;
}
# 如果使用memcached作为缓存, 也可以使用前缀匹配
location ^~ /api/services/topic/load {
memcached_pass memcached-cluster;
}
# 前缀匹配^~也可以是转发到应用服务, 但不推荐, 应该让静态文件访问处于更高的优先级

# 正则匹配也可以用来处理静态文件
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}

# 正则匹配用来转发到后端应用服务
location ~ ^/api/v2 {
proxy_pass http://tomcat:8080
}

# 最后普通字符匹配, 用来向后端应用转发
# 毕竟目前的一些RESTFUL框架的流行, 带.php,.jsp后缀的情况很少了
location / {
proxy_pass http://tomcat:8080/

rewrite

rewrite用来更改location, 实现跳转到其他location.
rewrite只能放在server{},location{},if{}中, 语法为rewrite regex replacement [flag];, 例如:

  • rewrite ^/help(.*) /static/help$1 last;
  • rewrite (.*) http://a.changyan.com$1 last;

rewrite的flag标记

  • last : rewrite之后, 跳出当前location, 并重新走一遍当前server的流程, 浏览器地址栏看起来仍是rewrite之前的URL;
  • break : 请求在这个location终结, 不再重新走server;
  • redirect : 返回302临时重定向, 浏览器地址栏会显示跳转后的地址;
  • permanent : 返回301永久重定向, 浏览器地址栏会显示跳转后的地址;

如果rewrite在location之外, last和break不会有任何区别, 都会跳过后面的rewrite直接进入location:

server {
rewrite ^/AAA/.* /BBB/$1 last; // 如果命中^AAA规则, 直接进入location, 下面的所有rewrite被跳过;
rewrite ^/XXX/.* /ZZZ/$1 last;
location ~ /BBB {
}
}

proxy_pass

用location的proxy_pass实现代理,

location /api {
proxy_pass http://127.0.0.1:8080 # 结尾没有/, 表示相对路径
}

proxy_pass相对路径, 将会跳转到(http://127.0.0.1:8080/api/**)

location /api {
proxy_pass http://127.0.0.1:8080/ # 结尾有/, 表示绝对路径
}

将会跳转到(http://127.0.0.1:8080/**), 没有”/api”

Log

Nginx日志主要分为两种:访问日志和错误日志。日志开关在Nginx配置文件(/etc/nginx/nginx.conf)中设置,两种日志都可以选择性关闭,默认都是打开的。

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" $host $request_time';
access_log /opt/logs/nginx/access.log main;
error_log /opt/logs/nginx/error.log notice;

allow,deny

示例:

allow 192.168.1.0/24
deny all;

子网掩码的表示:

  • /24: 255.255.255.0
  • /16: 255.255.0.0
  • /8: 255.0.0.0

module

Nginx模块一般分为三大类: filter, upstream, handler

upstream

示例:

proxy_pass http://webapp
...
upstream webapp {
// [均衡方式]
server 192.168.1.9:8080;
}

负载均衡

  • 轮询(默认):
  • 带weight的轮询: 访问后端比例和weight成正比, 用于解决后端服务器性能不均衡
  • ip_hash: 来访ip hash, 用于解决session问题
  • url_hash: 后端服务器为缓存时

需要注意的:

  • nginx配置文件支持include conf: include cache.conf;
  • if判断字符串(注意是= 而不是==):
if ($arg_client_id = "cxsh9byIb") {
return 200 ':)';
}

Nginx返回502, 503, 504

502: Bad Gateway
作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。可能的原因:

  • 高并发, 后端服务线程池耗尽[?]
  • 后端服务(php-fpm/tomcat..)shutdown
  • 后端程序执行太久,后端服务终止了此次请求的Worker进程,Nginx发现自己与后端服务断开

503: Service Unavailable
由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。如果能够预计延迟时间,那么响应中可以包含一个 Retry-After 头用以标明这个延迟时间。如果没有给出这个 Retry-After 信息,那么客户端应当以处理500响应的方式处理它。可能的原因:

  • 后端服务器当前因为过载无法处理请求,主动拒绝响应,比较少见到

504: Gateway Timeoua
作为网关或者代理工作的服务器尝试执行请求时,未能及时从后端服务器或者辅助服务器(例如DNS)收到响应。可能的原因:

  • nginx发起请求,在最大等待时间内没有收到返回
  • nginx的timeout是否设置的太短
  • 查询DNS超时也会504

参考 http 502 和 504 的区别 - 后端 - 掘金 @Ref

代码解读

施工中…