器部署實(shí)戰(zhàn):Xmanager環(huán)境下安裝Oracle 11g與Tomcat 8全流程)
我有個(gè)老項(xiàng)目要部署一套業(yè)務(wù)系統(tǒng)環(huán)境是CentOS 7.6數(shù)據(jù)庫(kù)選的Oracle 11g中間件用的Tomcat 8客戶端機(jī)器是Windows。遠(yuǎn)程操作我直接用了Xmanager全家桶里的Xshell和Xstart這套流程從頭到尾跑了三遍把踩過(guò)的坑都補(bǔ)齊了今天把這套全流程操作步驟整理出來(lái)。如果你也在折騰Linux服務(wù)器上裝Oracle 11g和Tomcat這篇東西應(yīng)該能幫你少走很多彎路。先說(shuō)下為什么要用Xmanager來(lái)做安裝操作。Oracle 11g的安裝程序是圖形界面雖然理論上可以用靜默模式裝但生產(chǎn)環(huán)境里你基本沒(méi)法保證每臺(tái)機(jī)器的參數(shù)都一樣跑圖形界面能看到實(shí)際校驗(yàn)信息出問(wèn)題了也方便現(xiàn)場(chǎng)排查。而CentOS 7服務(wù)器大多是無(wú)桌面環(huán)境或者遠(yuǎn)程機(jī)房直接在服務(wù)器上操作圖形界面并不現(xiàn)實(shí)Xmanager恰好解決了這個(gè)問(wèn)題它能把服務(wù)端的圖形界面重定向到你的Windows屏幕上。Xmanager全家桶里面我主要用兩個(gè)組件Xshell負(fù)責(zé)SSH命令行操作Xstart負(fù)責(zé)把圖形界面程序拉到本地顯示。這套組合比直接用VNC輕量不少不用在服務(wù)器上裝額外的桌面組件安全性也好一些畢竟走的是加密通道。1. 環(huán)境準(zhǔn)備與初始配置1.1 服務(wù)器基礎(chǔ)環(huán)境檢查我拿到手的服務(wù)器是CentOS 7.6內(nèi)存16G四核CPU磁盤(pán)200G。Oracle 11g在CentOS 7上跑對(duì)資源要求不算特別苛刻但有幾個(gè)底線必須確認(rèn)清楚。內(nèi)存方面至少2G以上推薦4G起步swap分區(qū)建議至少2G生產(chǎn)環(huán)境最好配到內(nèi)存的1.5倍。我見(jiàn)過(guò)有人用1G內(nèi)存裝Oracle 11g結(jié)果安裝界面卡得跟幻燈片一樣最后裝到一半直接OOM崩潰。磁盤(pán)看情況Oracle軟件本體加數(shù)據(jù)庫(kù)文件至少要留出30G空間再加上Tomcat和業(yè)務(wù)系統(tǒng)的部署包40G起步比較穩(wěn)妥。系統(tǒng)架構(gòu)必須是64位這個(gè)不用多解釋Oracle 11g對(duì)32位系統(tǒng)的支持早就不行了。操作系統(tǒng)版本最好選CentOS 7.6到7.9之間的版本太老的內(nèi)核跟Oracle 11g的兼容性有問(wèn)題太新又可能觸發(fā)奇怪的庫(kù)沖突。還要檢查主機(jī)名和網(wǎng)絡(luò)配置。主機(jī)名別用帶下劃線的Oracle的安裝程序?qū)χ鳈C(jī)名要求比較嚴(yán)格下劃線這種字符可能導(dǎo)致監(jiān)聽(tīng)器起不來(lái)。我在某臺(tái)測(cè)試機(jī)上就吃過(guò)這個(gè)虧主機(jī)名設(shè)成prod_db_01結(jié)果netca配置監(jiān)聽(tīng)時(shí)直接報(bào)錯(cuò)改回prod-db-01就正常了。1.2 Xmanager連接配置Xmanager連接服務(wù)器前我習(xí)慣先確認(rèn)SSH端口通不通。CentOS 7默認(rèn)開(kāi)22端口用Xshell連接時(shí)填上IP和端口就能進(jìn)。如果改了SSH端口記得在Xshell的會(huì)話屬性里同步修改。Xstart的配置相對(duì)復(fù)雜一些這是很多新手容易卡住的地方。Xstart通過(guò)SSH協(xié)議連到服務(wù)器后它會(huì)執(zhí)行你指定的命令并把圖形輸出重定向到本地顯示。具體配置方法是這樣的在Xmanager中新建一個(gè)Xstart會(huì)話協(xié)議選SSH主機(jī)填服務(wù)器IP用戶名填root認(rèn)證方式選密碼或者密鑰都行。最關(guān)鍵的是命令這一欄要填入你要執(zhí)行的圖形程序。比如裝Oracle時(shí)命令填xhost 和 export DISPLAY:0.0 是不對(duì)的這些是本地顯示用的Xstart會(huì)自動(dòng)處理DISPLAY變量。直接填你要運(yùn)行的程序路徑即可比如/opt/oracle/database/runInstaller。如果只是想測(cè)試圖形界面是否通了可以先跑/usr/bin/xterm能彈出終端窗口就說(shuō)明Xstart鏈路通暢。Xstart還有一個(gè)需要注意的地方就是命令執(zhí)行時(shí)要保持會(huì)話不退出。很多人配置完命令后程序啟動(dòng)起來(lái)Xstart窗口就關(guān)掉了結(jié)果圖形界面跟著消失。實(shí)際上Xstart會(huì)持續(xù)維持這個(gè)會(huì)話讓圖形程序一直駐留在遠(yuǎn)程服務(wù)器上本地窗口只是負(fù)責(zé)顯示關(guān)掉本地窗口程序不會(huì)中斷。1.3 系統(tǒng)初始化與依賴包安裝CentOS 7默認(rèn)安裝比較精簡(jiǎn)Oracle 11g需要的依賴包和庫(kù)文件有很多沒(méi)裝所以系統(tǒng)準(zhǔn)備階段要先把這些補(bǔ)齊。我這里列一下我實(shí)際用到的包清單yum install -y binutils compat-libcap1 compat-libstdc-33 compat-libstdc-33.i686 \ elfutils-libelf elfutils-libelf-devel gcc gcc-c glibc glibc.i686 glibc-devel glibc-devel.i686 \ ksh libaio libaio.i686 libaio-devel libaio-devel.i686 libgcc libgcc.i686 libstdc libstdc.i686 \ libstdc-devel libXi libXi.i686 libXtst libXtst.i686 make sysstat unixODBC unixODBC-devel這里有個(gè)容易踩的坑compat-libstdc-33這個(gè)包在CentOS 7的默認(rèn)yum源里其實(shí)沒(méi)有如果你用默認(rèn)源直接裝會(huì)報(bào)找不到包。解決辦法是安裝EPEL源或者從CentOS 6的安裝光盤(pán)中提取這個(gè)rpm包手動(dòng)裝。EPEL源裝起來(lái)很簡(jiǎn)單yum install -y epel-release yum clean all yum makecache然后再執(zhí)行上面的依賴包安裝命令。有些老依賴包在當(dāng)前yum源中找不到也沒(méi)關(guān)系我后來(lái)測(cè)試發(fā)現(xiàn)Oracle 11g的安裝程序在缺失某些兼容庫(kù)時(shí)不會(huì)直接中止但會(huì)在后續(xù)啟動(dòng)監(jiān)聽(tīng)器或者實(shí)例時(shí)暴露出問(wèn)題。所以寧可一次裝齊也別等到裝完再折騰。另外還要確認(rèn)libaio和libaio-devel這兩個(gè)包沒(méi)裝的話Oracle數(shù)據(jù)庫(kù)創(chuàng)建實(shí)例時(shí)會(huì)有rpm校驗(yàn)警告雖然可以跳過(guò)但會(huì)導(dǎo)致后續(xù)調(diào)用某些API報(bào)錯(cuò)。手動(dòng)處理起來(lái)很麻煩所以還是老老實(shí)實(shí)裝好。2. Oracle 11g安裝前的系統(tǒng)調(diào)優(yōu)2.1 內(nèi)核參數(shù)調(diào)整Oracle官方文檔要求修改/etc/sysctl.conf文件來(lái)調(diào)整內(nèi)核參數(shù)。這里說(shuō)的參數(shù)直接決定了Oracle數(shù)據(jù)庫(kù)能否正常啟動(dòng)和分配足夠的內(nèi)存所以不能只盯著安裝步驟這步得確保數(shù)值和你實(shí)際機(jī)器配置匹配才行。我用的參數(shù)配置如下fs.aio-max-nr 1048576 fs.file-max 6815744 kernel.shmall 2097152 kernel.shmmax 4294967295 kernel.shmmni 4096 kernel.sem 250 32000 100 128 net.ipv4.ip_local_port_range 9000 65500 net.core.rmem_default 262144 net.core.rmem_max 4194304 net.core.wmem_default 262144 net.core.wmem_max 1048576配置完成后執(zhí)行sysctl -p使其生效。如果你服務(wù)器物理內(nèi)存特別大比如32Gkernel.shmmax建議設(shè)成物理內(nèi)存的一半左右。這個(gè)參數(shù)控制的是共享內(nèi)存段的最大大小Oracle SGA在啟動(dòng)時(shí)會(huì)嘗試申請(qǐng)一個(gè)或者多個(gè)共享內(nèi)存段如果shmmax太小Oracle只能創(chuàng)建多個(gè)共享內(nèi)存段來(lái)湊夠SGA大小性能會(huì)有明顯下降。還有一個(gè)參數(shù)容易忘記就是kernel.sem的四段含義。250是每個(gè)信號(hào)量集合的最大信號(hào)量數(shù)32000是系統(tǒng)范圍內(nèi)最大信號(hào)量數(shù)100是每個(gè)信號(hào)量集合的最大操作數(shù)128是系統(tǒng)范圍內(nèi)最大信號(hào)量集合數(shù)。Oracle安裝程序在環(huán)境檢查時(shí)會(huì)校驗(yàn)這些值不達(dá)標(biāo)會(huì)直接打紅叉。2.2 用戶與目錄規(guī)劃Oracle 11g不允許直接用root用戶安裝必須創(chuàng)建專(zhuān)屬用戶和用戶組。我按官方最佳實(shí)踐創(chuàng)建了oinstall組和dba組oracle用戶的主組設(shè)為oinstall附加組設(shè)為dba。這樣做的好處是后續(xù)備份、恢復(fù)、安裝補(bǔ)丁時(shí)權(quán)限管理清晰不容易出現(xiàn)DBA組權(quán)限不足的問(wèn)題。創(chuàng)建命令如下groupadd oinstall groupadd dba useradd -g oinstall -G dba oracle passwd oracle目錄結(jié)構(gòu)方面我習(xí)慣把Oracle的軟件安裝目錄和數(shù)據(jù)目錄分開(kāi)。軟件目錄放在/u01/app/oracle數(shù)據(jù)目錄放在/u02/oradata或者直接用Oracle默認(rèn)的/u01/app/oracle/oradata。如果你服務(wù)器上就一塊磁盤(pán)那放在一起問(wèn)題不大但如果有獨(dú)立的數(shù)據(jù)盤(pán)強(qiáng)烈建議把數(shù)據(jù)目錄指到獨(dú)立磁盤(pán)上對(duì)IO性能和故障隔離都有好處。目錄權(quán)限記得要改成oracle用戶有權(quán)限訪問(wèn)mkdir -p /u01/app/oracle mkdir -p /u02/oradata chown -R oracle:oinstall /u01 chown -R oracle:oinstall /u02 chmod -R 775 /u01 chmod -R 775 /u02這里有個(gè)細(xì)節(jié)目錄的屬主最好設(shè)置成oracle用戶不要用root。我試過(guò)一次用root創(chuàng)建目錄沒(méi)改屬主就直接裝Oracle等Oracle的安裝程序往里寫(xiě)文件時(shí)才提示權(quán)限不足又回頭改權(quán)限白白浪費(fèi)了十幾分鐘。2.3 安全級(jí)別與防火墻調(diào)整CentOS 7默認(rèn)開(kāi)了firewalld如果這個(gè)防火墻沒(méi)放行Oracle需要的端口即使Oracle本身裝好了遠(yuǎn)程客戶端也連不上數(shù)據(jù)庫(kù)。Oracle 11g默認(rèn)的監(jiān)聽(tīng)端口是1521Tomcat默認(rèn)端口是8080這兩個(gè)都要在防火墻里放行。操作命令firewall-cmd --zonepublic --add-port1521/tcp --permanent firewall-cmd --zonepublic --add-port8080/tcp --permanent firewall-cmd --reload如果嫌麻煩也可以直接把防火墻停掉生產(chǎn)環(huán)境建議還是用白名單方式放行特定IP訪問(wèn)。另外還要注意SELinux的影響CentOS 7的SELinux默認(rèn)是enforcing模式Oracle的安裝文檔里并沒(méi)有要求一定關(guān)閉SELinux但實(shí)際安裝過(guò)程中我發(fā)現(xiàn)SELinux會(huì)對(duì)Oracle的某些文件訪問(wèn)權(quán)限做限制尤其是監(jiān)聽(tīng)器啟動(dòng)時(shí)綁定端口那一步。為了避免不必要的麻煩我統(tǒng)一把SELinux設(shè)成了permissive模式sed -i s/SELINUXenforcing/SELINUXpermissive/g /etc/selinux/config setenforce 0注意setenforce 0只是臨時(shí)關(guān)閉當(dāng)前內(nèi)核的SELinux重啟后還是會(huì)變成enforcing所以必須同步修改配置文件。3. Oracle 11g安裝全流程走通3.1 安裝介質(zhì)準(zhǔn)備與解壓Oracle 11g的安裝包分兩個(gè)zip文件一個(gè)是linux.x64_11gR2_database_1of2.zip另一個(gè)是linux.x64_11gR2_database_2of2.zip。下載好之后傳到服務(wù)器的某個(gè)臨時(shí)目錄下比如/home/oracle/db_install。解壓必須用oracle用戶身份解壓否則解壓出來(lái)的文件屬主會(huì)變成root后面Oracle安裝程序會(huì)有文件權(quán)限校驗(yàn)很可能會(huì)被卡住。解壓命令su - oracle mkdir -p /home/oracle/db_install cd /home/oracle/db_install unzip linux.x64_11gR2_database_1of2.zip unzip linux.x64_11gR2_database_2of2.zip解壓完會(huì)在當(dāng)前目錄下生成一個(gè)database目錄里面就是全套安裝程序。解壓時(shí)如果提示某個(gè)zip文件損壞大概率是傳輸過(guò)程中出了問(wèn)題重新傳一遍就能解決不需要重新下載整個(gè)包。3.2 通過(guò)Xstart啟動(dòng)圖形化安裝裝好系統(tǒng)依賴、配置好用戶和內(nèi)核參數(shù)之后重頭戲來(lái)了用Xstart啟動(dòng)Oracle的安裝程序。打開(kāi)Xmanager的Xstart工具填寫(xiě)如下信息主機(jī)服務(wù)器IP地址協(xié)議SSH用戶名oracle認(rèn)證密碼方式命令/home/oracle/db_install/database/runInstaller初次點(diǎn)擊執(zhí)行按鈕后Xstart會(huì)彈出一個(gè)日志窗口顯示SSH連接的建立過(guò)程和DISPLAY環(huán)境變量的設(shè)置情況。過(guò)幾秒鐘Windows桌面就會(huì)彈出Oracle Universal Installer的圖形界面看到這個(gè)界面就是成功了。這個(gè)環(huán)節(jié)有個(gè)最常見(jiàn)的坑就是點(diǎn)了Xstart后報(bào)錯(cuò)提示無(wú)法打開(kāi)DISPLAY或者連接不上X server。原因往往是服務(wù)器上的X11轉(zhuǎn)發(fā)依賴包沒(méi)裝。CentOS 7的SSHd配置文件里X11Forwarding默認(rèn)是啟用的但如果沒(méi)有xorg-x11-xauth這個(gè)包轉(zhuǎn)發(fā)鏈路就會(huì)斷掉。解決方法是yum install -y xorg-x11-xauth裝完之后重新用Xstart執(zhí)行命令基本上就正常了。如果Xstart啟動(dòng)圖形界面過(guò)程中彈出了java異常窗口這多半是因?yàn)镃entOS 7自帶的OpenJDK版本跟Oracle安裝程序不兼容。解決思路是在啟動(dòng)runInstaller之前先卸載系統(tǒng)自帶的OpenJDK或者設(shè)置JAVA_HOME指向Oracle安裝包自帶的JDK。Oracle 11g的安裝程序里其實(shí)自帶了jdk目錄不需要額外裝Java直接設(shè)置環(huán)境變量JAVA_HOME指向database目錄下的jdk即可。3.3 圖形界面中的安裝選項(xiàng)配置Oracle Universal Installer啟動(dòng)后第一步是配置安全更新和接收郵件通知這里直接取消勾選即可。接下來(lái)會(huì)讓你選擇安裝類(lèi)型我一般選創(chuàng)建和配置單實(shí)例數(shù)據(jù)庫(kù)這樣裝完后數(shù)據(jù)庫(kù)實(shí)例就直接創(chuàng)建好了省得再單獨(dú)運(yùn)行DBCA建庫(kù)。高級(jí)安裝模式比典型安裝多幾個(gè)自定義步驟比如字符集、內(nèi)存分配、存儲(chǔ)路徑、ASM等選項(xiàng)。首次安裝建議走高級(jí)模式可以提前指定很多關(guān)鍵參數(shù)省得裝完后又要改配置。關(guān)鍵是字符集我選的是AL32UTF8這個(gè)字符集支持中文存儲(chǔ)和各種語(yǔ)言如果業(yè)務(wù)系統(tǒng)只跑中文用ZHS16GBK也行但我個(gè)人更推薦UTF8兼容性更好也方便后續(xù)數(shù)據(jù)遷移。內(nèi)存分配這里需要注意Oracle 11g的自動(dòng)內(nèi)存管理AMM功能默認(rèn)是開(kāi)啟的如果你設(shè)置的SGA和PGA總和超過(guò)了實(shí)際物理內(nèi)存數(shù)據(jù)庫(kù)實(shí)例可能在啟動(dòng)時(shí)直接失敗。我這里內(nèi)存16G給Oracle分配了SGA 4GPGA 2G這個(gè)比例夠用。如果你服務(wù)器內(nèi)存小SGA給2GPGA給1G也能跑。重要的是給操作系統(tǒng)留夠余量別把內(nèi)存全部分完。數(shù)據(jù)庫(kù)身份驗(yàn)證那里設(shè)置的是SYS和SYSTEM用戶的密碼這個(gè)密碼要記好建議用大小寫(xiě)字母加數(shù)字組成的強(qiáng)密碼。Oracle 11g對(duì)密碼復(fù)雜度默認(rèn)有校驗(yàn)太簡(jiǎn)單的密碼比如oracle123這種可以直接過(guò)但類(lèi)似123456這種純數(shù)字的會(huì)提示太弱無(wú)法通過(guò)。3.4 安裝過(guò)程中的組校驗(yàn)與腳本執(zhí)行安裝過(guò)程中有個(gè)環(huán)節(jié)會(huì)卡住不少人就是在指定Oracle用戶屬組的時(shí)候安裝程序會(huì)自動(dòng)檢測(cè)oinstall組和dba組是否存在并顯示綠色對(duì)勾或黃色警告。如果警告提示找不到dba組說(shuō)明之前的groupadd沒(méi)有成功回頭執(zhí)行g(shù)roups oracle命令確認(rèn)一下如果沒(méi)有dba附加組用usermod -G dba oracle補(bǔ)上。安裝進(jìn)行到70%左右時(shí)會(huì)彈出一個(gè)窗口要求以root身份執(zhí)行兩個(gè)腳本一個(gè)是orainstRoot.sh另一個(gè)是root.sh。這一步很多人會(huì)疑惑到底要不要執(zhí)行答案是必須執(zhí)行而且要等腳本跑完才能點(diǎn)確定繼續(xù)。操作方式是另開(kāi)一個(gè)Xshell窗口用root登錄服務(wù)器依次執(zhí)行/u01/app/oraInventory/orainstRoot.sh /u01/app/oracle/product/11.2.0/dbhome_1/root.shroot.sh執(zhí)行時(shí)會(huì)有交互提示問(wèn)你是否把oracle用戶加到dba組直接填y回車(chē)就行。整個(gè)root.sh腳本執(zhí)行過(guò)程會(huì)創(chuàng)建一些系統(tǒng)級(jí)別的目錄和啟動(dòng)腳本確保Oracle監(jiān)聽(tīng)和數(shù)據(jù)庫(kù)隨系統(tǒng)自動(dòng)啟動(dòng)的腳本能正常運(yùn)行。這里要特別說(shuō)一下root.sh腳本的輸出信息綠色文本顯示的是腳本創(chuàng)建的關(guān)鍵目錄和文件紅色文本一般是警告或者錯(cuò)誤。我遇到過(guò)root.sh執(zhí)行時(shí)報(bào)錯(cuò)說(shuō)不能寫(xiě)/etc/oratab原因就是/etc目錄空間滿了清理掉一些無(wú)用的日志文件后重新執(zhí)行就好了。3.5 修改環(huán)境變量與驗(yàn)證安裝結(jié)果Oracle安裝完最后一件事是配置oracle用戶的環(huán)境變量。編輯/home/oracle/.bash_profile文件加入以下內(nèi)容export ORACLE_BASE/u01/app/oracle export ORACLE_HOME$ORACLE_BASE/product/11.2.0/dbhome_1 export ORACLE_SIDorcl export PATH$PATH:$ORACLE_HOME/bin export LD_LIBRARY_PATH$ORACLE_HOME/lib保存后執(zhí)行source .bash_profile使其生效。然后運(yùn)行sqlplus / as sysdba進(jìn)入SQL*Plus執(zhí)行select status from v$instance;看到OPEN狀態(tài)就說(shuō)明數(shù)據(jù)庫(kù)實(shí)例正常起來(lái)了。監(jiān)聽(tīng)器狀態(tài)可以通過(guò)lsnrctl status命令查看正常會(huì)顯示服務(wù)orcl已有1個(gè)實(shí)例處理程序。如果監(jiān)聽(tīng)沒(méi)啟動(dòng)用lsnrctl start手動(dòng)拉起之后可以檢查1521端口是否出現(xiàn)在LISTEN狀態(tài)。4. Tomcat 8安裝與部署4.1 JDK環(huán)境配置Tomcat是Java應(yīng)用服務(wù)器依賴JDK運(yùn)行。Oracle 11g安裝過(guò)程會(huì)自帶一個(gè)JDK但這個(gè)JDK版本比較老不建議直接拿給Tomcat用。我這邊是單獨(dú)安裝了OpenJDK 1.8Tomcat 8.5對(duì)JDK版本要求是1.8及以上。安裝JDK的方式有很多種最簡(jiǎn)單就是用yum裝yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel裝完后執(zhí)行java -version確認(rèn)版本然后設(shè)置JAVA_HOME。一般OpenJDK裝完路徑在/usr/lib/jvm/java-1.8.0-openjdk把這個(gè)路徑寫(xiě)進(jìn)/etc/profile里export JAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk export PATH$PATH:$JAVA_HOME/bin export CLASSPATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarsource /etc/profile后執(zhí)行echo $JAVA_HOME驗(yàn)證環(huán)境變量是否生效。這里有個(gè)容易出現(xiàn)的問(wèn)題如果服務(wù)器上同時(shí)裝了多個(gè)Java版本要注意PATH的優(yōu)先級(jí)確保指向1.8這個(gè)版本。4.2 Tomcat解壓與目錄規(guī)劃Tomcat的安裝方式非常直接下載apache-tomcat-8.5.x.tar.gz包解壓到指定目錄就行。我習(xí)慣放在/opt/tomcat下面結(jié)構(gòu)清晰備份也方便。下載和安裝命令mkdir -p /opt/tomcat tar -zxvf apache-tomcat-8.5.100.tar.gz -C /opt/tomcat --strip-components1 chmod x /opt/tomcat/bin/*.sh這里用到--strip-components1參數(shù)意思是解壓時(shí)去掉包內(nèi)最頂層目錄名直接解壓到/opt/tomcat下。如果不加這個(gè)參數(shù)文件會(huì)被解壓到/opt/tomcat/apache-tomcat-8.5.100目錄下還要多一層目錄嵌套看起來(lái)很別扭。Tomcat目錄結(jié)構(gòu)里bin目錄存放啟動(dòng)關(guān)閉腳本conf目錄存放配置文件webapps目錄是部署Web應(yīng)用的位置。下面重點(diǎn)看幾個(gè)配置文件因?yàn)槿绻渲糜袉?wèn)題項(xiàng)目部署上去跑不起來(lái)排查很浪費(fèi)時(shí)間。4.3 Tomcat核心配置調(diào)整首先是conf/server.xml這是Tomcat的主配置文件。要關(guān)注三塊內(nèi)容。端口監(jiān)聽(tīng)配置默認(rèn)8080如果項(xiàng)目有特殊要求可以改成其他端口但要和防火墻放行規(guī)則保持一致。連接器參數(shù)主要調(diào)整maxThreads和minSpareThreads這兩個(gè)參數(shù)控制Tomcat的線程池大小。我沒(méi)改動(dòng)線程池但要注意的是connectionTimeout別設(shè)置太短否則上傳大文件時(shí)容易被掐斷連接。然后是conf/catalina.sh的配置JAVA_OPTS環(huán)境變量在這里設(shè)置。內(nèi)存優(yōu)化的參數(shù)如下JAVA_OPTS-Xms512m -Xmx1024m -XX:MaxPermSize256m如果是JDK 1.8MaxPermSize參數(shù)已經(jīng)沒(méi)有意義了JVM用Metaspace代替了永久代所以可以去掉這個(gè)參數(shù)。推薦配置JAVA_OPTS-server -Xms512m -Xmx2048m -XX:MetaspaceSize256m -XX:MaxMetaspaceSize512m這里-Xms和-Xmx建議設(shè)成相同值可以避免JVM在運(yùn)行過(guò)程中動(dòng)態(tài)調(diào)整堆大小帶來(lái)的性能抖動(dòng)。-XX:MetaspaceSize和MaxMetaspaceSize也是同理直接設(shè)成一致能減少Full GC頻率。最后是部署業(yè)務(wù)系統(tǒng)WAR包的方式。有兩種一種是直接把WAR包扔到webapps目錄下Tomcat啟動(dòng)時(shí)自動(dòng)解壓并部署另一種是在conf/Catalina/localhost目錄下創(chuàng)建XML配置文件通過(guò)docBase指定WAR包的絕對(duì)路徑。生產(chǎn)環(huán)境我推薦用第二種好處是部署路徑可以在外部靈活控制不用把業(yè)務(wù)包混在Tomcat默認(rèn)目錄結(jié)構(gòu)里同時(shí)方便多個(gè)應(yīng)用獨(dú)立管理。4.4 Tomcat開(kāi)機(jī)自啟動(dòng)配置為了讓Tomcat在服務(wù)器重啟后自動(dòng)啟動(dòng)我寫(xiě)了一個(gè)systemd服務(wù)腳本。創(chuàng)建/usr/lib/systemd/system/tomcat.service文件內(nèi)容如下[Unit] DescriptionApache Tomcat Web Application Container Afternetwork.target [Service] Typeforking EnvironmentJAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk EnvironmentCATALINA_HOME/opt/tomcat EnvironmentCATALINA_BASE/opt/tomcat ExecStart/opt/tomcat/bin/startup.sh ExecStop/opt/tomcat/bin/shutdown.sh Userroot Grouproot Restartalways [Install] WantedBymulti-user.target保存后依次執(zhí)行以下命令設(shè)置開(kāi)機(jī)自啟并立即驗(yàn)證systemctl daemon-reload systemctl enable tomcat.service systemctl start tomcat.service systemctl status tomcat.service注意Typeforking這個(gè)配置很關(guān)鍵startup.sh腳本啟動(dòng)Tomcat后會(huì)立即返回真正的Tomcat進(jìn)程以子進(jìn)程方式在后臺(tái)運(yùn)行所以必須用Typeforking來(lái)告訴systemd這是forking類(lèi)型服務(wù)否則systemd會(huì)認(rèn)為啟動(dòng)腳本執(zhí)行完就退出了不會(huì)持續(xù)追蹤Tomcat進(jìn)程。上面Userroot是圖方便才設(shè)置成root生產(chǎn)環(huán)境建議單獨(dú)創(chuàng)建一個(gè)tomcat用戶來(lái)跑Tomcat進(jìn)程這樣可以實(shí)現(xiàn)權(quán)限隔離即使Tomcat被攻破了攻擊者拿到的也只是tomcat用戶權(quán)限對(duì)系統(tǒng)整體危害會(huì)小很多。4.5 驗(yàn)證Tomcat與業(yè)務(wù)系統(tǒng)聯(lián)調(diào)Tomcat部署完成后通過(guò)瀏覽器訪問(wèn)http://服務(wù)器IP:8080看到Tomcat默認(rèn)首頁(yè)就說(shuō)明Tomcat本身跑起來(lái)了。如果頁(yè)面打不開(kāi)排查順序是第一看systemctl status tomcat服務(wù)狀態(tài)是否active第二看8080端口有沒(méi)有LISTEN第三看防火墻放行了沒(méi)有最后看SELinux有沒(méi)有攔把SELinux設(shè)置成permissive模式可以排除這個(gè)因素的影響。業(yè)務(wù)系統(tǒng)WAR包部署后如果應(yīng)用依賴Oracle數(shù)據(jù)庫(kù)需要把Oracle JDBC驅(qū)動(dòng)包ojdbc6.jar放到Tomcat的lib目錄下。Tomcat 8.5對(duì)驅(qū)動(dòng)包的管理有講究全局共享的驅(qū)動(dòng)放在lib目錄單個(gè)應(yīng)用獨(dú)享的驅(qū)動(dòng)放在webapps/WEB-INF/lib目錄。如果驅(qū)動(dòng)版本不對(duì)最常見(jiàn)的報(bào)錯(cuò)是ClassNotFoundException或者SQLState異常解決辦法就是到Maven倉(cāng)庫(kù)里下載對(duì)應(yīng)版本的ojdbc6.jar替換。部署完WAR包后重啟Tomcatsystemctl restart tomcat.service觀察日志輸出tail -f /opt/tomcat/logs/catalina.out啟動(dòng)日志中看到Deployment of web application archive has finished說(shuō)明業(yè)務(wù)系統(tǒng)部署成功。再配合數(shù)據(jù)庫(kù)監(jiān)聽(tīng)狀態(tài)確認(rèn)整條鏈路就通了。5. 常見(jiàn)問(wèn)題與排查技巧實(shí)錄5.1 Xstart無(wú)法顯示圖形界面Xstart連接服務(wù)器后報(bào)錯(cuò)提示Cant connect to X11 window server這是最典型的圖形界面轉(zhuǎn)發(fā)問(wèn)題。排查步驟是確認(rèn)服務(wù)器上是否安裝了xorg-x11-xauth包沒(méi)有就裝上。確認(rèn)SSH服務(wù)端的X11Forwarding設(shè)置為yes確認(rèn)/etc/ssh/sshd_config配置中有X11UseLocalhost yes這個(gè)參數(shù)。真正處理這個(gè)坑時(shí)我發(fā)現(xiàn)還有個(gè)更隱蔽的問(wèn)題就是Xstart的配置文件里指定了錯(cuò)誤的SSH端口或者密鑰認(rèn)證方式。如果服務(wù)器改了SSH端口Xstart里也要同步修改。還有如果服務(wù)器上配置了SSH key并且禁用了密碼登錄Xstart認(rèn)證方式要改成Public Key并把本地私鑰路徑填進(jìn)去。另一個(gè)少見(jiàn)但特別麻煩的問(wèn)題是CentOS 7.5及以上版本默認(rèn)的/etc/ssh/sshd_config里X11Forwarding被注釋掉了需要手動(dòng)取消注釋并重啟sshd服務(wù)。重啟sshd前要注意會(huì)不會(huì)影響已有的SSH連接其實(shí)不會(huì)重啟sshd服務(wù)對(duì)已建立的連接沒(méi)有影響只對(duì)新的連接生效。5.2 Oracle安裝程序環(huán)境檢查不通過(guò)Oracle Universal Installer在正式安裝前會(huì)做環(huán)境預(yù)檢經(jīng)常見(jiàn)到某個(gè)檢查項(xiàng)是紅色的叉號(hào)。比如內(nèi)核參數(shù)中的kernel.sem不滿足要求、依賴包缺失、內(nèi)存大小不滿足最小限制等等。出現(xiàn)紅叉不要直接點(diǎn)忽略因?yàn)楹罄m(xù)安裝或者運(yùn)行時(shí)還會(huì)暴露問(wèn)題?;仡櫸野惭b過(guò)程中預(yù)檢不通過(guò)的情況大部分是缺少32位兼容庫(kù)比如glibc.i686和libaio.i686。Oracle 11g雖然是64位版本但它的某些組件會(huì)調(diào)用32位庫(kù)不裝好直接裝Oracle后面創(chuàng)建數(shù)據(jù)庫(kù)時(shí)容易報(bào)ORA-12547錯(cuò)誤。等價(jià)交換的話如果你對(duì)依賴包沒(méi)底可以在預(yù)檢失敗后點(diǎn)Check Another然后查看對(duì)應(yīng)的日志文件。日志文件通常放在/tmp目錄下文件名帶OraInstall前綴打開(kāi)后可以看到具體的檢查結(jié)果和缺失項(xiàng)比官方界面彈窗提示的粒度細(xì)得多。5.3 Oracle監(jiān)聽(tīng)器起不來(lái)Listener啟動(dòng)失敗也是高發(fā)問(wèn)題常見(jiàn)的情況是監(jiān)聽(tīng)器已啟動(dòng)但狀態(tài)顯示unknown或service not registered。最直接的原因是listener.ora文件配置錯(cuò)誤監(jiān)聽(tīng)的位置寫(xiě)錯(cuò)了端口或者主機(jī)IP。用netca重新配置監(jiān)聽(tīng)是最省事的辦法命令行輸入netca根據(jù)圖形界面提示一步步操作就行。還有種情況是Oracle數(shù)據(jù)庫(kù)實(shí)例沒(méi)有注冊(cè)到監(jiān)聽(tīng)器導(dǎo)致客戶端連接時(shí)報(bào)ORA-12514: TNS listener does not currently know of service requested in connect descriptor。解決辦法是檢查listener.ora里是否配置了靜態(tài)的SID信息或者在數(shù)據(jù)庫(kù)本地通過(guò)sqlplus執(zhí)行alter system register;手動(dòng)注冊(cè)實(shí)例到監(jiān)聽(tīng)器。動(dòng)態(tài)注冊(cè)是Oracle 11g的默認(rèn)機(jī)制實(shí)例啟動(dòng)時(shí)會(huì)自動(dòng)向監(jiān)聽(tīng)器注冊(cè)但前提是實(shí)例的service_name和監(jiān)聽(tīng)器的監(jiān)聽(tīng)端口匹配。如果不匹配就要修改initSID.ora里的local_listener參數(shù)指定正確的監(jiān)聽(tīng)器地址。5.4 端口沖突排查端口沖突這個(gè)坑在Tomcat啟動(dòng)時(shí)特別常見(jiàn)。Tomcat默認(rèn)8080端口如果服務(wù)器上已經(jīng)部署了其他Web服務(wù)比如Nginx、Apache或者另一個(gè)Tomcat實(shí)例端口就會(huì)被占用Tomcat啟動(dòng)報(bào)Address already in use錯(cuò)誤。排查命令很簡(jiǎn)單ss -tlnp | grep 8080 netstat -tlnp | grep 8080找到占用端口的進(jìn)程后要么把占用進(jìn)程停掉要么修改Tomcat的server.xml端口配置換一個(gè)可用端口。提醒一下如果Tomcat作為自啟動(dòng)服務(wù)端口修改后要確認(rèn)配置文件里沒(méi)有其他地方寫(xiě)死監(jiān)聽(tīng)端口否則Tomcat會(huì)加載舊配置導(dǎo)致端口沖突問(wèn)題復(fù)發(fā)。Oracle 1521端口也有類(lèi)似問(wèn)題如果服務(wù)器上裝了多個(gè)版本的Oracle或者監(jiān)聽(tīng)器配置錯(cuò)誤都會(huì)導(dǎo)致端口沖突。通過(guò)lsnrctl status查看監(jiān)聽(tīng)的IP和端口確認(rèn)沒(méi)有和其他服務(wù)重疊。5.5 中文顯示亂碼問(wèn)題我遇到過(guò)一次Oracle數(shù)據(jù)庫(kù)中的數(shù)據(jù)是中文但通過(guò)Java應(yīng)用查詢出來(lái)是問(wèn)號(hào)的情況。原因是數(shù)據(jù)庫(kù)的字符集和JDBC連接字符串中的字符集不一致。解決辦法是把數(shù)據(jù)庫(kù)字符集改成AL32UTF8同時(shí)JDBC連接URL加上characterEncodingUTF-8參數(shù)。還有一個(gè)可能是Tomcat連接器配置里添加URIEncodingUTF-8。記住改數(shù)據(jù)庫(kù)字符集不是改一個(gè)參數(shù)就能完成的事情要修改數(shù)據(jù)庫(kù)的locale、nls_lang環(huán)境變量、以及數(shù)據(jù)庫(kù)的national character set。如果是在建庫(kù)之前就發(fā)現(xiàn)這個(gè)問(wèn)題直接在建庫(kù)時(shí)選對(duì)字符集最省事建庫(kù)之后再改會(huì)牽扯數(shù)據(jù)遷移工作量翻倍。6. 運(yùn)維踩坑經(jīng)驗(yàn)總結(jié)裝完這套環(huán)境后我復(fù)盤(pán)了一遍整個(gè)流程有些心得值得單獨(dú)拎出來(lái)說(shuō)。第一個(gè)經(jīng)驗(yàn)是Oracle安裝目錄和數(shù)據(jù)目錄盡量獨(dú)立規(guī)劃不要什么都扔在根分區(qū)。我的服務(wù)器根分區(qū)50GOracle安裝加數(shù)據(jù)文件很快就占了一半后來(lái)日志一膨脹直接導(dǎo)致根分區(qū)滿了Oracle和Tomcat同時(shí)罷工。應(yīng)急辦法是清理日志文件但要想根治還是得把Oracle數(shù)據(jù)目錄、歸檔日志目錄、Tomcat日志目錄都單獨(dú)掛載到獨(dú)立分區(qū)用df -h提前確認(rèn)各分區(qū)容量留有足夠余量。第二個(gè)經(jīng)驗(yàn)是Oracle的數(shù)據(jù)庫(kù)備份不能只依賴數(shù)據(jù)庫(kù)自身的物理備份需要結(jié)合邏輯備份。物理備份適合災(zāi)難恢復(fù)邏輯備份適合數(shù)據(jù)遷移和誤操作恢復(fù)。我自己就是用RMAN做物理備份每周跑一次expdp邏輯導(dǎo)出雙保險(xiǎn)機(jī)制。一旦數(shù)據(jù)庫(kù)崩潰RMAN恢復(fù)整庫(kù)萬(wàn)一只是某個(gè)表被誤刪expdp的dmp文件恢復(fù)起來(lái)更靈活。第三個(gè)經(jīng)驗(yàn)是Tomcat的日志輪轉(zhuǎn)必須配置好。默認(rèn)情況下Tomcat的catalina.out日志是不滾動(dòng)切割的時(shí)間一長(zhǎng)能膨脹到幾十G服務(wù)器磁盤(pán)會(huì)被吃光。解決方案是用Linux自帶的logrotate工具配置/etc/logrotate.d/tomcat按天切割并壓縮保留最近30天日志就夠。這個(gè)配置特別重要我見(jiàn)過(guò)有生產(chǎn)服務(wù)器一個(gè)月沒(méi)看日志直接占用30G磁盤(pán)應(yīng)用直接因?yàn)榇疟P(pán)滿宕機(jī)。第四個(gè)經(jīng)驗(yàn)是關(guān)于安全的尤其是生產(chǎn)環(huán)境千萬(wàn)別為了方便直接關(guān)防火墻和將SELinux設(shè)成disabled。我建議防火墻按需放行端口SELinux設(shè)成permissive并仔細(xì)查看日志中的違規(guī)記錄手動(dòng)放行Oracle和Tomcat需要的操作。這樣既不影響功能又保留了一層安全防線。第五個(gè)經(jīng)驗(yàn)是快照備份。裝這套系統(tǒng)前我給服務(wù)器做了個(gè)快照后面所有踩坑操作都能一鍵回滾。如果別的環(huán)境沒(méi)法做快照至少把修改過(guò)的配置文件提前復(fù)制一份到/tmp/backup目錄下出了問(wèn)題還能對(duì)照原始版本恢復(fù)。這套環(huán)境我前后折騰了三次才走通所有細(xì)節(jié)前面兩次就是沒(méi)有快照每次配置改亂了都只能從頭再來(lái)。第六個(gè)經(jīng)驗(yàn)也是最重要的就是不要盲目復(fù)制別人給的參數(shù)值。服務(wù)器配置不同內(nèi)存、CPU、磁盤(pán)完全一樣才能直接用別人的配置。比如kernel.shmmax這個(gè)參數(shù)機(jī)器內(nèi)存是4G的話設(shè)成4294967295就太大了反而可能導(dǎo)致Oracle的共享內(nèi)存申請(qǐng)不到系統(tǒng)整體性能下降。根據(jù)實(shí)際硬件資源配參數(shù)才是正路。這套環(huán)境裝好之后業(yè)務(wù)系統(tǒng)在Tomcat里跑著數(shù)據(jù)落在Oracle里穩(wěn)定運(yùn)行了一段時(shí)間沒(méi)有出過(guò)重啟問(wèn)題。后續(xù)如果需要擴(kuò)容無(wú)外乎加內(nèi)存、加磁盤(pán)、調(diào)Tomcat線程池、加Oracle SGA這些都是同樣的思路方法論已經(jīng)通了。