Azure 服务结构资源管理器中的 Java Webapp 部署

Posted

技术标签:

【中文标题】Azure 服务结构资源管理器中的 Java Webapp 部署【英文标题】:Java Webapp Deployment in Azure Service fabric explorer 【发布时间】:2017-01-30 00:39:16 【问题描述】:

我们有一个无状态 Java 应用程序,我想将它部署在 Azure 结构中。我已经按照文档安装了 Fabric SDK 和 Visual Studio 工具。

之后,我创建了 Service Fabric 应用程序“Guest Executable”模板,我的项目结构如下:

我已按照与https://azure.microsoft.com/en-us/documentation/articles/service-fabric-deploy-existing-app/ 中的文档类似的步骤进行操作

我的 ServiceManifest.xml 如下:

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="Guest1Pkg"
                 Version="1.0.0"
                 xmlns="http://schemas.microsoft.com/2011/01/fabric"
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ServiceTypes>
    <StatelessServiceType ServiceTypeName="Guest1Type" UseImplicitHost="true" />
  </ServiceTypes>
  <CodePackage Name="Code" Version="1.0.0">
    <EntryPoint>
      <ExeHost>
        <Program>HelloWorld.war</Program>
        <Arguments></Arguments>
        <WorkingFolder>CodePackage</WorkingFolder>
      </ExeHost>
    </EntryPoint>
  </CodePackage>
  <ConfigPackage Name="Config" Version="1.0.0" />
  <Resources>
    <Endpoints>
      <Endpoint Name="JavaAppTypeEndpoint" Protocol="http" Port="8080" Type="Input" />
    </Endpoints>
  </Resources>
</ServiceManifest>

我的 ApplicationManifest.xml sn-p 如下:

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest ApplicationTypeName="Application1Type"
                     ApplicationTypeVersion="1.0.0"
                     xmlns="http://schemas.microsoft.com/2011/01/fabric"
                     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Parameters>
    <Parameter Name="Guest1_InstanceCount" DefaultValue="-1" />
  </Parameters>
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="Guest1Pkg" ServiceManifestVersion="1.0.0" />
    <ConfigOverrides />
  </ServiceManifestImport>
  <DefaultServices>
    <Service Name="Guest1">
      <StatelessService ServiceTypeName="Guest1Type" InstanceCount="[Guest1_InstanceCount]">
        <SingletonPartition />
      </StatelessService>
    </Service>
  </DefaultServices>
</ApplicationManifest>

我在本地部署到 Service Fabric Explorer,构建和发布步骤很好,没有任何错误:

-------- Package: Project: Application1 succeeded, Time elapsed: 00:00:00.3530634 --------
2>Started executing script 'Deploy-FabricApplication.ps1'.
2>. 'C:\Users\samanoha\Documents\Visual Studio 2015\Projects\Application1\Application1\Scripts\Deploy-FabricApplication.ps1' -ApplicationPackagePath 'C:\Users\samanoha\Documents\Visual Studio 2015\Projects\Application1\Application1\pkg\Debug' -PublishProfileFile 'C:\Users\samanoha\Documents\Visual Studio 2015\Projects\Application1\Application1\PublishProfiles\Local.5Node.xml' -DeployOnly:$true -UnregisterUnusedApplicationVersionsAfterUpgrade $false -OverrideUpgradeBehavior 'None' -OverwriteBehavior 'Always' -SkipPackageValidation:$true -ErrorAction Stop
2>Copying application to image store...
2>Copy application package succeeded
2>Registering application type...
2>Register application type succeeded
2>Removing application package from image store...
2>Remove application package succeeded
2>Finished executing script 'Deploy-FabricApplication.ps1'.
2>Time elapsed: 00:00:01.9327912
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
========== Deploy: 1 succeeded, 0 failed, 0 skipped ==========

Started executing script 'Publish-NewServiceFabricApplication'.
[void](Connect-ServiceFabricCluster); Import-Module 'C:\Program Files\Microsoft SDKs\Service Fabric\Tools\PSModule\ServiceFabricSDK\ServiceFabricSDK.psm1'; Publish-NewServiceFabricApplication -ApplicationPackagePath 'C:\Users\samanoha\Documents\Visual Studio 2015\Projects\Application1\Application1\pkg\Debug' -ApplicationParameterFilePath 'C:\Users\samanoha\Documents\Visual Studio 2015\Projects\Application1\Application1\PublishProfiles\..\ApplicationParameters\Local.5Node.xml' -ApplicationParameter @_WFDebugParams_='[]' -Action Create -SkipPackageValidation:$true -ErrorAction Stop
Creating application...


ApplicationName        : fabric:/Application1
ApplicationTypeName    : Application1Type
ApplicationTypeVersion : 1.0.0
ApplicationParameters  :  "_WFDebugParams_" = "[]" 

Create application succeeded.


Finished executing script 'Publish-NewServiceFabricApplication'.
Time elapsed: 00:00:01.8691591
Started executing script 'Get-ServiceFabricApplicationStatus'.
[void](Connect-ServiceFabricCluster); Import-Module 'C:\Program Files\Microsoft SDKs\Service Fabric\Tools\PSModule\ServiceFabricSDK\ServiceFabricSDK.psm1'; Get-ServiceFabricApplicationStatus -ApplicationName 'fabric:/Application1' -ErrorAction Stop
The application has started.
Service Status:
fabric:/Application1/Guest1 is ready.

The application is ready.
Finished executing script 'Get-ServiceFabricApplicationStatus'.
Time elapsed: 00:00:01.0230548

但是应用程序健康状态显示错误并且事件是

"Error event: SourceId='System.Hosting', Property='CodePackageActivation:Code:EntryPoint'.
There was an error during CodePackage activation."

我不知道部署中可能存在什么问题,除了上面提到的之外,是否还需要在应用程序服务入口点中包含任何内容。

此外,在独立 tomcat 上部署的 Java Web 应用程序具有以下上下文 http://localhost:8080/HelloWorld/hello 。如果应用程序部署在 Service Fabric 集群中,它的 URL 上下文是否会保持不变,还是应该像 http://localhost:8080/Application1/Guest1/HelloWorld/hello 一样,因为它周围有 Azure 结构包装器?

【问题讨论】:

【参考方案1】:

最后发现我们需要在Host虚拟机(Azure VM或本地桌面)中单独安装Java,然后我们必须引用java路径。

所以我的服务清单是

<EntryPoint>
      <ExeHost>
        <Program>scripts\launchConfig.cmd</Program>
        <Arguments></Arguments>
        <WorkingFolder>CodePackage</WorkingFolder>
        <ConsoleRedirection FileRetentionCount="5" FileMaxSizeInKb="2048"/>
      </ExeHost>
</EntryPoint>

我在 Code 文件夹下创建了一个名为 scripts 的文件夹,脚本文件“launchConfig.cmd”只有一行,如下所示:

"C:\Program Files (x86)\Java\jre1.8.0_101\bin\java.exe" -jar HelloWorld.war

我们可能需要删除路径硬编码,但这就是它最终引用的方式。

【讨论】:

如果这只是在那场战争中运行 java,那不是要开始侦听 java 应用程序设置侦听的任何端口吗?我在一台机器dev asf集群上的spring webapi war应用程序上尝试了这种方法,它在一个“节点”上成功,在另外两个上失败,如果其他两个“节点”试图打开端口8080,这将是有意义的节点 1 已打开。 是的@GregoryBillings,您与指定端口上的java执行有关。但最初我的印象是平台依赖,即。 Java 安装本身将由 ServiceFabric 负责,但事实证明这是我们需要确保安装它的额外步骤。 啊,明白了@Satheesh。这仍然非常令人不安。我希望框架为您处理端口重定向,因此您不必手动跟上端口。我敢打赌,他们将严重依赖 docker 来实现此功能。【参考方案2】:

如之前的回答中所述,一种方法是将 Java 单独安装到机器上。

我在https://blog.vjrantal.net/2017/04/11/high-availability-java-hosting-in-azure-using-service-fabric/ 写了一个替代方法,它基于将所需的 Java 运行时打包到应用程序包中。

【讨论】:

【参考方案3】:

您放入程序配置的内容必须是可执行文件(.exe、.cmd 等)。 Service Fabric 将尝试执行您放入其中的任何内容。

例如,在您链接到的文档中,要执行 node.js 应用程序,程序是 node.exe,参数指向应用程序:

<ExeHost>
  <Program>node.exe</Program>
  <Arguments>bin/www</Arguments>
  <WorkingFolder>CodePackage</WorkingFolder>
</ExeHost>

【讨论】:

谢谢!你能指导我如何使用 Fabric 运行 J2EE 战争包吗?是否需要为 JVM 设置配置任何其他配置,因为我们这里没有 .exe 类型的可执行文件。任何参考文档都会很棒 如果你可以从命令行运行它(它有嵌入式服务器吗?)像这样:java -jar HelloWorld.war,那么程序是java,参数是-jar HelloWorld.war。这行得通吗? 谢谢!我使用嵌入式 tomcat 容器构建了 war 文件,当像“java -jar HelloWorld.war”一样启动时,它在我的本地运行良好。当我尝试通过与您提到的相同的方法时,出现错误“Register-ServiceFabricApplicationType:找不到入口点 java。”我们是否需要对 Azure 服务结构中的 Java 初始化进行任何其他设置?指定为 java.exe 也不起作用 是否可以按照步骤在本地Windows操作系统上部署基于java的应用程序?【参考方案4】:

入口点应该是一个命令。 HelloWorld.war 不是命令。来宾可执行文件旨在运行命令或 exe。

<SetupEntryPoint>
     <ExeHost>
         <Program>scripts\launchConfig.cmd</Program>
     </ExeHost>
  </SetupEntryPoint>

并且launchConfig.cmd 应该包含用于运行Tomcat 或jboss(或任何j2ee 应用服务器)的脚本。在运行服务器之前,您应该安装 java、配置 tomcat/ jboss、部署 HelloWorld.war 并配置端口。

【讨论】:

以上是关于Azure 服务结构资源管理器中的 Java Webapp 部署的主要内容,如果未能解决你的问题,请参考以下文章

在 Azure API 管理器中验证 POST 请求正文

在服务结构 Azure 上升级服务不可达状态

了解 Azure 中的无服务器计算

在 terraform 的 azure 数据资源管理器中使用 eventthub 的默认消费者组

创建应用程序实例(在服务结构集群资源管理器中)忽略本地计算机上的实例数

已删除的数据库仍显示在对象资源管理器中