日常使用nginx总结的出来小记

nginx一个轻量级的web服务器,同时可以作为反向代理服务器,将web请求分发至后端的realserver。作为webserver 和proxy-server nginx本身来说有什么优点呢?
  1、作为web服务器
  并发量高,在30000的并发量下,在nginx+PHP(fastcgi)架构下,开启10个nginx进程会消耗10*15=150M内存,开启64个CGI进程会消耗64*20=1280M内存。在内存、cpu的消耗量不是很大的情况下,实现了高并发量。
  nginx选用的是epoll网络I/O模型,而apace则采用的是select,所以nginx的处理速度更快。
  在10000个非活动连接的长连接的情况下。只需要消耗2.5M内存。
  在启动nginx后,主进程master会生成相应数量的worker进程。worker进程用来接收client的请求。如果我们的服务器配置发生了改变。原来已经生成的并且正在为client提供请求的进程继续使用原来的配置。当服务结束之后,master进程将老配置的worker进程终止,在重新生成新的进程。
  2、作为proxy服务器
  比较流行的反向代理服务器有nginx,haproxy,lvs等,三种反向代理服务器有各自的优缺点:
  lvs是基于四层实现的负载均衡,所谓的四层基于的是socket实现反向代理,比如说把A的80请求全部代理到B的80上去。lvs工作四层之上,仅做分发之用,不会产生额外的开销,这就决定的了lvs的性能超强,其对内存和cpu的开销都是很小的。
  lvs在代理的过程中,DR单纯的把请求分发到后面的realserver,realserver直接对client端进行响应。所以lvs的分发性能是其他的反向代理服务器不能比较的。
  lvs请求图示(DR模型)
  nginx对于lvs而言,首先nginx是工作在七层之上的反向代理服务器。所谓的七层表示nginx可以针对某个目录,某个url来进行反向代理。比如说把A服务器的 /app01/这个目录代理到B服务器的/app01/目录。这样就实现了基于应用的反向代理。同时nginx可以实现对后端服务器的健康检查,当分发的请求发生错误之后,会将请求重新分发到另外的realserver,同样nginx可以承受大并发请求,且采用异步请求处理,减轻了后端服务器的压力。
  haproxy本身作为作为反向代理服务器,会比nginx具有更好的处理速度,而且可以解决nginx出现的session共享问题。(nginx可以采用ip_hash的调度方法解决)。haproxy同样可以对后端服务器进行健康检查。但是haproxy的配置相对于nginx来说略微复杂(个人意见仅供参考)。
  nginx反向代理图示
  How nginx
  nginx无论作为web服务器还是反向代理服务器,location和正则表达式的灵活应用都是他的一大优势,可以任意的匹配我们想进行操作的url,并对相应的url做rewrite和proxy_pass处理。对于nginx的location匹配我有话说。
  1
  location分类:正则location和普通的location
  正则location:以”~”和”~*”开头,其中*好表示后面的正则表达式忽略大小写
  普通location:“=”,“^~ ”和“@ ”和无任何前缀的都属于普通location 。
  2
  如果nginx配置中两种location都存在,先匹配那个呢,另外location的匹配和书写的顺序有关系吗?
  在正则location和普通location都存在的时候,location的匹配规则是先匹配普通的location,在匹配普通location的过程中,遵循的是最长匹配原则。然后再匹配正则的location,但后边匹配到的正则location会覆盖掉先前的普通的location,除非普通的location是完全匹配的。
  下面用几个简单的例子加以说明:
  1、location =/ {
  }
  2、location / {
  }
  3、location ^~ /image/ {
  }
  4、 location ~* \.(gif|jpg|jpeg)${
  }
  请求:
  /                                                ----->匹配第一个url
  /documents/docment.html        ----->匹配第二个url
  /images/boc.gif                         ----->匹配第三个url
  /documents/boc.jpg                  ----->匹配第四个url
  解析
  1:如果location中明确标注了=号,那么此location只能精确的匹配根/这个location,因为此时是精确匹配,所以不再进行正则的匹配。
  2:/documents/docment.html只有/这个location会匹配。虽然前缀不是那么长,但是在这四个location中算是最长的匹配。
  3:/images/boc.gif,这个url首先会匹配到/这个普通的location和/image/这两个,但是/image/的匹配前缀更长,所以选择后面的进行匹配。~^表示的是在匹配的过程中,匹配完普通location之后不在进行正则的匹配。
  4:/documents/boc.jpg  首先会匹配到/,然后进行正则的匹配,会匹配到最后的~* \.(gif|jpg|jpeg)$,匹配到之后,正则的会把普通的覆盖掉。
  location匹配进阶
  server {
  listen       80;
  server_name  www.mingpaixinxi.com.cn;
  location /boc/test.html {
  allow all;
  }
  location ^~ / {
  root   html;
  index  index.html index.htm;
  deny all;
  }
  location ~ \.html$ {
  allow all;
  }
  }
  分别访问 curl -I  http://www.mingpaixinxi.com.cn/,http://www.mingpaixinxi.com.cn/a.html,http://www.mingpaixinxi.com.cn/boc/test.html,http://www.mingpaixinxi.com.cn/test.html。
  总结:为什么除了/boc/test.html之外,其余根开始匹配的全部都返回的是403呢,因为在匹配的过程中,匹配到根路径之后,前面^~说明就不在进行正则的匹配。所以直接执行了里面的deny all请求,所以返回了403。
  如果我们把前面的^~符号去掉会发生什么呢?
  server {
  listen       80;
  server_name  www.mingpaixinxi.com.cn;
  location /boc/test.html {
  allow all;
  }
  location / {
  root   html;
  index  index.html index.htm;
  deny all;
  }
  location ~ \.html$ {
  allow all;
  }
  }
  总结:除了根的匹配之外,其余的全部是404的返回值,为什么呢,因为location /之后还会进行正则的匹配,结果匹配到了 ~ \.html$ 就会把最开始的进行覆盖,执行里面的allow all(虽然是allow all,但是没有文件,返回是404,404表明请求已经到达了服务器,但是服务器不存在客户端请求的文件,而403表示的是请求根本没有到达服务器直接被拒绝掉,这两个存在本质的区别)就返回了404状态吗。
  location的匹配规则你懂了吗?
  总结
  普通location会先于正则location进行匹配。
  如果匹配到普通之后,想结束不再匹配正则的location,那么可以在普通的location前面加上 ^~这两个符号。
  如果继续匹配正则location,正则匹配到的结果会覆盖普通匹配到的结果。
  匹配正则的过程中,和正则的为上下位置有关系,因为正则location是匹配到一个随即停止匹配。并不存在普通location的最大前缀匹配原则。
  3
  nginx rewrite规则
  在nginx中rewrite可以使我们将url进行灵活的转换,但是nginx在转换的过程中会有许多的坑,下面的这些坑你踩过吗?
  rewrite既可以写在server中又可以写在location中,但是写在这两个中有什么区别呢,会有什么先后的顺序吗?
  答案是肯定的,如果两者同时出现的话,首先会匹配的是server中的rewrite规则,然后进行匹配的是location中的rewrite规则,那server中location匹配完了之后会在继续匹配location中的rewrite规则吗?如果想解决这个问题,需要简要的说下rewrite的4个flag位。
  1、last:匹配完当前的uri之后不在进行匹配。
  2、break:匹配完当前的uri之后不在进行匹配。
  3、permanent:永久重定向,http请求返回码301。
  4、redirect:临时重定向,http请求返回码302。
  没看错吧,为什么last和break的定义一样呢?解析的是从官方翻译过来的,下面看几个例子。
  server {
  listen       80;
  server_name  www.mingpaixinxi.com.cn ;
  root html;
  rewrite_log on;   # 打开 URL 重写模块的日志开关,以便写入 error_log
  location  /aaa.html {
  rewrite "^/aaa\.html$"  /bbb.html;
  rewrite "^/bbb\.html$"  /ddd.html;
  }
  location  /bbb.html {
  rewrite "^/bbb\.html$" /ccc.html;
  }
  }
  请求:
  curl http://www.mingpaixinxi.com.cn/aaa.html
  返回bbb.html,这个应该不难理解,先是匹配自己location中的uri规则,之后生成的新的uri也会继续匹配,直到匹配完成。
  server {
  listen       80;
  server_name  www.mingpaixinxi.com.cn ;
  root html;
  rewrite_log on;   # 打开 URL 重写模块的日志开关,以便写入 error_log
  location  /aaa.html {
  rewrite "^/aaa\.html$"  /bbb.html last;
  rewrite "^/bbb\.html$"  /ddd.html;
  }
  location  /bbb.html {
  rewrite "^/bbb\.html$" /ccc.html;
  }
  }
  curl http://www.mingpaixinxi.com.cn/aaa.html
  返回ccc.html
  为什么会返回的是ccc.html呢,因为rewrite "^/aaa\.html$"  /bbb.html last;后面的flag位last,这表明停止当前location中的uri的继续的匹配,但是重新生成的uri不会停止匹配,会继续匹配其他的location,所以匹配到了 /bbb.html,所以返回的是ccc.html。
  erver {
  listen       80;
  server_name  www.mingpaixinxi.com.cn ;
  root html;
  rewrite_log on;   # 打开 URL 重写模块的日志开关,以便写入 error_log
  location  /aaa.html {
  rewrite "^/aaa\.html$"  /bbb.html break;
  rewrite "^/bbb\.html$"  /ddd.html;
  }
  location  /bbb.html {
  rewrite "^/bbb\.html$" /ccc.html;
  }
  }
  请求:
  curl http://www.mingpaixinxi.com.cn/aaa.html
  返回bbb.html,当遇到break之后,停止一切的匹配。从此处结束。所以说break比last的力度会更大些。就好像是程序里面的循环一样,遇到break之后,结束所有的循环。
  同样,如果rewrite规则同时在server和location中出现,server的总是先于location的匹配,直到匹配结束。
  nginx的rewrite规则你了解了吗?
  Use nginx
  核心配置
  upstream  boc  {
  server 192.168.1.1  weight=1 max_fails=2 fail_timeout=2;
  server 192.168.1.2  weight=1 max_fails=2 fail_timeout=2;
  }
  server
  {
  listen       80;
  server_name www.mingpaixinxi.com;
  location / {
  proxy_pass        http://boc;
  proxy_set_header   Host             $host;
  proxy_set_header   X-Real-IP        $remote_addr;
  proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
  }
  access_log  off;
  }
  在这里,定义了一个web的集群,包含两台realserver,并定义了健康检查的规则。当client访问www.mingpaixinxi.com.cn这个域名的时候,前方的nginx就会把请求发送到192.168.1.1和192.168.1.2这两台服务器,默认的分配规则是roundrobin。
  上面简单的对nginx作为反向代理服务器和其他的几款反向代理软件简单的做了些比较,也介绍了些nginx中的location和反向代理集群的配置。无论是nginx还是haproxy亦或是lvs。都有自己的优势和不足的地方。没有那个好那个坏的区分。在应用中,选择自己合适的才是最好的。正所谓无论白猫还是黑猫,能抓到老鼠的都是好猫。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值