小研究 - 多租户Java虚拟机的设计与实现(二)

news2024/11/25 1:01:06

多租户技术,让一个软件实例同时服务于不同的组织,在云计算环境中被广泛运用,极大的节约了基础设施资源。但是,云计算环境中使用最广的Java语言却没有提供相应的多租户功能。为此,云服务提供商不得不对自己的应用服务器进行虚拟化,以此来提供多租户功能。但是这也使得用户必须修改应用来适应各个云服务提供商的多租户技术,增加了工作量,也使得同一个应用无法在不同的云计算平台上使用。因此,为标准Java虚拟机(JVM)添加多租户功能已经变得尤为迫切,让任何Java应用可以不做任何修改,直接实现多租户的功能。

目录

2  技术综述

2.1  多租户技术

2.2  JSR 121

2.3  JSR 284

2.4  JVM的垃圾回收

2.5  本章小结


2  技术综述

2.1  多租户技术

多租户技术是一种软件体系架构设计,目前主要的多租户应用主要是用于软件即服务的应用程序中。在云计算服务中,资源是具有高度可伸缩性的,资源的分配的是由实际环境中,根据应用的实际使用来决定的。而多租户技术则是探讨和实现在基于相同的用户环境和应用程序下,如何确保多租户的各自程序能正常运行以及各用户间的数据的隔离。

多租户技术其实可以看作是一种对应用程序的虚拟化,是多个组织(租户)共同使用一个应用程序实例,但是每一个租户在数据集和配置方面有相应的虚拟划分。通过多租户技术可以达到表面上看每个租户都运行的是一个自我定制的应用,实际是多个租户使用的是运行在同一台服务器上的同一个应用程序实例。基础架构层的多租户结构是一种最简单的软件栈(software stack)概念,一个栈对应了一个租户。从最底层的硬件到最上面的应用程序层,多租户概念存在于软件栈的各个层面。在不同的软件栈层面,它代表了不同的部署密度,所以在不同的场景中,决策者需要选择不同的多租户策略。

 

图2.1和图2.2显示了在不同软件栈层里的多租户的实现。层级越高,整个软件架构中涉及到的用户配置信息更多,同时其部署维护代价更小,但开发成本相应增加,层级越低的多租户场景与之相反。SO 到 S1 反应了软件架构的共享粒度越来越大,而隔离性却越来越差。

SO:单例情况,完全运行在独立的环境中,没有任何共享部分。

S1:多操作系统,通过虚拟技术,在一台硬件上虚拟出多个操作系统。这里共享的是硬件资源。

S2:多软件栈,多个租户在同一个服务器上运行完全独立的相同应用,每个应用的所属的软件栈都完全不同。共享的是操作系统和硬件资源。

S3:多应用实例,多个租户的应用所属的软件栈底层部分相同,如中间件,数据库一致。这里共享的是数据库,中间件以下的部分。其中共享数据库是指数据库资源,但其中租户的数据集在数据库是以不同分库的形式来达到完全隔离的。

S4:多租户,这里是指支持多租户的应用,但数据集是分开的。

S5:共享多租户,这种形式不仅包含了多租户应用,其它各租户的数据
集也是放在一起的。

多租户的技术不仅为租户带来了方便,也为云计算服务提供商降低了成本,其主要的优势表现在以下几个方面:

1、以服务的形式来提供软件,比起自身维护一套独立的系统成本更低。

2、部署更简洁,启动和运行更快,同时迭代更新更快,更容易。

3、让租户专注于自身服务的质量,而不是应用运行环境。

4、资源共享,减少资源浪费,节约成本。

5、租户使用同共享的环境,方便提供商管理,维护和升级。

2.2  JSR 121

JSR121规范中定义了一套API来隔离应用,使得同时在一个JVM上运行。

通常情况下,一个Java应用程序有一个JRE (Java运行时环境)与之相对应。每一个Java应用对应一个独立的OS进程,多个Java进程通过进程实现完全独立,一个Java进程崩溃了,其它进程不会受到影响。而与通常情况不一样的是,JSR121定义的是多个Java应用运行在一个JRE里,即只存在一个唯一的Java进程,共享一个JVM。图2.3展现了JSR121所定义的多租户环境。

在JSR121中,每一个运行的Java应用被称为一个Isolate,所有Isolate共享同一个JRE, Isolate之间是相互隔离的,它们有各自的生命周期,在运行逻辑中是彼此不受影响。

Java本身是支持多任务,一般情况下, Java的多任务是指多个线程通过调用不同的应用的main()函数。JSR121所定义的JVM在这种情况下,还需要做到以下四点:

1、隔离性:每个租户的应用必须有自己的VM环境。多个租户的应用环境不会相互影响。JSR121允许每个Isolate共享所有JDK的基类,但是不允许Isolate通过这些基类来共享彼此的数据集。它保证了每个Isolate的基本属性是独立,比如静态变量, AWT线程,结束钩子(shutdown hook),Properties,I/O 等。

2、 可靠的终止:当一个租户的应用出错停止里, JVM能够有效的停止该应用,并能回收相应的资源。与线程的stop(), interrup()不一样,提供System.exit()和 System.halt()来实现 Runtime.exit()和 Runtime.halt()。

3、高效:减少资源使用的冗余,在多租户的应用之间最大限度的进行共享。资源的共享主要是指在应用启动过程中的共享,尤其是对JDK基类的共享。Java 5最少需要128M的RAM, JVM启动过程所需的库与系统的核心类占了所消耗的内存大部分。

JSR121中没有明确要求需要实现对JNI (本地接口)的隔离,也就是说JSR121定义的隔离级别主要是指在Java部分。

2.3  JSR 284

JSR284定义了一套在JSR121里没有涉及到的资源管理规范,以此来实现一种“虚拟的 Java虚拟机”,可以说 JSR284 是 JSR121 的一种补充。JSR284规范定义了在一个 JVM 实例上,实现对多个 Java 应用(即 JSR121 里定义的Isolate)进行资源的管理和控制。

JSR284中提到的虚拟与虚拟机中的虚拟概念一致,同样都是把资源分配给虚拟的用户,只是具体谁来负责资源的管理不同,虚拟机(如XEN)则是交给虚拟监视器(Hypervisor,一种运行在基础物理服务器与操作系统之间的是中间件层,可允许多个操作和应用共享硬件资源)来负责的,而JSR284 中定义负责资源管理的是 JVM.JSR284 规范中定义让 JVM 来管理资源,一是方便用户通过Java接口管理不同平台的资源,二是对Java应用更有针对性,比如它可以实现对JVM内存区域中某个应用所使用的HEAP时间进行管理。当然, JSR284中只明确要求必须实现对CPU使用时间的管理,其它资源没有做具体要求。但是它提供了一套框架来实现资源的管理和监控。下面对JSR284 涉及到的重要概念进行简要说明。

1.粒度
JSR284定义的控制级别是基于线程级别的,有别于通常情况下基于进程级别的管理。基于线程级别的资源管理在云计算环境中十分有必要,因为很多时候在一个JVM实例中,可能某个租户的应用在过分消耗某种资源,而导致其它租户的应用无法申请相关资源,从而应用被挂起。针对一个JVM进程实例,常用的进程级别的资源管理是无法深入到JVM内部进行管理和监控的。

2. 资源抽象

JSR284只是定义一套最基本的,用来管理资源的机制。它只是一个高层设计思想,允许开发者对其进行二次开发,以实现具体的如何对各种资源的管理和控制。JSR284 对核心的资源管理接口进行抽象定义。

1)资源域(ResourceDomain)

将资源的使用策略封装在域中,一个资源域包括了一个特定的资源,一组与该资源相关的资源消费者以及相关的消费策略。

2)资源属性(ResourceAttributes)

资源属性接口中描述了相关的RCM属性,包括:

a、disposable (可重用),是指一个资源在被使用后能被返回到资源池中再次被重用,比如JDBC连接。
b、unbounded (无界),当某个资源数量没有特定的限定值时,便称为它是无界的,如CPU资源, 1O资源等,但是内存,文件句柄就是有界的。

c、reservable (预留),针对有界的资源,为了下一个资源请求,可能会先预留一定量的资源。

这三个属性的关系是:无界的资源不可能是预留的;如果一个资源是可重用的,那么它不可能是无界的。JSR284中还定义了其它属性,如Granularity(粒度,资源的基本单位,如内存的粒度字节)等。

3)约束控制(Constraints)与通知(Notifications)

约束控制是指当一个资源请求被调用后的一个反馈。约束控制是与资源域绑定在一起的。而通知则是当一个资源请求被处理后的一个反馈。通知比约束控制在活动周期上更靠后,后者是请求处理前,提供一个preConsume()方法,前者是请求处理后结束时才会的,提供一个postConsume()方法。

2.4  JVM的垃圾回收

Java不同与其它语言,内存的分配与管理工作不需要程序员来关心,是JVM自动完成的。垃圾回收目的是释放那些不用的内存,防止应用程序因为Java堆内存不足,导致不能创建新的对象,从而发生内存溢出(OutOfMemory,OOM)错误退出。垃圾回收是针对那些死对象的,即没有引用指向的对象,但是不是当对象刚死就立即进行回收, JVM会选择一个合适的时刻进行垃圾回收,但可以确定的是死对象最后肯定是会被回收的。下面对垃圾回收中比较重要的概念和常用回收算法进行简要阐述。

1. 对象的状态

1)可达态

是指一个对象创建后,有一个以上的引用指向它,在Java堆中,可以从根出发经过有限的路径访问到该对象,即可称该对象处于可达态。注意,这里是指从根出发。如果对象有引用指向,但却无法从根进行访问,如孤立的循环引用,这种对象也不可称为可达态。

2) 可恢复态

当一个对象不再有任何引用指向它时,它先进入可恢复态。此时处于垃圾回收的准备阶段,如果垃圾回收器进行资源整理后(即调用finalize()方法),有一个以上的引用重新指向它,那么该应用重新变成可达态,否则为不可达态。

3) 不可达态

当垃圾回收器进行资源整理后仍没有引用的指向的对象是为处于不可达态。不可达态的对象为垃圾回收器回收的对象。

2. 主要的垃圾回收形式

1) 引用计数回收器

引用计数回收器会被每个Java堆中的Java对象进行跟踪,一旦发现其被引用了,则其引用计数加一,当引用销毁时减一。如果一个对象的引用计数为零,则表明没有任何引用指向。所以当发现一个对象的引用计数为零时,可以立即进行垃圾回收。但缺陷是需要维护一个大数据集也记录对象的引用数量,对内存是一个消耗。另外对于循环引用,可能会造成计数永远不为零,使得造成一定的内存泄露。

2) 引用跟踪回收器

引用跟踪回收器,是从初始存活对象出发,通过遍历引用建立可达堆,所有遍历到的对象则是可达态对象,整个Java堆中除了可达堆以外的部分则是不可达的,垃圾回收器则回收这部分对象。因为计数的缺陷,所以目前大部分的垃圾回收器都是采用的引用跟踪方式。

3. 常用的垃圾回收算法

1) 拷贝式垃圾回收算法:

拷贝回收往往是存在两个相同大小的FROM区和TO区。FROM区分配对象, TO区空闲,回收时将存活的对象从FROM区移动到TO区。过程如下:

a)分配:对象的分配往往是分配在FROM区,如图2.4所示:

b)拷贝:当垃圾回收时,将FROM区的可达态对象直接依次拷贝到TO区中,如图2.5所示:

c)再分配:回收完后,接着上一轮垃圾回收拷贝后的地址进行创建新的对象。新一轮的垃圾回收则FROM区和TO区的角色进行互换,如图2.6 所示:

该算法的缺点是每一轮垃圾回收周期中,都有一半的内存空间是空着的,浪费资源。另外,在进行拷贝时,是“stop-the-world”式的,即程序的所有线程都会被挂起,直到GC结束,这会影响应用程序的响应时间。

2) 标记-清理式垃圾回收算法
此算法将垃圾回收分为两个阶段,第一阶段是标记,从根出发开始遍历,所有遍历到的对象标记为可达态。第二阶段,再次遍历整个Java堆,如果发现没有内存中的某个对象没有被标记为可达态,那么将该地址清理,并将其保存在空闲列表中。下次分配对象时,则从空闲列表中进行分配。缺陷是存在内存碎片,并且在进行分配对象时,需要在空闲列表中查找一个适合对象大小的区域进行分配。同时,在清理阶段完成前,应用程序是被挂起的,并且暂时的时间取决于堆的大小和可达态对象的数量。

3) 分代式垃圾回收算法
由于Java堆中的对象的生命同期往往很短,所以针对另一个小部分生命周期很长的对象往往没有必要每次都进行标记和判断。

2.5  本章小结

本章主要对多租户JVM涉及到的相关技术进行了阐述,包括多租户的形式以及带来的好处、多租户规范和资源管理规范所描述JVM系统以及常用的JVM垃圾回收机制,描述了多租户JVM使用到的技术背景知识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/939514.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

arcgis的MapServer服务查询出来的结果geometry坐标点带*的问题

不知道小伙伴使用arcgis server服务做查询的时候,有没有遇到下面的问题 原因是查询结果中出现*字符 这个问题一直困扰了我很久:因为从数据库查询的坐标点是没有问题的。 一开始有同事遇到过,说重新插入下就好了,有时候确实能解决…

Qt-creater 在线安装太慢,换国内源

Qt 在线安装太慢,换国内源 下载安装包 实例使用清华源 如下图先下载安装包exe文件 url: 链接: https://mirrors.tuna.tsinghua.edu.cn/qt/official_releases/online_installers/ 下载安装包到本地目录D:\ Powershell进入本地目录D:\ 使用参数方式换国内清华源 换国内清华源 …

嵌入式AI助力当代商业的发展

数字化转型的业务影响是广泛的,但购买者应寻求嵌入式AI在以下领域具有最大的影响力: 1.业务流程和任务的自动化 当买家搜索购买包含AI的软件时,他们应该研究该解决方案为员工自动执行日常任务的方式。嵌入式AI应该节省员工的时间和精力&#…

Maven之高版本的 lombok 和 tomcat 7 插件冲突问题

高版本的 lombok 和 tomcat 7 插件冲突问题 在开发期间,当我们使用 tomcat7-maven-plugin 来作为运行环境运行我们项目使,如果我们项目中使用了 1.16.20 及以上版本的 lombok 包,项目启动时会报错: for annotations org.apache.…

工业级PDA高精度导航定位

工业级PDA是指能到达防尘、防水、防摔三防等级,并具备实时采集、自动存储、即时显示、即时反馈、自动处理和自动传输等功能的移动智能终端。为满足如农业、铁路、空间、勘测与绘图等复杂环境领域的需要,目前高端工业级PDA普遍具备高精度的导航定位功能&a…

Apple Configurator iphone ipad 设备管控 描述文件使用方法

一、准备 App Store 下载安装 Apple Configurator 二、Apple Configurator 注册组织, -----------这个组织可以是个人,或者其它组织导出-------再导入进来: 三、描述文件配置:“” 根据管控需求进行配置 “” 四、使用 Ap…

Django(7)-项目实战-发布会管理

登录功能 模板页面 sign/templates/index.html <!DOCTYPE html> <html> <head><title>Login Page</title> </head> <body><h1>发布会管理</h1><form action"/login/" method"post"><la…

Flask加amis学校管理系统java学生教务信息jsp源代码Mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 Flask加amis学校管理系统 系统有3权限&#xff1a;学…

lnmp架构-mysql1

1.MySQL数据库编译 make完之后是这样的 mysql 初始化 所有这种默认不在系统环境中的路径里 就这样加 这样就可以直接调用 不用输入路径调用 2.初始化 重置密码 3.mysql主从复制 配置master 配置slave 当master 端中还没有插入数据时 在server2 上配slave 此时master 还没进…

【java基础——interface接口】

JAVA基础 interface接口 文章目录 JAVA基础接口 Interface 接口 Interface 接口是一种特殊的抽象类&#xff0c;它定义了一组抽象方法和常量&#xff0c;并且不包含具体实现。 只允许声明静态常量&#xff1a;必须且默认为 public static final 。声明抽象方法&#xff1a;必…

数据结构1

数据结构是计算机科学中存储和组织数据的一种方式&#xff0c;它定义了数据的表示方式和对数据进行操作的方法&#xff0c;常见的数据结构包括数组、栈、链表、队列、树、图等。 目录 一、常见的数据结构 1.数组 2.栈 3.队列 4.链表 5.树 6.图 一、常见的数据结构 1.数…

H5 + C3基础(五)(seo相关标签 顶部快捷栏实践 Logo seo)

seo相关标签 & 顶部快捷栏实践 seo相关标签titledescriptionkeywords 顶部快捷栏实践Logo seo seo相关标签 seo&#xff1a;搜索引擎优化&#xff0c;是一种利用搜索引擎规则提高网站在搜索引擎结果中自然排名的方式&#xff0c;进而提高网站的自然流量。 前端开发中主要s…

【Tkinter系列01/15】界面初步和布局

一、说明 一般来说&#xff0c;界面开发中&#xff0c;如果不是大型的软件&#xff0c;就不必用QT之类的实现&#xff0c;用Tkinter已经足够&#xff0c;然而即便是Tkinter规模不大&#xff0c;也需要一个系统专业的学习过程&#xff0c;本篇将是对Tkinter系列介绍的一篇博文。…

JavaSE(下)

一、集合进阶 双列集合Map<>【Java】Map集合概述 双列集合特点 Map常见API 三种遍历方式 1、由键找值,创建键的集合 2、通过键值对对对象进行遍历 3、利用lambda表达式进行遍历 HashMap HashMap的特点 HashMap的底层 总结 例题 package com.itheima.Mapdemo;import java.…

探索音视频出海的无限可能|中企出海领袖班第八期成功举办

​近年来&#xff0c;音视频社交出海赛道的热度吸引了众多企业纷纷进军海外市场。然而&#xff0c;面对复杂多变的海外市场&#xff0c;无论是产品的本地化策略&#xff0c;还是对海外网络环境的适应以及网络安全防御等因素&#xff0c;都成为决定产品能否在海外市场脱颖而出的…

Error while validating pooled Jedis object.

如何处理 jedis得连接池得异常&#xff0c;顺着找到Jedis的工厂类JedisFactory&#xff0c;对应看下这两个方法的实现&#xff0c;熟悉的代码找到了&#xff0c;可疑的点也找到了&#xff1a; public boolean validateObject(PooledObject<Jedis> pooledJedis) {final Bi…

widnows 制作winpe启动盘

下载 官网 大白菜官网,大白菜winpe,大白菜U盘装系统, u盘启动盘制作工具 点击装机版&#xff0c;进行下载&#xff0c;等待下载完成 安装 解压 双击exe运行 插入u盘 识别到的u盘 点击【一键制作成usb启动盘】 点击确定&#xff0c;等待制作完成 重启电脑&#xff0c;选择从…

问道管理:市盈率市净率两个指标含义怎么算?

市盈率和市净率是出资领域常用的两个目标&#xff0c;用于评价公司的估值和出资的报答状况。本文将从多个视点剖析这两个目标的含义和计算方法&#xff0c;帮助读者更好地了解和运用它们。首先&#xff0c;市盈率&#xff08;P/E ratio&#xff09;是用来衡量公司股票价格与每股…

【Win10安装NVIDIA驱动、CUDA、CUDNN】

Win10安装NVIDIA驱动、CUDA、CUDNN 1 NVIDIA驱动下载2 下载CUDA2.1 查看CUDA版本2.2 下载并安装CUDA 3 下载并安装CUDNN3.1 输入账号和密码后&#xff0c;登录CUDNN官方网站进行下载3.2 安装3.2.1 解压下载的压缩包3.2.2 将解压后bin目录的内容全部放到CUDA对应的bin目录3.2.3 …

银河麒麟V10(Tercel)服务器版安装 Docker

一、服务器环境 ## 查看系统版本&#xff0c;确认版本 cat /etc/kylin-release Kylin Linux Advanced Server release V10 (Tercel)## 操作系统 uname -p aarch64## 内核版本&#xff08;≥ 3.10&#xff09; uname -r 4.19.90-21.2.ky10.aarch64## iptables 版本&#xff08;…