Tomcat7涓瓀eb搴旂敤鍔犺浇鍘熺悊锛堜竴锛塁ontext鏋勫徐

Tomcat7涓瓀eb搴旂敤鍔犺浇鍘熺悊锛堜竴锛塁ontext鏋勫缓

涓轰粈涔堝叧蹇僒omcat涓竴涓獁eb搴旂敤鐨勫姞杞借繃绋嬶紵鍦ㄥ墠闈㈢殑鏂囩珷涓湅杩囧娆omcat鐨勭粍浠剁粨鏋勫浘锛岃繖閲屽啀璐村嚭鏉ュ洖椤句竴涓嬶細

Tomcat7涓瓀eb搴旂敤鍔犺浇鍘熺悊锛堜竴锛塁ontext鏋勫徐
涔嬪墠鐨勩€奣omcat7鍚姩鍒嗘瀽銆嬬郴鍒楁枃绔犱腑鐪嬪埌Tomcat鍚姩鐨勬椂鍊欏皢浼氳В鏋恠erver.xml锛屾牴鎹噷闈㈡墍閰嶇疆鐨勫悇涓妭鐐逛俊鎭€愪竴鍒濆鍖栧拰鍚姩鐩稿簲缁勪欢锛堝嵆鍒嗗埆璋冪敤瀹冧滑鐨刬nit鍜宻tart鏂规硶锛夛紝浣嗘祻瑙堜竴涓婽omcat7婧愮爜涓殑server.xml鐨勫唴瀹癸紝閲岄潰瀵瑰簲涓婂浘涓殑宸茬粡榛樿閰嶇疆鐨勫悇绾х粍浠跺寘鎷琒erver銆丼ervice銆丒ngine銆丆onnector銆丠ost銆乂alve銆備笂鍥句腑鐨凜ontext缁勪欢瀹為檯灏辨槸鎴戜滑閫氬父鎵€璇寸殑涓€涓獁eb搴旂敤锛屾湁瓒g殑鏄湪server.xml涓苟娌℃湁閰嶇疆璇ョ粍浠讹紝鑰屾垜浠粯璁ゅ惎鍔ㄧ殑鏃跺€欏疄闄呬笂宸茬粡鏈夊ソ鍑犱釜web搴旂敤鍙互璁块棶浜嗭細

Tomcat7涓瓀eb搴旂敤鍔犺浇鍘熺悊锛堜竴锛塁ontext鏋勫徐
杩欎釜鍒板簳鏄€庝箞鍥炰簨锛?/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>

Tomcat7涓瓀eb搴旂敤鍔犺浇鍘熺悊锛堜竴锛塁ontext鏋勫徐
鍓嶉潰鐨勫嚑绡囨枃绔犱腑娑夊強浜唌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>