Contents[hide] |
[edit] nginx是什么
下面的话摘自nginx官方网站
nginx [engine x]是Igor Sysoev编写的一个HTTP和反向代理服务器,另外它也可以作为邮件代理服务器。 它已经在众多流量很大的俄罗斯网站上使用了很长时间,这些网站包括Yandex、Mail.Ru、VKontakte,以及Rambler。据Netcraft统计,在2012年8月份,世界上最繁忙的网站中有11.48%使用Nginx作为其服务器或者代理服务器。
[edit] nginx的安装
[edit] 编译安装
todo
[edit] ubuntu安装
todo
[edit] centos安装
todo
[edit] mac安装
todo
[edit] nginx基本配置简介
[edit] 安装目录介绍
#whereis nginx nginx: /usr/sbin/nginx /etc/nginx /usr/share/nginx /usr/share/man/man1/nginx.1.gz
# cd /etc/nginx #nginx ll 总用量 60 drwxr-xr-x 2 root root 4096 1月 21 13:23 conf.d -rw-r--r-- 1 root root 898 7月 13 2012 fastcgi_params -rw-r--r-- 1 root root 2258 7月 13 2012 koi-utf -rw-r--r-- 1 root root 1805 7月 13 2012 koi-win -rw-r--r-- 1 root root 2085 7月 13 2012 mime.types -rw-r--r-- 1 root root 5287 7月 13 2012 naxsi_core.rules -rw-r--r-- 1 root root 287 7月 13 2012 naxsi.rules -rw-r--r-- 1 root root 1698 1月 21 13:23 nginx.conf -rw-r--r-- 1 root root 131 7月 13 2012 proxy_params -rw-r--r-- 1 root root 465 7月 13 2012 scgi_params drwxr-xr-x 2 root root 4096 1月 21 12:28 sites-available drwxr-xr-x 2 root root 4096 1月 21 12:28 sites-enabled -rw-r--r-- 1 root root 532 7月 13 2012 uwsgi_params -rw-r--r-- 1 root root 3071 7月 13 2012 win-utf
[edit] 默认配置简介
#运行用户 user nobody; #启动进程,通常设置成和cpu的数量相等 worker_processes 1; #全局错误日志及PID文件 #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; #工作模式及连接数上限 events { #epoll是多路复用IO(I/O Multiplexing)中的一种方式, #仅用于linux2.6以上内核,可以大大提高nginx的性能 use epoll; #单个后台worker process进程的最大并发链接数 worker_connections 1024; # 并发总数是 worker_processes 和 worker_connections 的乘积 # 即 max_clients = worker_processes * worker_connections # 在设置了反向代理的情况下,max_clients = worker_processes * worker_connections / 4 为什么 # 为什么上面反向代理要除以4,应该说是一个经验值 # 根据以上条件,正常情况下的Nginx Server可以应付的最大连接数为:4 * 8000 = 32000 # worker_connections 值的设置跟物理内存大小有关 # 因为并发受IO约束,max_clients的值须小于系统可以打开的最大文件数 # 而系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右 # 我们来看看360M内存的VPS可以打开的文件句柄数是多少: # $ cat /proc/sys/fs/file-max # 输出 34336 # 32000 < 34336,即并发连接总数小于系统可以打开的文件句柄总数,这样就在操作系统可以承受的范围之内 # 所以,worker_connections 的值需根据 worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置 # 使得并发总数小于操作系统可以打开的最大文件数目 # 其实质也就是根据主机的物理CPU和内存进行配置 # 当然,理论上的并发总数可能会和实际有所偏差,因为主机还有其他的工作进程需要消耗系统资源。 # ulimit -SHn 65535 } http { #设定mime类型,类型由mime.type文件定义 include mime.types; default_type application/octet-stream; #设定日志格式 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; #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件, #对于普通应用,必须设为 on, #如果用来进行下载等应用磁盘IO重负载应用,可设置为 off, #以平衡磁盘与网络I/O处理速度,降低系统的uptime. sendfile on; #tcp_nopush on; #连接超时时间 #keepalive_timeout 0; keepalive_timeout 65; tcp_nodelay on; #开启gzip压缩 gzip on; gzip_disable "MSIE [1-6]."; #设定请求缓冲 client_header_buffer_size 128k; large_client_header_buffers 4 128k; #设定虚拟主机配置 server { #侦听80端口 listen 80; #定义使用 www.nginx.cn访问 server_name www.nginx.cn; #定义服务器的默认网站根目录位置 root html; #设定本虚拟主机的访问日志 access_log logs/nginx.access.log main; #默认请求 location / { #定义首页索引文件的名称 index index.php index.html index.htm; } # 定义错误提示页面 error_page 500 502 503 504 /50x.html; location = /50x.html { } #静态文件,nginx自己处理 location ~ ^/(images|javascript|js|css|flash|media|static)/ { #过期30天,静态文件不怎么更新,过期可以设大一点, #如果频繁更新,则可以设置得小一点。 expires 30d; } #PHP 脚本请求全部转发到 FastCGI处理. 使用FastCGI默认配置. location ~ .php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } #禁止访问 .htxxx 文件 location ~ /.ht { deny all; } } }
[edit] nginx反向代理介绍
[edit] 不得不说的正向代理
正向代理,也就是传说中的代理,他的工作原理就像一个跳板,简单的说,我是一个用户,我访问不了某网站,但是我能访问一个代理服务器 这个代理服务器呢,他能访问那个我不能访问的网站 于是我先连上代理服务器,告诉他我需要那个无法访问网站的内容 代理服务器去取回来,然后返回给我
从网站的角度,只在代理服务器来取内容的时候有一次记录 有时候并不知道是用户的请求,也隐藏了用户的资料,这取决于代理告不告诉网站
结论就是 正向代理 是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。
[edit] 反向代理
继续举例:例用户访问 http://bigc.at/readme但bigc.at上并不存在readme页面 他是偷偷从另外一台服务器上取回来,然后作为自己的内容吐给用户
但用户并不知情 这很正常,用户一般都很笨
这里所提到的 bigc.at 这个域名对应的服务器就设置了反向代理功能
结论就是 反向代理正好相反,对于客户端而言它就像是原始服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理 的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端,就像这些内容 原本就是它自己的一样。
[edit] 正向代理反向代理的区别
- 从用途上来讲:
正向代理的典型用途是为在防火墙内的局域网客户端提供访问Internet的途径。正向代理还可以使用缓冲特性减少网络使用率。反向代理的典型用途是将 防火墙后面的服务器提供给Internet用户访问。反向代理还可以为后端的多台服务器提供负载平衡,或为后端较慢的服务器提供缓冲服务。
另外,反向代理还可以启用高级URL策略和管理技术,从而使处于不同web服务器系统的web页面同时存在于同一个URL空间下。
- 从安全性来讲:
正向代理允许客户端通过它访问任意网站并且隐藏客户端自身,因此你必须采取安全措施以确保仅为经过授权的客户端提供服务。
反向代理对外都是透明的,访问者并不知道自己访问的是一个代理。
[edit] 实例
server { listen 80; server_name t.ide.bdp.360buy.com; location / { root html; index index.html index.htm; proxy_pass http://192.168.198.95:7022; proxy_set_header X-Real-IP $remote_addr; client_max_body_size 100m; } location /upload/ { autoindex on; } }
[edit] nginx负载均衡配置
[edit] 负载均衡策略
nginx的负载均衡策略可以划分为两大类:内置策略和扩展策略。内置策略包含加权轮询和ip hash,在默认情况下这两种策略会编译进nginx内核,只需在nginx配置中指明参数即可。扩展策略有很多,如fair、通用hash、consistent hash等,默认不编译进nginx内核,是第三方模块。nginx 的 upstream目前支持 4 种方式的分配 :
- 轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
upstream mysvr { server 192.168.198.95:7022 ; server 192.168.198.94:7022 ; }
- weight
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
upstream mysvr { #weigth参数表示权值,权值越高被分配到的几率越大 server 192.168.198.95:7022 weight=5; server 192.168.198.94:7022 weight=1; }
- ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
upstream load_balance{ ip_hash; server localhost:8001; server localhost:8002; }
- fair(第三方)
这是比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的upstream_fair模块。
upstream load_balance{ fair; server localhost:8001; server localhost:8002; }
- url_hash(第三方)
此方法按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身是不支持url_hash的,如果需要这种高度算法,必须安装Nginx的hash软件包。
upstream backserver { server squid1:3128; server squid2:3128; hash $request_uri; hash_method crc32; }
- 重试策略
可以为每个 backend 指定最大的重试次数,和重试时间间隔。所使用的关键字是 max_fails 和 fail_timeout。如下所示:
upstream backend { server backend1.example.com weight=5; server 54.244.56.3:8081 max_fails=3 fail_timeout=30s; }
在上例中,最大失败次数为 3,也就是最多进行 3 次尝试,且超时时间为 30秒。max_fails 的默认值为 1,fail_timeout 的默认值是 10s。传输失败的情形,由 proxy_next_upstream 或 fastcgi_next_upstream 指定。而且可以使用 proxy_connect_timeout 和 proxy_read_timeout 控制 upstream 响应时间。
有一种情况需要注意,就是 upstream 中只有一个 server 时,max_fails 和 fail_timeout 参数可能不会起作用。导致的问题就是 nginx 只会尝试一次 upstream 请求,如果失败这个请求就被抛弃了 : ( ……解决的方法,比较取巧,就是在 upstream 中将你这个可怜的唯一 server 多写几次,如下:
upstream backend { server backend.example.com max_fails fail_timeout=30s; server backend.example.com max_fails fail_timeout=30s; server backend.example.com max_fails fail_timeout=30s; }
- 备机策略
从 Nginx 的 0.6.7 版本开始,可以使用“backup”关键字。当所有的非备机(non-backup)都宕机(down)或者繁忙(busy)的时候,就只使用由 backup 标注的备机。必须要注意的是,backup 不能和 ip_hash 关键字一起使用。举例如下:
upstream backend { server backend1.example.com; server backend2.example.com backup; server backend3.example.com; }
[edit] 最简单的实例
#设定负载均衡的服务器列表 upstream mysvr { #weigth参数表示权值,权值越高被分配到的几率越大 server 192.168.198.95:7022 weight=5; server 192.168.198.94:7022 weight=1; } server { listen 80; server_name t.ide.bdp.360buy.com; location / { root html; index index.html index.htm; proxy_pass http://$mysvr; #以下是一些反向代理的配置可删除. proxy_redirect off; #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #允许客户端请求的最大单文件字节数 client_max_body_size 10m; #缓冲区代理缓冲用户端请求的最大字节数, client_body_buffer_size 128k; #nginx跟后端服务器连接超时时间(代理连接超时) proxy_connect_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时) proxy_read_timeout 90; #设置代理服务器(nginx)保存用户头信息的缓冲区大小 proxy_buffer_size 4k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置 proxy_buffers 4 32k; #高负荷下缓冲大小(proxy_buffers*2) proxy_busy_buffers_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传 proxy_temp_file_write_size 64k; } }
[edit] nginx指令
[edit] location指令
- ~ #波浪线表示执行一个正则匹配,区分大小写
- ~* #表示执行一个正则匹配,不区分大小写
- ^~ #^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录
- = #进行普通字符精确匹配
- @ #"@" 定义一个命名的 location,使用在内部定向时,例如 error_page, try_files
location 匹配的优先级(与location在配置文件中的顺序无关) = 精确匹配会第一个被处理。如果发现精确匹配,nginx停止搜索其他匹配。 普通字符匹配,正则表达式规则和长的块规则将被优先和查询匹配,也就是说如果该项匹配还需去看有没有正则表达式匹配和更长的匹配。^~ 则只匹配该规则,nginx停止搜索其他匹配,否则nginx会继续处理其他location指令。 最后匹配理带有"~"和"~*"的指令,如果找到相应的匹配,则nginx停止搜索其他匹配;当没有正则表达式或者没有正则表达式被匹配的情况下,那么匹配程度最高的逐字匹配指令会被使用。
location 优先级官方文档
Directives with the = prefix that match the query exactly. If found, searching stops. All remaining directives with conventional strings, longest match first. If this match used the ^~ prefix, searching stops. Regular expressions, in order of definition in the configuration file. If #3 yielded a match, that result is used. Else the match from #2 is used. =前缀的指令严格匹配这个查询。如果找到,停止搜索。 所有剩下的常规字符串,最长的匹配。如果这个匹配使用^〜前缀,搜索停止。 正则表达式,在配置文件中定义的顺序。 如果第3条规则产生匹配的话,结果被使用。否则,如同从第2条规则被使用。
- 具体实例:
location = / { # 只匹配"/". [ configuration A ] } location / { # 匹配任何请求,因为所有请求都是以"/"开始 # 但是更长字符匹配或者正则表达式匹配会优先匹配 [ configuration B ] } location ^~ /images/ { # 匹配任何以 /images/ 开始的请求,并停止匹配 其它location [ configuration C ] } location ~* \.(gif|jpg|jpeg)$ { # 匹配以 gif, jpg, or jpeg结尾的请求. # 但是所有 /images/ 目录的请求将由 [Configuration C]处理. [ configuration D ] }
[edit] rewrite指令
- 1. 执行server块的rewrite指令(这里的块指的是server关键字后{}包围的区域,其它xx块类似)
- 2. 执行location匹配
- 3. 执行选定的location中的rewrite指令
如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件
如果循环超过10次,则返回500 Internal Server Error错误
一些具体的实例:
- 目录对换 /123456/xxxx -> /xxxx?id=123456
rewrite ^/(/d+)/(.+)/ /$2?id=$1 last;
- 例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下
if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /nginx-ie/$1 break; }
- 域名302跳转
if ($host # 'www.360buy.com' ) { rewrite ^/(.*)$ http://www.jd.com/$1 permanent; }
[edit] break指令
// todo
[edit] if指令
// todo
[edit] return指令
// todo
[edit] nginx控制与命令
[edit] nginx 命令行参数
-c </path/to/config> 为 Nginx 指定一个配置文件,来代替缺省的。
-t 不运行,而仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件。
-v 显示 nginx 的版本。
-V 显示 nginx 的版本,编译器版本和配置参数。
[edit] nginx 启动、停止、重启命令
- nginx启动
sudo /usr/local/nginx/nginx (nginx二进制文件绝对路径,可以根据自己安装路径实际决定)
- nginx从容停止命令,等所有请求结束后关闭服务
ps -ef |grep nginx
kill -QUIT nginx主进程号
- nginx 快速停止命令,立刻关闭nginx进程
ps -ef |grep nginx kill -TERM nginx主进程号
- 如果以上命令不管用,可以强制停止
kill -9 nginx主进程号
- 如果嫌麻烦可以不用查看进程号,直接使用命令进行操作
其中/usr/local/nginx/nginx.pid 为nginx.conf中pid命令设置的参数,用来存放nginx主进程号的文件kill -信号类型(HUP|TERM|QUIT) `cat /usr/local/nginx/nginx.pid`
例如kill -QUIT `cat /usr/local/nginx/nginx.pid`
- nginx重启命令
nginx重启可以分成几种类型
- 1.简单型,先关闭进程,修改你的配置后,重启进程。
kill -QUIT `cat /usr/local/nginx/nginx.pid` sudo /usr/local/nginx/nginx
- 2.重新加载配置文件,不重启进程,不会停止处理请求
- 3.平滑更新nginx二进制,不会停止处理请求
[edit] 使用信号加载新的配置
Nginx 支持几个信号,能在它运行时控制其操作。其中最普通的是 15 ,用来中止运行的进程:
ps aux | egrep '(PID|nginx)' USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 2213 0.0 0.0 6784 2036 ? Ss 03:01 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
kill -15 2213
而最有趣的是能平滑改变 nginx 配置的选项(请注意,在重载前,要先测试一下配置文件):
nginx -t -c /etc/nginx/nginx.conf 2006/09/16 13:07:10 [info] 15686#0: the configuration file /etc/nginx/nginx.conf syntax is ok 2006/09/16 13:07:10 [info] 15686#0: the configuration file /etc/nginx/nginx.conf was tested successfully
ps aux | egrep '(PID|nginx)' USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 2213 0.0 0.0 6784 2036 ? Ss 03:01 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
kill -HUP 2213
当 nginx 接收到 HUP 信号,它会尝试先解析配置文件(如果指定配置文件,就使用指定的,否则使用默认的),成功的话,就应用新的配置文件(例如:重新打开日志文件或监听的套接 字)。之后,nginx 运行新的工作进程并从容关闭旧的工作进程。通知工作进程关闭监听套接字但是继续为当前连接的客户提供服务。所有客户端的服务完成后,旧的工作进程被关闭。 如果新的配置文件应用失败,nginx 将继续使用旧的配置进行工作。
[edit] 平滑升级到新的二进制代码
// todo
[edit] 经验操作
- 验证修改的配置是否正确
- 平滑的重启nginx(不接受新的请求,老的请求处理完成后重启)
nginx -t killall -s HUP nginx
[edit] nginx tcp模块使用
nginx默认不支持tcp代理,需要安装模块满足。参照开源项目:
[edit] 安装过程
$ wget 'http://nginx.org/download/nginx-1.2.1.tar.gz' $ tar -xzvf nginx-1.2.1.tar.gz $ cd nginx-1.2.1/ $ patch -p1 < /path/to/nginx_tcp_proxy_module/tcp.patch $ ./configure --add-module=/path/to/nginx_tcp_proxy_module $ make $ make install
[edit] 配置使用
tcp { timeout 1d; proxy_read_timeout 10d; proxy_send_timeout 10d; proxy_connect_timeout 30; upstream openfire5222{ server 192.168.198.95:5222; server 192.168.198.94:5222; } server{ listen 5222; proxy_pass openfire5222; so_keepalive on; tcp_nodelay on; } upstream openfire5223{ server 192.168.198.95:5223; server 192.168.198.94:5223; } server{ listen 5223; proxy_pass openfire5223; so_keepalive on; tcp_nodelay on; } }
[edit] 问题
- web controller取客户端ip出现127.0.0.1的情况
- 修改查询条件后列表数据没更新
- 上线时web服务完全不可访问
- 访问的地址错误了,每次都跳到京东主页了
- 基于地理显示不同的网站页面或跳转到不同的子站
- 基于用户ID号码或登录IP的AB Test