关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » JAVA »高密度Java应用部署的一些实践

    高密度Java应用部署的一些实践

    2014-08-21 00:00:00 出处:strongme.cn
    分享

    传统的Java应用部署模式,一般遵循“硬件->操作系统->JVM->Java应用”这种自底向上的部署结构,其中JEE应用可以细化为“硬件->操作系统->JVM->JEE容器->JEE应用”的部署结构。这种部署结构往往比较重,操作系统、JVM和JEE容器造成的overhead很高,而很多时候一个Java应用并不需要跑满整个硬件的资源,导致这种模式的资源利用率是比较低的。

    而另一方面,硬件虚拟化技术逐渐成熟:VMware Hypervisor、Xen、KVM、Power LPAR等技术能够帮助我们在同一个硬件上部署多个操作系统实例,而时下流行的OS Container技术如LXC、Docker等,则是把操作系统虚拟化为多个实例,实现更轻量级的虚拟化。无论哪个层面的虚拟化,其目的都是对资源利用率更加高效的追求,从而成为如今构建云计算平台底层架构的基础技术。

    Java应用也可以通过同样的思路来实现高密度的部署。JVM虚拟化是比OS虚拟化更高一层的做法,可以更大程度的提高资源利用率,降低平均应用的部署成本。ITJS的这篇文章将介绍Multi-tenant JVM这一方案实现高密度Java应用部署的一些特点和思路。

    背景介绍

    早在2004年,Sun公司就提出过Java应用虚拟化这方面的想法。当时Grzegorz Czajkowski领导了一个叫做巴塞罗那的研究项目,该项目基于Java HotSpot虚拟1.5版本开发了Multi-Tasking Virtual Machine(MVM)。MVM的目的旨在提高Java程序的启动速度,节省内存开销。不过自从Sun被甲骨文收购后,我们没有听到关于该项目的任何新的进展。

    尽管我们没有看到MVM成功产品化,不过它却留下两个JSR规范:JSR121和JSR284。对于JSR284,目前在java.net上有一个实现它的孵化项目。

    从2009年开始,我所在的IBM Java团队开始研究Java应用的SaaS化方案,即让一个应用实例服务于多个租户。为了保证多个租户在使用同一个应用实例时候数据的隔离,该方案在应用这个层面做了一些Bytecode Instrument(BCI)的工作,主要通过改写getstatic/putstatic使每个租户有独立的类的静态数据拷贝而没有相互影响。但是,该方案在Bytecode层面更改带来的额外性能开销, 以及Java Reflection等访问带来的安全性/正确性的问题。 而且,除了数据上的隔离,也需要针对关键性的资源譬如CPU、Heap、IO等资源的使用进行管理,于是该方案下沉到了JVM层面,形成现在的多租户JVM(Multi-tenant JVM)方案。

    Multi-tenant JVM是JVM层面的虚拟化,其思路是把多个Java应用部署在同一个JVM上,让这些应用共享底层的GC、JIT、Java运行时库等基础组件。除了IBM的团队之外,爱尔兰的Waratek公司也实现了多租户的JVM。和IBM Multi-tenant JVM类似,Waratek允许多个应用运行在同一个CloudVM上,每一个应用运行在一个叫Java Virtual Container(JVC)的容器里。从现有公开的资料开看,IBM Multi-tenant JVM是基于Java 7的,而Waratek是基于Java 6的,两者支持的CPU架构和平台也有所不同。

    此外,JEE方面在两年前也有讨论计划增加对PaaS和多租户的支持,这项提议旨在定义PaaS环境下如何使得JEE应用支持多租户,保证不同租户在使用这些应用时相互隔离,以及资源方面的管理(如JMS资源),不过该项提议已经推迟到JEE 8。

    除了提升部署密度之外,多租户的另一项好处在于应用启动的加速。快速的程序启动受益于不同的应用共享同一个JVM,我们称之为javad。Java核心的类库在javad运行后,不再需要被重新装载和定义。你也许可以用Nailgun来加速你的启动时间,但Nailgun的问题是没有安全的数据隔离,这包括类的静态数据以及Java属性值,而且Nailgun在易用性等方面也不如Multi-tenent JVM。

    多租户JVM的实现思路

    跟传统JVM相比,多租户JVM的主要工作围绕隔离而进行,其针对JVM/JDK的改动主要实现三个方面的目标:

    租户之间的数据隔离 Java类库支持多租户语境 资源管理隔离

    租户之间的数据隔离

    让每个租户应用拥有独立的类静态数据拷贝,这个目标主要通过修改getstatic/putstatic字节码指令实现。下面是一个简单的例子:

    public class HelloWorld {
        public static void main(String[] args) {
            System.out.println("Hello World!");
        }
    }

    每一个运行在Multi-tenant JVM上的程序都有不同System.out实例。就java.lnag.System内部实现来说,out是其类静态变量:

    public final class System {
    
        // The standard input, output, and error streams.
        // Typically, these are connected to the shell which
        // ran the Java program.
        /**
         * Default input stream
         */
        public static final InputStream in = null;
        /**
         * Default output stream
         */
        public static final PrintStream out = null;
        /**
         * Default error output stream
         */
        public static final PrintStream err = null;
    ……
    }

    Multi-tenant JVM对于标准的JVM行为进行的更改如下:

    每一个租户第一次使用java/lang/System时,都会触发它的初始化,也就是<clinit>。而一般的JVM,java/lang/System只会被初始化一次。 <clinit>的执行,对于每一个静态成员变量存取,都被重新定向到了具体的租户存贮空间。比如对于out = null赋值,putstatic执行时实际上会找到当前的租户,然后把值存到该租户的空间去 ,getstatic有着类似的道理。

    Java类库支持多租户语境

    这部分主要通过改造类库实现,具体的功能包括:

    System.exit(code) 调用只会使当前租户退出,而不会令整个JVM退出。而租户申请的一些诸如File/Socket句柄之类系统资源,会随着租户的推出而被释放。 租户A不可能通过类似如下
    ThreadGroup group = Thread.currentThread().getThreadGroup();
    ThreadGroup parent = group.getParent();

    枚举线程的办法获得租户B的线程。不同租户的线程分属于不同的线程组。

    Java属性值的隔离,比如同样的语句System.getProperty(“name”)对于不同的租户可能是不同的值。

    资源管理隔离

    这是Multi-tenant JVM很重要的功能。在Multi-tenant JVM上,Heap/CPU/Disk IO/Net IO这些资源的使用是受资源策略保护的,比如你可以去限制某个租户它的CPU最少可以使用20%,而在系统空闲时,最大可以用到100%。

    Multi-tenant JVM通过Token Bucket来对IO(Disk/Net)和CPU资源进行管理。对于IO而言,Multi-tenant JVM截获IO有关的OS API调用,使得IO发生之前受制于我们预先规定的资源策略。我们举个网络IO的例子,例如Java程序从Socket的读取操作,JDK内部的实现通过JNI实际上会对应到系统的API调用

    ssize_t recv(int sockfd, void *buf, size_t len, int flags);

    在recv调用发生之前,Multi-tenant JVM通过资源策略保证租户的IO使用带宽不会超过给它设定的限制。关于网络IO,我们这里有一个很好的演示:

    用简单的-Xlimit:netIO=6M参数限制运行在Multi-tenant JVM上的Ftp Server带宽上限读写各为6Mib/s。

    关于对CPU管理,Multi-tenant JVM实现的基本的思路是,把租户线程所花费的CPU时间量化为Tokens,运行时每一个租户线程都会被周期性检查是否其当前CPU时间的使用超过了给它设定的限制。如果超过,当前线程会被挂起,直到满足限制为止。周期性检查的代码是由Multi-tenant JVM插入到租户线程里去的,对于用户程序而言完全是透明的。

    Multi-tenant JVM对于Heap的管理建立在Balanced GC Policy基础之上。同一般的Java程序类似,你可以使用-Xms/-Xmx为租户程序设定最大/最小的堆内存值。Balanced GC Policy基于Region对Heap进行管理,每个租户程序根据-Xms/-Xmx的设定来为其分配Region,而租户对象的分配也必然只能发生在它自己拥有的区域内。

    多租户JVM的用法与限制

    IBM发布的Java 7 R1默认支持多租户JVM,在命令行上添加-Xmt参数即可启用。由于多租户JVM对JVM的变更,JNI Native Libraries、JVMTI以及GUI programs在多租户状态下的使用是受限制的。Multi-tenant JVM并未实现对JNI的隔离,所以不同的租户应用不能装载依赖同样的JNI Native Lib,所有发生在JNI Native Lib里的IO,不会受限于该租户资源消费策略。同样的情况适用于CPU以及Memory。

    Multi-tenant JVM目前没有实现对JVMTI Agent的改造用以支持我们前面所描述的静态数据的隔离,这可能会对用户如果想调试Java核心类库代码(不是用户代码)造成困扰。

    关于GUI,Multi-tenant JVM没有实现底层对于UI程序消息队列的隔离,所以不支持在同一个Multi-tenant JVM运行大于1个的GUI程序。

    还有一点,不要在非Daemon线程里写 “暴力”的死循环代码,例如:

    while(true)
    {  
    try () {
        ....
    } catch(Throwable t) {
    {
    }
    
    }

    最后需要注意的是,当开启IO资源控制时,尽量一次写出更多的字节,避免影响程序的IO性能。

    总结

    Multi-tenant JVM目前在应用启动时间和更小的内存占用开销方面已经被证实有效。根据目前的一些基准测试结果来看,对于简单的应用,相较于一般JVM,Multi-tenant JVM可以获得5~6倍的运行个数。后续计划发布的版本仍然会集中在提高启动时间、更小的内存开销这两个方面,也会陆续有一些性能的报告发布。

    长远来看,Multi-tenant JVM会基于用户、IBM产品线以及技术社区等的反馈,做进一步的提高,以及解决一些目前所存在的局限性,比如对于JNI隔离的支持,JVMTi的多租户支持等等。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    商业智能成CIO优先关注点 技术落地方显成效(1)

    用linux安装MySQL时产生问题破解

    JAVA中关于Map的九大问题

    windows 7旗舰版无法使用远程登录如何开启telnet服务

    Android View 事件分发机制详解

    MySQL用户变量的用法

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。