Tomcat 第二篇:啓動流程

1 Tomcat 基本知識

首先介紹一些 Tomcat 的基本知識,防止有純小白看的雲裏霧裏的。

下面這張圖是一個下載好二進制版的的 Tomcat ,直接解壓得到的,雖然版本是 9.x ,但是這個目錄結構和 8.5 是一致的,不影響介紹。

  • bin : 主要用來存放一些腳本文件,一種格式是 sh 的是在 Linux 使用的腳本,另一種格式是 bat 的是在 Windows 中使用的腳本。
  • conf : 主要用來存放一些 Tomcat 的配置文件,有 xml 格式的也有 properties 格式的。
  • lib : 用來存放一些 Tomcat 運行時所需要的 jar 包。
  • logs : 日誌目錄。
  • temp : 存放一些運行過程中產生的臨時文件。
  • webapps : 這個應該很熟悉,主要用來存放應用程序,可以是 war 包或者是 jar 包。
  • work : 主要用來存放 Tomcat 在運行時的編譯後文件。清空work目錄,然後重啓 Tomcat ,可以達到清除緩存的作用。

現在的 IDE(Integrated Development Environment) 工具可以直接將 Tomcat 配置在工具中,比如最常用的 Eclipse 和 IDEA ,啓動 Tomcat 的時候只需要點一下按鈕就可以啓動,實際上這兩個 IDE 工具只是幫我們調用了 Tomcat 的啓動腳本。

Tomcat 的各種腳本都放在 bin 這個目錄下,我們打開看一下:

可以輕易的找到兩個啓動腳本 startup.batstartup.sh 。一個是 Windows 下的腳本,一個 Linux 下的。

同樣,還可以看到兩個停止腳本 shutdown.batshutdown.sh

這是在 Tomcat 的二進制包中,我們還可以看下源碼包下是什麼樣的。

可以看到,基本上該有的都有,最重要的啓停腳本都還在。

既然我現在是在 Windows 環境下,那麼啓動就從 startup.bat 看起。

2 Tomcat 啓動第一步:startup.bat

第一個打開 startup.bat 這個啓動腳本,看下里面寫了啥具體,這段腳本不長,我把裏面的內容摘出來:

setlocal

rem Guess CATALINA_HOME if not defined
set "CURRENT_DIR=%cd%"
if not "%CATALINA_HOME%" == "" goto gotHome
set "CATALINA_HOME=%CURRENT_DIR%"
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
cd ..
set "CATALINA_HOME=%cd%"
cd "%CURRENT_DIR%"
:gotHome
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHome

set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat"

rem Check that target executable exists
if exist "%EXECUTABLE%" goto okExec
echo Cannot find "%EXECUTABLE%"
echo This file is needed to run this program
goto end
:okExec

rem Get remaining unshifted command line arguments and save them in the
set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
:doneSetArgs

call "%EXECUTABLE%" start %CMD_LINE_ARGS%

:end

最開始一大段的 rem 註釋我沒摘,只摘了最後一部分會執行的內容。

第一段是在設置當前的 CATALINA_HOME 的環境變量,如果沒有設置的話,會將當前運行腳本的目錄作爲該環境變量的值,然後跳轉到 :okHome 那裏。

接下來設置了 EXECUTABLE 的路徑是 %CATALINA_HOME%\bin\catalina.bat

然後開始驗證驗證設置的 EXECUTABLE 中的 catalina.bat 這個文件存不存在,如果不存在的話直接結束,如果存在的話接着往下走。

接下來是將運行腳本前設置的其他參數保存到 CMD_LINE_ARGS 這個變量中,然後在最後執行了 catalina.bat 這個文件,跟了兩個參數,第一個是 start ,第二個就是剛纔保存的變量 CMD_LINE_ARGS

這種腳本代碼建議放在編輯器裏看,千萬不要使用那個 Windows 自帶的記事本,用那玩意看估計大多數人直接就看懵了。

我通常是放在 VSCode 中看,會自動對代碼進行高亮展示,給大家看下上面這段腳本放在 VSCode 中的樣子:

可以看到,正常註釋變灰,關鍵字變藍高亮,並且跳轉語句直接變橙色,非常方便我們閱讀。

3 Tomcat 啓動第二步:catalina.bat

這個腳本太長了,我就單純的截取比較重要的進行介紹。

set "CURRENT_DIR=%cd%"
if not "%CATALINA_HOME%" == "" goto gotHome
set "CATALINA_HOME=%CURRENT_DIR%"
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
cd ..
set "CATALINA_HOME=%cd%"
cd "%CURRENT_DIR%"
:gotHome

if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHome

在最開頭的地方,校驗 CATALINA_HOME 是否存在,如果不存在,則設置 CATALINA_HOME 爲當前路徑。

接着下面設置了一下 CATALINA_BASE 這個變量。

if not "%CATALINA_BASE%" == "" goto gotBase
set "CATALINA_BASE=%CATALINA_HOME%"
:gotBase

接下來到了一個重點內容,判斷 setclasspath.bat 是否存在,如果存在的話就執行一下:

rem Get standard Java environment variables
if exist "%CATALINA_HOME%\bin\setclasspath.bat" goto okSetclasspath
echo Cannot find "%CATALINA_HOME%\bin\setclasspath.bat"
echo This file is needed to run this program
goto end
:okSetclasspath
call "%CATALINA_HOME%\bin\setclasspath.bat" %1
if errorlevel 1 goto end

這個文件實際上是校驗是否設置了 JAVA_HOME 或者 JRE_HOME 的環境變量,如果沒有設置則會在控制檯打印對應的信息。

接下來是有關於 CLASSPATH 的設置和校驗,然後是一堆變量的設置和校驗,無需關注,接着使用 echo 打印了一些信息:

echo Using CATALINA_BASE:   "%CATALINA_BASE%"
echo Using CATALINA_HOME:   "%CATALINA_HOME%"
echo Using CATALINA_TMPDIR: "%CATALINA_TMPDIR%"
if ""%1"" == ""debug"" goto use_jdk
echo Using JRE_HOME:        "%JRE_HOME%"
goto java_dir_displayed
:use_jdk
echo Using JAVA_HOME:       "%JAVA_HOME%"
:java_dir_displayed
echo Using CLASSPATH:       "%CLASSPATH%"

各種比較重要的變量在這裏進行了一些打印,接下來又設置了一些比較重要的變量:

set _EXECJAVA=%_RUNJAVA%
set MAINCLASS=org.apache.catalina.startup.Bootstrap
set ACTION=start
set SECURITY_POLICY_FILE=
set DEBUG_OPTS=
set JPDA=

這裏的 _EXECJAVA 實際上是我們在 JAVA_HOME 或者是 JRE_HOME 中 bin 下面的 java.exe

這裏出現的 _RUNJAVA 變量,是在上面的 setclasspath.bat 那個腳本中進行設置的。

而這個 MAINCLASS 的值是 org.apache.catalina.startup.Bootstrap ,這個是我們第一篇文章啓動 Tomcat 時候的那個類,不知道各位還有印象不。

接下來設置了一個變量 ACTION 的動作時 start ,用屁股想想應該是啓動的意思。

然後對參數進行了一次判斷:

if ""%1"" == ""debug"" goto doDebug
if ""%1"" == ""run"" goto doRun
if ""%1"" == ""start"" goto doStart
if ""%1"" == ""stop"" goto doStop
if ""%1"" == ""configtest"" goto doConfigTest
if ""%1"" == ""version"" goto doVersion

如果沒有其他參數做覆蓋,這裏的參數就是上面設置的 start ,直接跳轉到最後的 doStart 去了,不過可以看到, Tomcat 啓動可以接受的參數有 debug , run , start , stop , configtestversion ,我們平時在 IDE 工具裏用的比較多的應該有 debug , run , start , stop , 剩下的兩個至少我是基本上沒有使用過,如果不是今天看到這裏了,我都不知道 Tomcat 還能有 configtestversion 這兩個參數。

:doDebug
shift
set _EXECJAVA=%_RUNJDB%
set DEBUG_OPTS=-sourcepath "%CATALINA_HOME%\..\..\java"
if not ""%1"" == ""-security"" goto execCmd
shift
echo Using Security Manager
set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"
goto execCmd

:doRun
shift
if not ""%1"" == ""-security"" goto execCmd
shift
echo Using Security Manager
set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"
goto execCmd

:doStart
shift
if "%TITLE%" == "" set TITLE=Tomcat
set _EXECJAVA=start "%TITLE%" %_RUNJAVA%
if not ""%1"" == ""-security"" goto execCmd
shift
echo Using Security Manager
set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"
goto execCmd

上面這一段就是我們最常用的三種啓動方式,從腳本上來看, debugrun 單純的多設置了兩個變量 _EXECJAVADEBUG_OPTS ,而 start 則是多了一個 TITLE 的判斷。

接着往下看,基本上就已經到了這個腳本的最底部,這裏執行了一句話,也是核心的一句話:

%_EXECJAVA% %CATALINA_LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -D%ENDORSED_PROP%="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%

_EXECJAVA 是我們剛纔說的那個 java.exe ,然後是各種運行時參數和系統屬性,最後面的 MAINCLASS ,也就是 org.apache.catalina.startup.Bootstrap ,接着是 CMD_LINE_ARGS ,這也是一個命令參數,就是 main 方法上的那個 args 參數,最後一個參數是 ACTION 也就是 start

最後歸根結底就是一句話,執行 Bootstrap 裏面的 main 方法,別看這些個腳本寫了一大堆,主要工作就是在校驗環境配置以及一些基礎系統設置和一些運行時參數的設置。

4 小結

腳本整體來講不難,而且每段腳本上面都已經有了簡單的英文註釋,簡明扼要的寫清楚了這一段腳本在做什麼,稍微瞭解一些基礎的 DOS 命令,都可以進行閱讀。

至於其他的腳本可以大致瀏覽下,基本上兜兜轉轉最後還是會回到 catalina.bat 這個腳本,而在這個腳本中,最後肯定會執行 Bootstrap 裏面的 main 方法。

在 Windows 系統中,使用的是 bat 腳本,在 Linux 系統中,就會使用 sh 腳本,這個本質上沒有什麼大的差別,整體原理都是一樣的,有興趣的同學可以自己研究下 sh 腳本,就當學 shell 語法了。

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