The principle Tomcat hot deployment

On principle Tomcat hot deployment

   The principle of hot deployment tomcat: tomcat start when there will start a thread from time to time will be to judge (the total number of class changes, modifications class) whether the application of political reform in the loaded class happen if the change will apply to the start of the thread to stop off, clear the reference, and to load the application WebappClassLoader set to null, and then create a new WebappClassLoader to reload the application. tomcat after the hot deployment timing diagram found in a series of class political reform to stop the work to be done as follows:


 

 

    The timing chart above, only the critical flow of steps drawn out, there are some details of the deal are not fully drawn, inherited the structure of this part of the code is quite complex, debug the above process, when all kinds of jumps. First explain the timing diagram above, the timing diagram is from WebappLoader of backgroundProcess () method begins, backgroundProcess () thread is over when starting tomcat in a method which is the entry code of tomcat hot deployment. One of the most critical steps. It is WebappLoader of stopInternal () method and WebappClassLoader the stop () method. In WebappLoader of stopInternal () in

protected void stopInternal() throws LifecycleException {
…..
// Throw away our current class loader
((Lifecycle) classLoader).stop();
……..
classLoader = null;
}

    In ((Lifecycle) classLoader) .stop (); WebappClassLoader are examples of the classLoader. That is called WebappClassLoader the stop () method. as follows:

Copy the code
public void stop() throws LifecycleException {
    // Clearing references should be done before setting started to // false, due to possible side effects  clearReferences(); started = false; int length = files.length; for (int i = 0; i < length; i++) { files[i] = null; } length = jarFiles.length; for (int i = 0; i < length; i++) { try { if (jarFiles[i] != null) { jarFiles[i].close(); } } catch (IOException e) { // Ignore  } jarFiles[i] = null; } notFoundResources.clear(); resourceEntries.clear(); resources = null; repositories = null; repositoryURLs = null; files = null; jarFiles = null; jarRealFiles = null; jarPath = null; jarNames = null; lastModifiedDates = null; paths = null; hasExternalRepositories = false; parent = null; permissionList.clear(); loaderPC.clear(); if (loaderDir != null) { deleteDir(loaderDir); } }
Copy the code

 


    We can see the stop () method to do a lot of work to remove references. Wherein clearReferences () in

Copy the code
  protected void clearReferences() {
// De-register any remaining JDBC drivers
 clearReferencesJdbc(); // Stop any threads the web application started  clearReferencesThreads(); // Check for leaks triggered by ThreadLocals loaded by this class loader  checkThreadLocalsForLeaks(); // Clear RMI Targets loaded by this class loader  clearReferencesRmiTargets(); // Null out any static or final fields from loaded classes, // as a workaround for apparent garbage collection bugs if (clearReferencesStatic) { clearReferencesStaticFinal(); } // Clear the IntrospectionUtils cache.  IntrospectionUtils.clear(); // Clear the classloader reference in common-logging if (clearReferencesLogFactoryRelease) { org.apache.juli.logging.LogFactory.release(this); } // Clear the resource bundle cache // This shouldn’t be necessary, the cache uses weak references but // it has caused leaks. Oddly, using the leak detection code in // standard host allows the class loader to be GC’d. This has been seen // on Sun but not IBM JREs. Maybe a bug in Sun’s GC impl?  clearReferencesResourceBundles(); // Clear the classloader reference in the VM’s bean introspector  java.beans.Introspector.flushCaches(); }
Copy the code

 


    还进行了清除应用线程等工作。最后在WebappClassLoader的stopInternal()方法中执行了 classLoader = null; 那这个类加载器的实例就没有被引用了。 最后调用WebappLoader中的startInternal()方法,创建新的WebappClassLoader实例,然后开始重新加载应用。到此tomcat的热部署流程就完成了。

浅谈Tomcat热部署原理

   tomcat的热部署实现原理:tomcat启动的时候会有启动一个线程每隔一段时间会去判断应用中加载的类是否发生变法(类总数的变化,类的修改),如果发生了变化就会把应用的启动的线程停止掉,清除引用,并且把加载该应用的WebappClassLoader设为null,然后创建一个新的WebappClassLoader来重新加载应用。 tomcat中热部署发现类变法之后要做的一系列停止工作的时序图如下:


 

 

    上面时序图中只把关键的流转步骤画出来了,还有一些细节的处理没有完全画出来,这部分代码的继承的结构还是比较复杂的,debug上面的流程的时候,各种跳转。先解释一下上面的时序图,这个时序图是从WebappLoader的backgroundProcess()方法开始的,backgroundProcess()就是随tomcat启动的时候启动的线程中其中的一方法,是tomcat热部署代码的入口。 其中最关键的两步。就是WebappLoader的stopInternal()方法和WebappClassLoader的stop()方法。 在WebappLoader的stopInternal()中

protected void stopInternal() throws LifecycleException {
…..
// Throw away our current class loader
((Lifecycle) classLoader).stop();
……..
classLoader = null;
}

    在 ((Lifecycle) classLoader).stop(); 中classLoader是WebappClassLoader的实例。也就是调用了WebappClassLoader的stop()方法。如下:

Copy the code
public void stop() throws LifecycleException {
    // Clearing references should be done before setting started to // false, due to possible side effects  clearReferences(); started = false; int length = files.length; for (int i = 0; i < length; i++) { files[i] = null; } length = jarFiles.length; for (int i = 0; i < length; i++) { try { if (jarFiles[i] != null) { jarFiles[i].close(); } } catch (IOException e) { // Ignore  } jarFiles[i] = null; } notFoundResources.clear(); resourceEntries.clear(); resources = null; repositories = null; repositoryURLs = null; files = null; jarFiles = null; jarRealFiles = null; jarPath = null; jarNames = null; lastModifiedDates = null; paths = null; hasExternalRepositories = false; parent = null; permissionList.clear(); loaderPC.clear(); if (loaderDir != null) { deleteDir(loaderDir); } }
Copy the code

 


    可以看到stop()方法做了很多清除引用的工作。其中 clearReferences() 中

Copy the code
  protected void clearReferences() {
// De-register any remaining JDBC drivers
 clearReferencesJdbc(); // Stop any threads the web application started  clearReferencesThreads(); // Check for leaks triggered by ThreadLocals loaded by this class loader  checkThreadLocalsForLeaks(); // Clear RMI Targets loaded by this class loader  clearReferencesRmiTargets(); // Null out any static or final fields from loaded classes, // as a workaround for apparent garbage collection bugs if (clearReferencesStatic) { clearReferencesStaticFinal(); } // Clear the IntrospectionUtils cache.  IntrospectionUtils.clear(); // Clear the classloader reference in common-logging if (clearReferencesLogFactoryRelease) { org.apache.juli.logging.LogFactory.release(this); } // Clear the resource bundle cache // This shouldn’t be necessary, the cache uses weak references but // it has caused leaks. Oddly, using the leak detection code in // standard host allows the class loader to be GC’d. This has been seen // on Sun but not IBM JREs. Maybe a bug in Sun’s GC impl?  clearReferencesResourceBundles(); // Clear the classloader reference in the VM’s bean introspector  java.beans.Introspector.flushCaches(); }
Copy the code

 


    Also a clear application threads and so on. Finally () method is executed in classLoader = null WebappClassLoader of stopInternal; instance of the class loader that is not being referenced. The last call startInternal WebappLoader in () method, create a new instance of WebappClassLoader, then began to reload the application. This heat tomcat deployment process is complete.

Guess you like

Origin www.cnblogs.com/yuanjia2717/p/11279312.html