Tomcat7涓瓀eb搴旂敤鍔犺浇鍘熺悊锛堜竴锛塁ontext鏋勫徐
涓轰粈涔堝叧蹇僒omcat涓竴涓獁eb搴旂敤鐨勫姞杞借繃绋嬶紵鍦ㄥ墠闈㈢殑鏂囩珷涓湅杩囧娆omcat鐨勭粍浠剁粨鏋勫浘锛岃繖閲屽啀璐村嚭鏉ュ洖椤句竴涓嬶細
涔嬪墠鐨勩€奣omcat7鍚姩鍒嗘瀽銆嬬郴鍒楁枃绔犱腑鐪嬪埌Tomcat鍚姩鐨勬椂鍊欏皢浼氳В鏋恠erver.xml锛屾牴鎹噷闈㈡墍閰嶇疆鐨勫悇涓妭鐐逛俊鎭€愪竴鍒濆鍖栧拰鍚姩鐩稿簲缁勪欢锛堝嵆鍒嗗埆璋冪敤瀹冧滑鐨刬nit鍜宻tart鏂规硶锛夛紝浣嗘祻瑙堜竴涓婽omcat7婧愮爜涓殑server.xml鐨勫唴瀹癸紝閲岄潰瀵瑰簲涓婂浘涓殑宸茬粡榛樿閰嶇疆鐨勫悇绾х粍浠跺寘鎷琒erver銆丼ervice銆丒ngine銆丆onnector銆丠ost銆乂alve銆備笂鍥句腑鐨凜ontext缁勪欢瀹為檯灏辨槸鎴戜滑閫氬父鎵€璇寸殑涓€涓獁eb搴旂敤锛屾湁瓒g殑鏄湪server.xml涓苟娌℃湁閰嶇疆璇ョ粍浠讹紝鑰屾垜浠粯璁ゅ惎鍔ㄧ殑鏃跺€欏疄闄呬笂宸茬粡鏈夊ソ鍑犱釜web搴旂敤鍙互璁块棶浜嗭細
杩欎釜鍒板簳鏄€庝箞鍥炰簨锛?/p>
聽
鐪嬭繃鍓嶉潰鐨勩€奣omcat7涓竴娆¤姹傚鐞嗙殑鍓嶄笘浠婄敓銆嬬郴鍒楁枃绔犵殑浜哄簲璇ョ煡閬擄紝娴忚鍣ㄤ竴娆¤姹傞€佸埌Tomcat鏈嶅姟鍣ㄤ箣鍚庯紝鏈€缁堜細鏍规嵁娴忚鍣ㄤ腑鐨剈rl璺緞鎵惧埌鐩稿簲鐨勫疄闄呰璁块棶鐨剋eb搴旂敤鐨刢ontext瀵硅薄锛堥粯璁ゅ嵆org.apache.catalina.core.StandardContext绫荤殑瀹炰緥锛夈€傛瘮濡傝闂殑url涓篽ttp://localhost:8080/锛岄偅涔堝皢浼氶€佸埌涓婂浘ROOT鏂囦欢澶硅〃绀虹殑web搴旂敤涓紝璁块棶鐨剈rl涓篽ttp://localhost:8080/docs锛岄偅涔堝皢璁块棶docs鏂囦欢澶硅〃绀虹殑web搴旂敤銆傛墍浠ヨ兘澶熺寽鍒扮殑鏄湪Tomcat鍚姩瀹屾垚鍚庯紝蹇呭畾瀹瑰櫒鍐呴儴宸茬粡鏋勯€犲ソ浜嗚〃绀虹浉搴攚eb搴旂敤鐨勫悇涓猚ontext瀵硅薄銆?/p>
聽
鏈枃灏卞杩欎釜闂涓€鎺㈢┒绔熴€傚湪銆奣omcat7鏈嶅姟鍣ㄥ叧闂師鐞嗐€?/a>鐨勫紑澶存彁鍒帮紝榛樿鐨勯厤缃笅Tomcat鍚姩瀹屼箣鍚庝細鐪嬪埌鍚庡彴瀹為檯涓婃€诲叡鏈?涓嚎绋嬪湪杩愯锛?/p>
鍓嶉潰鐨勫嚑绡囨枃绔犱腑娑夊強浜唌ain銆乭ttp-bio-8080-Acceptor-0銆乭ttp-bio-8080-AsyncTimeout銆乤jp-bio-8009-Acceptor-0銆乤jp-bio-8009-AsyncTimeout锛屽凡缁忚皥鍒颁簡杩欎簺绾跨▼鐨勪綔鐢紝瀹冧滑鏄浣曚骇鐢熷苟鍝嶅簲璇锋眰鐨勩€備絾鏈変竴涓嚎绋嬫病鏈夎锛屽嵆ContainerBackgroundProcessor[StandardEngine[Catalina]]锛岃€屾湰鏂囪瑙g瓟鐨勯棶棰樺ゥ绉樺氨鍦ㄨ繖涓嚎绋嬩箣涓€?/p>
聽
鍏堢湅鐪嬭繖涓嚎绋嬫槸濡備綍浜х敓鐨勶紝鍏跺疄浠庡懡鍚嶅氨鍙互鐪嬪嚭涓€浜涚鍊紝瀹冨彨鍋氬鍣ㄥ悗鍙板鐞嗗櫒锛屽苟涓旇窡StandardEngine鍏宠仈璧锋潵锛屽畠鐨勪骇鐢熶簬浣滅敤涔熷悓鏍峰姝ゃ€?/p>
Tomcat7涓墍鏈夌殑榛樿瀹瑰櫒缁勪欢锛圫tandardEngine銆丼tandardHost銆丼tandardContext銆丼tandardWrapper锛夐兘浼氱户鎵跨埗绫籵rg.apache.catalina.core.ContainerBase锛屽湪杩欎簺瀹瑰櫒缁勪欢鍚姩鏃跺皢浼氳皟鐢ㄨ嚜宸卞唴閮ㄧ殑startInternal鏂规硶锛屽湪璇ユ柟娉曞唴閮ㄤ竴鑸細璋冪敤鐖剁被鐨剆tartInternal鏂规硶锛圫tandardContext绫荤殑瀹炵幇闄ゅ锛夛紝姣斿org.apache.catalina.core.StandardEngine绫讳腑鐨剆tartInternal鏂规硶锛?/p>
@Override protected synchronized void startInternal() throws LifecycleException { // Log our server identification information if(log.isInfoEnabled()) log.info( "Starting Servlet Engine: " + ServerInfo.getServerInfo()); // Standard container startup super.startInternal(); }
鏈€鍚庣殑super.startInternal()鍗宠皟鐢ㄧ埗绫籵rg.apache.catalina.core.ContainerBase鐨剆tartInternal鏂规硶锛屽湪璇ユ柟娉曟渶鍚庯細
// Start the Valves in our pipeline (including the basic), if any if (pipeline instanceof Lifecycle) ((Lifecycle) pipeline).start(); setState(LifecycleState.STARTING); // Start our thread threadStart();
绗?琛岃缃簡LifecycleState.STARTING鐘舵€侊紙杩欐牱灏嗗悜瀹瑰櫒鍙戝竷涓€涓狶ifecycle.START_EVENT浜嬩欢锛夛紝杩欎竴琛岀殑浣滅敤鏈枃鍚庨潰浼氭彁鍒帮紝鏆備笖鎸変笅涓嶈〃銆傜9琛岃皟鐢╰hreadStart鏂规硶锛岀湅鐪媡hreadStart鏂规硶鐨勪唬鐮侊細
// -------------------- Background Thread -------------------- /** * Start the background thread that will periodically check for * session timeouts. */ protected void threadStart() { if (thread != null) return; if (backgroundProcessorDelay <= 0) return; threadDone = false; String threadName = "ContainerBackgroundProcessor[" + toString() + "]"; thread = new Thread(new ContainerBackgroundProcessor(), threadName); thread.setDaemon(true); thread.start(); }
杩欓噷鍙互鐪嬪埌濡傛灉涓や釜鍓嶇疆鏍¢獙鏉′欢閫氳繃鐨勮瘽灏嗕細鍚姩涓€涓嚎绋嬶紝骞朵笖绾跨▼鐨勫悕瀛楀嵆浠? ContainerBackgroundProcessor[ "寮€澶达紝绾跨▼鍚嶅瓧鍚庨潰鍙栫殑鏄璞$殑toString鏂规硶锛屼互StandardEngine涓轰緥锛岀湅鐪媜rg.apache.catalina.core.StandardEngine鐨則oString鏂规硶瀹炵幇锛?/p>
/** * Return a String representation of this component. */ @Override public String toString() { StringBuilder sb = new StringBuilder("StandardEngine["); sb.append(getName()); sb.append("]"); return (sb.toString()); }
浠ヤ笂瑙i噴浜嗚繖涓悗鍙扮嚎绋嬬殑鏉ュ巻銆?/p>
聽
浣嗚繖閲屾湁涓€涓棶棰橈紝鏃㈢劧StandardEngine銆丼tandardHost閮戒細璋冪敤super.startInternal()鏂规硶锛屾寜榛樿閰嶇疆锛屽悗鍙扮悊搴斾骇鐢熶袱涓悗鍙扮嚎绋嬶紝瀹為檯涓轰粈涔堝彧鏈変竴涓紵
鍥炲埌org.apache.catalina.core.ContainerBase鐨則hreadStart鏂规硶锛屽湪鍚姩绾跨▼浠g爜涔嬪墠鏈変袱涓牎楠屾潯浠讹細
if (thread != null) return; if (backgroundProcessorDelay <= 0) return;
瀹瑰櫒缁勪欢瀵硅薄鍒濆鍖栨椂thread涓簄ull锛宐ackgroundProcessorDelay鏄?1
/** * The background thread. */ private Thread thread = null; /** * The processor delay for this component. */ protected int backgroundProcessorDelay = -1;
浣唎rg.apache.catalina.core.StandardEngine鍦ㄥ叾鑷韩鏋勯€犲嚱鏁颁腑鍋氫簡涓€鐐逛慨鏀癸細
public StandardEngine() { super(); pipeline.setBasic(new StandardEngineValve()); /* Set the jmvRoute using the system property jvmRoute */ try { setJvmRoute(System.getProperty("jvmRoute")); } catch(Exception ex) { log.warn(sm.getString("standardEngine.jvmRouteFail")); } // By default, the engine will hold the reloading thread backgroundProcessorDelay = 10; }
鏋勯€犲嚱鏁版渶鍚庡皢鐖剁被鐨刡ackgroundProcessorDelay鐨勫€肩敱-1鏀规垚浜?0锛屾墍浠omcat鍚姩瑙f瀽xml鏃剁鍒颁竴涓狤ngine鑺傜偣灏变細瀵瑰簲浜х敓涓€涓悗鍙板鐞嗙嚎绋嬨€?/p>
聽
璁插畬浜嗚繖涓悗鍙板鐞嗙嚎绋嬬殑浜х敓锛岀湅鐪嬭繖涓嚎绋嬫墍浣滅殑浜嬫儏锛屽啀鐪嬩笅杩欎釜绾跨▼鐨勫惎鍔ㄤ唬鐮侊細
thread = new Thread(new ContainerBackgroundProcessor(), threadName); thread.setDaemon(true); thread.start();
鎵€浠ヨ繖涓嚎绋嬪皢浼氭墽琛孋ontainerBase鐨勫唴閮ㄧ被ContainerBackgroundProcessor鐨剅un鏂规硶锛岀湅涓婥ontainerBackgroundProcessor鐨勫叏閮ㄥ疄鐜颁唬鐮侊細
/** * Private thread class to invoke the backgroundProcess method * of this container and its children after a fixed delay. */ protected class ContainerBackgroundProcessor implements Runnable { @Override public void run() { while (!threadDone) { try { Thread.sleep(backgroundProcessorDelay * 1000L); } catch (InterruptedException e) { // Ignore } if (!threadDone) { Container parent = (Container) getMappingObject(); ClassLoader cl = Thread.currentThread().getContextClassLoader(); if (parent.getLoader() != null) { cl = parent.getLoader().getClassLoader(); } processChildren(parent, cl); } } } protected void processChildren(Container container, ClassLoader cl) { try { if (container.getLoader() != null) { Thread.currentThread().setContextClassLoader (container.getLoader().getClassLoader()); } container.backgroundProcess(); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); log.error("Exception invoking periodic operation: ", t); } finally { Thread.currentThread().setContextClassLoader(cl); } Container[] children = container.findChildren(); for (int i = 0; i < children.length; i++) { if (children[i].getBackgroundProcessorDelay() <= 0) { processChildren(children[i], cl); } } } }
鍦ㄥ畠鐨剅un鏂规硶鏆傚仠涓€娈垫椂闂翠箣鍚庝細璋冪敤processChildren鏂规硶锛岃€宲rocessChildren鏂规硶鍋氫簡涓や欢浜嬶紝涓€鏄皟鐢ㄥ鍣ㄧ粍浠惰嚜韬殑backgroundProcess鏂规硶锛岃€屾槸鍙栧嚭璇ュ鍣ㄧ粍浠剁殑鎵€鏈夊瓙瀹瑰櫒缁勪欢骞惰皟鐢ㄥ畠浠殑processChildren鏂规硶銆傚綊缁撹捣鏉ヨ繖涓嚎绋嬬殑瀹炵幇灏辨槸瀹氭湡閫氳繃閫掑綊鐨勬柟寮忚皟鐢ㄥ綋鍓嶅鍣ㄥ強鍏舵墍鏈夊瓙瀹瑰櫒鐨刡ackgroundProcess鏂规硶銆?/p>
鑰岃繖涓猙ackgroundProcess鏂规硶鍦–ontainerBase鍐呴儴宸茬粡缁欏嚭浜嗗疄鐜帮細
@Override public void backgroundProcess() { if (!getState().isAvailable()) return; if (cluster != null) { try { cluster.backgroundProcess(); } catch (Exception e) { log.warn(sm.getString("containerBase.backgroundProcess.cluster", cluster), e); } } if (loader != null) { try { loader.backgroundProcess(); } catch (Exception e) { log.warn(sm.getString("containerBase.backgroundProcess.loader", loader), e); } } if (manager != null) { try { manager.backgroundProcess(); } catch (Exception e) { log.warn(sm.getString("containerBase.backgroundProcess.manager", manager), e); } } Realm realm = getRealmInternal(); if (realm != null) { try { realm.backgroundProcess(); } catch (Exception e) { log.warn(sm.getString("containerBase.backgroundProcess.realm", realm), e); } } Valve current = pipeline.getFirst(); while (current != null) { try { current.backgroundProcess(); } catch (Exception e) { log.warn(sm.getString("containerBase.backgroundProcess.valve", current), e); } current = current.getNext(); } fireLifecycleEvent(Lifecycle.PERIODIC_EVENT, null); }
杩欐浠g爜灏变笉涓€涓€瑙i噴浜嗭紝姒傛嫭璧锋潵璇村氨鏄€愪釜璋冪敤涓庡鍣ㄧ浉鍏冲叾瀹冨唴閮ㄧ粍浠剁殑backgroundProcess鏂规硶銆傛渶鍚庢敞鍐屼竴涓狶ifecycle.PERIODIC_EVENT浜嬩欢銆?/p>
聽
涓婇潰灏辨槸Tomcat7鐨勫悗鍙板鐞嗙嚎绋嬫墍浣滅殑浜嬫儏鐨勬杩帮紝鍦═omcat鐨勬棭鏈熺増鏈腑鏈変竴浜涘悗鍙板鐞嗙殑浜嬫儏鍘熸潵鏄湪鍚勪釜缁勪欢鍐呴儴鍒嗗埆鑷畾涔変竴涓嚎绋嬪苟鍚姩锛屽湪Tomcat5涓敼鎴愪簡鎵€鏈夊悗鍙板鐞嗗叡浜悓涓€绾跨▼鐨勬柟寮忋€?/p>
聽
鍥炲埌鏈枃瑕佽В绛旂殑闂锛寃eb搴旂敤濡備綍鍔犺浇鍒板鍣ㄤ腑鐨勶紵鍦–ontainerBase绫荤殑backgroundProcess鏂规硶鐨勬渶鍚庯細
fireLifecycleEvent(Lifecycle.PERIODIC_EVENT, null);
鍚戝鍣ㄦ敞鍐屼簡涓€涓狿ERIODIC_EVENT浜嬩欢銆傚墠闈㈣閬撻粯璁ょ殑ContainerBackgroundProcessor[StandardEngine[Catalina]]绾跨▼浼氬畾鏈燂紙榛樿涓?0绉掞級鎵цEngine銆丠ost銆丆ontext銆乄rapper鍚勫鍣ㄧ粍浠跺強涓庡畠浠浉鍏崇殑鍏跺畠缁勪欢鐨刡ackgroundProcess鏂规硶锛屾墍浠ヤ篃浼氬畾鏈熷悜Host缁勪欢鍙戝竷涓€涓狿ERIODIC_EVENT浜嬩欢锛岃繖閲岀湅涓婼tandardHost閮戒細鍏宠仈鐨勪竴涓洃鍚櫒org.apache.catalina.startup.HostConfig锛?/p>
鍦═omcat鍚姩瑙f瀽xml鏃秓rg.apache.catalina.startup.Catalina绫荤殑386琛岋細digester.addRuleSet(new HostRuleSet("Server/Service/Engine/"))
鍦℉ostRuleSet绫荤殑addRuleInstances鏂规硶涓細
public void addRuleInstances(Digester digester) { digester.addObjectCreate(prefix + "Host", "org.apache.catalina.core.StandardHost", "className"); digester.addSetProperties(prefix + "Host"); digester.addRule(prefix + "Host", new CopyParentClassLoaderRule()); digester.addRule(prefix + "Host", new LifecycleListenerRule ("org.apache.catalina.startup.HostConfig", "hostConfigClass")); digester.addSetNext(prefix + "Host", "addChild", "org.apache.catalina.Container");
绗?鍒?2琛岀湅鍒帮紝鎵€鏈塇ost鑺傜偣閮戒細娣诲姞涓€涓猳rg.apache.catalina.startup.HostConfig瀵硅薄浣滀负org.apache.catalina.core.StandardHost瀵硅薄鐨勭洃鍚櫒
锛夛紝鍦℉ostConfig鐨刲ifecycleEvent鏂规硶涓彲浠ョ湅鍒板鏋淗ost缁勪欢鏀跺埌浜哃ifecycle.PERIODIC_EVENT浜嬩欢鐨勫彂甯冩墍浣滃嚭鐨勫搷搴旓紙濡傛灉瀵筎omcat7鐨凩ifecycle鏈哄埗涓嶆竻妤氬彲浠ョ湅涓?a href="/blog/1920896" title="Tomcat7鍚姩鍒嗘瀽锛堜簲锛塋ifecycle鏈哄埗鍜屽疄鐜板師鐞? target="_blank">銆奣omcat7鍚姩鍒嗘瀽锛堜簲锛塋ifecycle鏈哄埗鍜屽疄鐜板師鐞嗐€?/a>锛夛細
public void lifecycleEvent(LifecycleEvent event) { // Identify the host we are associated with try { host = (Host) event.getLifecycle(); if (host instanceof StandardHost) { setCopyXML(((StandardHost) host).isCopyXML()); setDeployXML(((StandardHost) host).isDeployXML()); setUnpackWARs(((StandardHost) host).isUnpackWARs()); } } catch (ClassCastException e) { log.error(sm.getString("hostConfig.cce", event.getLifecycle()), e); return; } // Process the event that has occurred if (event.getType().equals(Lifecycle.PERIODIC_EVENT)) { check(); } else if (event.getType().equals(Lifecycle.START_EVENT)) { start(); } else if (event.getType().equals(Lifecycle.STOP_EVENT)) { stop(); } }
绗?7琛岋紝濡傛灉鍙戝竷鐨勪簨浠舵槸PERIODIC_EVENT灏嗕細鎵цcheck鏂规硶銆傜19琛岋紝濡傛灉鍙戝竷鐨勪簨浠舵槸START_EVENT鍒欐墽琛宻tart鏂规硶銆俢heck鏂规硶鍜宻tart鏂规硶鏈€鍚庨兘浼氳皟鐢╠eployApps()鏂规硶锛岀湅涓嬭繖鏂规硶鐨勫疄鐜帮細
/** * Deploy applications for any directories or WAR files that are found * in our "application root" directory. */ protected void deployApps() { File appBase = appBase(); File configBase = configBase(); String[] filteredAppPaths = filterAppPaths(appBase.list()); // Deploy XML descriptors from configBase deployDescriptors(configBase, configBase.list()); // Deploy WARs deployWARs(appBase, filteredAppPaths); // Deploy expanded folders deployDirectories(appBase, filteredAppPaths); }
杩欓噷鍗冲悇绉嶄笉鍚屾柟寮忓彂甯僿eb搴旂敤鐨勪唬鐮併€?/p>
聽
鏈枃鍓嶉潰鎻愬埌榛樿鎯呭喌涓嬬粍浠跺惎鍔ㄧ殑鏃跺€欎細鍙戝竷涓€涓狶ifecycle.START_EVENT浜嬩欢锛堝湪org.apache.catalina.core.ContainerBase绫荤殑startInternal鏂规硶鍊掓暟绗簩琛岋級锛屽洖鍒癏ostConfig鐨刲ifecycleEvent鏂规硶涓紝鎵€浠ラ粯璁ゅ惎鍔ㄦ椂灏嗕細鎵цHostConfig鐨剆tart鏂规硶锛屽湪璇ユ柟娉曠殑鏈€鍚庯細
if (host.getDeployOnStartup()) deployApps();
鍥犱负榛樿閰嶇疆host.getDeployOnStartup()杩斿洖true锛岃繖鏍峰鍣ㄥ氨浼氬湪鍚姩鐨勬椂鍊欑洿鎺ュ姞杞界浉搴旂殑web搴旂敤銆?/p>
聽
褰撶劧锛屽鏋滃湪server.xml涓璈ost鑺傜偣鐨刣eployOnStartup灞炴€ц缃负false锛屽垯瀹瑰櫒鍚姩鏃朵笉浼氬姞杞藉簲鐢紝鍚姩瀹屼箣鍚庝笉鑳界珛鍗虫彁渚泈eb搴旂敤鐨勬湇鍔°€備絾鍥犱负鏈変笂闈㈡彁鍒扮殑鍚庡彴澶勭悊绾跨▼鍦ㄨ繍琛岋紝浼氬畾鏈熸墽琛孒ostConfig鐨刢heck鏂规硶锛?/p>
/** * Check status of all webapps. */ protected void check() { if (host.getAutoDeploy()) { // Check for resources modification to trigger redeployment DeployedApplication[] apps = deployed.values().toArray(new DeployedApplication[0]); for (int i = 0; i < apps.length; i++) { if (!isServiced(apps[i].name)) checkResources(apps[i]); } // Check for old versions of applications that can now be undeployed if (host.getUndeployOldVersions()) { checkUndeploy(); } // Hotdeploy applications deployApps(); } }
濡傛灉Host鑺傜偣鐨刟utoDeploy灞炴€ф槸true锛堥粯璁よ缃嵆涓簍rue锛夛紝鍙互鐪嬪埌check鏂规硶鏈€鍚庡悓鏍蜂細鍔犺浇web搴旂敤銆?/p>