1.概述nginx
分佈式系統緩存已經變得不可或缺,本文主要闡述如何實現redis主從複製集羣的負載均衡,以及 redis的"高可用"實現, 呵呵雙引號的"高可用"並非傳統意義的高可用哈,而是 redis集羣掛了,並不影響asp.net core 的運行, 欲知詳情,請看下文.web
注意: 本文主要闡述redis 的複製均衡和"高可用", 故redis 的主從複製搭建略, 請自行百度.redis
2.負載均衡實現後端
目前在tcp 負載均衡這塊, haproxy 是官方實現, nginx 是三方實現, 我的偏向haproxy的簡單易用. 故redis的負載均衡採用haproxy實現.api
Haproxy配置文件以下:緩存
global log 127.0.0.1 local2 #log語法:log <address_1>[max_level_1] # 全局的日誌配置,使用log關鍵字,指定使用127.0.0.1 上的syslog服務中的local0日誌設備,記錄日誌等級爲info的日誌 chroot /var/lib/haproxy #當前工做目錄 pidfile /var/run/haproxy.pid #當前進程id文件 maxconn 6000 #最大併發鏈接數 user haproxy #所屬用戶 group haproxy #所屬組 daemon #以守護進程方式運行haproxy stats socket /var/lib/haproxy/stats defaults mode http #默認的模式mode { tcp|http|health },tcp是4層,http是7層,health只會返回OK log global #應用全局的日誌配置 option httplog #啓用日誌記錄HTTP請求,默認haproxy日誌記錄是不記錄HTTP請求日誌 option dontlognull # 啓用該項,日誌中將不會記錄空鏈接。所謂空鏈接就是在上游的負載均衡器或者監控系統爲了探測該 服務是否存活可用時,須要按期的鏈接或者獲取某一固定的組件或頁面,或者探測掃描端口是否在監聽或開放等動做被稱爲空鏈接;官方文檔中標註,若是該服務上游沒有其餘的負載均衡器的話,建議不要使用該參數,由於互聯網上的惡意掃描或其餘動做就不會被記錄下來 option http-server-close #每次請求完畢後主動關閉http通道 option forwardfor except 127.0.0.0/8 #若是服務器上的應用程序想記錄發起請求的客戶端的IP地址,須要在HAProxy上 配置此選項, 這樣 HAProxy會把客戶端的IP信息發送給服務器,在HTTP請求中添加"X-Forwarded-For"字段。 啓用 X-Forwarded-For,在requests頭部插入客戶端IP發送給後端的server,使後端server獲取到客戶端的真實IP。 option redispatch # 當使用了cookie時,haproxy將會將其請求的後端服務器的serverID插入到cookie中,以保證會話的SESSION持久性;而此時,若是後端的服務器宕掉了, 可是客戶端的cookie是不會刷新的,若是設置此參數,將會將客戶的請求強制定向到另一個後端server上,以保證服務的正常。 retries 3 # 定義鏈接後端服務器的失敗重連次數,鏈接失敗次數超過此值後將會將對應後端服務器標記爲不可用 timeout http-request 10s #http請求超時時間 timeout queue 1m #一個請求在隊列裏的超時時間 timeout connect 10s #鏈接超時 timeout client 1m #客戶端超時 timeout server 1m #服務器端超時 timeout http-keep-alive 10s #設置http-keep-alive的超時時間 timeout check 10s #檢測超時 maxconn 6000 #每一個進程可用的最大鏈接數 listen stats #統計界面 mode http bind *:2080 stats enable stats refresh 30s stats uri /hastats stats realm Haproxy\ Statistics stats auth admin:admin stats admin if TRUE frontend healthcheck bind :1099 #定義外部檢測機制 mode http #http 負載均衡 option httpclose option forwardfor default_backend AnuoApcNodes frontend http-in bind *:88 #監聽的端口,處理請求的服務器集羣爲 default_backend 的配置值 mode http log global option httpclose option logasap #不等待響應結束就記錄日誌,表示提早記錄日誌,通常日誌會記錄響應時長,此不記錄響應時長 option dontlognull #不記錄空信息 capture request header Host len 20 #記錄請求首部的前20個字符 capture request header Referer len 60 #referer跳轉引用,就是上一級 default_backend AnuoApcNodes #處理請求的服務器集羣 backend AnuoApcNodes #處理請求的服務器集羣 mode http balance roundrobin #check : 下面的check 表示ha 須要檢查此節點的狀態 server websrv1 192.168.2.108:9090 check maxconn 6000 server websrv2 192.168.1.112:88 check maxconn 6000 listen SQLServer :1433 #tcp 負載均衡 mode tcp balance roundrobin #weight : 權重, 表示此節點的優先級,值越高(最高256) , 優先執行越高 #check port : 檢測是否存活的端口 #inter : interval 檢測是否存活的 時間間隔 #rise : server 從離線狀態轉爲正常狀態後, 須要複查的次數(看是否正常) #fall : server 從正常狀態轉換爲不可用狀態須要檢查的次數 server SQLServer1 192.168.2.101:1433 weight 1 maxconn 6000 check port 1433 inter 2000 rise 2 fall 2 server SQLServer2 192.168.2.203:1433 weight 1 maxconn 6000 check port 1433 inter 2000 rise 2 fall 2 listen Redis :6377 #tcp 負載均衡 mode tcp balance roundrobin #weight : 權重, 表示此節點的優先級,值越高(最高256) , 優先執行越高 #check port : 檢測是否存活的端口 #inter : interval 檢測是否存活的 時間間隔 #rise : server 從離線狀態轉爲正常狀態後, 須要複查的次數(看是否正常) #fall : server 從正常狀態轉換爲不可用狀態須要檢查的次數 server Redis1 192.168.2.101:6379 weight 1 maxconn 6000 check port 6379 inter 2000 rise 2 fall 2 server Redis2 192.168.2.102:6379 weight 1 maxconn 6000 check port 6379 inter 2000 rise 2 fall 2
其中最後的配置:服務器
爲redis的負載均衡配置, 能夠看到負載了兩個redis IP, 101和102 .cookie
在實際運行中, redis的主庫通常用做寫, 從庫用做讀, so , 通常針對redis的從庫進行負載.併發
只需將上面的兩個IP 替換爲本身的ip 便可完成對 redis 從庫的負載.負載均衡
3. asp.net core 端針對 redis "高可用"實現
實現思路: 此處的實現不是傳統意義的高可用實現,而是C#端檢測到redis集羣掛了, 自動將redis從系統中剔除, 保證asp.net core 能繼續運行
業界問題: redis 的高可用有官方實現叫sentinel , 如今應用案例並很少, 也逮到官方文檔看了哈, 看了半天沒看到, 有sentinel實戰教程推薦的,或其餘高可用實現的, 望留言 ^_^
先下載完整源碼: http://pan.baidu.com/s/1i52ViWP
源碼配置運行步驟以下:
以下圖
3.1.配置VIPPort的值爲 haproxy 暴露的redis 集羣端口,以下圖值
3.2.配置ClusterVIPCom值爲 haproxy 所在服務器 的 IP
3.3.配置ClusterMultiIPCom 值爲 redis主從複製集羣中的所有從庫IP, 用分號分割IP
3.4. 代碼運行起來, 調用 Sample 接口, 以下圖
調用URL: Get方法 http://localhost:9526/api/RedisTest/Sample
運行邏輯以下:
第一次取數據, redis沒得緩存, 製造緩存對象, 緩存到redis, 成功返回.
第二次取數據, redis 有緩存, 從緩存中取, 成功返回.
第三次取數據, 假如redis掛了, 製造緩存對象, 仍是成功返回.
第四次取數據, redis恢復了, 重啓 asp.net core , 程序自動鏈接上redis, 從redis返回數據, 成功返回.
至此達到了, redis 和 asp.net core 的徹底解耦, 即redis掛了不影響 asp.net core 的繼續運行 .
能夠想象哈, 當你半夜收到一個警報說redis掛了的時候, 你能夠鎮定自若的去公司慢慢改, 由於asp.net core 還在運行, 只是慢了點而已.