小生博客:http://xsboke.blog.51cto.com

   如果有疑问,请点击此处,然后发表评论交流,作者会及时回复。

  

 

                             -------谢谢您的参考,如有疑问,欢迎交流


一、 代理和nginx相关概念

   1. 代理类型


    • 正向代理:代理局域网对internet的连接请求

    • 反向代理:代理internet对局域网的连接请求


   2. Nginx反向代理(reverseproxy)的作用


    • 在一定程度上确保web服务器的安全(因为任何来自internet的请求都需要经过代理服务器)

    • 通过缓存功能加速web访问

    • 可以实现后端服务器的负载均衡


   3. Nginx简介

     1)  核心特点


    • 支持跨平台

    • 配置简单

    • 使用非阻塞模型、高并发连接(官测5W,实际2-3W

    • 事件驱动:通信机制使用epoll模型(一个进程处理多个请求)

    • Master/worker结构:一个master进程,生成一个或多个woker进程

    • 内存消耗小:进程开启数量影响内存占用,而nginx的一个进程可以处理多请求

    • 内置健康检查功能

    • 节省带宽:支持Gzip压缩

    • 稳定性高


     2)  Nginxmaster/worker结构详解

       wKioL1j8qNvhQzk0AAA3_zxtkz0511.jpg



    • Master:维护worker队列

    • Worker:进行实际逻辑运算,并将结果返回给master

    • 一个Master进程产生多个worker进程,然后每个worker进程处理多个请求,一个worker进程中断后,不会影响其他worker进程,并且master会重新启动新的worker进程


     3)  阻塞和非阻塞模型的区别


    • 阻塞模式:当读写事件没有准备好时,只能等待,当前线程将被挂起

    • 非阻塞模式:事件马上返回,但是响应为事件还没准备好,过会再来,然后每隔一段时间就来检查一下事件,直到事件准备好,在这期间这个线程可以处理其他事情


     4)  Nginx使用的epoll非阻塞通信机制的特点


    • Epoll工作机制也称为:异步非阻塞事件处理机制

    • Epoll存在一个队列事件,所有未完成的事件,将被放到epoll事件队列中,非阻塞模式需要在每个未完成的事件之间进行切换,这样导致了cpu开销很大,而epoll模型的通信机制不会,epoll模型只是在请求之间进行切换,而且切换也是因为异步事件未准备好,而主动让出的,所以这里的切换不需要任何代价,这样nginx实现了高并发和轻量级(只需要几个进程即可)


二、 主要知识点简介

   1. nginx-sticky-module模块


    • 主要实现会话保持,后面会介绍配置项

    • 其他实现会话保持的方法:ip_hash


   2. Nginx实现LB的调度方案


    • RR:轮询(默认)

    • Ip_hash:请求按访问IPhash结果分配,可以有效解决session共享问题

    • Least_conn:请求被发送到当前活跃连接最少的后端服务器上,会考虑weight的值

    • url_hash:按照urlhash结果分配请求,需要nginxhashnginx_upstream_hash支持

    • fair:依据页面大小和加载时间长短智能地进行负载均衡,需要第三方nginx模块upstream_fair支持


   3. 负载均衡与健康检查


    • nginx自带是没有针对负载均衡后端节点的健康检查的,但是可以通过默认自带的ngx_http_proxy_module 模块和ngx_http_upstream_module 模块中的相关指令来完成当后端节点出现故障时,自动切换到下一个节点来提供访问


   4. Nginxproxy缓存


    • 缓存也就是将jscssimage等静态文件从后端服务器缓存到nginx指定的缓存目录下,既可以减轻后端服务器负担,也可以加快访问速度,但这样缓存及时清理成为了一个问题,所以需要 ngx_cache_purge 这个模块来在过期时间未到之前,手动清理缓存。


三、 nginx反向缓存代理服务器搭建

   实验环境

   wKiom1j8qcGj2bMkAAAqh6BdgGs895.png

   1. 后端web服务器的配置

    1)   为了实验模拟的更为真实,我们将两台后端服务器的域名改为一样的

      wKioL1j8qeCR-9AlAADAN_2ao3I717.jpg

     2)   为了可以模拟负载均衡,我们为两个后端服务器配置相同文件名,内容不同的html文件

        Web1192.168.1.5

        wKiom1j8qf_C4MuhAAB_xmzAJn4558.jpg

        Web2192.168.1.6

        wKioL1j8qg3zzkVIAACFC3Mfih0552.jpg

     3)   分别在两台后端服务器上开启80端口例外

        wKioL1j8qjfDIK9SAABre6QbY44731.jpg

   2. Nginx的安装

     首先安装依赖包

     wKiom1j8qlnxATruAAA7yBflrfc989.jpg


    • Nginxsession和缓存清除功能都需要第三方模块的支持,在编译nginx的时候需要指定,所以我们首先解压第三方模块


     wKiom1j8qmeRhzELAADlP6lsF04844.jpg

     然后创建nginx运行时需要的用户

     wKiom1j8qpLypXDjAAAoiqCGO5w536.jpg

     解压nginx并且进行编译安装


    • nginx默认自带的 ngx_http_proxy_module 模块 ngx_http_upstream_module模块实现后端服务器的健康检查

    • 使用第三方模块nginx-sticky-module扩展模块实现Cookie会话黏贴(保持会话)

    • 使用第三方模块ngx_cache_purge实现更强大的缓存清除功能


     wKiom1j8qrLzDEJlAAFwEfPd-aA560.jpg

     wKiom1j8qr7gpQl4AAAsiXDpjI8048.jpg

     安装完成后的优化及其处理

     wKioL1j8qtCArY8LAAIu_9uWhlA334.jpg

     Nginx不支持动态加载模块,但是第三方模块可以在nginx安装后再次添加,添加方法是:


    • 解压模块文件

    • 解压nginx文件

    • ./configure  --add-module=第三方模块压缩文件位置

    • 然后make,但是不make  install

    • 最后将新的nginx主程序替换旧的nginx主程序

    • cp  objs/nginx /usr/local/nginx1.10/sbin/nginx


     查看nignx安装的模块

     wKiom1j8qvSQYOHdAAErsH73HYg661.jpg

四、 修改nginx配置文件实现:反向代理+负载均衡+健康检查

  1. 配置文件总览

    wKiom1j8qxjCyBE5AAKXyUnzGXk560.jpg

     图片不太清晰,下面我直接将配置粘贴了过来

user  www www;
worker_processes  2;
worker_cpu_affinity 01 10;
error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
worker_rlimit_nofile 10240;
pid        logs/nginx.pid;
events {
    use epoll;
    worker_connections  4096;
}
http {
    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"'
                      '"$upstream_cache_status"';
    access_log  logs/access.log  main;
    server_tokens off;
    sendfile        on;
    #tcp_nopush     on;
    #keepalive_timeout  0;
    keepalive_timeout  65;
    #Compression Settings
    gzip on;
    gzip_comp_level 6;
    gzip_http_version 1.1;
    gzip_proxied any;
    gzip_min_length 1k;
    gzip_buffers 16 8k;
    gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;
    gzip_vary on;
    #end gzip
    # http_proxy Settings
    client_max_body_size   10m;
    client_body_buffer_size   128k;
    proxy_connect_timeout   75;
    proxy_send_timeout   75;
    proxy_read_timeout   75;
    proxy_buffer_size   4k;
    proxy_buffers   4 32k;
    proxy_busy_buffers_size   64k;
    proxy_temp_file_write_size  64k;
    proxy_buffering off;
    proxy_temp_path /usr/local/nginx1.10/proxy_temp;
    proxy_cache_path /usr/local/nginx1.10/proxy_cache levels=1:2 keys_zone=my-cache:100m max_size=1000m inactive=600m max_size=2g;
    #load balance Settings
    upstream backend {
        #sticky;
        server 192.168.1.5:80 weight=1 max_fails=2 fail_timeout=10s;
        server 192.168.1.6:80 weight=1 max_fails=2 fail_timeout=10s;
    }
    #virtual host Settings
    server {
        listen       80;
        server_name  localhost;
        charset utf-8;
        location  ~/purge(/.*) {
           allow 127.0.0.1;
           allow 192.168.1.0/24;
           deny all;
           proxy_cache_purge my-cache $host$1$is_args$args;
        }
        location / {
            index  index.php index.html index.htm;
            proxy_pass        http://backend;
            proxy_redirect off;
            proxy_set_header  Host  $host;
            proxy_set_header  X-Real-IP  $remote_addr;
            proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_ignore_headers Set-Cookie;
            proxy_hide_header Set-Cookie;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        }
        location ~ .*\.(gif|jpg|png|html|htm|css|js|ico|swf|pdf)(.*) {
           proxy_pass  http://backend;
           proxy_redirect off;
           proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
           proxy_cache my-cache;
           add_header Nginx-Cache $upstream_cache_status;
           proxy_cache_valid 200 304 301 302 8h;
           proxy_cache_valid 404 1m;
           proxy_cache_valid any 1d;
           proxy_cache_key $host$uri$is_args$args;
           expires 30d;
        }
        location /nginx_status {
            stub_status on;
            access_log off;
            allow 192.168.1.0/24;
            deny all;
        }
    }
}




  2. 分区解释:一

    wKioL1j8q5OQgx8MAACLyzWXet8163.jpg

  3. 分区解释:二

    wKiom1j8q6HxrMMHAACU-ilnOHM919.jpg

  4. 分区解释:三

    wKioL1j8q62T7BipAABmoOcpXVE108.jpg

  5. 分区解释:四

    wKiom1j8q7zCZDDcAAD45IjFwwg758.jpg

  6. 分区解释:五

    wKioL1j8q86A-M_mAACYB3Cgyss671.jpg



    • 例:如果需要指定其他调度方法直接在这个配置区域中添加调度方法的配置项即可,如:使用IP_hash算法

     wKioL1j8q_LjxwbuAABhFCww2FA818.jpg

  7. 分区解释:六

    wKiom1j8rADB_IpeAABv3r1xbuM772.jpg

  8. 分区解释:七

    wKiom1j8rBqxQvs4AAE9ve2hZ4Y654.jpg  


    • 要想修改代理服务器发送给后端服务器的头信息,实现后端服务器记录真实的客户机IP,只修改这里不行,还需要修改后端服务器的web配置文件

    • 我使用的后端服务器是apache,下面是需要修改的参数,两台后端服务器都需要修改

    wKiom1j8rEiAt040AAEs4DQ6lk4834.jpg

  9. 分区解释:八

    wKiom1j8rGyCQRuXAACrqxzU2YI246.jpg

  10. 分区解释:九

    wKioL1j8rLniqQ9XAABlIxru2aI591.jpg

五、 验证

  1. 验证缓存

   第一次访问

   wKiom1j8rKbSr0MWAAGnMwJD1p0097.jpg

   第二次访问

   wKiom1j8rM_jitCTAAEiuH2y2QQ300.jpg

  2. 验证缓存清除功能:清空在代理服务器上的缓存

   wKioL1j8rN-BF-QxAABwdQ-v5tY886.jpg

  3. 验证负载均衡功能


    • 因为有会话保持和缓存功能,在此环境中体现不出负载均衡功能,所以先将这里两个参数注释掉不用

   wKioL1j8rPLy7TvsAADsEqYyd-c736.jpg

   重启nginx使配置生效

   wKiom1j8rP_TRoX0AAAuhjbXEnw787.jpg

   第一次访问web页面

   wKiom1j8rQ7yKAB_AABtqZF_b48327.jpg

   第二次访问web页面

   wKiom1j8rRyAWOxGAABrAKJ6Jnk819.jpg

  4. 验证健康检查

   首先关闭一台后端web服务器的web服务

   wKiom1j8rS_hwkFqAABpwn6_nyU914.jpg

   验证

   wKiom1j8rT7jnSLoAACIFmqVkVQ276.jpg

   然后启动刚刚停掉的后端第一台web服务器的httpd服务

   wKioL1j8rUuhoBp2AAA2ybinS6U218.jpg

   再次验证

   wKiom1j8rVeD49aRAABiw8tZPb8460.jpg

  5. 验证后端服务器日志记录的IP是否为真实客户端的IP

   首先使用客户端访问web页面

   wKiom1j8rXHR_m0oAAA0N2KKieU047.png

   然后在后端服务器上查看访问日志

   wKiom1j8rYPxdGAwAADk8-grnas753.jpg