linux——Nginx——反向代理服务器

Posted 月未央

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux——Nginx——反向代理服务器相关的知识,希望对你有一定的参考价值。

nginx文档:http://nginx.org/en/docs/   http://tengine.taobao.org/book/     http://saiyaren.iteye.com/blog/1914865

 

1、介绍:

Nginx是一个网页服务器,能够代理HTTP、HTTPS、SMTP、IMPS、POP3的协议连接,以及一个负载均衡器、及HTTP缓存。

2、特点:

  1. Nginx是一款面向性能设计的HTTP服务器,相较于Apache、lighttpd,具有占有内存少、稳定性高等优势。
  2. Nginx不采用每客户机一线程的设计模型,而是充分使用异步逻辑削减了上下文调度开销,所以并发服务能力更强
  3. 整体采用模块化设计,有丰富的模块库和第三方模块库,配置灵活
  4. 在LInux操作系统下,Nginx使用epool时间模型,得益于此,nginx在Linux操作系统下效率相当高;

         nginx的优点:

         1、高并发连接:官方测试能够支撑5万并发连接,在实际生产环境中跑到2——3万并发连接数;

         2、内存消耗少:在3万并发连接下,开启10个Nginx进程才消耗150M内存;

         3、配置文件非常简单:风格跟程序一样通俗易懂;

         4、成本低廉:开源软件,可免费使用;

         5、内置的健康检查功能:后端服务器宕机了,不会影响前端服务的访问;

         6、稳定性高:用于反向代理,宕机的概率微乎其微;

         主要应用:

         1、使用Nginx结合FastCGI运行php、JSP、Perl等;

         2、使用Nginx做反向代理、负载均衡、规则过滤;

         3、使用Nginx运行 静态html页面、图片;

         防范攻击配置:

        1、封停IP:deny ip;

        2、限制一段时间内单个IP请求数;

        3、CXID的合法性校验;

        Nginx FastCGI模块配置:

       1、支持网络socket和文件socket两种方式:

             网络socket:fastcgi_pass localhost:9000;

             文件socket: fastcgi_pass unix:/tmp/fastcgi.socket;

       2、环境变量:

             fastcgi_param HTTP_COOKIE  $http_cookie;

             fastcgi_param REMOTE_ADDR   $remote_addr;

             fastcgi_param QUERY_STRING  $query_string

3、可大量平行处理:         

  • Nginx在官方测试结果中,能够支持五万个平行连接,而在实际的运作中,可以支持两万到四万个平行连接

4、nginx服务介绍

4.1  启动脚本:

  1.  1 #! /bin/bash
     2 # Parameters
     3 ###################################
     4 PREFIX="."
     5 SERVER="${PREFIX}/bin/nginx"
     6 STD_LOG="${PREFIX}/logs/std.log"
     7 ERR_LOG="${PREFIX}/logs/std.log.err"
     8 EXEC_USER="root"
     9 ####################################
    10 
    11 if [ `whoami` != ${EXEC_USER} ]; then
    12  echo MUST USE ${EXEC_USER}!
    13  exit 1
    14 fi
    15 
    16 killall -9 nginx
    17 
    18 rm -f logs/access_log
    19 /sbin/sysctl -w net.ipv4.tcp_timestamps=1 //TCP时间戳(会在TCP包头增加12个字节),以一种比重发超时更精确的方法(参考RFC 1323)来启用对RTT (Round-Trip Time: 往返时延)的计算,为实现更好的性能应该启用这个选项。1-启用,0-禁用
    20 /sbin/sysctl -w net.ipv4.tcp_tw_recycle=1  // 能够更快地回收TIME-WAIT套接字。
    21 
    22 ${SERVER} -p ${PREFIX} 1>>${STD_LOG} 2>>${ERR_LOG} &

    sysctl命令被用于在内核运行时动态地修改内核的运行参数,可用的内核参数在目录/proc/sys中。它包含一些TCP/ip堆栈和虚拟内存系统的高级选项, 这可以让有经验的管理员提高引人注目的系统性能。用sysctl可以读取设置超过五百个系统变量。
    具体介绍见: http://man.linuxde.net/sysctl, http://www.cnblogs.com/fczjuever/archive/2013/04/17/3026694.html

4.2  bin文件夹内容

  • nginx.pid:进程文件,存放的是nginx主进程(即master进程)号。若在nginx.conf中配置了pid文件存放路径,则该文件存放的就是nginx主进程号,若没指定则放在nginx的logs目录下,有了pid文件,就不用通过命令ps -ef|grep nginx|grep master来查找主进程号了。每次重启nginx,此文件内容就动态修改为本次主进程号。有了主进程号,就可以发送信号停止nginx了,如:
    1. kill -QUIT 主进程号 // 发送信号,从容停止Nginx
    2. kill -TERM 主进程号 // 快速停止Nginx
    3. kill -9 nginx // 强制停止Nginx
  • nginx:可执行文件;

4.3 conf文件夹内容:

4.3.1  nginx.conf

nginx配置文件主要分为六个区域: 
main(全局设置)events(nginx工作模式)http(http设置)、 
sever(主机设置)location(URL匹配)upstream(负载均衡服务器设置)

 1 main 
 2 events   {
 3   ....
 4 }
 5 http        {
 6   ....
 7   upstream myproject {
 8     .....
 9   }
10   server  {
11     ....
12     location {
13         ....
14     }
15   }
16   server  {
17     ....
18     location {
19         ....
20     }
21   }
22   ....
23 }

 

4.3.1.1  main模块:全局设置

pid   bin/nginx.pid; // 主进程号存储文件位置
worker_processes  8; // 子进程数,一般和cpu核数相同

#daemon off; // 关闭后台守护进程

worker_rlimit_nofile 51200; //用于指定一个nginx进程可以打开的最多文件描述符数目

 

4.3.1.2  events模块

          来用指定nginx的工作模式和工作模式及连接数上限:

events {
    use epoll; // 指定Nginx的工作模式
    worker_connections  51200; // 定义Nginx每个进程的最大连接数,即接收前端的最大请求数
}

use用来指定Nginx的工作模式。Nginx支持的工作模式有select、poll、kqueue、epoll、rtsig和/dev/poll。其中select和poll都是标准的工作模式,kqueue和epoll是高效的工作模式,不同的是epoll用在Linux平台上,而kqueue用在BSD系统中,因为Mac基于BSD,所以Mac也得用这个模式,对于Linux系统,epoll工作模式是首选

worker_connections是表示每个worker进程所能建立连接的最大值,所以,一个nginx能建立的最大连接数,应该是worker_connections * worker_processes。当然,这里说的是最大连接数,对于HTTP请求本地资源来说,能够支持的最大并发数量是worker_connections * worker_processes,而如果是HTTP作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/2。因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接。

4.3.1.3  http模块

        最核心的模块,它负责HTTP服务器相关属性的配置,它里面的server和upstream子模块,至关重要。

http{
    include       mime.types; // 来用设定文件的mime类型,类型在配置文件目录下的mime.type文件定义,来告诉nginx来识别文件类型
    default_type  application/octet-stream;//设定了默认的类型为二进制流,也就是当文件类型未定义时使用这种方式,例如在没有配置asp 的locate 环境时,Nginx是不予解析的,此时,用浏览器访问asp文件就会出现下载了。
//用于设置日志的格式,和记录哪些参数,这里设置为main,刚好用于access_log来纪录这种类型。
    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  /usr/local/var/log/nginx/access.log  main;//用来纪录每次的访问日志的文件地址,后面的main是日志的格式样式,对应于log_format的main。
    sendfile        on;//参数用于开启高效文件传输模式。将tcp_nopush和tcp_nodelay两个指令设置为on用于防止网络阻塞。
    tcp_nopush      on;
    tcp_nodelay     on;
    keepalive_timeout  10;//设置客户端连接保持活动的超时时间。在超过这个时间之后,服务器会关闭该连接。
    gzip  on; //开启gzp压缩
    
// 连接到后端fastcgi超时时间,单位秒,
     fastcgi_connect_timeout 300;
//向fastcgi请求超时时间(这个指定值已经完成两次握手后向fastcgi传送请求的超时时间)
     fastcgi_send_timeout 300;
//接收fastcgi应答超时时间,同理也是2次握手后。
     fastcgi_read_timeout 300;
//读取fastcgi应答第一部分需要多大缓冲区,该值表示使用1个64kb的缓冲区读取应答第一部分(应答头),可以设置为fastcgi_buffers选项缓冲区大小。
     fastcgi_buffer_size 64k;
//这个参数指定了从FastCGI进程到来的应答,本地将用多少和多大的缓冲区读取,假设一个PHP或JAVA脚本所产生页面大小为256kb,那么会为其分配4个64kb的缓冲来缓存;若页面大于256kb,那么大于256kb的部分会缓存到fastcgi_temp指定路径中,这并非是个好办法,内存数据处理快于硬盘,一般该值应该为站点中PHP或JAVA脚本所产生页面大小中间值,如果站点大部分脚本所产生的页面大小为256kb,那么可把值设置为16 16k,4 64k等。
     fastcgi_buffers 4 64k;
//限制读入临时缓冲区的大小
     fastcgi_busy_buffers_size 128k;
 //在写入缓存文件时使用多大的数据块,默认值是fastcgi_buffers的两倍。
     fastcgi_temp_file_write_size 128k;    
     
    upstream myproject {
        .....
    }
    server {
        ....
    }
}

4.3.1.4  upstream模块:负载均衡服务器设置,里面是链接的后端服务器ip列表。在http结点下添加,可以将相关配置单拉一个文件server.conf,配置后在http中使用“include server.conf”,或者直接在http结点中书写;

// 可以接收请求,然后根据path分发到不同的server上,在相同类型的server上,还可以进行负载均衡设置
// 服务列表1
upstream my_server_list_1 {
       server 127.0.0.1:port1 max_fails=1000 fail_timeout=15s;
       server ip2:port2 max_fails=1000 fail_timeout=15s backup;
       server ip3:port3 max_fails=1000 fail_timeout=15s backup;
       ...
}

// 服务列表2
upsteam my_server_list_2 {
       server ip4:port4 max_fails=1000 fail_timeout=15s;
       server ip5:port5 max_fails=1000 fail_timeout=15s;
       ...
}

nginx判断节点失效状态:nginx默认判断失效节点状态以connect_refuse和time out状态为准,不以HTTP错误状态进行判断,因为HTTP只要能返回状态说明该节点还可以正常连接,所以nginx认为其还是存活状态;除非添加了proxy_next_upstream指令设置 对404、502、503、504、500和time out等错误进行转到备机处理,在next_upstream过程中,会对fails进行累加,如果备用机器处理还是错误则直接返回错误信息(但404不进行记录到错误数,如果不配置错误状态也不对其进行错误状态记录)。综述,nginx记录错误数量只记录timeout、connect refuse、502、500、503、504这六种状态,timeout和connect refuse是永远被记录错误状态,而502、500、503、504只有在配置proxy_next_upstream后nginx才会记录者4中HTTP错误到fails中,当fails大于等于max_fails时,则该节点失效。注:404——Not Found,请求失败,请求所希望得到的资源未被在服务器上发现,但允许用户的后续请求;500——Internal Server Error,通用错误消息,服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理;502——Bad Gateway,作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应;503——Service Unavailable,由于临时的服务器维护或者过载,服务器当前无法处理请求。504——Gateway Timeout,作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,如HTTP、FTP、)辅助服务器(如DNS)收到响应。

nginx处理节点失效和恢复的触发条件:nginx可以通过设置max_fails(最大尝试失败次数)fail_timeout(失效时间,在到达最大尝试失败次数后,在fail_timeout的时间范围内此节点被置为无效;除非所有节点都失效,否则该时间内,节点不进行恢复)对节点失败的尝试次数和失效时间进行设置,当超过最大尝试次数或者失效时间未超过配置失效时间,则nginx会对节点状态置为失效状态,nginx不对该后端进行连接,直到超过失效时间或者所有节点都失效后,该节点重新置为有效,重新探测。

所有节点失效后nginx将重新恢复所有节点进行探测:若探测所有节点都失效,备机也为失效时,那么nginx会对所有节点恢复为有效,重新尝试探测有效节点,若探测到有效节点则返回正确节点内容,否则,若还是全部错误,则继续探测下去,直到找到正确的位置;

负载均衡算法有:轮询、weight、ip_hash、fair(第三方插件)、url_hash(第三方插件),具体描述见:http://www.cnblogs.com/myyan/p/5824965.html

  轮询:默认的,每个请求按顺序逐一分配到不同的后端服务器,若后端服务器down掉了(超过了最大失败次数(max_fails,默认1)),在失效时间内(fail_timeout,默认10秒),该节点失效权重变为0,超过失效时间后,则恢复正常,后者全部节点都为down后,那么将所有节点都恢复为有效继续探测,

    upstream test {
    server 192.168.109.5:81;
    servse 192.168.109.3:80;
   }

  weight:设置权重,用于后端服务器性能不均的情况,访问比率约等于权重之比:可以实现小流量分流,若某台服务器挂了,则将流量分发到其他服务器上;

  upstream test {
    server 192.168.109.5:81 weight=1;
    servse 192.168.109.3:80 weight=5;
  }
    ip_hash 解决了session问题:每个请求按访问IP的hash结果分配,但是如果这台服务器不可用,则将请求转发到其他的服务器上,这样每个访客将会在很大概率上连接到同一个后端服务器。但是会造成负载不均,有的服务接受到的请求多,有的服务接收到的请求少。无法将weight和ip_hash一起使用,若某台服务器不可用,则将其标记为down。
配置文件:
    upstream test {
             ip_hash;
    server 192.168.109.5:81;
    servse 192.168.109.3:80 down;
  }
  fair(第三方):按后端服务器的响应时间分配请求,响应时间短的优先。
  upstream test {
    server 192.168.109.5:81;
    servse 192.168.109.3:80;
    fair;
  }
  url_hash(第三方):按照请求url的hash进行分配,使相同url定向到同一个后端服务器,但是也会造成分配不均的情况,这种模式后端服务器为缓存时比较好。另外,在upstream中加入hash语句后,server语句不能写入weight等其他参数。
  upstream test {
    server squidIP1:3128;
    servse squidIP2:3128;
               hash  $request_uri;
              hash_method  crc32;
         }
  每个设备的状态设置为:
  1.down 表示单前的server暂时不参与负载
  2.weight 默认为1.weight越大,负载的权重就越大。
  3.max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误
  4.fail_timeout:max_fails次失败后,暂停的时间,默认为10s。
  5.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。
 
  nginx支持同时设置多组的负载均衡,用来给不用的server来使用。
  client_body_in_file_only 设置为On 可以讲client post过来的数据记录到文件中用来做debug
  client_body_temp_path 设置记录文件的目录 可以设置最多3层目录
  location 对URL进行匹配.可以进行重定向或者进行新的代理 负载均

4.3.1.5  server模块

http{
     ...
    server{
          listen 80;     // 监听端口号
          server_name xxx.com;  // 接收到的请求的域名,域名可以有多个,空格隔开;

          access_log  logs/access_log main;
          error_log   logs/error_log;
          // 默认请求
          location / {
              usertrack on;
              root html;  // root目录下定义的一个html页面,目录:./html/index.html
          }

          location  /ask {   // 当请求path为ask时的动作,启用反向代理转发请求;
                usertrack on;
                fastcgi_pass myserver; // upstream 为myserver,反向代理
                expires off; // 不缓存
          }
         // js和css缓存时间设置
         location ~* \\.(js/css)${
               expires 1h;   // 缓存1小时
          }
         // 图片缓存时间设置
         location ~* \\.(gif|jpg|jpeg|png|pbmp|swf)$ {
              expires 24h;
         }
         location ~* \\.(sql|bak|inc|old)${
              return 403;
         }
        // 定义错误提示页面
        error_page 400 403 404 500 501 502 503 504 505 /error.html;
        location = /error.html{
             root error;  // 主目录下定义的一个html页面,./error/error.html
        }
    }
}

     fastcgi_pass:后面是具体的ip:port,可以是本机;proxy_pass:后面是具体域名;

       

 

conf文件夹内容

以上是关于linux——Nginx——反向代理服务器的主要内容,如果未能解决你的问题,请参考以下文章

Linux平台部署nginx反向代理实例

Linux服务:Nginx反向代理与负载均衡

linux下实现nginx反向代理

Linux安装Nginx使用反向代理

[nginx] linux nginx 安装

linux-nginx-3(反向代理+负载均衡)