欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Tomcat啟動

系統(tǒng) 2549 0
Bootstrapping Tomcat
The bootstrapping process is actually rather simple. All we have to do is:
1、Set up the environment variables required by this Tomcat instance
2、Instantiate the general class loaders that will be used for our running? Tomcat instance
3、Initialize this Tomcat instance
4、Parse the main configuration file for a Tomcat instance, server.xml,?converting each configuration element into the appropriate Tomcat?component
5、Start up our outermost Top Level Element—the Server instance
6、Set up a shutdown hook
分別看看如何執(zhí)行:
1、執(zhí)行startup.bat,調(diào)用catalina.bat進行環(huán)境變量的設(shè)置,否則通過
Bootstrap的ini()
// Set Catalina path
setCatalinaHome ();
setCatalinaBase();
2、 classloader
Our Bootstrap instance holds references to the following three class loaders:
1、commonLoader, which loads classes that are common across Tomcat, as well?
as all the web applications.
2、catalinaLoader, or serverLoader, which loads classes that are used just?
by Tomcat.
3、sharedLoader, which loads classes that are common just across all the web?
applications within a Tomcat instance.
其中:org.apache.catalina.startup.CatalinaProperties類解析catalina.properties文件,
org.apache.catalina.startup.ClassLoaderFactory?的createClassLoader()方法將.jar文件url放入set,并返回StandardClassLoader
Tomcat啟動
在ini方法中會
?
initClassLoaders();
Thread. currentThread ().setContextClassLoader( catalinaLoader );
SecurityClassLoad. securityClassLoad ( catalinaLoader );
// Load our startup class and call its process() method
if ( log .isDebugEnabled())
log .debug( "Loading startup class" );
Class startupClass =
catalinaLoader .loadClass
( "org.apache.catalina.startup.Catalina" );
Object startupInstance = startupClass.newInstance();
而其中的initClassLoaders()方法會初始化loaders,如下:
private void initClassLoaders () {
try {
commonLoader = createClassLoader( "common" , null );
if ( commonLoader == null ) {
// no config file, default to this loader - we might be in a 'single' env .
commonLoader = this .getClass().getClassLoader();
}
catalinaLoader = createClassLoader( "server" , commonLoader );
sharedLoader = createClassLoader( "shared" , commonLoader );
} catch (Throwable t) {
log .error( "Class loader creation threw exception" , t);
System. exit (1);
}
}
上面代碼
Class startupClass = catalinaLoader .loadClass ( "org.apache.catalina.startup.Catalina" );
Object startupInstance = startupClass.newInstance();
實例化了startup實例。
?
4、解析Server.xml,使用了?Apache Commons Digester?
?It takes an XML document?and a RuleSet document as inputs, and generates a graph of Java objects that?
represents the structure that is defined in the XML instance document
The pattern:sax方式,例如:Server/Service/Connector
The rule:普通有4種
1、Creational actions (create an instance of a given class to represent this? XML element)
創(chuàng)建行為
2、Property setting actions (call setters on the Java object representing this? XML element, passing in the value of either a child element or an attribute)
屬性設(shè)置
3、Method invocation actions (call the specified method on the Java object?representing this element, passing in the specified parameters)
激活方法
4、Object linking actions (set an object reference by calling a setter on one? object while passing in the other as an argument)
對象引用
Server.xml的Digester
通過Catalina.java中的 createStartDigester ()方法創(chuàng)建,并設(shè)置規(guī)則
?
5、?在 Catalina.java中調(diào)用start()方法中調(diào)用getServer().initialize();
接著:services[i].initialize();
接著:connectors[i].initialize();
。。。(詳見最后的代碼跟蹤)
6、shutdown hook
A shutdown hook is a standard Thread that encapsulates cleanup actions that?should be taken before the Java runtime exits. All shutdown hooks are called by? the runtime when the JVM is shutting down.
Therefore, the last task that we perform is to install a shutdown hook, as?implemented by CatalinaShutdownHook. This hook is registered with the? Java Runtime by invoking its addShutdownHook() method:
Runtime.getRuntime().addShutdownHook(),
CatalinaShutdownHook is an inner class of Catalina and so has access to all the?data members of Catalina. Its run() method is very simple. It just ensures that?stop() is called on this instance of Catalina. This method invokes stop() on the?StandardServer instance, which in turn performs a cascaded invocation of stop()?on all its child components. Each child does the same for its children, until the entire?server has been cleanly stopped.
使用類 CatalinaShutdownHook實現(xiàn),它繼承Thread,run中進行清理
// Register shutdown hook
if ( useShutdownHook ) {
if ( shutdownHook == null ) {
shutdownHook = new CatalinaShutdownHook();
}
Runtime. getRuntime (). addShutdownHook ( shutdownHook );
// If JULI is being used, disable JULI's shutdown hook since
// shutdown hooks run in parallel and log messages may be lost
// if JULI's hook completes before the CatalinaShutdownHook()
LogManager logManager = LogManager. getLogManager ();
if (logManager instanceof ClassLoaderLogManager) {
((ClassLoaderLogManager) logManager).setUseShutdownHook(
false );
}
}
?
啟動tomat代碼跟蹤
View Code
1、Bootstrap.java中的main方法,啟動tomcat;
調(diào)用init()方法初始化,并用Catalina.load(),獲取server對象,并調(diào)用ini方法
// ?Start?the?new?server
if ?(getServer()? instanceof ?Lifecycle)?{
try ?{
getServer().initialize();
}? catch ?(LifecycleException?e)?{
if ?(Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE"))
throw ? new ?java.lang.Error(e);
else ?
log.error("Catalina.start",?e);
}
}?
但是server對象是怎么來的??
往回看,在load方法中,
// ?Create?and?execute?our?Digester
Digester?digester?=?createStartDigester();?中創(chuàng)建了規(guī)則,如下:

// ?Configure?the?actions?we?will?be?using
digester.addObjectCreate("Server",
"org.apache.catalina.core.StandardServer",
"className");?
經(jīng)過反射,到類ObjectCreateRule類的begin方法中
// ?Instantiate?the?new?object?and?push?it?on?the?context?stack
Class?clazz?=?digester.getClassLoader().loadClass(realClassName);
Object?instance?=?clazz.newInstance();?
利用反射創(chuàng)建對象,其中:realClassName?=org.apache.catalina.core.StandardServer
在類org.apache.catalina.core.StandardServer構(gòu)造方法中調(diào)用ServerFactory.setServer( this );?
實現(xiàn)單例Server對象創(chuàng)建。

2、?
getServer().initialize();方法中調(diào)用service的ini方法:其中services為解析server.xml
// ?Initialize?our?defined?Services
???????? for ?( int ?i?=?0;?i?<?services.length;?i++)?{
????????????services[i].initialize();
????????}
在?initialize
執(zhí)行connector的ini方法
for ?( int ?i?=?0;?i?<?connectors.length;?i++)?{
try ?{
connectors[i].initialize();?
connectors的來源也是server.xml配置文件,默認配置:
?<Connector?connectionTimeout="20000"?port="80"?protocol="HTTP/1.1"?redirectPort="8443"/>
???????<!--?Define?an?AJP?1.3?Connector?on?port?8009?-->
????<Connector?port="8009"?protocol="AJP/1.3"?redirectPort="8443"/>


3、接下來分析connector,默認使用protocol="HTTP/1.1"協(xié)議
? // ?Initializa?adapter
????????adapter?=? new ?CoyoteAdapter( this );
????????protocolHandler.setAdapter(adapter);
生成CoyoteAdapter,并設(shè)置,調(diào)用ini方法
protocolHandler.init();
4、接下來調(diào)用
endpoint.init();?
我們了看看JIoEndpoint?類是做神馬的?
?*?Handle?incoming?TCP?connections.
?*
?*?This? class ?implement?a?simple?server?model:?one?listener?thread?accepts?on?a?socket?and
?*?creates?a? new ?worker?thread? for ?each?incoming?connection.
此類實現(xiàn)了簡單的server模型:一個監(jiān)聽線程,接受socket并且為每一個到來的連接創(chuàng)建一個worker線程
真正干活的是這個!后面我們會分析它的start方法
接下來初始化其他conector

5、當(dāng)以上初始化完成后,調(diào)用Catalina.start()方法,接著啟動server.start()方法:
((Lifecycle)?getServer()).start();?
接著調(diào)用service.start()方法
接下來是一系列的container的start,后續(xù)在分析(會部署所有的項目)

在service.start()中,調(diào)用executors,connectors的start方法,我們直接往下看
synchronized ?(executors)?{
for ?(? int ?i=0;?i<executors.size();?i++?)?{
executors.get(i).start();
}
}
// ?Start?our?defined?Connectors?second
synchronized ?(connectors)?{
for ?( int ?i?=?0;?i?<?connectors.length;?i++)?{
try ?{
((Lifecycle)?connectors[i]).start();
}? catch ?(Exception?e)?{
log.error(sm.getString(
"standardService.connector.startFailed",
connectors[i]),?e);
}
}
}?
6、直到調(diào)用protocolHandler.start();?接下來:JIoEndpoint.start();
public ? void ?start()
throws ?Exception?{
// ?Initialize?socket?if?not?done?before
if ?(!initialized)?{
init();
}
if ?(!running)?{
running?=? true ;
paused?=? false ;
// ?Create?worker?collection
if ?(executor?==? null )?{
workers?=? new ?WorkerStack(maxThreads);
}
// ?Start?acceptor?threads
for ?( int ?i?=?0;?i?<?acceptorThreadCount;?i++)?{
Thread?acceptorThread?=? new ?Thread( new ?Acceptor(),?getName()?+?"-Acceptor-"?+?i);
acceptorThread.setPriority(threadPriority);
acceptorThread.setDaemon(daemon);
acceptorThread.start();
}
}
}?
7、此方法會創(chuàng)建一個線程(acceptorThreadCount默認=1),此線程Acceptor對象,看run方法
/**
*?The?background?thread?that?listens?for?incoming?TCP/IP?connections?and
*?hands?them?off?to?an?appropriate?processor.
*/
public ? void ?run()?{
// ?Loop?until?we?receive?a?shutdown?command
while ?(running)?{
// ?Loop?if?endpoint?is?paused
while ?(paused)?{
try ?{
Thread.sleep(1000);
}? catch ?(InterruptedException?e)?{
// ?Ignore
}
}
// ?Accept?the?next?incoming?connection?from?the?server?socket
try ?{
Socket?socket?=?serverSocketFactory.acceptSocket(serverSocket);
serverSocketFactory.initSocket(socket);
// ?Hand?this?socket?off?to?an?appropriate?processor
if ?(!processSocket(socket))?{
// ?Close?socket?right?away
try ?{
socket.close();
}? catch ?(IOException?e)?{
// ?Ignore
}
}
} catch ?(?IOException?x?)?{
if ?(?running?)?log.error(sm.getString("endpoint.accept.fail"),?x);
}? catch ?(Throwable?t)?{
log.error(sm.getString("endpoint.accept.fail"),?t);
}
// ?The?processor?will?recycle?itself?when?it?finishes
}
}?
這就是前面介紹的作用:接受socket并分配處理,最終關(guān)閉socket
方法:
/**
*?Process?given?socket.
*/
protected ? boolean ?processSocket(Socket?socket)?{
try ?{
if ?(executor?==? null )?{
getWorkerThread().assign(socket);
}? else ?{
executor.execute( new ?SocketProcessor(socket));
}
}? catch ?(Throwable?t)?{
// ?This?means?we?got?an?OOM?or?similar?creating?a?thread,?or?that
// ?the?pool?and?its?queue?are?full
log.error(sm.getString("endpoint.process.fail"),?t);
return ? false ;
}
return ? true ;
}?
其中g(shù)etWorkerThread()返回的worker?thread
/**
*?Return?a?new?worker?thread,?and?block?while?to?worker?is?available.
*/
protected ?Worker?getWorkerThread()?{
// ?Allocate?a?new?worker?thread
synchronized ?(workers)?{
Worker?workerThread;
while ?((workerThread?=?createWorkerThread())?==? null )?{
try ?{
workers.wait();
}? catch ?(InterruptedException?e)?{
// ?Ignore
}
}
return ?workerThread;
}
}
在看worker對象的run方法:
public ? void ?run()?{
// ?Process?requests?until?we?receive?a?shutdown?signal
while ?(running)?{
// ?Wait?for?the?next?socket?to?be?assigned
// 當(dāng)沒有請求時,此線程一直處于等待狀態(tài),直到被喚醒,也就是notifyAll(),在之前的getWorkerThread().assign(socket)被喚醒
Socket?socket?=?await();
if ?(socket?==? null )
continue ;
// ?Process?the?request?from?this?socket
if ?(!setSocketOptions(socket)?||?!handler.process(socket))?{
// ?Close?socket
try ?{
socket.close();
}? catch ?(IOException?e)?{
}
}
// ?Finish?up?this?request
socket?=? null ;
recycleWorkerThread( this );
}
}?
最終執(zhí)行在handler.process,我們之前分析的Http11Protocol類中的內(nèi)部類實現(xiàn)了Handler,如下:
protected ? static ? class ?Http11ConnectionHandler? implements ?Handler?

對于我們的protocol="HTTP/1.1"?connector來說,此類執(zhí)行了process方法,處理socket
調(diào)用processor.process()方法處理http請求,包括servlet、靜態(tài)資源等
/**
*?Process?pipelined?HTTP?requests?on?the?specified?socket.
*
*?
@param ?socket?Socket?from?which?the?HTTP?requests?will?be?read
*?and?the?HTTP?responses?will?be?written.
*?
*?
@throws ?IOException?error?during?an?I/O?operation
*/
public ? void ?process(Socket?theSocket)
throws ?IOException?{
RequestInfo?rp?=?request.getRequestProcessor();
rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);
// ?Set?the?remote?address
remoteAddr?=? null ;
remoteHost?=? null ;
localAddr?=? null ;
localName?=? null ;
remotePort?=?-1;
localPort?=?-1;
// ?Setting?up?the?I/O
this .socket?=?theSocket;
inputBuffer.setInputStream(socket.getInputStream());
outputBuffer.setOutputStream(socket.getOutputStream());
// ?Error?flag
error?=? false ;
keepAlive?=? true ;
int ?keepAliveLeft?=?maxKeepAliveRequests;
int ?soTimeout?=?endpoint.getSoTimeout();
// ?When?using?an?executor,?these?values?may?return?non-positive?values
int ?curThreads?=?endpoint.getCurrentThreadsBusy();
int ?maxThreads?=?endpoint.getMaxThreads();
if ?(curThreads?>?0?&&?maxThreads?>?0)?{
// ?Only?auto-disable?keep-alive?if?the?current?thread?usage?%?can?be
// ?calculated?correctly
if ?((curThreads*100)/maxThreads?>?75)?{
keepAliveLeft?=?1;
}
}
// 以下設(shè)置了超時,如果沒有超時,那依然使用同一個socket請求資源,此時不用重建socket,效率高
try ?{
socket.setSoTimeout(soTimeout);
}? catch ?(Throwable?t)?{
log.debug(sm.getString("http11processor.socket.timeout"),?t);
error?=? true ;
}
boolean ?keptAlive?=? false ;
while ?(started?&&?!error?&&?keepAlive?&&?!endpoint.isPaused())?{
// ?Parsing?the?request?header
try ?{
if ?(keptAlive)?{
if ?(keepAliveTimeout?>?0)?{
socket.setSoTimeout(keepAliveTimeout);
}
else ? if ?(soTimeout?>?0)?{
socket.setSoTimeout(soTimeout);
}
}
inputBuffer.parseRequestLine();
request.setStartTime(System.currentTimeMillis());
keptAlive?=? true ;
if ?(disableUploadTimeout)?{
socket.setSoTimeout(soTimeout);
}? else ?{
socket.setSoTimeout(timeout);
}
inputBuffer.parseHeaders();
}? catch ?(IOException?e)?{
error?=? true ;
break ;
}? catch ?(Throwable?t)?{
if ?(log.isDebugEnabled())?{
log.debug(sm.getString("http11processor.header.parse"),?t);
}
// ?400?-?Bad?Request
response.setStatus(400);
adapter.log(request,?response,?0);
error?=? true ;
}
if ?(!error)?{
// ?Setting?up?filters,?and?parse?some?request?headers
rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);
try ?{
prepareRequest();
}? catch ?(Throwable?t)?{
if ?(log.isDebugEnabled())?{
log.debug(sm.getString("http11processor.request.prepare"),?t);
}
// ?400?-?Internal?Server?Error
response.setStatus(400);
adapter.log(request,?response,?0);
error?=? true ;
}
}
if ?(maxKeepAliveRequests?>?0?&&?--keepAliveLeft?==?0)
keepAlive?=? false ;
// ?Process?the?request?in?the?adapter
if ?(!error)?{
try ?{
rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
adapter.service(request,?response);
// ?Handle?when?the?response?was?committed?before?a?serious
// ?error?occurred.?Throwing?a?ServletException?should?both
// ?set?the?status?to?500?and?set?the?errorException.
// ?If?we?fail?here,?then?the?response?is?likely?already
// ?committed,?so?we?can't?try?and?set?headers.
if (keepAlive?&&?!error)?{? // ?Avoid?checking?twice.
error?=?response.getErrorException()?!=? null ?||
statusDropsConnection(response.getStatus());
}
}? catch ?(InterruptedIOException?e)?{
error?=? true ;
}? catch ?(Throwable?t)?{
log.error(sm.getString("http11processor.request.process"),?t);
// ?500?-?Internal?Server?Error
response.setStatus(500);
adapter.log(request,?response,?0);
error?=? true ;
}
}
// ?Finish?the?handling?of?the?request
try ?{
rp.setStage(org.apache.coyote.Constants.STAGE_ENDINPUT);
// ?If?we?know?we?are?closing?the?connection,?don't?drain?input.
// ?This?way?uploading?a?100GB?file?doesn't?tie?up?the?thread?
// ?if?the?servlet?has?rejected?it.
if (error)
inputBuffer.setSwallowInput( false );
inputBuffer.endRequest();
}? catch ?(IOException?e)?{
error?=? true ;
}? catch ?(Throwable?t)?{
log.error(sm.getString("http11processor.request.finish"),?t);
// ?500?-?Internal?Server?Error
response.setStatus(500);
adapter.log(request,?response,?0);
error?=? true ;
}
try ?{
rp.setStage(org.apache.coyote.Constants.STAGE_ENDOUTPUT);
outputBuffer.endRequest();
}? catch ?(IOException?e)?{
error?=? true ;
}? catch ?(Throwable?t)?{
log.error(sm.getString("http11processor.response.finish"),?t);
error?=? true ;
}
// ?If?there?was?an?error,?make?sure?the?request?is?counted?as
// ?and?error,?and?update?the?statistics?counter
if ?(error)?{
response.setStatus(500);
}
request.updateCounters();
rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);
// ?Don't?reset?the?param?-?we'll?see?it?as?ended.?Next?request
// ?will?reset?it
// ?thrA.setParam(null);
// ?Next?request
inputBuffer.nextRequest();
outputBuffer.nextRequest();
}
rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
// ?Recycle
inputBuffer.recycle();
outputBuffer.recycle();
this .socket?=? null ;
// ?Recycle?ssl?info
sslSupport?=? null ;
}
?

Tomcat啟動


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 91久久老司机福利精品网 | 亚欧视频在线观看 | 色黄网站在线观看 | 国产xxx在线观看 | 先锋资源站| 一区二区三区在线 | 日本 | 欧美搞黄视频 | 精品国产青草久久久久福利 | 亚洲毛片网站 | 欧美精品videosex极品 | 一级在线观看 | 亚洲综合色婷婷在线观看 | 精品国产福利在线 | 国产天堂网| 日韩视频www | 成人欧美日韩一区二区三区 | 国产日韩一区二区三免费高清 | 亚洲日韩中文字幕一区 | 国产一区在线观看免费 | 边摸边吃奶边做激情叫床文章 | 久久久久免费观看 | 精品久久久中文字幕一区 | 骚视频在线观看 | 亚洲一区二区中文字幕 | 成人欧美在线观看免费视频 | 国产品久久 | 91婷婷韩国欧美一区二区 | 日本欧美中文字幕人在线 | 欧美一级三级 | 国产人妻互换一区二区水牛影视 | 性xxxxx视频| 五月天激激婷婷大综合蜜芽 | 国产一区二区三区久久久久久久久 | 色www精品视频在线观看 | 波多野结衣在线看片 | 日本福利一区二区 | 国内精品久久久久激情影院 | 国产一级淫 | 久久久久中文字幕 | 精品72久久久久久久中文字幕 | 色综合久久综合欧美综合 |