快人一步
VMware 提供培训和认证,助您加速发展。
了解更多经过数月热火朝天的编码,我很高兴宣布 SpringSource Application Platform 1.0 的 Beta 版发布。
2007 年初,我们开始讨论企业 Java 已变得与单体和重量级应用服务器同义的替代方案。客户正在寻找一个轻量级、模块化且足够灵活以满足其开发和部署需求的平台。
Spring 和 Tomcat 的搭配表明开发者和运维人员可以成功地在生产环境中使用轻量级平台。尽管这种组合取得了成功,但缺乏模块化以及对非 Web 应用的明确支持限制了其适用性和灵活性。
我们着手构建 SpringSource Application Platform 来满足这些需求并消除这些限制。
平台的核心是动态模块内核(DMK)。DMK 是一个基于 OSGi 的内核,充分利用了 OSGi 平台的模块化和版本化特性。DMK 构建于 Equinox 之上,扩展了其在配置和库管理方面的能力,并为平台提供了核心功能。
为了保持最小的运行时占用空间,OSGi 捆绑包由 DMK 配置子系统按需安装。这使得应用可以安装到正在运行的平台中,并且其依赖项可以从外部仓库中满足。这不仅消除了手动安装所有应用依赖项的繁琐需求,还能将内存使用量保持在最低水平。
DMK 本身只需要最少的捆绑包即可运行,并通过一个 profile 进行配置,精确控制加载哪些额外的模块。例如,DMK 不需要存在 Tomcat,但默认的平台 profile 包含了 Tomcat,以便部署 Web 应用。如果您想在没有 Tomcat 的情况下运行平台,只需编辑 profile,它就不会被安装。(如果您尝试此操作 - 请记住,移除 Web 支持意味着 Web 模块将无法部署,因此请删除 pickup 目录的内容,以便平台在启动时不会尝试安装 Admin 和 splash screen 应用。)安装了管理控制台的默认平台配置仅占用 15MB 内存。
我对企业 Java 一直感到沮丧的一点是,应用通常被硬塞进生硬的筒仓中,并且缺乏对不同应用类型的明确支持。考虑一个在线商店的应用。这个应用有一个 Web 前端、一个消息驱动的订单处理模块、一个批处理驱动的库存重新排序模块和一个 B2B Web 服务模块。如今,许多这样的应用会打包成 WAR 或 EAR,并且模块看起来非常相似,很少支持模块类型之间的差异。有趣的是,许多人会称之为 Web 应用,而不是带有 Web 模块的应用。
在 SpringSource Application Platform 中,应用是模块化的,每个模块都有一个描述其类型的 personality:web、批处理、web 服务等。平台以特定于 personality 的方式部署每种 personality 的模块。例如,Web 模块在 Tomcat 中配置有 Web 上下文。应用中的每个模块都可以独立于其他模块进行更新,同时保持其作为更大应用一部分的身份。无论您构建的是何种类型的应用,编程模型都保持标准的 Spring 和 Spring DM。
在 1.0 平台版本中,我们支持 web 和 bundle personality,这使您能够构建复杂的 Web 应用。未来的版本将包含更多 personality 的支持,详情将在后面介绍。
平台支持以下三种形式打包的应用
平台直接支持标准 WAR 文件。在部署时,WAR 文件会被转换为 OSGi 捆绑包并安装到 Tomcat 中。所有标准的 WAR 契约都会得到遵循,您现有的 WAR 文件应该可以直接放入并部署而无需更改。
任何符合 OSGi 规范的捆绑包都可以直接部署到平台中,并且可以充分利用针对 Import-Package 和 Require-Bundle 引用的任何依赖项的即时配置功能。
PAR 格式是打包和部署平台应用的推荐方法。PAR 只是将一组 OSGi 捆绑包(模块)组合在一个标准的 JAR 文件中,并带有一个唯一标识应用的名称和版本。PAR 文件作为一个单独的单元部署到平台中。平台将从 PAR 中提取所有模块并安装它们。第三方依赖项将根据需要即时安装。
与直接将捆绑包部署到平台中相比,PAR 格式有三个主要优点。首先,它更容易。一个中等规模的企业应用可能包含 12 个或更多的捆绑包——手动部署这些捆绑包会非常麻烦。其次,PAR 文件在应用中的所有捆绑包周围形成了一个明确的作用域,这可以防止使用重叠类型或服务的应用相互冲突。此作用域也被一些高级功能(例如加载时织入)使用,以确保一个应用的织入不会干扰另一个应用的织入。最后,PAR 形成一个逻辑分组,用于定义哪些模块是一个应用的一部分以及该应用有哪些第三方依赖项。此分组被管理工具用于提供应用的详细视图。一个典型的 PAR 应用如下所示
应用中模块之间的依赖关系通常使用 Import-Package 和 Export-Package 来表达。对第三方库的依赖也可以用同样的方式表达,但对于许多库来说,这可能会容易出错且耗时。当使用像 Hibernate 这样的库时,您通常需要导入比您最初预期的更多的包。为了解决这个问题,您可以使用 Require-Bundle,但这有一些语义上的缺陷,例如 split packages,其中一个逻辑包被分割到两个或更多的类加载器中,导致运行时出现问题。平台引入了两种新的机制来引用第三方依赖项:Import-Bundle 和 Import-Libary。Import-Bundle 类似于 Require-Bundle,但它防止了 split packages 和 Require-Bundle 的其他问题。Import-Library 提供了一种机制,可以通过单个声明引用一组捆绑包导出的所有包,例如 Spring Framework 中的所有捆绑包
Bundle-SymbolicName: com.myapp.dao.jdbc
Bundle-Version: 1.0.0
Import-Bundle: org.apache.commons.dbcp;version="1.2.2.osgi"
Import-Library: org.springframework.spring;version="2.5.4.A"
在这里,我有一个模块捆绑包,它依赖于 Commons DBCP 捆绑包和 Spring Framework 库。Spring Framework 库包含了在您的应用中使用 Spring 所需的所有捆绑包。
Import-Library 和 Import-Bundle 在底层会展开为 Import-Package,因此与标准的 OSGi 语义一致。
平台理解模块的 personality,并由此可以推断如何配置模块的执行环境。部署 Web 模块时,典型 Spring MVC 应用所需的所有 Servlet 基础设施都会自动创建,消除了在不同应用中重新创建这些样板代码的需要。在 1.0 最终版本中,将为 Web 模块 personality 添加更多智能功能,以支持 Spring Web Flow 等其他技术。
无论您选择哪种打包格式,编程模型都只是 Spring Framework 和 Spring Dynamic Modules,其他 Spring Portfolio 产品在其上运行。
可维护性是整个工程团队的关键考虑因素。我们花费了大量时间关注日志消息的格式和堆栈跟踪的大小,以确保诊断应用问题尽可能容易。每当我们发现一项重复且耗时的任务时,我们都会寻找自动化它或完全取消它的方法。
为了帮助问题诊断,平台在日志消息和跟踪消息之间进行了严格区分。日志消息供最终用户查阅,让您可以快速获取最重要的故障信息,而无需翻阅数 GB 的跟踪内容。所有应用故障都会在日志输出中显示并编码——这些代码是访问知识库或支持内容的便捷方式。要理解为什么这如此有用,请考虑以下平台启动输出
[2008-04-29 12:12:01.124] main <SPKB0001I> Platform starting.
[2008-04-29 12:12:04.037] main <SPKE0000I> Boot subsystems installed.
[2008-04-29 12:12:06.013] main <SPKE0001I> Base subsystems installed.
[2008-04-29 12:12:07.396] platform-dm-1 <SPPM0000I> Installing profile 'web'.
[2008-04-29 12:12:07.674] platform-dm-1 <SPPM0001I> Installed profile 'web'.
[2008-04-29 12:12:07.721] platform-dm-14 <SPSC0000I> Creating ServletContainer on port 8080
[2008-04-29 12:12:08.036] platform-dm-10 <SPPM0002I> Platform open for business with profile 'web'.
[2008-04-29 12:12:09.405] fs-watcher <SPSC1000I> Creating web application '/admin'
[2008-04-29 12:12:09.652] async-delivery-thread-1 <SPSC1001I> Deploying web application '/admin'
那些详细描述启动调用链中每个类型内部工作机制的长篇大论输出不见了。取而代之的是,您会收到真正有意义的消息。当然,这并不意味着您无法了解每个类型正在做什么:我们仍然保留了详细的跟踪信息。实际上,因为我们将最重要的日志消息从跟踪中分离出来,我们的跟踪信息可以更详细,因为它们的目的不是被频繁阅读。
平台中的严重故障会生成一个服务转储,可以传递给支持人员,以帮助诊断过程。此转储包含平台中所有主要子系统的状态,并通过 AspectJ 介入,以确保我们捕获到可能抛出未经检查异常的每个位置。
平台还会主动监控 JVM 中的问题并触发转储。在 1.0 版本中,这仅限于死锁监控,但在未来版本中将包括内存、锁竞争和 CPU 竞争。
这个 Beta 版本仅仅是 SpringSource Application Platform 的开始。我们初步定义了 2.0 版本的路线图,重点关注五个主要领域:管理控制台、中间件集成、额外的 personality、集群和 DMK 2.0。
通过管理控制台,我们希望利用平台所拥有的所有应用知识,并将其提供给最终用户。管理控制台将允许从模块级别开始,一直深入到 Bean 级别,对应用进行详细检查。应用将与其依赖的库和捆绑包关联,管理控制台将提供动态升级这些库的能力。通过理解应用包含的不同类型的 Bean,管理控制台将提供对应用内部的详细洞察,并允许对某些应用组件进行动态重新配置。
为了支持典型的企业部署场景,平台 2.0 版本将提供对常见企业中间件组件的明确支持,例如 Oracle、TIBCO EMS 和 IBM MQSeries。与管理控制台的集成将允许在几分钟而不是几小时或几天内建立与这些中间件提供者的连接。应用将能够使用 OSGi 服务注册表和 Spring DM 的 <osgi:reference> 来访问这些连接。
2.0 版本将引入额外的 personality,以涵盖批处理、Web 服务和 SOA 应用。
集群是 2.0 版本的重要功能,其中集群范围内的单一系统映像 (SSI) 是关键部分,负载均衡和集群缓存也在路线图上。通过 SSI 支持,管理和部署操作将在整个集群中传播。最终,我们希望支持在整个集群中进行按模块更新,如果升级破坏了已部署的应用,则可以进行完全的集群回滚。
DMK 2.0 将包括并发子系统的改进,以支持大量频繁更改的捆绑包,并支持具有更复杂相互依赖关系的大量模块。此外还将包括配置子系统的更新以及对内存、线程、IO 和 CPU 的集成资源管理和监控。
请下载平台并试用。我们非常渴望了解您构建新应用和部署现有应用的经验。欢迎所有反馈,无论是积极的还是消极的。我们尤其感兴趣的是如何使构建和部署应用的过程更轻松、更愉快。
二进制版本和论坛可以在这里找到。用户指南 (user's guide) 和程序员指南 (programmer's guide) 都可以在线获取。我们在这里设置了一个 JIRA 实例。