了解 PureApplication System 中的共享服务工作负载

学习如何构建共享服务,一个为其他工作负载提供通用功能的工作负载

IBM® PureApplication™ System 和 IBM Workload Deployer 提供了在云中运行众多不同工作负载的功能,其中一项功能是共享服务,这是一种帮助客户端向其他工作负载提供通用功能的工作负载。这些通用功能和运行时服务改善了云密度,同时简化了复杂或高级特性的使用。在本文中,作者将介绍共享服务的一些基本概念,描述插件开发工具包 (PDK) 中的示例共享服务插件,该工具包为创建新共享服务提供了一个不错的起点。作者还将介绍如何将示例共享服务转换为功能性的一般媒介共享服务,这是一种一般服务存储库,客户端部署可在其中获取通用文件。

Jim Riordan, 开发人员, IBM

Jim Riordan 在 IBM 已工作了 10 年,编写过多个测试案例、内部开发文档(比如设计文档、开发人员指南和用户指南),审核并编写了多个 IBM 产品的外部信息中心文档,包括 WebSphere®、WebSphere Business Integration/Connect 和 IBM Workload Deployer。他目前担任 IBM Workload Deployer 和 IBM PureApplication System 技术的开发人员。



James Kochuba, WebSphere 云共享服务架构师, IBM

James Kochuba 是 WebSphere 云共享服务架构师和可服务性主管,从事 Workload Deployer 和 PureScale Application System 研究工作。他以前在 IBM 担任过的职位包括 WebSphere Application Server 安全测试架构师、AIM 高级支持团队和 WebSphere Application Server 支持团队。他是共享服务(比如日志记录、监视和缓存服务)和针对 IBM 平台即服务产品的服务(比如疑难解答)的技术领导。借助他以前的客户和技术背景,Jim 帮助生产更高质量的服务来满足客户使用需求。



2012 年 11 月 08 日

共享服务是一种预定义的模式,它部署在云中,并由云中的多个客户端应用程序部署(比如虚拟应用程序、虚拟系统和虚拟设备)共享。共享服务向多个应用程序提供一些运行时服务或代表多个应用程序向最终用户提供服务。

您通常仅会在每个云组中发现一个共享服务引用(云组是定义云的典型的硬件分组),共享服务可供云组中的所有应用程序部署使用。这意味着共享服务必须提供多租户访问能力。

图 1. 共享服务是一种预定义的模式,由多个应用程序部署来部署和共享
共享服务是一种预定义的模式,由多个应用程序部署来部署和共享

出于本文的用途,我们将共享服务定义为一个可供其他虚拟应用程序(客户端部署)使用的部署。一个或多个客户端部署可连接到单个共享服务部署来访问一个通用数据存储库。

本文介绍从插件开发工具包 (PDK) 导入和自定义示例共享服务的步骤,这个共享服务称为示例共享服务或媒介服务。

有关本文的一些不错的补充性学习资源(根据您与本主题相关的经验水平,可能甚至是必备资源),请参阅 边栏

媒介共享服务的概念

一个虚拟应用程序部署常常需要安装某种形式的预备性二进制程序;例如一个构建服务器上的二进制文件或 ISO DVD 映像。可能有一些原因会导致不使用应用程序模式或组件插件封装这些二进制文件,比如许可、代码分发问题,或者二进制文件可能需要独立于应用程序模式进行更新。

在云环境中,多个应用程序部署可能需要引用相同的媒介文件。如果需要的文件位于云外的较慢(或许远程的)网络上,那么将文件下载到每个部署的虚拟应用程序中可能需要很长时间。

来解决这些问题,我们建议创建一个新的媒介共享服务,该服务拥有一个供云组中的任何虚拟应用程序使用的二进制文件存储库。媒介服务可以独立于虚拟应用程序和插件来部署并加载预备文件。

无需在每次开始部署新应用程序时从云外部的某个地方复制文件,您可以将文件复制到媒介服务虚拟机 (VM) 中一次,将它们放在云中的本地。这使管理员能够在更加集中化的设计中管理此服务,而不是通过不共享任何通用框架的独立 VM。

文件从媒介服务复制到虚拟应用程序的速度可能快得多,因为此操作完全在机架(表示 PureApplication System)和云组内部进行,使多个部署能够快速访问数据。

下面的示例是媒介服务的一个典型流:

  1. 部署共享服务/媒介服务。
  2. 媒介服务 VM 启动并通过云组上的 NFS 加载要共享的二进制文件。
  3. 部署一个使用该媒介服务的虚拟应用程序(模式中的组件标记或策略)。
  4. 虚拟应用程序向媒介服务请求二进制文件位置和/或连接信息。
  5. 虚拟应用程序可通过 NFS 从媒介服务 VM 挂载文件存储库。
  6. 对多个虚拟应用程序部署重复上述过程。每个部署会获得通过媒介服务访问共享文件的能力。

我们将首先看看插件开发工具包中提供的示例共享服务,与您一起分析所提供的元素,然后将共享服务导入到将部署到云中的 IBM PureApplication System 或 IBM Workload Deployer 产品中。这会为您提供添加一般共享服务的总体信息。

然后我们将介绍如何修改示例共享服务插件,使其成为媒介共享服务,展示您可以如何轻松地添加新共享服务。在这一节之后是完成此任务的步骤和代码段,您可轻松地使用所提供的资源创建自己的媒介共享服务和未来的自定义共享服务。


构建和安装 PDK、服务和客户端虚拟应用程序

PDK v1.0.0.4 中提供的示例共享服务可作为一个不错的自定义框架。它设置了所需的文件结构,并定义用于以下方面的代码脚本:

  • 一个具有 REST API 管理接口的示例共享服务。
  • 一个客户端虚拟应用程序组件,它使用调用 REST API 管理界面的示例共享服务。

首先导入示例代码,然后继续添加自定义功能。

下载 PDK v1.0.0.4。部署插件的最低需求是 IBM Workload Deployer 3.1.0.2 或 IBM PureApplication System v1.0。请参阅 边栏参考资料 了解使用 PDK 的说明。

要记住的一些事项:

  1. 确保您导入了所有包含共享服务和共享服务客户端的项目。
  2. 转到 plug-in.depends 项目并使用 ANT 运行 build.xml。按该顺序执行清理和发布目标。这会构建所有包含共享服务和共享服务客户端的插件项目。
  3. 转到 patterntype.hello 并使用 ANT 运行 build.patterntype.xml。按该顺序执行清理并发布目标。这会将来自 plug-in.depends 的输出封装到一个要导入的模式中。

现在让我们在 Workload Deployer 或 PureApplication System 中安装该模式类型。


在 IWD 或 IBM PureApplication System 中安装该模式类型

安装包含示例共享服务插件的模式类型:

  1. 在 IBM Workload Deployer 控制台或 PureApplication System Workload 控制台中,转到 Cloud > Pattern types
  2. 如果 pattnertype.hello 模式类型已经存在,则选择它并单击 Delete
  3. 备注:确保没有正在运行的部署在使用来自此模式类型的插件,否则您将无法删除它。还需要等待片刻,等待该过程完成,然后页面才会刷新。
  4. 单击了绿色的加号导入您的新模式类型。
  5. 从 Eclipse 工作区导入该文件:patterntype.hello/export/ptype.hello-2.0.0.2.tgz 文件。
  6. 完成导入后,选择 patterntype.hello 模式并通过接受许可来启用它。

备注:如果希望修改并重新部署客户端,而不是重新部署共享服务,那么可以独立地封装它,更改版本号(只有惟一的版本才能导入)并通过 Cloud > System Plug-ins 页面上传它。

接下来,我们将要部署示例共享服务。


部署示例共享服务

将示例共享服务部署到一个云组中,为使用该共享服务做好准备:

  1. 在 Workload Deployer 控制台或 PureApplication System Workload 控制台中,转到 Cloud > Shared Services
  2. 选择示例共享服务标题下的 Sample Shared Service
  3. 单击 Deploy
  4. 输入需要的部署参数:
    1. Enable REST API:勾选。
    2. Management VM Number:1。
    3. Service VM Number:0。
    图 2. 示例共享服务的部署参数
    示例共享服务的部署参数
  5. 单击 OK
  6. 在下一个屏幕上,为您的环境指定正确的部署参数并单击 OK
  7. 查看 Instances > Shared Services 下的部署。

等待已部署的示例共享服务变为绿色并准备好使用,然后再进入下一步,部署共享服务客户端。


部署共享服务客户端

为共享服务客户端创建一个将使用示例共享服务的模式。请注意,共享服务客户端要求示例共享服务正在运行,然后才能成功部署它。

  1. 在 Workload Deployer 控制台或 PureApplication System Workload 控制台中,转到 Patterns > Virtual Applications
  2. 选择下拉列表中的 patterntype.hello 并选择加号以创建新模式。
  3. 在模式编辑器中,将 Shared Service Client Sample 从左侧方框拖到中央。
    图 3. 为共享服务客户端创建一个模式
    为共享服务客户端创建一个模式
  4. 单击 Save 并命名您的新应用程序。我们将它命名为 SharedServiceClient。
  5. 关闭 App Builder 窗口并刷新 Virtual Application Patterns 屏幕。
  6. 选择新客户端 SharedServiceClient
  7. 单击 Deploy
  8. 为您的环境指定正确的部署参数并单击 OK
  9. 查看 Instances > Virtual Applications 下的部署。

等待已部署的客户端模式变为绿色并为使用做好准备,然后再进入下一步,进入 Management Operations 控制台,您可在该控制台中与已部署的 VM 进行交互。


揭示 Management Operations 控制台屏幕

Management Operations 屏幕允许用户与已部署的 VM 进行交互。示例共享服务部署和共享服务客户端应用程序部署都有一个 Management Operations 屏幕。

查看示例共享服务的 Management Operations 屏幕:

  1. Instances > Shared Services > Sample Shared Service 下查看该部署。
  2. 在它运行后,单击 Manage link
  3. 单击 Operation 选项卡。
  4. 单击 SharedService-Management.ServiceSample 角色。请注意,直到您向此链接添加了一些操作后,该链接才会存在。我们稍后会添加一些操作。

查看共享服务客户端的 Management Operations 屏幕:

  1. Instances > Virtual Applications 下查看该部署。
  2. 在它运行后,单击 Manage link
  3. 单击 Operation 选项卡。
  4. 单击 SharedService-Client.ServiceClient 角色。
图 4. 共享服务客户端的 Management Operations 页面
共享服务客户端的 Management Operations 页面

在示例代码中,您可以使用客户端的 Management Operations 与示例共享服务 REST API 进行交互。要查看该交互,可以使用 Operation 屏幕提交一个对共享服务的 REST 调用。例如:

  1. 展开 REST Calls 部分。
  2. 输入以下信息:
    URL:  test
    REST METHOD:  PUT
    JSON:  {}
  3. 单击 Submit

这会在共享服务上调用 REST API,但它目前并不会真正执行任何有用的操作。

这是部署管理员使客户端能够与共享服务进行交互的一种方式。客户端也可让自己的生命周期脚本自动调用共享服务来完成相关操作,无需用户干预。这完全取决于客户希望如何公开与共享服务的交互。后面几节将分析一个相关的示例实现。

让我们来查看将示例共享服务修改为媒介服务的共享服务代码。


示例服务和客户端的代码演练

提供生命周期脚本和预定义的模式来创建和管理共享服务的示例共享服务插件(来自 PDK)名为 plug-in.com.ibm.sample.sharedservcie.service。它创建一个或多个 VM,运行一个 REST API 供客户端使用。您将自定义此插件来创建一个媒介服务。

以下文件也包含在您从 PDK 获取的插件包中:

  • src/com.ibm.service.internal/SampleRegistryProvider.java:此文件定义此共享服务的注册表响应信息。例如,客户端代码调用 getRegistry,此方法返回此共享服务的 IP。返回的注册表对象是一个 JSON 对象,所以它也可获取任何其他数据。此代码在系统的管理进程中运行(比如在 IBM Workload Deployer 设备或 PureApplication System 管理器节点中)。请注意,此文件的名称和包可自定义,但您需要确保也在 OSGI-INF 文件中更新了文件名 (OSGI-INF/serviceRegistryProvider.xml)。
  • OSGI-INF/serviceRegistryProvider.xml:此文件包含一个程序包的 OSGi 细节,它创建了一个引用,供其他程序调用此程序包并正确地执行。此文件名可以自定义,需要清单文件 (META-INF/MANIFEST.MF) 来供插件记录自定义名称。
  • plug-in/appmodel/metadata.json:此文件定义用户在部署共享服务时的部署参数。在这种情况下,用户可以启用或禁用 REST API,并设置要创建的管理和服务 VM 的数量。此文件名不可以自定义。

    示例共享服务包含部署多个 VM 的能力:一个管理 VM 和一个或多个服务 VM。它的理念是服务 VM 在需要时可扩展来实现故障转移或配备更多资源。

    • 管理 VM 拥有主要 REST API 并运行 REST API 脚本。
    • 服务 VM 也拥有一个 REST API,但它是冗余的。
    这里使用的理念是,用户可在服务 VM 之间实现数据冗余逻辑和通信,并为动态创建或删除服务 VM 设置缩小或扩展指标。这些主题是更高级的主题,不属于本文的介绍范围。

    出于本文的用途,我们假设仅部署了一个示例共享服务 VM:管理 VM。为了避免混淆,我们忽略了服务 VM。

  • plug-in/templates/servicesample.vm:这是定义所创建的 VM 的 VM 模板文件。在此文件中,定义了两个 VM 类型:
    • SharedService-Management 用于管理 VM。
    • SharedService-Service 用于服务 VM。
    该文件中引用的属性由用户在部署时通过直接映射到 metadata.json 来提供。例如,servicesample.vm 包含 ${attributes.managementNum},后者在 metadata.json 中定义:"id":"managementNum"。

    VM 模板基于 Apache Velocity,所以您可以向该模板添加逻辑来动态更改最终生成的拓扑结构。可以看到,只有在用户在部署时输入一个大于 0 的数字时,#if 逻辑才定义 SharedService-Service VM:#if (${attributes.serviceNum} > 0)。对于本文,我们没有部署 SharedService-Service VM,所以 attributes.serviceNum 为 0。

  • plug-in/nodeparts/servicesampleapi/common/install/7_servicesampleapi.py:可以在 VM 安装期间运行此脚本来设置 REST API。该名称需要以一个数字开头,然后才能在 nodeparts 运行时按预期的顺序正确运行,但下划线后的名称 (servicesampleapi.py) 可以自定义。
  • plug-in/nodeparts/servicesampleapi/servicesampleapi/properties/servicesampleapi.json:此 JSON 文件定义要公开的 REST API 方法。
  • plug-in/parts/servicesample.scripts/scripts/ServiceSample/restapi.py:这是在调用 REST API 时运行的 Python 脚本。它在 servicesampleapi.json 中为每次 REST API 调用引用。该文件名可以自定义,但您需要确保 servicesampleapi.json 正确地使用了自定义名称。

共享服务客户端插件是 plug-in.com.ibm.sample.sharedservcie.client。当部署它时,它为客户端部署提供了与共享服务交互的能力。以下文件也包含在插件包中:

  • src/com.ibm.service.internal/SampleServiceProvisioner.java:展示客户端服务配备程序。它在部署客户端之后,创建客户端 VM 之前运行。它展示了如何获取共享服务的引用并调用共享服务 REST API。

    配备程序的一个示例用法是告诉共享服务,另一个客户端正在配备。例如,使用 REST API,共享服务可创建新用户/密码并返回该数据供客户端连接使用。这不是必需的,但是,当这个部署的共享服务不正确时,它能够使客户端部署优雅地失败。另一个示例:如果对服务的预期不正确,那么这可以阻止客户端部署的发生。然后用户需要与共享服务管理员合作修复共享服务,以免将资源浪费在失败的应用程序部署 VM 上。

  • plug-in/appmodel/operation.json:此 JSON 文件定义了部署的 Management Operations 控制台屏幕上可使用的操作,使客户端部署的管理员能够执行易于使用的操作。此文件名不可自定义。在执行该操作时,它会根据此行的定义来调用 action.py 脚本:"script": "action.py call"
  • plug-in/parts/clientsample/scripts/ServiceClient/action.py:在从 Management Operations 控制台运行某个操作时会运行此脚本。它生成对共享服务的一个 REST 调用,然后使用 maestro.pcurl 命令执行 HTTP 调用。

现在您应该已经很好地理解了组成共享服务场景的客户端和服务关系的各个组成部分。让我们继续看一看如何将示例共享服务自定义为媒介服务。我们将介绍创建自定义媒介服务所需的简单修改。


媒介服务细节

对 plug-in.com.ibm.sample.sharedservcie.service 项目进行以下更改。

  1. 向共享服务注册表添加一些信息。编辑文件 src/com.ibm.service.internal/SampleRegistryProvider.java,在 getRegistry 命令中返回注册表的代码前添加此行代码:
    registry.put("mountPoint", "/shared_repository");

    添加的这部分信息是您创建的 NFS 挂载点的文件路径。客户端代码需要读取此值,然后才知道如何对存储库进行 NFS 挂载。

  2. 添加到共享服务 REST API 中。修改文件 plug-in/nodeparts/servicesampleapi/servicesampleapi/properties/servicesampleapi.json,在 GET 部分中添新函数listRepository
    { "resource":"listRepository", 
    "clientdeploymentexposure":true, 
    "role":"SharedService-Management.ServiceSample", 
    "script": "restapi.py listRepository", 
    "timeout" : 60000},

    这返回以下信息:

    • listRepositoryGET 调用。
    • 该调用可用于其他客户端部署(而不仅仅是核心 IBM Workload Deployer/IPAS 代码)。
    • 该调用由 VM 角色类型 SharedService-Management.ServiceSample 运行。
    • 当调用时,它返回脚本 restapi.py 并将 listRepository 作为参数传递。我们稍后将更新 restapi.py 脚本,以便使用这个新参数。
    • 响应超时设置为 60 秒。
  3. 为这个服务添加将在 Management Operations 屏幕上公开的相同参数。定义两个操作:listRepositoryimportFile

    创建一个名为 plug-in/appmodel/operation.json 的新文件:

    {
         "ServiceSample": [
              {
                   "id": "listRepository", 
                   "label": "List repository", 
                   "description": "List files in the repository", 
                   "script": "action.py listRepository"               
              },
              {
                "id": "importFile",                
                "label": "Import file via HTTP", 
                "description": "Import a single file into the repository via http url.", 
                "script": "action.py importFile", 
                "attributes": [                         
                        {
                             "label": "URL to import", 
                             "type": "string", 
                             "id": "url", 
                             "required": true, 
                             "description": "HTTP URL of a single file to import into 
                                             the repository."
                        },                                   
                   ]
              }
         ]
    }
  4. 编写将在这些操作运行时执行的 Python 方法。创建一个名为 parts/servicesample.scripts/scripts/ServiceSample/action.py 的新文件。此脚本将在从 Management Operations 页面运行一项操作时调用。它包含两个新方法和运行它们所需的框架逻辑。
  5. 更新 parts/servicesample.scripts/scripts/ServiceSample/restapi.py 脚本,以便添加新的 REST API。要向脚本添加一个新方法,请运行以下代码:
    def listRepository():
        logger.debug('Called listRepository in restapi')
        ret = os.listdir(SHARED_REPOSITORY_PATH)
        #create JSON string out of return value
        ret = '{"fileList":"'+str(ret)+'"}'
        logger.debug('return value = ' + str(ret))
        maestro.operation['return_value'] = ret

    更新主要 run() 方法以调用新方法:

    def run():
         ...
        elif mode == "listRepository":
            listRepository()
  6. 将该逻辑添加到 start.py 生命周期脚本中,以便实际创建 NFS 共享。

执行这些修改后,您已经创建一个已准备构建和部署的媒介服务。

现在可以测试该共享服务了。构建模式类型,然后重新安装,重新部署该共享服务。完成部署之后,请转到 Operations 屏幕,尝试导入一个文件并列出该存储库。

请注意,此 VM 必须能够通过网络看见文件导入 URL。如果您愿意,还可以使用 scp 命令或者甚至一个 NFS 共享来自定义要导入的操作参数和 Python 脚本。Python 脚本也可以调用一个 shell 脚本,所以存在多种可能。

图 5. 将一个文件上传到媒介服务之后的 Management Operations 页面
将一个文件上传到媒介服务之后的 Management Operations 页面

可选:在部署之前加载文件

目前为止,此练习详细介绍了在部署之后加载文件,但如果希望在单击部署前指定要加载的文件该怎么办?示例代码中未包含此内容,但下面给出了一些建议。

可向部署参数中添加一个可选的用户输入字段 metadata.json:

         {
            "id":"filesToLoad",
            "label":"URL listing of files to load",
            "description":"List one or more URLs of files to import into the repository.
                           Multiple URLs must be separated by a comma.",
            "required":false,
            "type":"string",            
         }

将用户输入放在拓扑结构文档 templates/servicesample.vm 中。

在 SharedService-Management 的 vm-template 下编辑 roles 代码块,以便添加 parms 部分:

            "roles": [
                 {
                    "type": "ServiceSample", 
                    "name": "ServiceSample"
                    "parms":{
                        #if ( ${attributes.filesToLoad })
                        "filesToLoad":"${attributes.filesToLoad }",
                        #end                        
                      }
                }

这些 parms 可供 ServiceSample 角色中的生命周期脚本使用。例如 parts/servicesample.scripts/scripts/ServiceSample/install.py:

if 'filesToLoad' in maestro.parms:
     filesToLoad = maestro.parms['filesToLoad']

然后,您的脚本需要分析用户的输入并下载相关文件。您可以在我们介绍客户端配置时自行测试此功能。


媒介服务客户端细节

通过创建客户端插件来实际使用您构建的媒介服务。首先对 plug-in.com.ibm.sample.sharedservcie.client 项目进行以下更改。

  1. 当执行客户端部署时,首先运行的内容之一是在客户端配备程序 SampleServiceProvisioner.java。在此文件中,有多个对链接的共享服务的 REST API 调用的示例。目前这些调用执行的操作很少,但可以针对媒介服务来修改它。新调用测试了新的 listRepository REST API,如果返回一个错误,则抛出一个异常。此异常会立即停止部署(在创建任何 VM 之前)并记录异常详细信息。

    我们仅检查了 HTTP 返回调用,但您也可以检查响应中的特定数据。请注意,这是可选的代码,可完全删除,但是,如果在启动 VM 之前检测遗留的预备内容,那么可以节省部署人员的时间和云中的系统资源。

    createService() 方法中,在紧挨现有的 REST API 调用之后,添加另一个调用:

              // Make a call to the Shared Service, and throw an exception if a valid 
                 response is not returned.
              response = this.registrySvc.callOperationOnSharedService(serviceName,
                    clientCloudGroup, clientVersion, ip, "listRepository", "GET", null);
              logger.logp(Level.INFO, CLASS_NAME, METHOD_NAME, "Client Sample Service
                          Provisioner: Called example GET listRepository REST call to the
                          shared service: {0}  URL: {1}",
                        new Object[] { serviceName, "listRepository"});
              int statusCode = response.getStatusCode();
              JSONObject responseData = response.getOperationResponse();
              logger.logp(Level.INFO, CLASS_NAME, METHOD_NAME, "Client Sample Service
                       Provisioner: Response back from the REST call was response status
                          code: {0}  Data: {1}",
                   new Object[] { statusCode, responseData });
              if (statusCode!= HttpURLConnection.HTTP_OK) {
                // there was a problem with the REST call to the shared service. It may 
                      not be running.
                   // Throw an exception which will stop the deployment 
                   logger.logp(Level.SEVERE, CLASS_NAME, METHOD_NAME, "Client Service
                               Provisioner: There was a problem with the response.");
                   throw new Exception ("The required Shared Service did not return a
                                         valid response. Please ensure the Shared 
                                         Service is running.");
              }
  2. 在客户端的生命周期脚本 (install.py) 中调用 REST API listRepository,让 VM 知道哪些文件在媒介服务之上。您需要创建另一个 install.py 来安装 ServiceClient 角色,所以我们创建了一个名为 plug-in/parts/clientsample/scripts/ServiceClient/install.py 的新文件。
  3. 添加检索共享服务注册表信息的代码:
    regInfo = maestro.registry.getRegistry("sample", "1.0")        
    ipAddr = regInfo['ip']
    mountPoint = regInfo['mountPoint']
  4. 添加调用 REST API 的代码:
    # Drive pcurl method
    jsonResults = pcurlInvoke(ipAddr, "sample", method, sslOpts, url, str(json))
    # now use the results however you wish
    logger.debug('return value of listRepository = ' + str(jsonResults))
  5. 添加从媒介服务挂载共享存储库并复制所有文件的代码:
    mountCommand = 'mount ' +ipAddr+":/"+mountPoint+" "+ localMountPoint
    logger.debug('mount command = ' + str(mountCommand))
    rc = maestro.trace_call(logger, mountCommand , shell=True)
    logger.debug('return value mount command = ' + str(rc))
    
    logger.debug('Copying all files')
    rc = maestro.trace_call(logger, 'cp -r '+ localMountPoint+"/* 
         " +localRepository, shell=True)
    logger.debug('return value from copy command = ' + str(rc))
  6. 查看完整的文件实现的完整源代码。

在此示例中,我们使用了在共享服务的 plug-in/applications/servicesample/appmodel.json 中注册的共享服务名称(在本例中为 “sample”)来查询共享服务注册表:"servicename": "sample"。这将返回在 SampleRegistryProvider.java 的 getRegistry 方法中创建的 JSON 对象。在本例中,返回了共享服务的 IP 地址和挂载点。拥有该信息后,您就可以挂载文件系统并复制文件。然后可以修改该脚本,以便在虚拟应用程序中使用复制的文件;例如解压并启动一个安装程序。

完成所有修改后,您就已经为媒介服务创建了一个已准备构建和部署的客户端插件。

现在,您可构建和测试客户端项目了。关注前面用来构建、重新安装和部署共享服务和客户端虚拟应用程序的步骤。

部署媒介服务后,使用 Management Operations 控制台将一个文件上传到其中,然后部署客户端虚拟应用程序。检查共享服务和共享服务客户端的日志文件。您应该看到客户端连接到媒介服务并从中下载相关文件。


改进想法

我们提供了改进此过程的一些想法,但具体操作留给您自己去探索。

  • 将媒介从共享服务管理 VM 备份到任何服务 VM。
  • 在媒介服务的服务 VM 上创建一个扩展策略并实现数据复制。
  • 向 REST API 添加更多智能来获取连接信息(您可为各种服务 VM 使用循环路由)。
  • 使用备用的或更安全的连接:
    • 在 REST API 调用中提供客户端 IP 地址,以便让媒介服务仅向允许的 IP 打开 IP 防火墙端口。
    • 使用 NFS 或 HTTP 以外的备用的安全挂载和文件副本。
  • 具有基于所加载源数据的文件验证的更多媒介上传方法。
  • 在从媒介服务到客户端的传输过程中,对文件副本进行更多过滤。
  • 验证用户输入,以提高安全性。添加用户输入和 REST API 参数验证,防止运行不希望出现的命令。在我们的代码中,直接将来自媒介服务的导入文件操作的输入参数传递给命令行,允许用户潜在地在媒介服务 VM 上运行恶意命令。
  • 将媒介服务客户端连接到媒介服务的代码是紧密耦合的,并全面集成到客户端中。如果您只有一个媒介服务模式,那么这样做不会出现问题,但如果您创建了多个都够使用该媒介服务的不同的客户端应用程序模式,那么您会发现需要将相同的媒介服务连接脚本复制到每个插件中。在这种情况下,最好将媒介服务客户端逻辑分离到它自己的插件中。这包括一个一般性插件片段,其中仅包含连接到媒介服务并下载必要文件的连接逻辑脚本。例如,它有一个 install.py 或 configure.py 生命周期脚本连接到媒介服务并下载一个文件。任何新客户端的编写都不需要媒介服务客户端逻辑,只需引用此媒介服务客户端插件。部署新虚拟应用程序后,媒介服务客户端插件脚本会拉入到您的虚拟机中,并与您的应用程序一起运行。

结束语

在本文中,我们通过 IBM 提供的示例共享服务插件帮助演示了一个共享服务,还介绍了它如何为未来的共享服务提供一个不错的框架。我们展示了如何利用该框架并创建了一个媒介共享服务,该媒介共享服务托管着一个可通过 Management Operations 控制台加载文件的共享存储库。然后我们分析了如何自定义一个虚拟应用程序来创建此共享服务的客户端,连接到媒介服务共享存储库。在启动时,客户端 VM 对存储库执行 NFS 挂载并复制文件。

现在,您的云中已有一个可供虚拟应用程序使用的简单共享存储库。您可修改它,得到更复杂的存储库,比如添加安全性、不同的存储库等,您能想象到的任何增强。


下载

描述名字大小
本文的样例代码sharedservice-workspace.zip86.9KB

参考资料

学习

获得产品和技术

讨论

  • 加入 developerWorks 中文社区。浏览开发人员推动的博客、论坛、群组和维基,并与其他 developerWorks 用户进行交流。

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Cloud computing, WebSphere
ArticleID=844913
ArticleTitle=了解 PureApplication System 中的共享服务工作负载
publish-date=11082012