nginx笔记

  1. 介绍
    nginx用途:
    a.静态http服务器;
    b.反向代理(反向代理为何叫反向代理)。正向代理中,proxy和client同属一个LAN,对server透明;反向代理中,proxy和server同属一个LAN,对client透明;
    c.负载均衡,比如通过统一的域名进入然后将请求转发到不同的服务器上,以减轻单台服务器的压力;
    d.虚拟主机,不同域名访问同一个服务器上的不同的应用;
    e.限流;
    中文文档:http://tengine.taobao.org/nginx_docs/cn/docs/

  2. 源码安装

     sudo apt-get update
     sudo apt-get install build-essential zlib1g-dev libpcre3 libpcre3-dev libssl-dev libxslt1-dev libxml2-dev libgd2-xpm-dev libgeoip-dev libgoogle-perftools-dev libperl-dev libtool
     sudo apt-get install openssl
     # 最新链接见http://nginx.org/en/download.html
     wget http://nginx.org/download/nginx-1.14.0.tar.gz
     tar -zxvf nginx-1.14.0.tar.gz
     cd nginx-1.14.0
     ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-stream --with-mail=dynamic
     make
     make install
     # -c指定配置文件路径
     sudo /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
     # 查看nginx进程:
     ps -ef|grep nginx
     
    参考:[](https://www.linuxidc.com/Linux/2017-09/147157.htm) 
    
  3. yum安装

     创建文件:/etc/yum.repos.d/nginx.repo
     ```
     [nginx]
     name=nginx repo
     baseurl=http://nginx.org/packages/OS/OSRELEASE/$basearch/
     gpgcheck=0
     enabled=1
     ```
     将“OS”替换为“rhel”或者“centos”,根据系统版本是6.x或者7.x将“OSRELEASE”替换为“6”或者“7” 。
     参考:[](http://nginx.org/en/linux_packages.html#stable)
    
  4. 控制命令

     # 直接关闭 nginx
     nginx -s stop
     # 会在处理完当前正在的请求后退出,也叫优雅关闭
     nginx -s quit
     # 重新加载配置文件,相当于重启
     nginx -s reload
     # 重新打开日志文件
     nginx -s reopen
    
  5. 配置文件位置
    /usr/local/nginx/conf, /etc/nginx, /usr/local/etc/nginx

  6. 配置示例一

     # this is a comment
     events {  
         worker_connections  4096;  ## Default: 1024
     }
     http {    
         server {          
             listen 80;        
             server_name  domain1.com www.domain1.com;        
             access_log  logs/domain1.access.log  main;
             root        html;
             location ~ \.php$ {
                 fastcgi_pass 127.0.0.1:1025;
             }
             # /data/www
             location / {    
                 root /data/www;
             }
         # /data/images
             location /images/ {    
                 root /data;
             }
         }
         server {
             listen 8080;
             server_name domain2.com www.domain2.com;
             access_log logs/domain2.access.log  main;
             root html;
             location / {
                 proxy_pass http://localhost:8080;
             }
             # 以.gif .jpg .png结尾的url
             location ~ \.(gif|jpg|png)${
                 root /data/images;
             }
         }
     }
    
  7. 配置示例二(负载均衡)(参考

     # 工作模式及连接数上限
     events {
         use epoll; # epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,可以大大提高nginx的性能
         worker_connections 1024; # 单个后台worker process进程的最大并发链接数
         # multi_accept on; 
     }
     http {
         # 设定负载均衡的服务器列表
         upstream mysvr {
             # weigth参数表示权值,权值越高被分配到的几率越大
             # 本机上的Squid开启3128端口
             server 192.168.8.1:3128 weight=5;
             server 192.168.8.2:80  weight=1;
             server 192.168.8.3:80  weight=6;
         }
         server {          
             listen 80;        
             server_name  domain1.com www.domain1.com;        
             access_log  logs/domain1.access.log  main;
             root        html;
             location / {
                 root   /root;#定义服务器的默认网站根目录位置
                 index index.php index.html index.htm;#定义首页索引文件的名称
                 proxy_pass  http://mysvr; # 请求转向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;   #缓冲区代理缓冲用户端请求的最大字节数,
                 proxy_connect_timeout 90;       #nginx跟后端服务器连接超时时间(代理连接超时),单位:秒
                 proxy_send_timeout 90;          #后端服务器数据回传时间(代理发送超时),单位:秒
                 proxy_read_timeout 90;          #连接成功后,后端服务器响应时间(代理接收超时),单位:秒
                 proxy_buffer_size 4k;           #设置代理服务器(nginx)保存用户头信息的缓冲区大小
                 proxy_buffers 4 32k;            #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
                 proxy_busy_buffers_size 64k;    #高负荷下缓冲大小(proxy_buffers*2)
                 proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
             }
         }
     }
    
  8. upstream负载均衡策略

     # 轮询,每一个请求按时间顺序逐一分配到不同的后端服务器。假设后端服务器down掉。能自己主动剔除。尽管这样的方式简便、成本低廉。但缺点是:可靠性低和负载分配不均衡。适用于图片服务器集群和纯静态页面服务器集群。
     upstream servers { 
         server 10.0.6.108:7080; 
         server 10.0.0.85:8980; 
     }
     # 权重,指定轮询几率
     upstream servers{ 
         server 10.0.0.77 weight=5; 
         server 10.0.0.88 weight=10; 
     }
     # 每一个请求按訪问ip的hash结果分配。这样每一个訪客固定訪问一个后端服务器,能够解决session的问题。
     upstream servers{ 
         ip_hash; 
         server 10.0.0.10:8080; 
         server 10.0.0.11:8080; 
     }
     # fair(第三方,需要安装upstream-fair),按后端服务器的响应时间来分配请求。响应时间短的优先分配。与weight分配策略相似。
     upstream servers{      
         server 10.0.0.10:8080; 
         server 10.0.0.11:8080; 
         fair; 
     }
     # url_hash (第三方),按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。 在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法
     upstream servers { 
         hash $request_uri; 
         hash_method crc32; 
         server localhost:8080;
         server localhost:8081;
     } 
    
  9. 备用服务器
    在平时不使用,nginx不会给它转发任何请求。只有当其他节点全部无法连接的时候,nginx才会启用这个节点。

     upstream  testproxy  {
         server   127.0.0.1:8080;
         server   192.168.1.15:8080 backup;
     }
    
  10. 日志字段

    $remote_addr 	客户端地址
    $remote_user 	客户端用户名称
    $time_local 	访问时间和时区
    $request 	请求的URI和HTTP协议
    $http_host 	请求地址,即浏览器中你输入的地址(IP或域名)
    $status 	HTTP请求状态
    $upstream_status 	upstream状态
    $body_bytes_sent 	发送给客户端文件内容大小
    $http_referer 	url跳转来源
    $http_user_agent 	用户终端浏览器等信息
    $ssl_protocol 	SSL协议版本
    $ssl_cipher 	交换数据中的算法
    $upstream_addr 	后台upstream的地址,即真正提供服务的主机地址
    $request_time 	整个请求的总时间
    $upstream_response_time 	请求过程中,upstream响应时间
    
  11. 在负载均衡模式下,将真实地址返回到客户端(在测试环境下帮助问题定位)

    add_header Upstream-Addr $upstream_addr;
    
  12. 反向代理非80端口有时丢失端口

    proxy_set_header   Host             $host:$server_port;
    
  13. 反向代理传递将来源host、客户端ip

    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    
  14. 判断文件或者目录是否存在

    • -f和!-f用来判断是否存在文件
    • -d和!-d用来判断是否存在目录
    • -e和!-e用来判断是否存在文件或目录
    • -x和!-x用来判断文件是否可执行
    if  ( !-e $request_filename ) { # if后面需要有空格!!
        rewrite ^/data/attachment/forum/(.*)$ http://img.xxx.com/forum/$1 permanent;
    }
    if^(^$host^!=^‘www.0xcafebaby.com‘^){ # ^表示空格
    }
    

    redirect为302临时重定向;permanent为301永久重定向;

  15. 几个host: $proxy_host $host $http_host

    如果客户端发过来的header中有Host字段,则$http_host和$host都是原始的Host字段;
    如果客户端发过来的header中没有Host字段,则$host表示请求中的server name;

    $proxy_host默认是upstream解析的ip地址(proxy_set_header Host $proxy_host;),也就是如果反向代理没有设置proxy_set_header,则默认使用upstream的ip作为$proxy_host。
    因此,如果upstream是域名且也是类似反向代理,就需要设置proxy_set_header。
    如果需要传递端口,则:````proxy_set_header Host $host:$proxy_port```

  16. nginx压测

    安装:
    ubuntu: apt-get install apache2-utils
    centos: yum install httpd-tools

    使用:1000个并发,进行连接1000次 ab -c 1000 -n 1000 http://localhost/ab.html

  17. 正向代理

    server {
        access_log /var/log/nginx/access.log;
        listen          8087;
    
        resolver 114.114.114.114;
        location / {
                proxy_pass http://$http_host$request_uri;
        }
    }
    
    
  18. 限流及ip白名单

    geo $whiteiplist {
        default 1;
        10.10.1.111 0;
        10.10.1.111 1;
    }
    map $whiteiplist $limitbyip {
        1 $binary_remote_addr;
        0 "";
    }
    # 限制同一个ip连接数
    limit_conn_zone $binary_remote_addr zone=somename1:10m;
    # 限制同一个ip每分钟1个请求
    limit_req_zone $limitbyip zone=somename2:3m rate=1r/m;
    
    http {
        limit_conn somename1 1;
    

   limit_req zone=somename1 burst=5 nodelay;
# 限速500kB每秒,限速对象是单个连接
limit_rate 500k;
# 和limit_rate配合使用表示在下载的文件大小达到设定数后开启限速效果
limit_rate_after 50m;
}

```
burst=5:重点说明一下这个配置,burst爆发的意思,这个配置的意思是设置一个大小为5的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内等待,但是这个等待区里的位置只有5个,超过的请求会直接报503的错误然后返回。
nodelay:如果设置,会在瞬时提供处理(burst + rate)个请求的能力,请求超过(burst + rate)的时候就会直接返回503,永远不存在请求需要等待的情况。(这里的rate的单位是:r/s)
如果没有设置,则所有请求会依次等待排队。(摘自:https://blog.csdn.net/hellow__world/article/details/78658041)

其他链接:

  1. Nginx+upstream针对后端服务器容错的运维笔记
  2. nginx proxy_next_upstream
posted @ 2018-04-19 23:08  liqipeng  阅读(418)  评论(0编辑  收藏  举报