引言
Apache Axis2(主要的开源 Web 服务平台之一)提供了一系列新功能,最为可贵的是,其中的很多功能都对向开发人员提供更为用户友好的方法起到了促进作用。在之前的 Axis 版本中,并不十分重视用户友好性。例如,在 Axis1 中,用户必须手动调用管理客户机并更新服务器类路径,然后重新启动服务器以应用更改。这个有点麻烦的部署模型对新手肯定是一道障碍。因此,Axis2 经过了精心的设计,能够克服此缺点,并提供更为灵活、可方便进行配置的部署模型。
Axis2 部署新功能
Axis2 部署模型将一系列新功能引入了 Apache Web 服务堆栈中(其中一些功能对于 Web 服务范式并非新事物)。以下列出了最为重要的主要更改和新功能:
- 类似于 Java™ 2 Platform Enterprise Edition (J2EE) 的部署机制(基于存档)
- 热部署和热更新
- 存储库(可以在其中放置服务和模块)
- 处理程序(模块)部署的更改
- 新部署描述符
- 多个部署选项
在下面的内容中,我们将逐个对每个方面进行详细讨论。
回页首
类似于 J2EE 的部署机制
在任何 J2EE 应用服务器中,都可以将应用程序作为自包含包部署,可以将所有的资源、配置文件和二进制文件打包为一个文件并进行部署。这显然非常实用,而也正是因为如此,Axis2 也引入了相同的机制来更方便地部署服务(和模块)。
考虑这样的情况,假如您有一个存在多个第三方依赖关系和一组属性文件的服务,同时假定没有类似于 J2EE 的部署机制。必须手动将所有这些依赖 JAR 文件和属性文件放入类路径中。如果有一个或两个服务器,这项工作的量将翻倍!在存在数百副本的集群环境中,将依赖 JAR 文件和其他资源添加到类路径中的做法并不实际。有了类似于 J2EE 的部署机制后,就没有这些问题了,只需要将服务放入副本中,而不需要进行任何其他工作了。
Axis2 自包含包(或存档文件)的内部结构如图 1 中所示。两种 Axis2 服务(存档和模块存档)非常相似。二者之间的细微差别包括:
- 对于 Axis 服务,描述符文件是 services.xml;而对于 Axis 模块,描述符文件是 module.xml。
- Axis2 服务的文件扩展名是 .aar(服务的文件名将为 foo.aar),模块的文件扩展名为 .mar(模块的文件名将为 foo.mar)。
图 1. 存档文件的结构
回页首
热部署和热更新
对于企业级应用程序,可用性是一个大问题。即使短时间的停机都可能带来很大损失,因此重新启动服务器并不是一个较好的做法。需要在不用关闭系统的情况下对其进行更新。而这就是热部署和热更新的用武之地。热部署和热更新是 Apache Web 服务堆栈(如 Axis 和 Axis2)中的新功能。这两个新功能如下所述:
- 热部署是指在系统启动并运行的情况下部署新服务的能力。例如,假定您有两个服务——service1 和 service2——已启动并运行,现在要在不用关闭系统的情况下部署名为 service3 的新服务。部署 service3 就是一个热部署场景。作为系统管理员,如果不喜欢服务的热部署,则可以通过更改名为 axis2.xml 的 Axis2 全局配置文件,将全局配置参数更改为以下所示,从而关闭此功能:
<parameter name="hotdeployment">false</parameter>
。 - 热更新是指在不关闭系统的情况下更改现有 Web 服务的能力。这是一个重要的特性,是测试环境中需要的一个功能。不过,在实时系统中使用热更新并不明智,因为这可能导致系统进入未知状态。此外,还可能会丢失该服务的现有服务数据。为了防止出现这种情况,Axis2 缺省将热更新参数设置为 FALSE。如果希望使用此功能,请按照以下所示更改配置参数,从而启用此功能:
<parameter name="hotupdate">true</parameter>
。
回页首
存储库
Axis2 存储库实际上就是文件系统中具有特定结构的目录。它可以位于本地,也可以位于远程计算机上。之所以引入存储库概念,目的是为了方便地支持基于存档的热部署功能。
存储库目录包含两个主要子目录,分别名为 services 和 modules。还可能有一个可选的子目录,名为 lib。如果希望部署服务,需要将服务存档文件放入 services 目录中。类似地,如果希望部署模块,请将模块存档文件放入 modules 目录。对于 lib 目录,要将其作为放置对服务和模块公用的第三方库的位置。图 2 显示了存储库的图形表示形式。
图 2. Axis2 存储库
注意:如果 modules 目录中的部分或全部模块希望共享某些资源,可以将这些资源添加到 modules 目录中的 lib 目录内。类似地,如果 services 目录中的全部或部分服务希望共享公共资源,恰当的位置是在 services 目录内的 lib 目录。
回页首
处理程序(模块)部署的更改
服务扩展(或模块)的概念是 Apache Axis 范式的一个新功能。其基本思想是对系统的核心功能进行扩展或提供服务质量保证。对于 Axis1,如果希望扩展其核心功能,则需要编写处理程序(执行链中的最小单位),更改全局配置文件添加该处理程序,最后要重新启动系统。
模块进行相同的工作,但会减少所需进行的工作量。同时,模块可以通过使用模块描述文件 modul.xml 来包含一个或多个处理程序。大多数情况下,模块是特定 WS 规范的实现,例如 Axis2 addressing 模块就是 WS-Addressing 的实现。
如前面提到的,可以将模块作为存档文件部署。模块存档文件的结构如图 3 中所示。
图 3. 模块存档文件的结构
回页首
新部署描述符
Axis2 的灵活性和可扩展性的重点是其部署描述符。将不再仅处理一个配置文件,而是针对不同的配置级别有不同的配置文件。例如,如果希望向系统添加处理程序,则没有必要更改全局配置;可以通过仅更改模块配置文件来完成此工作。Axis2 中有三种类型的描述符或配置文件:
- 全局描述符 (axis2.xml)
- 服务描述符 (services.xml)
- 模块描述符 (module.xml)
在全局描述符中,所有系统级的配置都在 axis2.xml 中给出,包括以下内容:
Axis2 提供了缺省 axis2.xml。其中包含启动 Axis2 所需的最小配置,但可以自由对其进行更改,从而使用您自己的 axis2.xml 启动 Axis2。务必注意,如果对 axis2.xml 进行了任何更改,则必须重新启动系统,以使这些更改生效。
在服务描述符中,由 services.xml 给出关于服务的配置。为了使服务有效,需要在服务存档文件中包含 services.xml 文件。服务配置文件包含以下内容:
- 服务级别的参数
- 服务的描述
- 消息接收方
- 需要作为 Web 操作(服务中的操作)公开的操作
- 服务级别的模块
模块描述符文件 (module.xml) 包含将模块插入到系统中所需的配置数据。主要配置包括以下方面:
务必注意,module.xml 还可能包含以下元素:
- 关于模块的描述(及其实现的规范)
- 端点(对于可靠消息传递的情况,就是类似于 create sequence 的端点)
回页首
Axis2 中可用的部署方法
在 Axis2 中,可采用三种主要方式部署服务:
- 将服务存档文件放入存储库中。
- 使用存档文件以编程方式创建服务。
- 将服务作为传统 Java 对象(Plain Old Java Object,POJO)部署。
在 Axis2 中,部署服务的最常用方法是直接将服务存档文件复制或放置到存储库中(services 目录)。如果使用基于 Axis2 WAR 文件的分发版本,则有两个选择:
- 手动将存档文件放置到存储库中。
- 使用 Web 控制台上载服务。
以编程方式部署并非用户需求,而是模块创建者的需求,因为某些模块要求 Web 服务的部署提供模块的全部功能。若要以编程方式创建服务,需要使用 services.xml、类加载器(可用于加载您的类文件)和 AxisConfiguration
。此方法的优势在于,您并不需要将服务存档文件复制到存储库中,而且仅在运行时服务才可见。清单 1 可帮助您形成对编程服务部署方法的基本认识。
清单 1. 编程服务部署
AxisConfiguration axisConfig; // you need to have reference to AxisConfiguration File file = new File("Location of the file""); ClassLoader clsLoader = new URLClassLoader(new URL[]{file.toURL()}); InputStream in = new FileInputStream("location of service.xml"); AxisService service = DeploymentEngine.buildService(in, clsLoader, axisConfig); |
使用 Java 类部署服务是 Axis2 中提供的一项使用非常方便的功能,在这种情况下没有必要生成服务存档文件或 services.xml。唯一的要求是,必须在创建服务前将 Java 类放入类路径中。在运行时,可以由模块或服务创建新服务并进行部署。在 Axis2 中部署 POJO 仅需要三行代码,如清单 2 中所示。
清单 2. 在 Axis2 中部署 POJO
AxisService service = AxisService.createService( MyService.class.getName(), axisConfig, RPCMessageReceiver.class); axisConfig.addService(service); |
回页首
总结
Axis2 在这里并不是证明 Web 服务概念,而是提供更好的 SOAP 处理模型,且相对于 Axis1 及其他现有 Web 服务引擎而言,此模型在速度和内存方面性能有了很大的改善。此外,它还提供了方便的部署机制。现在已经进入 Axis2 的时代了!