負載均衡 Nginx Session 一致性
HTTPS 請求跳轉
如下面的配置:
location /test {
proxy_pass http://www.baidu.com/;
}
在訪問 URI 爲 /test 時會跳轉到百度,但此時瀏覽器中的 URL 也會發生變化。
這是因爲:向 http://www.baidu.com/ 發送請求後, Nginx 返回的是一個跳轉的響應。
此後, 客戶端會重新向 https://www.baidu.com/ 發送請求(此過程不再經歷 Nginx)。
所以,最終瀏覽器發生了跳轉, 而非 Nginx 的負載均衡。
問題解決
將配置中的 http 改爲 https 即可。
Session 一致性
在使用 Nginx 做反向代理時,如果後端服務器是 Tomcat 等動態服務器,則可能會出現 Session 一致性問題。
即: 無法確保同一個 Session 一定對應同一個 Server;
配置網絡
下面使用 Docker 來演示。
配置 IP 地址:
並在 Server1 和 Server2 上啓動 Tomcat。
配置 Server
在 Server 端創建 jsp 頁面:
Server 1
[root@c5477d71795c ROOT]# pwd
/var/lib/tomcat/webapps/ROOT
[root@c5477d71795c ROOT]# cat index.jsp
from 172.20.1.101
<br/>
session=<%=session.getId()%>
Server 2
[root@c5477d71795c ROOT]# pwd
/var/lib/tomcat/webapps/ROOT
[root@c5477d71795c ROOT]# cat index.jsp
from 172.20.1.102
<br/>
session=<%=session.getId()%>
然後訪問 http://172.20.1.101:8080/ 和 http://172.20.1.102:8080/。
可分別顯示來自哪個 Server 和對應的 SessionId,並且刷新頁面時 SessionId 不會變化(即使是使用 Ctrl+F5 刷新)。
配置 Nginx
修改 Nginx 的配置文件, 加入新的 upstream 配置和 server 配置。
upstream tomcat {
server 172.20.1.101:8080;
server 172.20.1.102:8080;
}
server {
......
location /cat {
proxy_pass http://tomcat/;
}
}
重啓 Nginx:
[root@ce12b3b4ce00 sbin]# ./nginx -s reload
訪問 http://172.20.1.10/cat 並刷新,發現 from 172.20.1.10x 一直在變化,並且 session=xxx 也變化。
說明:此時 Nginx 的配置無法保證 Session 一致性!
解決方案
在 Tomcat 後面部署 Redis,MemCached 等內存數據庫來保存 Session 相關信息。
本例中在 Nginx 服務器上安裝 memcached 來解決 Session 一致性問題。
安裝 memcached
在 Nginx 容器中使用 yum 安裝:
yum install -y memcached
啓動 memcached
使用 memcached 命令啓動:
memcached -d -m 128m -p 11211 -l 172.20.1.10 -u root -P /tmp/
參數說明:
-
-d: 後臺啓動
-
-m: 緩存大小
-
-p: 端口
-
-l: IP 地址
-
-P: 服務啓動後系統進程 ID 存儲文件的目錄
-
-u: 服務器以哪個用戶作爲管理用戶
修改 Tomcat 配置
在兩臺 Server 中修改 tomcat 的配置:
[root@3a53f7504511 ROOT]# vi /etc/tomcat/context.xml
# context標籤中加入下面的內容
<Manager
class
memcachedNodes="n1:172.20.1.10:11211"
sticky="false"
sessionBackupAsync="false"
lockingMode="auto"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
sessionBackupTimeout="1000"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" />
導入 jar 包使用 yum 安裝的 Tomcat 可將 jar 包放在 /usr/share/java/tomcat/ 目錄下。
需要的 jar 包:
Maven 依賴如下:
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>com.couchbase.client</groupId>
<artifactId>couchbase-client</artifactId>
<version>1.4.11</version>
</dependency>
<dependency>
<groupId>com.googlecode</groupId>
<artifactId>kryo</artifactId>
<version>1.04</version>
</dependency>
<dependency>
<groupId>de.javakaffee</groupId>
<artifactId>kryo-serializers</artifactId>
<version>0.11</version>
</dependency>
<dependency>
<groupId>de.javakaffee.msm</groupId>
<artifactId>memcached-session-manager</artifactId>
<version>1.8.2</version>
</dependency>
<dependency>
<groupId>de.javakaffee.msm</groupId>
<artifactId>memcached-session-manager-tc7</artifactId>
<version>1.8.2</version>
</dependency>
<dependency>
<groupId>com.googlecode</groupId>
<artifactId>minlog</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>de.javakaffee.msm</groupId>
<artifactId>msm-kryo-serializer</artifactId>
<version>1.8.2</version>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>reflectasm</artifactId>
<version>1.01</version>
</dependency>
<dependency>
<groupId>net.spy</groupId>
<artifactId>spymemcached</artifactId>
<version>2.11.4</version>
</dependency>
注: 如果依賴和 Tomcat 版本不對應可能會什麼也不顯示,此時響應碼爲 500。
驗證
上述步驟都正確配置之後, 再次訪問 http://172.20.1.10/cat 並刷新會發現 SessionId 不再變化。
轉自:張小凱と彼の Blog,
鏈接:https://jasonkayzk.github.io/2020/04/13 / 負載均衡 Nginx - 一些常見的問題 /
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/-TeOAUS1l0IuZvw6plGf-A