解決cas集羣時登錄需要刷新多次纔可以登錄成功

解決問題

CAS登錄過程會有三次請求,我們依次命名爲Authentication Request / Validation Request / Wrapper Request。Nginx缺省的分發規則,同一個瀏覽器的請求,會按照nginx自身某種規則進行分發。在雙點集羣環境下,Authentication Request和ValidationRequest可能會恰好被分發到兩臺服務器,這就會導致登錄過程死循環,導致在集羣下,點擊登錄後會在登錄頁面刷新多次。

工作原理

Sticky是nginx的一個模塊,它是基於cookie的一種nginx的負載均衡解決方案,通過分發和識別cookie,來使同一個客戶端的請求落在同一臺服務器上,默認標識名爲route

1.客戶端首次發起訪問請求,nginx接收後,發現請求頭沒有cookie,則以輪詢方式將請求分發給後端服務器。

2.後端服務器處理完請求,將響應數據返回給nginx。

3.此時nginx生成帶route的cookie,返回給客戶端。route的值與後端服務器對應,可能是明文,也可能是md5、sha1等Hash值

4.客戶端接收請求,並保存帶route的cookie。

5.當客戶端下一次發送請求時,會帶上route,nginx根據接收到的cookie中的route值,轉發給對應的後端服務器。

安裝

Sticky模塊下載地址:

https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/master.tar.gz

解壓後放在/root/cluster/nginx-sticky目錄下

Nginx下載地址:http://nginx.org/download/nginx-1.14.0.zip

解壓後放在目錄/root/cluster/nginx-1.14.0目錄下

編譯安裝nginx,加入sticky模塊

[root@localhost ~]#cd cluster/nginx-1.14.0

[root@localhost nginx-1.14.0]# ./configure --prefix=/usr/local/nginx  --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module --add-module=/root/cluster/nginx-sticky

[root@localhost nginx-1.14.0]# make

[root@localhost nginx-1.14.0]# make install

安裝完查看nginx編譯參數


[root@localhost nginx-1.14.0]# /usr/local/nginx/sbin/nginx -V


如果出現以下內容說明安裝成功


nginx version: nginx/1.14.0

built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)

configure arguments: --prefix=/root/cluster/nginx --with-http_gzip_static_module --with-http_flv_module --with-http_dav_module --with-http_stub_status_module --with-http_realip_module --add-module=/root/cluster/nginx-sticky/

然後修改nginx的conf配置,修改文件usr/local/nginx/conf/nginx.conf

如果在以上編譯過程中報錯,提示找不到MD5等問題,可能的問題如下

ngx_http_sticky_misc.c: In function 「ngx_http_sticky_misc_md5」:

ngx_http_sticky_misc.c:152:15: ERROR:「MD5_DIGEST_LENGTH」 undeclared (first use in this function)

   u_char hash[MD5_DIGEST_LENGTH];

解決方式就是修改你下載解壓縮之後的sticky模塊文件夾中的ngx_http_sticky_misc.c文件,將這兩個模塊 <openssl/sha.h> and <openssl/md5.h>包含到文件ngx_http_sticky_misc.c

添加下面紅色標註的代碼

#include <nginx.h>

#include <ngx_config.h>

#include <ngx_core.h>

#include <ngx_http.h>

#include <ngx_md5.h>

#include <ngx_sha1.h>

#include <openssl/sha.h>

#include <openssl/md5.h>

 

#include "ngx_http_sticky_misc.h"

然後重新再編譯一次。

在upstream加入sticky配置,配置如下,nginx負載均衡配置參考文章《Nginx+Tomcat搭建高性能負載均衡集羣

upstream 192.168.203.176 {

     sticky;

     server 192.168.203.31:8090;

     server 192.168.203.32:8090;

     server 192.168.203.33:8090;

}

 

加入sticky;後,重啓nginx就可以了。

sticky參數解析

sticky [name=route] [domain=.foo.bar] [path=/] [expires=1h]

       [hash=index|md5|sha1] [no_fallback] [secure] [httponly];

[name=route]       設置用來記錄會話的cookie名稱

[domain=.foo.bar]    設置cookie作用的域名

[path=/]          設置cookie作用的URL路徑,默認根目錄

[expires=1h]        設置cookie的生存期,默認不設置,瀏覽器關閉即失效,需要是大於1秒的值

[hash=index|md5|sha1]   設置cookie中服務器的標識是用明文還是使用md5值,默認使用md5

[no_fallback]       設置該項,當sticky的後端機器掛了以後,nginx返回502 (Bad Gateway or Proxy Error) ,而不轉發到其他服務器,不建議設置

[secure]          設置啓用安全的cookie,需要HTTPS支持

[httponly]         允許cookie不通過JS泄漏

注意

1.同一客戶端的請求,有可能落在不同的後端服務器上

如果客戶端啓動時同時發起多個請求。由於這些請求都沒帶cookie,所以服務器會隨機選擇後端服務器,返回不同的cookie。當這些請求中的最後一個請求返回時,客戶端的cookie纔會穩定下來,值以最後返回的cookie爲準。

2.cookie不一定生效

由於cookie最初由服務器端下發,如果客戶端禁用cookie,則cookie不會生效。

3.cookie名稱不要和業務使用的cookie重名。Sticky默認的cookie名稱是route,可以改成任何值。

4.客戶端發的第一個請求是不帶cookie的。服務器下發的cookie,在客戶端下一次請求時才能生效。

5.Nginx sticky模塊不能與ip_hash同時使用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章