Nginx反向代理,負載均衡,redis session共用,keepalived高可用

来源:http://www.cnblogs.com/mrlinfeng/archive/2016/12/10/6146866.html
-Advertisement-
Play Games

相關知識自行搜索,直接上乾貨。。。 使用的資源: nginx主伺服器一臺,nginx備伺服器一臺,使用keepalived進行宕機切換。 tomcat伺服器兩台,由nginx進行反向代理和負載均衡,此處可搭建伺服器集群。 redis伺服器一臺,用於session的分離共用。 nginx主伺服器:19 ...


相關知識自行搜索,直接上乾貨。。。

使用的資源:

nginx主伺服器一臺,nginx備伺服器一臺,使用keepalived進行宕機切換。

tomcat伺服器兩台,由nginx進行反向代理和負載均衡,此處可搭建伺服器集群。

redis伺服器一臺,用於session的分離共用。

nginx主伺服器:192.168.50.133

nginx備伺服器:192.168.50.135

tomcat項目伺服器1:192.168.50.137

tomcat項目伺服器2:192.168.50.139

redis伺服器:192.168.50.140

註意訪問時需要配置防火牆規則,或者關閉防火牆

 

首先進行的通用安裝:

總的需要模擬五台伺服器,使用vmware,全部使用centos6.5 64位,五台伺服器全部安裝jdk,我使用的是jdk1.8.

1.安裝VMware虛擬機,安裝linux系統,此處使用centOS6.5 64位,安裝linux命令行工具,上傳文件工具,此處使用SecureCRT,SecureFX 。安裝教程不再贅述,百度一大堆..........

這步有問題請使勁點:www.baidu.com

 

 

2.在linux上安裝jdk:

安裝jdk:卸載openjdk版本,上傳解壓jdk,配置環境變數----參考:http://jingyan.baidu.com/article/ab0b56308966acc15afa7d18.html

 

一、Nginx反向代理與負載均衡:

架構圖:

 

此時需要用到三台伺服器,一臺nginx伺服器,兩台正式部署項目的伺服器:選擇的是192.168.50.133主nginx和192.168.50.137,192.168.50.139兩台tomcat伺服器

首先在兩台伺服器上安裝tomcat:這個也是簡單,不多說

安裝tomcat:上傳解壓即可使用,bin目錄下 startup.sh啟動,shutdown.sh關閉

配置防火牆埠:vim /etc/sysconfig/iptables 編輯,開放8080埠,80埠等一些常用埠,當然後邊有用到一些埠都是需要配置開放的,不建議關閉防火牆

編輯好後 service iptables restart 重新載入防火牆配置

 

如果是自己測試嫌配置麻煩,關閉防火牆: service iptables stop 重啟後防火牆打開,即在此次開機狀態下有效,完全關閉再使用 chkconfig iptables off ,即會在重啟後也關閉防火牆,註意有時候服務都起了但訪問出錯,可能就是防火牆問題哦

啟動tomcat訪問:192.168.50.137:8080,192.168.50.139:8080,打開tomcat首頁即成功。

然後編寫測試項目,部署到兩台tomcat上,eclipse新建web項目,項目名為testproject,在webapp下新建一個jsp頁面為index.jsp,添加如下內容

將項目中web.xml中的訪問順序<welcome-file>index.jsp</welcome-file>上移到第一個訪問

 

然後右鍵導出為war包,testproject.war,將該war包上傳到兩台伺服器的tomcat的webapps中

 

 然後修改tomcat的server.xml文件,在tomcat conf目錄中:可以使用notepad++的插件NppFTP直接連上linux,然後使用notepad++修改文件哦,保存記得使用UTF-8無BOM格式,具體去百度吧,哈哈

修改Engine標簽中,添加jvmRoute,用於標識nginx訪問的是哪個伺服器tomcat,137伺服器標識為137Server1,139伺服器標識為139Server2

在兩台tomcat的server.xml文件,Host標簽中添加:<Context path="" docBase="testproject"/>,path標識訪問路徑,docBase為項目名,表示訪問項目

此時,重新啟動tomcat,訪問192.168.50.137:8080,192.168.50.139:8080,顯示index.jsp內容:兩台伺服器訪問顯示如下

 

至此,兩台tomcat伺服器搭建完成。

 

在nginx主機192.168.50.133上安裝nginx:

 先使用yum命令安裝gcc,安裝pcre,zlib,openssl:

yum install -y gcc
yum install -y pcre pcre-devel
yum install -y zlib zlib-devel
yum install -y openssl openssl-devel

 在/usr/local/目錄下新建nginx-src目錄,將nginx-1.8.0.tar.gz放到此處,解壓 

tar -zxvf nginx-1.8.0.tar.gz

進入解壓後目錄

依次執行命令:

./configure

make

mkae install

 此時nginx安裝完畢,安裝目錄是/usr/local/nginx,nginx預設占用80埠

其中,sbin目錄為nginx執行命令,conf目錄下的nginx.conf為預設載入的配置文件

啟動nginx:

./sbin/nginx 

關閉nginx:

./sbin/nginx -s stop

 啟動nginx後訪問192.168.50.133:80即可訪問nginx:顯示nginx歡迎頁

 

 至此,nginx安裝完畢。

 

 

3.反向代理與負載均衡配置

現有兩台伺服器,一臺為192.168.50.137,一臺為192.168.50.139,伺服器上各有一臺tomcat,埠均為8080,在192.168.50.133上有nginx,經過配置nginx,當訪問192.168.50.133:80時,即可訪問192.168.50.137:8080,192.168.50.139:8080中隨機一臺,此時192.168.50.133:80被nginx監聽,當有請求時,代理到192.168.50.137:8080,192.168.50.139:8080隨機一臺即可,即為nginx反向代理功能,同時此時可以通過nginx將請求進行轉發,保證了一個入口,將所有請求轉發到兩台伺服器上也減輕了任何一臺的負載壓力,當有大量請求時,可以搭建大量伺服器,在入口代理伺服器上使用nginx進行轉發,即是負載均衡功能。

 

 配置即是配置nginx安裝目錄中conf目錄下的nginx.conf文件即可:具體配置如下,重點是紅色部分

#Nginx所用用戶和組
#user  niumd niumd;

#工作的子進程數量(通常等於CPU數量或者2倍於CPU)
worker_processes  2;

#錯誤日誌存放路徑
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
error_log  logs/error.log  info;

#指定pid存放文件
pid        logs/nginx.pid;

events {
    #使用網路IO模型linux建議epoll,FreeBSD建議採用kqueue
    #use epoll;
    
    #允許最大連接數
    worker_connections  1024;
}

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"';

    #access_log  off;
    access_log  logs/access.log;

    client_header_timeout  3m;
    client_body_timeout    3m;
    send_timeout           3m;
 
    client_header_buffer_size    1k;
    large_client_header_buffers  4 4k;

    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;

    #fastcgi_intercept_errors on; 
   
    error_page 404  /404.html;

    #keepalive_timeout  75 20;

    gzip                 on;
    gzip_min_length      1000;
    gzip_types           text/plain text/css application/x-javascript;

    #配置被代理的伺服器
    upstream blank {
        #ip_hash;
        server 192.168.50.137:8080;
        server 192.168.50.139:8080;
    }

    server {
            #nginx監聽80埠,請求該埠時轉發到真實目標
            listen       80;
            #配置訪問功能變數名稱
            server_name  192.168.11.133;                  
        
            location / {
                #這裡配置代理是指上面定義的兩個被代理目標,blank名字必須一致
                proxy_pass http://blank;
                
                #proxy_redirect          off;
                #非80埠使用,目的是將代理伺服器收到的用戶的信息傳到真實伺服器上,我也不是很理解
                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   300;
                proxy_send_timeout      300;
                proxy_read_timeout      300;
                proxy_buffer_size       4k;
                proxy_buffers           4 32k;
                proxy_busy_buffers_size 64k;
                proxy_temp_file_write_size 64k;
                add_header Access-Control-Allow-Origin *;
            }
            
            #此處定義500 502 503 504的錯誤頁面
            error_page   500 502 503 504  /50x.html;
            #錯誤頁面位置
            location = /50x.html {
            #root表示路徑 html為nginx安裝目錄中的html文件夾
            #位於/usr/local/nginx/html/下
               root   html;
            }        
    }
}

 

啟動兩台tomcat,重新啟動nginx:

訪問192.168.50.133:80將會隨機訪問192.168.50.137:8080和192.168.50.139:8080其中一臺。(問題:每次刷新nginx伺服器地址sessionid會變,session不能共用。

 

 

nginx輪詢策略:

nginx負載均衡到多台伺服器上時,預設採用輪詢策略:

常見策略:

1、輪詢

每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器down掉,能自動剔除。

2、weight
指定輪詢幾率,weight和訪問比率成正比,用於後端伺服器性能不均的情況,數字越大命中率越高。
例如:輪詢幾率是2:1
upstream bakend {
server 192.168.0.14 weight=2;
server 192.168.0.15 weight=1;
}

2、ip_hash
每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端伺服器,可以解決session的問題。
例如:
upstream bakend {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}

其他策略可以自行查詢學習,nginx還有很多其他可配置項,靜態資源緩存,重定向等,想深入的童鞋請自行學習

nginx配置詳解:http://blog.csdn.net/tjcyjd/article/details/50695922

 

實際問題:雖然解決了,但是不是很理解,記錄一下

其中192.168.50.133:80是有外網映射的,外網55.125.55.55:5555映射到192.168.50.133:80上,此時使用55.125.55.55:5555訪問,會映射到192.168.50.133:80上,然後會被轉發到192.168.50.137:8080或192.168.50.139:8080,但是此時卻出現圖片,js,css等靜態文件無法訪問的情況,通過兩種方法解決。

<1>.映射非80埠

讓55.125.55.55:5555映射192.168.50.133的非80埠,例如55.125.55.55:5555映射192.168.50.133:5555,然後再在nginx配置文件中配置如下,註意紅色加大部分:這地方不理解

........ 
upstream blank { #ip_hash; server 192.168.50.137:8080; server 192.168.50.139:8080; } server { #nginx監聽5555埠,請求該埠時轉發到真實目標 listen 5555; #配置訪問功能變數名稱 server_name 192.168.11.133; location / { #這裡配置代理是指上面定義的兩個被代理目標,blank名字必須一致 proxy_pass http://blank; #proxy_redirect off; #非80埠使用,目的是將代理伺服器收到的用戶的信息傳到真實伺服器上 proxy_set_header Host $host:5555; 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 300; proxy_send_timeout 300; proxy_read_timeout 300; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; add_header Access-Control-Allow-Origin *; }

........

 此時訪問55.125.55.55:5555,映射到192.168.50.133:5555上,然後轉發到192.168.50.137:8080或192.168.50.139:8080上,此時靜態文件均能訪問。

 

 <2>.使用功能變數名稱在外網伺服器上使用nginx進行轉發

將55.125.55.55綁定功能變數名稱為test.baidubaidu.com,此時在55.125.55.55伺服器上使用nginx,

........
location / { #加入判斷,如果功能變數名稱為test.baidubaidu.com,轉發到192.168.50.133:80,然後再進行轉發,註意,此處未進行測試,貌似是這麼寫的,$hostname為nginx變數,可以獲取功能變數名稱 if($hostname = "test.baidubaidu.com" ){   proxy_pass http://192.168.50.133:80; } #proxy_redirect off; #非80埠使用,目的是將代理伺服器收到的用戶的信息傳到真實伺服器上,我也不是很理解 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 300; proxy_send_timeout 300; proxy_read_timeout 300; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; add_header Access-Control-Allow-Origin *; }

........

 以上即nginx反向代理與負載均衡介紹,經過此次學習,發現nginx確實是博大精深,一個配置文件搞得我不要不要的。。。

 

二、session共用問題:

由於nginx是隨機分配請求,假設一個用戶登錄時訪問網站登錄時被分配到192.168.50.137:8080上,然後進行了登錄操作,此時該伺服器上就會有該用戶登錄的session信息,然後登陸後重定向到網站首頁或個人中心時,此時如果被分配到192.168.50.139:8080上,那麼這台伺服器上沒有該用戶session信息,於是又會變成未登錄狀態,所以由於nginx的負載均衡會導致session共用的問題。

解決方法:

1.nginx提供了ip_hash策略,可以保持用戶ip進行hash值計算固定分配到某台伺服器上,然後只要是該ip則會保持分配到該伺服器上,保證用戶訪問的是同一臺伺服器,那麼session問題就不存在了。這也是解決session共用的一種方式,也稱為黏性session。但是假設一臺tomcat伺服器掛了的話,那麼session也會丟失。所以比較好的方案是抽取session。

2.session存在memcache或者redis中,以這種方式來同步session,把session抽取出來,放到記憶體級資料庫裡面,解決了session共用問題,同時讀取速度也是非常之快。

 

本例中:

 

 

Redis解決session共用:

在redis伺服器192.168.50.140上搭建redis,redis預設埠為6379

Redis搭建:

redis依賴gcc,先安裝:

yum install -y gcc-c++

下載redis,我使用的是redis-3.2.1.tar.gz,上傳至linux /usr/local/redis-src/中,解壓

進入解壓後目錄redis-3.2.1,執行make命令進行編譯

安裝到目錄/usr/local/redis

執行:

make PREFIX=/usr/local/redis install

安裝完成之後將redis配置文件拷貝到安裝目錄下,redis.conf是redis的配置文件,redis.conf在redis源碼目錄,port預設6379。

執行命令:

cp /usr/local/redis-src/redis-3.2.1/redis.conf /usr/local/redis/

在redis安裝目錄啟動和關閉redis:

啟動:

./bin/redis-server ./redis.conf 

這種啟動方式叫做前端啟動,必須保持在當前視窗,如果ctrl + c 退出,那麼redis也就退出了,不建議使用

那麼後端啟動:

首先修改redis.conf中daemonize的值,打開可以看到預設是no,修改為daemonize yes,啟動即可。也可以在該配置文件中修改redis預設埠6379為其他值。

關閉redis:

 ./bin/redis-cli shutdown 

 

 至此,redis伺服器搭建完成。

 

 tomcat與redis集成實現session共用:

環境為tomcat7 + jdk1.6的話:

所有需要共用session的伺服器的tomcat中目錄下:

lib目錄中添加以下三個jar包,註意版本最好一致,不然極容易出現錯誤,下邊的測試是可用的:

conf目錄中content.xml中加入:配置redis服務

<Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve"/>  
<Manager className="com.radiadesign.catalina.session.RedisSessionManager"
host="192.168.50.140"
port="6379"
database="0"   
maxInactiveInterval="60" />

 

環境為tomcat7 + jdk1.7或1.8的話:

所有需要共用session的伺服器的tomcat中目錄下:

lib目錄中添加以下三個jar包,測試通過:

conf目錄中content.xml中加入:配置redis服務

<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />        
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager" 
host="192.168.50.140"   
port="6379"   
database="0"               
maxInactiveInterval="60"/>

 

根據我這測試,是jkd1.8+tomcat7,在137和139兩台tomcat中加入jar包且進行如上配置:

上傳jar包

 修改content.xml

啟動redis服務,重新啟動所有tomcat,啟動nginx,刷新nginx頁面,兩台tomcat頁面可以看到sessionid值不變,關閉某台tomcat,nginx中sessionid不變,說明session是共用的。

問題:

有可能此時訪問會報錯,redis無法訪問,這是由於redis的安全機制,預設只有127.0.0.1才能訪問,在redis.conf中可以找到bind 127.0.0.1,你可以將此ip改為訪問者ip,

如果有多個訪問者,也可以把bind 127.0.0.1註釋掉,然後在配置文件中找到protected-mode,修改protected-mode yes改為protected-mode no 關閉redis保護模式即可

詳細可以參考這:http://www.cnblogs.com/liusxg/p/5712493.html

 

三、keepalived高可用:

架構圖:

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Python爬蟲實戰 抓取圖書館借閱信息 原創作品,引用請表明出處:Python爬蟲實戰 抓取圖書館借閱信息 前段時間在圖書館借了很多書,借得多了就容易忘記每本書的應還日期,老是擔心自己會違約,影響日後借書,而自己又懶得總是登錄到學校圖書館借閱系統查看,於是就打算寫一個爬蟲來抓取自己的借閱信息,把每 ...
  • 官網 http://www.overbyte.be/ 下載 OverbyteIcsV816 完成後解壓到E:\Delphi7\OverbyteIcsV816\ 1、在library裡加入E:\Delphi7\OverbyteIcsV816\Source目錄。 2、從File->Open中打開E:\D ...
  • 1、基礎知識 最早的基礎知識僅限於那麼一點點的html和css,比牛毛還牛毛的一點點。所以最開始是從immoc上看視頻和跟著練習,花了有一個多月,看完一個路徑從:零開始學習ThinkPHP框架,由於基本沒有基礎,所以一開始有的地方很吃力,後來就先試著用不求甚解的方法去看,以後根據需要再慢慢來補,這樣 ...
  • 在SQL語句中有一些寫的是這樣的: 其中的“xx_id = %d”,這裡的%d指的是要取一個十進位的數(d的意思就是decimal十進位的意思),十進位數的內容就是後面的$bl['student_id']這個。 ps:每天收穫一點點! ...
  • 開始學習Jetty源碼,費了小半天才編譯成功,把自己拆過的坑記錄下來。 ...
  • 37:雇佣兵 37:雇佣兵 提問 提問 總時間限制: 1000ms 記憶體限制: 65536kB描述 雇佣兵的體力最大值為M,初始體力值為0、戰鬥力為N、擁有X個能量元素。 當雇佣兵的體力值恰好為M時,才可以參加一個為期M天的戰鬥期,戰鬥期結束體力值將為0。在同一個戰鬥期內,雇佣兵每連續戰鬥n天,戰鬥 ...
  • 網路方面用的比較多的庫是libevent和boost.asio,兩者都是跨平臺的。其中libevent是基於Reactor實現的,而boost.asio是基於Proactor實現的。Reactor和Proactor模式的主要區別就是真正的操作(如讀/寫)是由誰來完成的,Reactor中需要應用程式自 ...
  • 合理運用向上造型 ,能夠減少代碼量,優化代碼.總結如下: 1,向上造型 類型提升,自動類型轉換 基本類型自動類型轉換 byte → short → int → long → float → double ↑ char 引用類型自動類型轉換(向上造型) 小類型 → 自動轉換 → 大類型 //父類引用調 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...