1. 程式人生 > >nginx反向代理、負載均衡 + session共享

nginx反向代理、負載均衡 + session共享

前幾天我因為工作的需要,自己學習了下找了下各種文件,自己給自己挖了一堆坑,然後又自己慢慢的填!下面我就先介紹下我自己的安裝方式。

一:準備環境:

1.伺服器:centos6.6

2.nginx版本nginx-1.8.0                                             

3.下載pcre-8.02.tar.gzwget http://exim.mirror.fr/pcre/pcre-8.02.tar.gz

cd pcre-8.02

./configure && make  && make install

如果發現沒安裝gcc 等 則安裝gcc等依賴

yum install gcc gcc-c++ -y

然後再執行 ./configure && make  && make install

4下載zlib-1.2.8.tar.gz wget http://zlib.net/zlib-1.2.8.tar.gz

tar -zxvf zlib-1.2.8.tar.gz 

cd zlib-1.2.8

./configure && make && make install

5.下載openssl   wget http://www.openssl.org/source/openssl-1.0.1c.tar.gz

tar -zxvf openssl-1.0.1c.tar.gz

cd openssl-1.0.1c

yum install perl

./config

make

make install

6.解壓nginx tar -zxvf nginx-1.8.0.tar.gz 

將nginx目錄名修改為nginxmv nginx-1.8.0 nginx

7.最重要的一步,我在這卡里半天,找不到解決方案,很多部落格沒有備註明白,這裡是開啟nginx許可權的(也就是開啟nginx的一些別的功能的步驟)

--sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx/nginx.pid

--with-http_ssl_module --with-pcre=/usr/local/nginx/pcre-8.02 --with-zlib=/usr/local/nginx/zlib-1.2.8 --with-openssl=/usr/local/nginx/openssl-1.0.1c

--with-http_stub_status_module

7.編譯安裝

make

make install

二:nginx配置檔案

nginx的負載均衡和反向代理主要就是通過配置檔案來完成,那麼下面我們就來說說nginx的配置檔案。

廢話先不說,先上完整的配置檔案:

#執行使用者
#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 {
    use   epoll;             #epoll是多路複用IO(I/O Multiplexing)中的一種方式,但是僅用於linux2.6以上核心,可以大大提高nginx的效能
    worker_connections  1024;  #單個後臺worker process程序的最大併發連結數
    # multi_accept on; 
}

#設定http伺服器,利用它的反向代理功能提供負載均衡支援
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;

    #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]\.(?!.*SV1)";
    #設定請求緩衝
    client_header_buffer_size    1k;
    large_client_header_buffers  4 4k;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

    #設定負載均衡的伺服器列表
      upstream mysvr {
     # weigth引數表示權值,權值越高被分配到的機率越大
          #本機上的Squid開啟3128埠
#      server 192.168.122.105:8088;
      server 192.168.39.207:80;
      server 192.168.39.208:80;

#      ip_hash;
       }

    server {
    listen  80;
    server_name 127.0.0.1;

    rewrite ^(.*)$  https://$host$1 permanent;
    }

    server {
        #偵聽443埠
        listen       443 ;

        server_name  127.0.0.1;

        ssl on;

        ssl_certificate /usr/local/nginx/nginx/conf/server.crt;

        ssl_certificate_key /usr/local/nginx/nginx/conf/server.key;

        ssl_session_timeout 5m;

        ssl_protocols SSLv2 SSLv3 TLSv1;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;


        #charset koi8-r;
        #設定本虛擬主機的訪問日誌
#        access_log  logs/host.access.log;

        location /index.html {
             root   html;
      #       index  index.html index.htm; 
         }

        location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ {
             proxy_pass http://mysvr;
      #       index  index.html index.htm; 
                      }
      #

        #預設請求
        location / {
                 proxy_pass http://mysvr;
                 proxy_set_header   Host    $host;
                 proxy_set_header   X-Real-IP   $remote_addr;
                 proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
          #  root   html; #定義伺服器的預設網站根目錄位置
          #  index  index.html index.htm; #定義首頁索引檔案的名稱
        }

#       location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$ {

#        proxy_pass http://mysvr; 
#        } 

#       location /Tomcat {
#                 proxy_pass http://192.168.122.105:8080/;
#                 proxy_set_header   Host    $host;
#                 proxy_set_header   X-Real-IP   $remote_addr;
#                 proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
          #  root   html; #定義伺服器的預設網站根目錄位置
          #            #  index  index.html index.htm; #定義首頁索引檔案的名稱
#         }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        # 定義錯誤提示頁面
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }


        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #設定檢視Nginx狀態的地址
        location /nginx_status {
        stub_status on;
        # I do not need logs for stats
        access_log /usr/local/nginx/logs/status.log;
        auth_basic "NginxStatus";
        #deny all;
        }

        #location ~ /\.ht {
        #    deny  all;
        #}
    }



    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
   # server {
       # listen       443 ssl;

       # server_name  192.168.122.105;

       # ssl on;

       # ssl_certificate /usr/local/nginx/nginx/conf/server.crt;

        #ssl_certificate_key /usr/local/nginx/nginx/conf/server.key;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
   # }

}
好了 ,那麼下面我就說說主要功能的配置了:(大神勿噴)

由於我用的是實現的是https來做的請求加密那麼我還監聽80埠,然後把80埠轉向443(HTTPS預設埠443)

具體的寫法就是:

server {
    listen  80;
    server_name 127.0.0.1;

    rewrite ^(.*)$  https://$host$1 permanent;
    }

    server {
        #偵聽443埠
        listen       443 ;

        server_name  127.0.0.1;

        ssl on;

        ssl_certificate /usr/local/nginx/nginx/conf/server.crt;

        ssl_certificate_key /usr/local/nginx/nginx/conf/server.key;

        ssl_session_timeout 5m;

        ssl_protocols SSLv2 SSLv3 TLSv1;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

              ······
上面的例子就是把原來的HTTP80埠的請求重定向到https443埠,強制實現LLS加密傳輸。

下面我們來說說主要的負載均衡的配置(其實很簡單,但是我當初兩個後臺主機一臺部署tomcat,一臺部署apache ,結果發現有一個CSS、JS、圖片一致獲取不到,後來才發現服務不一樣,而存放靜態檔案的路徑也不對,靜態檔案再另一臺主機上未必有啊。 ),見笑了大家。

 #設定負載均衡的伺服器列表
      upstream mysvr {
     # weigth引數表示權值,權值越高被分配到的機率越大
          #本機上的Squid開啟3128埠
#      server 192.168.122.105:8088;
      server 192.168.39.207:80;
      server 192.168.39.208:80;

#      ip_hash; 
       }
上面的程式碼我配置的是輪詢訪問,就是這一次訪問的是207服務,那麼下次請求來了訪問的是208的服務。當然你也可以通過配置權值來讓哪個服務訪問的機率增大或減少。

具體還有很多的配置方式,大家可以百度或者google下,網上的例子很多的,我就不廢話了。還有一個就是

<pre name="code" class="html">ip_hash;

它的作用就是能夠將當前某個ip的請求定向到同一臺後端,這樣一來這個ip和這個後端伺服器就建立了穩定的session。

我們要負載均衡還缺少一步,那麼就是配置什麼樣的請求去找那幾個後臺伺服器。

 #charset koi8-r;
        #設定本虛擬主機的訪問日誌
#        access_log  logs/host.access.log;

        location /index.html {
             root   html;
      #       index  index.html index.htm; 
         }

        location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ {
             proxy_pass http://mysvr;
      #       index  index.html index.htm; 
                      }
      #

        #預設請求
        location / {
                 proxy_pass http://mysvr;
                 proxy_set_header   Host    $host;
                 proxy_set_header   X-Real-IP   $remote_addr;
                 proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
          #  root   html; #定義伺服器的預設網站根目錄位置
          #  index  index.html index.htm; #定義首頁索引檔案的名稱
        }

上面的例子很明顯,我配置了2個有效請求,一個是xxx.xxx.xxx.xxx:80/index.html 那麼另外一個就是預設請求,我們來主要看看預設請求的例子:
 location /
表示xxx.xxx.xxx.xxx 或者 https://xxx.xxx.xxx.xxx:443這樣的請求,後面沒有任何路徑,那麼我想xxx.xxx.xxx.xxx:80/test 去訪問剛才的負載均衡伺服器,那麼我就直接寫成:
 location /test {
這樣你的xxx.xxx.xxx.xxx:80/test 請求對應的就是你裡面配置的後臺伺服器請求路徑。
 proxy_pass http://mysvr;
這個是主要的,大家應該也發現了,它的http 後面跟著的是我們上面配置的負載均衡的一樣。那麼如果你上面配置了3個不同的負載均衡服務叢集。那麼你在這裡寫3個不同的請求方式,然後proxy_pass 對應不同的負載均衡叢集就完成了。至於裡面的另外幾個引數請大家去百度吧。嘿嘿(偷個懶!~~~~~)

再來說說反向代理:

其實你懂了負載均衡那麼反向代理也就不難理解了只是吧原來本該指向負載叢集的路徑指向了具體的IP+埠不就完了?最後再附上一個反向代理的例子:

 location /Tomcat {
#                 proxy_pass http://192.168.122.105:8080/;
#                 proxy_set_header   Host    $host;
#                 proxy_set_header   X-Real-IP   $remote_addr;
#                 proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
          #  root   html; #定義伺服器的預設網站根目錄位置
          #            #  index  index.html index.htm; #定義首頁索引檔案的名稱
#         }
好了,大家可以參考我的配置去自己搭建下,其實沒那麼難,剛開始我聽著也是感覺很高大上的樣子。自己搭建一次後感覺也就是那。後面我應該會寫一個關於多個負載均衡伺服器共同訪問而出現的一個session無法統一這樣的問題,那麼下一個我會用redis 來做session共享伺服器,包括相關的java程式碼。