Docker 快速驗證 tomcat 單機多例項方案
概述
主要講的是解決問題的思路。當然也附帶了儘可能詳細的步驟,感興趣的童鞋可以一步一步跟著來實踐一把。因為運維職業的緣故,基本上是把事故當故事來寫了,希望能夠喜歡。
緣起
至少10年了,沒在一線玩過 Tomcat 了,這次客戶現場就來了一場遭遇戰。雖然客戶說了他來搭建,但是專案進度不等人,還是自己動手吧。當然了,新伺服器是要走流程申請的,只能在現有伺服器想辦法。猶記得當年解決 Tomcat 部署這些都是小菜,沒想到在苛刻的商業環境中,處處是坑,步步有雷。不過,咱幹過開發也幹過運維,這點兒動手的事情,還不至於發郵件請救兵不是。幹!
伺服器在內網,有瘦終端可以訪問。MacBook 只能訪問外網,一邊查資料,一邊比對著在內網做,效果不好,老是擔心現有環境給整趴了:開發測試那邊就沒得玩了。幹過開發的都知道,伺服器從來都是直接上 root 賬號。幹過運維的人都知道,永遠別碰root。╮(╯▽╰)╭哎,職業病,還是小心謹慎地好。
只能調整了方法:先在MacBook上搭建單機多例項,驗證通過之後,再去內網伺服器動手。本來計劃20~30分鐘搞完的事,最終花了小半天時間驗證了方案,在內網實施的時候,又遇到苛刻的環境限制,逐步排雷,最終搞定。客戶滿意,專案進度開心。
思路
根據實際環境,判斷問題解決方向:單機多例項;放棄內網危險的嘗試:不能快速有效解決,且賬號許可權太大;選擇外網驗證方案後再進內網實施。很多時候,選擇大於努力。
我們先簡化問題
寫個驗證檔案打包成 war 包。為啥不使用現有程式碼。一是因為現有 war 包在內網,二是因為太複雜,除了問題不能排除是程式碼自身的問題還是我們的部署方式有問題,或者是內外網網路環境的問題,亦或是 RPWT。
對於驗證方案,排查問題時,儘量簡化,拋卻一切外在的東西,只驗證核心。方案驗證通過,再引入實際war包驗證。這和麵向物件程式設計的指導思想是一致的:通過抽象來提煉最核心的東西,每次聚焦一個地方,不要全面出擊。人,畢竟精力有限。
至於為什麼用 tomcat7,沒什麼,客戶這兒只允許這個版本。
先放出整理後方案
2017.8.8Update:
已 commit 到 docker hub,心急的童鞋自行
docker pull aninputforce/tomcat7-ins
最終方案
這個不是診斷問題的思路,是最終解決完問題後的,對整體方案的梳理,這樣的順序才整潔,有基礎時間緊的童鞋直接看這個就足夠了。有時間的童鞋可以看看正文,貫穿了分析問題解決問題的思路。
# 簡化問題:建模先--宿主機編輯 -> jdk7打war包 -> tomcat預設配置 -> 單機單例項 -> 單機雙例項
├── # docker搭建jdk7初始環境:用來打包驗證用的war包
│ ├── docker search jdk7
│ ├── docker pull codenvy/jdk7
│ ├── docker run --name jjj codenvy/jdk7 /bin/bash
│ ├── java -version && mkdir ~/web && ls ~/ && exit # 映象容器環境工作正常,建立工作目錄,退出
│ ├── mkdir ~/prms001 ~/prms002 # 宿主機
│ ├── # 編輯prms001/index.htm,編輯prms002/index.htm
│ ├── docker cp prms001 jjj:/home/user/web && docker cp prms002 jjj:/home/user/web
│ ├── docker exec -it jjj /bin/bash # 進入容器
│ ├── sudo chown -R user:user prms001 prms002 改變屬組
│ ├── cd ~/web/prms001 && jar -cvf prms001.war ./* && ls -la
│ ├── cd ~/web/prms002 && jar -cvf prms002.war ./* && ls -la && exit
│ ├── docker cp jjj:/home/user/web/prms001/prms001.war ~/.
│ ├── docker cp jjj:/home/user/web/prms002/prms002.war ~/.
│ └── docker rm jjj # 退出容器,jdk7容器使命結束
├── # docker搭建tomcat7初始環境:用來推演單機多例項
│ ├── # docker拉取tomcat7映象
│ ├── # 啟動名為www的tomcat容器
│ │ ├── ./startup.sh # 啟動web服務
│ │ ├── curl localhost:8080 # 訪問正常
│ │ ├── ./shutdown.sh # 停止web服務
│ │ └── # 搭建第一個例項
│ │ ├── mkdir tom-ins001
│ │ ├── mv work tom-ins001/ && mv conf/ tom-ins001/ mv logs/ tom-ins001/
│ │ ├── mv temp/ tom-ins001/ && mv webapps/ tom-ins001/
│ │ ├── export CATALINA_BASE=$CATALINA_HOME/tom-ins001/
│ │ ├── sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
│ │ ├── curl localhost:8080 # 訪問正常
│ │ └── exit && docker commit www mytomcat:latest && docker rm www # 容器www使命結束
│ └── docker run --name web -it -p 8080:8080 -p 80:80 mytomcat /bin/bash # 啟動新容器
│ ├── # 啟動第一個例項
│ │ ├── export CATALINA_BASE=$CATALINA_HOME/tom-ins001/
│ │ ├── sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
│ │ └── curl localhost:8080 # 訪問正常
│ └── # 搭建並啟動第二個例項
│ ├── cp -r tom-ins001/ tom-ins002
│ ├── # 編輯tom-ins002/conf/server.xml的3個埠,規避和例項1衝突,
│ │ ├── Server port="8001"、 Connector port="80" protocol="HTTP/1.1"
│ │ ├── Connector port="8002" protocol="AJP/1.3"
│ │ ├── docker cp www:/usr/local/tomcat/conf/server.xml .
│ │ ├── vi server.xml
│ │ └── docker cp ./server.xml www:/usr/local/tomcat/conf/
│ └── # 啟動新容器 啟動例項2
│ ├── export CATALINA_BASE=$CATALINA_HOME/tom-ins002/
│ ├── sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
│ ├── curl localhost:80 # 訪問正常
│ ├── exit && docker commit web mytomcat:latest
│ └── docker rm web # 容器web使命結束
└── # 展示單機雙例項:
├── # 配置例項2根目錄執行
│ ├── docker run --name web -d -it -p 8080:8080 -p 80:80 mytomcat /bin/bash # 啟動新容器
│ ├── docker exec -it web /bin/bash
│ ├── cd /usr/local/tomcat/tom-ins002/webapps && tar cvf rootbak.tar ./ROOT/*
│ ├── cd ROOT && rm -rf * # 清空ROOT目錄
│ ├── mkdir /usr/local/tomcat/myapps && exit # 建立例項2war包存放目錄,退出容器
├── # 部署例項1、例項2的war包,啟動驗證
│ ├── # 編輯ROOT.xml,配置例項2的war包解到 /usr/local/tomcat/tom-ins002/ROOT 目錄
│ ├── docker cp ~/ROOT.xml web:/usr/local/tomcat/tom-ins002/conf/Catalina/localhost
│ ├── docker cp ~/prms002.war web:/usr/local/tomcat/myapps
│ └── docker cp ~/prms001.war web:/usr/local/tomcat/tom-ins001/webapps
├── docker exec -it web /bin/bash
│ ├── export CATALINA_BASE=$CATALINA_HOME/tom-ins001/
│ ├── sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
│ ├── curl localhost:8080 # 訪問正常:Hello from Tomcat instance 001
│ ├── export CATALINA_BASE=$CATALINA_HOME/tom-ins002/
│ ├── sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
│ └── curl localhost # 訪問正常:Hello from Tomcat instance 002
└── # 宿主機驗證
├── curl localhost:8080 # 訪問正常:Hello from Tomcat instance 001
├── curl localhost # 訪問正常:Hello from Tomcat instance 002
└── exit && docker commit web mytomcat:latest # 退出,提交容器變動到映象,驗證通過;
以下開始講故事:
外網驗證方案
換做十年前,要學習 Java,光搭建個環境,就能耗盡新人 90% 的熱情。放棄內網嘗試,轉由外網先驗證方案,我也是經過略微的思想鬥爭的,不過轉念一想,有 Docker神器,也就淡定了。
開始之前,先列一下客戶的要求
- 部署新例項作為 UAT 測試環境,但是新伺服器還沒有
- 根目錄啊,別帶上 Project 路徑了
- 埠用 80 吧,你們開發測試還用 8080
需求分析
在內網的一番碰牆,也不是沒有一點兒成果,至少理順了方向:
- 方案的方向是單機多例項
- Server 部署在根目錄
- 別讓使用者敲埠訪問了
開始,進行 tomcat 單機多例項方案的推演。
至於 docker 環境搭建,請參考官方文件。我的另一篇筆記裡附有連結:Docker的第一次親密接觸請新增連結描述
上 Docker 搭建第一個例項
準備拉取映象
docker pull tomcat:7.0
啟動並執行 tomcat
容器名 www,埠8080:
ChinaDreams:work-diary kangcunhua$ docker run --name www -it -p 8080:8080 tomcat:7.0 /bin/bash
[email protected]:/usr/local/tomcat# cd bin
[email protected]:/usr/local/tomcat/bin# java -version
java version "1.7.0_131"
OpenJDK Runtime Environment (IcedTea 2.6.9) (7u131-2.6.9-2~deb8u1)
OpenJDK 64-Bit Server VM (build 24.131-b00, mixed mode)
[email protected]:/usr/local/tomcat/bin# ./startup.sh
[email protected]:/usr/local/tomcat/bin# ps -ef | grep java
[email protected]:/usr/local/tomcat/logs# tail -f catalina.out
[email protected]:/usr/local/tomcat/logs# curl localhost:8080
檢視 java 程序有,檢視日誌正常,訪問http://localhost:8080正常,證明映象和容器是可以正常工作的。
搭建第一個例項
[email protected]:/usr/local/tomcat# mkdir tom-ins001
[email protected]:/usr/local/tomcat# ls
LICENSE RELEASE-NOTES bin include logs native-jni-lib tom-ins001 work
NOTICE RUNNING.txt conf lib myapps temp webapps
[email protected]:/usr/local/tomcat# mv work tom-ins001/
[email protected]:/usr/local/tomcat# mv conf/ tom-ins001/
[email protected]:/usr/local/tomcat# mv logs/ tom-ins001/
[email protected]:/usr/local/tomcat# mv temp/ tom-ins001/
[email protected]:/usr/local/tomcat# mv webapps/ tom-ins001/
[email protected]:/usr/local/tomcat# ls
LICENSE NOTICE RELEASE-NOTES RUNNING.txt bin include lib myapps native-jni-lib tom-ins001
[email protected]:/usr/local/tomcat# cd tom-ins001/
[email protected]:/usr/local/tomcat/tom-ins001# ls
conf logs temp webapps work
[email protected]:/usr/local/tomcat/tom-ins001# echo $CATALINA_HOME
/usr/local/tomcat
[email protected]:/usr/local/tomcat/tom-ins001# export CATALINA_BASE=$CATALINA_HOME/tom-ins001/
[email protected]:/usr/local/tomcat/tom-ins001# sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
[email protected]:/usr/local/tomcat/tom-ins001# ps -ef | grep java
[email protected]:/usr/local/tomcat/tom-ins001# tail -f catalina.out
[email protected]:/usr/local/tomcat/tom-ins001# curl localhost:8080
啟動成功,宿主機訪問http://localhost:8080正常
提交變動到映象備份
[email protected]:/usr/local/tomcat/tom-ins001# exit
ChinaDreams:~ kangcunhua$ docker commit www mytomcat:latest
搭建第二個例項
啟動新容器,並啟動第一個例項
基於剛提交生成的映象,新啟一個容器。啟動例項1,驗證正常
ChinaDreams:~ kangcunhua$ docker run --name web -it -p 8080:8080 -p 80:80 mytomcat /bin/bash
[email protected]:/usr/local/tomcat/tom-ins001# export CATALINA_BASE=$CATALINA_HOME/tom-ins001
[email protected]:/usr/local/tomcat/tom-ins001# sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
[email protected]:/usr/local/tomcat/tom-ins001# ps -ef | grep java
[email protected]:/usr/local/tomcat/tom-ins001# tail -f catalina.out
[email protected]:/usr/local/tomcat/tom-ins001# curl localhost:8080
生成第二個例項目錄
[email protected]:/usr/local/tomcat# cp -r tom-ins001/ tom-ins002
[email protected]:/usr/local/tomcat# ls
LICENSE NOTICE RELEASE-NOTES RUNNING.txt bin include lib myapps native-jni-lib tom-ins001 tom-ins002
[email protected]:/usr/local/tomcat# cd tom-ins002
[email protected]:/usr/local/tomcat/tom-ins002# ls
conf logs temp webapps work
[email protected]:/usr/local/tomcat/tom-ins002# cd ..
[email protected]:/usr/local/tomcat# cd tom-ins001/
[email protected]:/usr/local/tomcat/tom-ins001# ls
conf logs temp webapps work
編輯 server.xml
主要是修改三處埠,避免和例項1埠衝突。
- Server port=”8001”
- Connector port=”80” protocol=”HTTP/1.1”
- Connector port=”8002” protocol=”AJP/1.3”
<?xml version='1.0' encoding='utf-8'?> <Server port="8001" shutdown="SHUTDOWN"> <!-- 此處省略了無修改的內容 --> <Service name="Catalina"> <Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8002" protocol="AJP/1.3" redirectPort="8443" /> <!-- 此處省略了無修改的內容 --> </Service> </Server>
編輯 ROOT.xml
作用是指定一個不在 webapps 目錄的 war 包,部署時自動解壓到 webapps\ROOT 目錄。
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/prms" docBase="/usr/local/tomcat/myapps/prms002.war"></Context>
cp 到 tomcat 容器 web 中檢視
ChinaDreams:~ kangcunhua$ docker cp ~/ROOT.xml www:/usr/local/tomcat/tom-ins002/conf/Catalina/localhost
ChinaDreams:~ kangcunhua$ docker exec -it www /bin/bash
[email protected]:/usr/local/tomcat# cd conf/Catalina/localhost/
[email protected]:/usr/local/tomcat/conf/Catalina/localhost# ls
ROOT.xml
[email protected]:/usr/local/tomcat/conf/Catalina/localhost# more ROOT.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/prms" docBase="/usr/local/tomcat/myapps/prms002.war"></Context>
[email protected]:/usr/local/tomcat/conf/Catalina/localhost# pwd
/usr/local/tomcat/conf/Catalina/localhost
檔案屬主不對,改
[email protected]:/usr/local/tomcat/conf/Catalina/localhost# ls -al
total 12
drwxr-xr-x 2 root root 4096 Jul 31 05:58 .
drwxr-xr-x 3 root root 4096 Jul 31 04:23 ..
-rw-r--r-- 1 502 dialout 111 Jul 31 05:56 ROOT.xml
[email protected]:/usr/local/tomcat/conf/Catalina/localhost# chown root:root ROOT.xml
[email protected]:/usr/local/tomcat/conf/Catalina/localhost# ls -la
total 12
drwxr-xr-x 2 root root 4096 Jul 31 05:58 .
drwxr-xr-x 3 root root 4096 Jul 31 04:23 ..
-rw-r--r-- 1 root root 111 Jul 31 05:56 ROOT.xml
打個 war 部署包
打 war 包報錯
在 tomcat 容器中,發現 jar 命令找不到。
[email protected]:/usr/local/tomcat/webapps/examples# jar -cvf prms.war ./*
bash: jar: command not found
構建 jdk7 環境
本地沒有 java 環境。果斷上docker構建一個
ChinaDreams:~ kangcunhua$ docker search jdk7
ChinaDreams:~ kangcunhua$ docker pull codenvy/jdk7
ChinaDreams:~ kangcunhua$ docker run --name jjj -it codenvy/jdk7 /bin/bash
[email protected]:/$ java -version
[email protected]:/$ jar
[email protected]:/$ mkdir ~/web && ls ~/ && exit 建立工作目錄,退出
宿主機編輯程式碼 cp 到容器中打 jar 包
ChinaDreams:~ kangcunhua$ mkdir ~/prms001 ~/prms002
ChinaDreams:~ kangcunhua$ vi ~/prms001/index.html
ChinaDreams:~ kangcunhua$ vi ~/prms002/index.html
ChinaDreams:~ kangcunhua$ docker cp prms001 jjj:/home/user/web && docker cp prms002 jjj:/home/user/web
ChinaDreams:~ kangcunhua$ docker exec -it jjj /bin/bash 進入容器
[email protected]:~/web$ sudo chown -R user:user prms001 prms002 改變屬組
[email protected]:~/web$ cd ~/web/prms001 && jar -cvf prms001.war ./* && ls -la
[email protected]:~/web$ cd ~/web/prms002 && jar -cvf prms002.war ./* && ls -la && exit
ChinaDreams:~ kangcunhua$ docker cp jjj:/home/user/web/prms001/prms001.war ~/.
ChinaDreams:~ kangcunhua$ docker cp jjj:/home/user/web/prms001/prms002.war ~/.
ChinaDreams:~ kangcunhua$ docker rm jjj 退出容器,jdk7容器使命結束
vi ~/prms001/index.html
<html>
<head>
<meta charset="UTF-8" >
<title> Tomcat instance 1</title>
</head>
<body>
<h1> Hello from Tomcat instance 1</h1>
</body>
</html>
vi ~/prms002/index.html
<html>
<head>
<meta charset="UTF-8" >
<title> Tomcat instance 2</title>
</head>
<body>
<h1> Hello from Tomcat instance 2</h1>
</body>
</html>
啟動例項1、例項2
回到 tomcat 容器
[email protected]:/usr/local/tomcat# export CATALINA_BASE=$CATALINA_HOME/tom-ins001
[email protected]:/usr/local/tomcat# sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
[email protected]:/usr/local/tomcat# curl localhost:8080 訪問正常
[email protected]:/usr/local/tomcat# export CATALINA_BASE=$CATALINA_HOME/tom-ins002/
[email protected]:/usr/local/tomcat# sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
[email protected]:/usr/local/tomcat# curl localhost:80 訪問正常
激動人心的時刻
提交映象和刪除舊容器 web
docker commit web mytomcat:latest && docker rm web
基於最新映象,啟動新容器命名為 web
docker run --name web -it -p 8080:8080 -p 80:80 mytomcat /bin/bash
宿主機訪問
http://localhost/ 訪問正常:Hello from Tomcat instance 001.
http://localhost:8080 訪問正常:Hello from Tomcat instance 002.
單機多例項方案本地通過
方案補充
啟動命令
export CATALINA_BASE=$CATALINA_HOME/tom-ins001 && sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
export CATALINA_BASE=$CATALINA_HOME/tom-ins002 && sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base
停止命令
export CATALINA_BASE=$CATALINA_HOME/tom-ins001 && sh $CATALINA_HOME/bin/shutdown.sh -Dcatalina.base
export CATALINA_BASE=$CATALINA_HOME/tom-ins002 && sh $CATALINA_HOME/bin/shutdown.sh -Dcatalina.base
排錯命令
ps -ef | grep java
kill -9 xxx tomcat例項程序號
tail -f $CATALINA_HOME/tom-ins001/logs/catalina.out
tail -f $CATALINA_HOME/tom-ins002/logs/catalina.out
curl localhost:8080/prms001/
curl localhost
目錄結構參考
保留了最關鍵的要素:
.
├── bin
├── lib
├── myapps
│ └── prms002.war
├── tom-ins001
│ ├── conf
│ │ └── server.xml
│ ├── logs
│ │ └── catalina.out
│ ├── webapps
│ │ ├── prms001
│ │ └── prms001.war
│ └── work
└── tom-ins002
├── conf
│ ├── Catalina
│ │ └── localhost
│ │ └── ROOT.xml
│ └── server.xml
├── logs
├── temp
├── webapps
│ └── ROOT
│ ├── META-INF
│ │ └── MANIFEST.MF
│ └── index.htm
└── work
提交到 docker hub
update:2017.8.8
ChinaDreams:work-diary kangcunhua$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mytomcat latest 3f6c6cce5355 7 days ago 370MB
ChinaDreams:work-diary kangcunhua$ docker tag 3f6c6cce5355 aninputforce/tomcat7-ins:latest
ChinaDreams:work-diary kangcunhua$ docker push aninputforce/tomcat7-ins
ChinaDreams:work-diary kangcunhua$ docker push aninputforce/tomcat7-ins:1.0
ChinaDreams:work-diary kangcunhua$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mytomcat latest 3f6c6cce5355 7 days ago 370MB
aninputforce/tomcat7-ins 1.0 3f6c6cce5355 7 days ago 370MB
aninputforce/tomcat7-ins latest 3f6c6cce5355 7 days ago 370MB
進內網玩:殘酷的商業環境
一切都很順利,直到碰上訪問80埠。。。。
順利
搭建例項1
備份後,搭建例項1,確保原始應用能正常;
搭建例項2
停止例項1,保證例項2預設也能執行;
根目錄部署例項2
編輯 server.xml,ROOT.xml,清空 ROOT 目錄,新建 myapps 目錄,拷貝 war 包進去;
curl http://localhost web server上訪問正常。
區域網訪問 ,http://10.29.11.23 不!能!訪!問!!!
坑:Suse訪問80埠
例項 2 需要使用80埠。受阻。
坑+:沒有任何限制。我們需要客戶的資訊,但是不能全信。就像這次請教客戶說的“我們對埠沒有任何限制”。不要盲目相信客戶說的,要相信科學排查。
依稀記得架構師課程PC大神講過,linux預設只有root使用者才能訪問80埠。當時我一直有個疑問,那我們web server需要用到80埠是怎麼解決的?我記得請教過PC老師,可惜當時課程緊,雖然聽的雲裡霧裡的,也沒好意思多追問,更沒線下自己實踐。直到這次在客戶現場栽了跟頭。
開發測試環境,我們倒是有root賬號,但是我們web server總不能用root部署吧,太不專業了。在Reboot校友群中厚著臉皮請教了各位童鞋,很快get瞭解決方案:將所有80埠的訪問,轉發到8081即可;8081就是我們可以配置的tomcat例項2的訪問埠,這個是普通使用者有許可權的。
修訂 IPtables 策略,轉發 80 埠請求
剛檢查防火牆時,看到 80 埠是放開的。部署機上可以訪問,區域網打不開:將所有針對 80 埠的訪問,轉發到 8081。
[[email protected]]# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8081
使用 8081 埠
修改了 tomins-002 的 server.xml,仍是部署機上可以訪問,區域網打不開;
檢查防火牆
配置上8081埠,重啟防火牆生效,部署機訪問正常,區域網開啟正常
找到 FW_SERVICES_EXT_TCP,加上 8081 埠
[[email protected]]# vi /etc/sysconfig/SuSEfirewall2
[[email protected]]# rcSuSEfirewall2 restart
切換到 tomcat 使用者,重啟 tomcat,區域網訪問正常。
坑:成熟平臺也有硬編碼
發現系統首頁這個連結,雖然配置的是”#”,但是一點選就回到 project 的路徑。經查詢檔案,發現是在開發平臺的兩個 js 檔案中,寫了硬編碼。應該是平臺自動生成程式碼時用了硬編碼,改之。
坑:成熟產品也不是沒有 Bug
發現只要是配置了根目錄訪問,統一認證就報錯。去掉統一認證接入就能正常訪問。反饋給客戶,協調解決;
懸了兩天,未能有任何反饋,追著逼急了,唯一答案就是:成熟產品,我們不要先去懷疑統一認證平臺。
我這個暴脾氣,馬上和工程師排查。單步跟一下,發現是提交到統一認證時,我們要傳過去一個引數 ssotarget,這個 ssotarget 是通過認證後,瀏覽器要開啟的首頁,context-path 不為空時,url 正常,context-path 為 null,即我們部署到根目錄時,ssotarget 只能得到個”/“。檢查統一認證接入邏輯,發現是使用了平臺提供的 filter,反編譯,單步跟蹤,發現 ssotarget 來自 homepage 的賦值。捏著鼻子看原始碼,果然程式碼邏輯有問題,偽演算法如下:
String ccontext_path=request.getContextPath(); // 得到web 服務上下文
String urlt = requerst.getRequestURL(); // 得到請求的完整網址
String cwebhost = urlt.substring(0, urlt.IndexOf (context-path)); // 得到http://hostname:埠
homepage = webhost + context_path + "/"; // 拼出web server的應用首頁地址
改之
String context_path = request.getContextPath();
String homepage = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
嘗試,自己改了原始碼之後重新打 jar 包,commit svn,jenkins 編譯部署後發現沒起作用。想起來使用的是 maven,所有jar包都來自平臺的私有倉庫,這。。。
換種思路,寫個 java 類繼承一下,結果一看對應邏輯所在 function,private 的,往上再看 class,finall 的,一萬隻神獸啊!!!
要啥面向物件,簡單粗暴,原始碼照抄,修訂了後命名為 MySsoFilter.java,在工程配置檔案替換上我們寫的 filter,svn commit,jenkins 立即構建部署,世間從此安靜。
參考和感謝
參考清單
- Tomcat 配置單機多例項 :這篇文章寫得簡潔有力,是技術類部落格的典範!
- Suse埠重定向
- Suse下開啟埠的方法
感謝專案組的小夥伴們,辛苦努力排查缺陷,撰寫了新的 filter;
感謝 Reboot 的同學群,關鍵時刻,是請教你們給指出了方向;
感謝 Reboot 的架構師課程和運維自動化課程,前者使我開闊了眼界,後者讓我收穫了docker 神器
docker + k8s
此課程為網路直播課程,一共 10 個課時,每週上一個全天,歷時兩個多月。附加:錄播視訊+筆記+除課堂外的答疑時間(7次+)2019-1-13 開課,原價 5800 ,現在週年活動 100 定金抵 800
課程主講師:GY 老師
10 年一線軟體開發經驗,先後經歷了傳統安全公司,以及多家網際網路公司;在安全開發方面,曾開發過 Linux 防火牆、web 應用防火牆、Linux 安全核心加固,基於大流量的 Web 安全威脅分析等專案;在網際網路公司工作時,曾基於 DPDK 高效能網路開發框架開發過基於全流量的網路流量分析平臺和基於 Sflow 網路流量分析平臺,基於Golang 開發 SmartDNS 等;開發語言也是從 C -> python -> golang 的轉變過程?現從事基於 K8S 和 Docker 在私有云平臺建設方面的研發工作;具備豐富的Linux系統開發經驗、網路開發經驗以及專案管理經驗;目前開發工作90+% 都在用 Golang,Golang 是一門簡潔、高效、強大且靈活的程式語言。
關於課程的具體內容想要了解的, 新增加小助手WeChat:17812796384 諮詢瞭解
本文由作者:蠻大人 授權釋出
連結:https://opsdev.fun/2017/08/01/O1-8-05-Docker%E5%BF%AB%E9%80%9F%E9%AA%8C%E8%AF%81tomcat%E5%8D%95%E6%9C%BA%E5%A4%9A%E5%AE%9E%E4%BE%8B%E6%96%B9%E6%A1%88/
著作權歸作者所有。
轉載請聯絡作者獲得授權。