【转】并行类加载——让tomcat玩转双十一 @双十一实战
原文:https://yq.aliyun.com/articles/4227?spm=5176.100239.yqblog1.20.cfRztB
摘要: 今年双十一,是应用容器的最新版本Ali-tomcat 7.0.59.x应对的第一次双十一。这个版本包含的一个主要功能是并行类加载,本文主要对并行类加载在双十一期间的支持做一个总结。 并行类加载在双十一期间最主要的业务系统,在双十一期间支撑了每秒14w订单创建,是一个非常了不起的成绩!
今年双十一,是应用容器的最新版本Ali-tomcat 7.0.59.x应对的第一次双十一。这个版本包含的一个主要功能是并行类加载,本文主要对并行类加载在双十一期间的支持做一个总结。
并行类加载在双十一期间最主要的业务系统,在双十一期间支撑了每秒14w订单创建,是一个非常了不起的成绩!
业务背景
由于各种原因,该业务系统比较庞大,依赖较为复杂。为了解决业务复杂性,应用引入了模块化系统,通过模块化的方式抽象出一系列的bundle,而bundle之间互相隔离,享有独立的类加载器。
由于bundle之间相互隔离,我们自然就会想到,是否能够在应用启动时多线程并行的初始化这些bundle呢?
原来的应用运行在JDK6上,Tomcat启动的时候,应用的Classloader(WebappClassLoader)在进行类加载的时候是顺序加载的,因为JDK6上Classloader.loadClass(String name)这个方法是synchonized的,如果应用里面有多个线程在同时调用loadClass方法进行类加载的话,那么锁的竞争将会非常激烈。
大家知道在JDK7上,如果调用Classloader.registerAsParallelCapable方法,则会开启并行类加载功能,把锁的级别从ClassLoader对象本身,降低为要加载的类名这个级别。换句话说只要多线程加载的不是同一个类的话,loadClass方法都不会锁住。遗憾的是,开启并行类加载必须要求一个类加载器继承链路上所有类加载器都调用registerAsParallelCapable,但tomcat7自带的WebappClassLoader并没有调用registerAsParallelCapable,所以老版本的tomcat7即使运行在JDK7上,也无法利用并行类加载的特性。
实现原理
从Ali-tomcat 7.0.59.2版本开始解决了这个问题,支持在WebappClassLoader中打开registerAsParallelCapable方法。但是情况没有那么简单,还需要解决的一个问题是如何兼容JDK6的问题,因为tomcat7.x版本是基于JDK6编译,同时运行在JDK6和JDK7+以上的。JDK6下是没有Classloader.registerAsParallelCapable这个方法的,所以JDK6下必须保持原有的行为,在JDK7下才能支持并行类加载功能。也就是说,即使用户配置了并行类加载,那么tomcat也必须根据运行时的JDK版本来决定是否开启并行类加载功能。Ali-tomcat通过反射机制解决了这个问题,在运行时刻对应用的WebappClassLoader尝试注册并行类加载功能,当发现没有这个方法时,会自动fall back到普通的类加载,也就是线性类加载功能。
并行类加载体系结构

可以看到,实际运行过程中,tomcat会自动根据JDK版本来选择是否启用并行类加载功能。当然这项功能默认是关闭的,需要用户通过配置文件显示开启。
双十一应用实际运行数据

我们看到在实际线上机器的启动时间上,当开启并行类加载功能后,模块化系统的启动时间提升了47%,应用整体启动时间提升了29%!
配置方式
- 确认tomcat的运行环境是JRE7及以上。
- 安装ali-tomcat 7.0.59.3版本
sudo yum install -b current taobao-tomcat-7.0.59.3
3.修改/home/admin/$APP/conf/tomcat/context.xml,如果这个文件不存在,则从/opt/taobao/tomcat/conf/context.xml拷贝一份。添加如下配置:
<Loader loaderClass="org.apache.catalina.loader.ParallelWebappClassLoader" />
4.重启Tomcat
5.成功启动后,应该会在控制台看到类似如下的日志:
6. 2015-10-12 14:22:50,444 org.apache.catalina.loader.ParallelWebappClassLoader <clinit>
INFO: ParallelWebappClassLoader registration succeeded.
开源社区贡献
并行类加载功能已经在捐献给Apache tomcat社区,并且被社区接受,在最新的Apache tomcat 7.0.65版本中已经包含该项功能。

结语
并行类加载功能在模块化业务应用,以及合并部署等等场景下对于性能有较大提升。后续Ali-tomcat会在开发体验,监控诊断等方面继续发力,帮助业务系统提升开发诊断效率!
【转】并行类加载——让tomcat玩转双十一 @双十一实战的更多相关文章
- 并行类加载与OSGI类加载
这回来分析一下OSGI的类加载机制. 先说一下OSGI能解决什么问题吧. 记得在上家公司的时候,经常参与上线.上线一般都是增加了一些功能或者修改了一些功能,然后将所有的代码重新部署.过程中要将之前的服 ...
- 转:手把手教你如何玩转Solr(包含项目实战)
原文地址:手把手教你如何玩转Solr(包含项目实战) 参考原文
- java类加载器-Tomcat类加载器
在上文中,已经介绍了系统类加载器以及类加载器的相关机制,还自定制类加载器的方式.接下来就以tomcat6为例看看tomat是如何使用自定制类加载器的.(本介绍是基于tomcat6.0.41,不同版本可 ...
- 手把手教你如何玩转Solr(包含项目实战)
一:Solr简介 Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口.用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引 ...
- Docker竟然还能这么玩?商业级4G代理搭建实战!
时间过得真快,距离这个系列的上一篇文章<商业级4G代理搭建指南[准备篇]>发布的时间已经过了两个星期了,上个星期由于各种琐事缠身,周二开始就没空写文章了,所以就咕咕咕了. 那么在准备篇中, ...
- Tomcat类加载器
1JVM类加载机制 JVM的ClassLoader通过Parent属性定义父子关系,可以形成树状结构.其中引导类.扩展类.系统类三个加载器是JVM内置的. 它们的作用分别是: 1)引导类加载器:使 ...
- 深入剖析Tomcat类加载机制
1JVM类加载机制 JVM的ClassLoader通过Parent属性定义父子关系,可以形成树状结构.其中引导类.扩展类.系统类三个加载器是JVM内置的. 它们的作用分别是: 1)引导类加载器:使用n ...
- Tomcat系列(7)——Tomcat类加载机制
1. 核心部分 1. 类加载器: 通过一个类的全限定名来获取描述此类的二进制字节流. 对于任意一个类,都需要由加载他的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一 ...
- 图解Tomcat类加载机制(阿里面试题)
Tomcat的类加载机制是违反了双亲委托原则的,对于一些未加载的非基础类(Object,String等),各个web应用自己的类加载器(WebAppClassLoader)会优先加载,加载不到时再交给 ...
随机推荐
- 龙珠超的新OP【限界突破×サバイバー】
这首歌真的很燃 下载>> 限界突破×サバイバー 中文歌词 演唱:冰川清志 兴奋了!就去宇宙吧 最先端的“着迷”怎么样! 握在手中 突然想要大笑 糊里糊涂也习惯了吗! I can't g ...
- C#文本框允许使用ctrl+A
C#文本框中默认是不允许使用全选的.可以通过以下事件完成: private void textBox1_KeyDown(object sender, KeyEventArgs e) { if (e.C ...
- PHP静态成员变量
静态成员:静态类中的成员加入static修饰符,即是静态成员.可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员不能访问非静态的成员.. ...
- [个人翻译]Redis 集群教程(下)
[个人翻译]Redis 集群教程(上) [个人翻译]Redis 集群教程(中) 官方原文地址:https://redis.io/topics/cluster-tutorial 水平有限,如果您在阅读过 ...
- Array方法归类总结
数组的转换方法 valueOf()方法,数组调用该方法后返回的还是原来的数组. toString()方法,数组调用该方法后会调用每一项的toStirng()方法,之后将每一项拼接成一个以逗号分割的字符 ...
- BZOJ 2142: 礼物
模非素数下的排列组合,简直凶残 调着调着就过了= = 都不知道怎么过的= = 直接上链接http://hi.baidu.com/aekdycoin/blog/item/147620832b567eb4 ...
- 解析令人费解的java泛型
对于我们java中的泛型,可能很多人知道怎么使用并且使用的还不错,但是我认为想要恰到好处的使用泛型,还是需要深入的了解一下它的各种概念和内部原理.本文将尽可能的囊括java泛型中的重要的概念.主要内容 ...
- 前端总结·基础篇·CSS(二)视觉
前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·CSS(四)兼容 目录 一.动画(animation)(IE ...
- hibernate切换数据源
起因: 公司的当前产品,主要是两个项目集成的,一个是java项目,还有一个是php项目,两个项目用的是不同的数据源,但都是mysql数据库,因为java这边的开发工作已经基本完成了,而php那边任务还 ...
- 【转】简单的java缓存实现
本文转自 http://my.oschina.net/u/866190/blog/188712 提到缓存,不得不提就是缓存算法(淘汰算法),常见算法有LRU.LFU和FIFO等算法,每种算法各有各的优 ...