65.9K
CodeProject 正在变化。 阅读更多。
Home

Java on Azure:首次云原生实践:自动化构建、测试和部署

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2021年4月20日

CPOL

15分钟阅读

viewsIcon

5783

downloadIcon

56

在本文中,我们将向您展示如何使用与GitHub集成的Azure DevOps Pipelines设置自动化的CI/CD管道。

在任何项目中,最困难的任务之一是创建和维护构建和部署流程。如果您有多个工作组使用多个项目,则部署过程中可能会遗漏步骤。这也可能导致构建过程的差异,从而创建无法部署的不兼容的交付物。这可能会导致整个企业瘫痪。Azure DevOps 提供了一种管理多个工作组使用多个项目进行构建和部署流程的方法,从而降低了这些风险。

为了演示如何使用Azure DevOps降低这些风险,我们将展示如何在单个组织中创建三个项目。在上一篇文章中,我们向您介绍了云原生应用程序的概念以及为什么应该使用它们。在本文中,我们将演示如何在组织中创建并添加一个项目。您将创建并添加另外两个项目。每个项目都将拥有一个唯一的构建和部署管道。每次代码推送到集成的GitHub存储库时,管道都会运行。这意味着您可以花费更多时间开发代码——而不是纠缠于如何运行它——因为更新后的代码的构建和部署是独一无二且自动化的。由于这一切都在云端,您和您的团队可以随时随地访问它。每个人都拥有正确版本的代码,并且不用担心因为机器崩溃而丢失最新版本。

本文不提供每个开发人员从当前环境迁移到Azure所需的具体步骤,因为每个开发团队都有自定义的构建和部署管道。但我们在此提出的过程将Eclipse/GitHub环境与Azure桥接起来。这为您未来选择完全迁移到Azure提供了途径。这样,您可以分步进行迁移,而无需进行“全面替换”即可获得在云中工作的优势。

我们假设您在开发中使用Eclipse/Java/GitHub堆栈,并向您展示了如何扩展该堆栈以部署Azure Functions。在此过程中,我们提供了文档链接,如果您使用的环境与我们的假设不符,或者您想进一步探索,可以获得帮助。

必备组件

本文假设您已具备

流程概述

由于我们在三个环境中工作:GitHub、Azure 和 Eclipse,您必须在 Eclipse 运行的同时登录 GitHub 和 Azure。

以下是主要步骤

  1. 将存储库添加到 GitHub。
  2. 使用 Azure Functions 创建一个函数应用。
  3. 创建一个 Azure DevOps 组织。
  4. 构建一个管道
    1. 添加一个项目。
    2. 创建一个服务连接
    3. 添加一个管道。
  5. 将 eGit 添加到您的 Eclipse 应用程序。
  6. 创建一个 Azure 函数
    1. 添加本地存储库。
    2. 提交代码。
    3. 推送前拉取以同步本地和远程存储库。
    4. 将代码推送到 GitHub。
  7. 验证构建和更新。

通常,您只需创建一次 DevOps 组织。由于本文仅向该组织添加一个项目,因此最好在创建组织后立即添加。您将自行添加另外两个项目以完成实现。

将存储库添加到 GitHub

在 GitHub 登录页面,点击“新建”。

将项目名称设置为“AzureFunctionHelloWorld”。选择“添加 README 文件”并选择“添加 .gitignore”。然后指定“Java”作为格式,然后点击“创建存储库”。

创建 Azure 函数应用

每个 Azure 函数应用都是一个无服务器应用程序,可提供对许多独立函数的访问。在此实现中,每个函数应用只提供一个函数。我们必须创建一个函数应用来提供运行时环境,我们可以在其中部署我们的 Azure 函数。Microsoft 提供了完整的文档。我们将只介绍创建函数应用的部分。

在 Azure 门户主页上,搜索“Function App”。在“Function App”概述中,点击“创建”。

选择您的订阅。由于我们将要在 Linux 上运行应用程序,因此为它们创建一个新的资源组。在“资源组”列表中,点击“新建”并输入名称。完成后点击“确定”。

将函数应用的名称设置为“AzureFunctionHelloWorld”。点击“下一步:托管”。

点击“托管”选项卡并选择“Linux”。点击“评审 + 创建”以接受其余默认值。

点击“创建”以创建您的函数应用。

部署完成后,您将看到此页面

创建 Azure DevOps 组织

Azure DevOps 是一个全方位服务平台,支持端到端的协作软件开发和交付。Microsoft 关于Azure DevOps的文章对 Azure DevOps 提供的服务进行了全面概述。我们将重点关注使用外部 GitHub 存储库设置管道,这是 Azure DevOps 工具集的一部分。还有其他选项,例如 Azure Repos 功能(请参阅DevOps Repos),它提供版本控制资源。如果您已经使用其他 Azure 服务,这会将所有内容保留在一个地方。

要设置 Azure DevOps 帐户,请按照DevOps Get Started网页上的说明进行操作。

要继续使用您现有的 GitHub 存储库,请访问Azure DevOps页面。点击“使用 GitHub 开始免费”。

GitHub 会要求您提供凭据。

提供您的凭据。点击“登录”。

GitHub 要求您提供授权。

提供您的授权。提供授权后,您将看到 DevOps 主页。

添加项目

现在您已经有了一个组织,就可以向其中添加项目了。此过程在DevOps 创建项目中有记录。

点击页面右上角的“新建项目”。

填写下一页的字段,如下所示。将此项目保持为私有。

项目创建完成后,您将看到以下页面。

创建服务连接

管道需要一个服务连接来创建构建和部署环境。服务连接是为每个项目配置的。

在项目主页上,点击左下角的“项目设置”。

滚动“项目设置”面板,直到看到“服务连接”。

对于新项目,您将看到以下屏幕截图所示的其中一个页面。

点击“新建服务连接”。选择“Azure Resource Manager”。点击右下角的“下一步”。

选择“服务主体(自动)”。点击右下角的“下一步”。

选择“订阅范围”级别。选择您的有效订阅和资源组。确保您选择的资源组与您在创建 Azure 函数时选择的资源组相同,否则构建将失败。

将服务连接名称设置为“AzureServiceConnector”。选择“授予所有管道访问权限”。点击右下角的“保存”。

添加管道

现在您可以添加管道了。

返回到项目主页。您将看到下面的概览页面之一。从项目工具面板中选择“Pipelines”选项。

点击“创建管道”。如果这是您的第一个项目,按钮在底部。

如果您有其他项目或管道,按钮在右上角。

要将管道连接到 GitHub 中的代码,请点击 GitHub。

此时,您将遇到几种工作流程之一。页面及其布局因以下因素而异:

  • 组织是否为新组织
  • 组织是使用 GitHub 还是 Azure 进行身份验证
  • Azure 的 Pipeline 应用程序是否之前已安装在 GitHub 中
  • 组织内的现有项目数量
  • 每个项目中的管道数量

您可能会遇到两种工作流程。一种称为“新组织”工作流程。另一种称为“现有组织”工作流程。

“新组织”工作流程

如果您有一个使用 GitHub 进行身份验证的新组织,或者您的组织没有任何项目或管道,则您的工作流程如下。

确认对 GitHub 的访问权限。

要授权管道访问所有存储库,请点击“所有存储库”。

登录您的 Microsoft 帐户。

如果您在“选择项目”列表中未看到现有项目,请点击“切换目录”链接,然后切换到创建项目的目录。

选择项目后,点击“继续”。

在可用存储库列表中,选择之前创建的“AzureFunctionHelloWorld”存储库。

下一页来自 GitHub,提示您在存储库中安装 Azure Pipelines。

点击左下角的“批准并安装”。您可能会被要求登录 Azure。

安装完成后,您将看到配置面板。

点击“显示更多”。

请注意,此工作流程将在下面的“现有组织”工作流程部分之后继续。

“现有组织”工作流程

如果您有一个包含项目或管道的现有组织,则可能需要授权 Azure Pipelines 连接到 GitHub。

Azure Pipelines 连接到 GitHub 并提供存储库列表。

下一页来自 GitHub,提示您在存储库中安装 Azure Pipelines。

点击左下角的“批准并安装”。您可能会被要求登录 Azure。

安装完成后,您将看到配置面板。

点击“显示更多”。

继续两个工作流程

上述两个工作流程在此处汇合。

创建管道后,向下滚动列表并点击“Maven”。

这将创建一个实现该过程构建步骤的 YAML 文件。

虽然这是一个不错的开始,但您的管道还需要部署该函数。用下面的代码替换所有起始代码。点击“保存”。

在 YAML 文件的顶部,设置一些部署时需要的变量

  • 您上面创建的服务连接的名称
  • 您的 Web 应用程序的名称(这与您上面使用 Azure CLI 创建 Web 应用程序时使用的名称相同)
  • 您的函数应用的名称(这是您在 pom.xml 中作为暂存目录提供的名称)
  • POM 文件所在目录的名称
variables:
  serviceConnectionToAzure: 'AzureJavaConnector'
  appName: 'AzureFunctionHelloWorld'
  functionAppName: 'AzureFunctionHelloWorld'
  POM_XML_Directory: 'AzureFunctionHelloWorld'

trigger:
- main

pool:
  vmImage: ubuntu-latest

steps:
- task: Maven@3
  inputs:
    mavenPomFile: '$(POM_XML_Directory)/pom.xml'
    mavenOptions: '-Xmx3072m'
    javaHomeOption: 'JDKVersion'
    jdkVersionOption: '1.11'
    jdkArchitectureOption: 'x64'
    publishJUnitResults: true
    testResultsFiles: '**/surefire-reports/TEST-*.xml'
    goals: 'package'

- task: CopyFiles@2
  displayName: Copy Files
  inputs:
    SourceFolder: $(system.defaultworkingdirectory)/$(POM_XML_Directory)/target/azure-functions/$(functionAppName)/
    Contents: '**'
    TargetFolder: $(build.artifactstagingdirectory)   

- task: PublishBuildArtifacts@1
  displayName: Publish Artifact
  inputs:
    PathtoPublish: $(build.artifactstagingdirectory)    

- task: AzureFunctionApp@1
  displayName: Azure Function App deploy
  inputs:
    azureSubscription: $(serviceConnectionToAzure)
    appType: 'functionAppLinux'
    appName: $(appName)
    package: $(build.artifactstagingdirectory)
    runtimeStack: 'JAVA|11'

提供提交消息。点击右下角的“保存”。

此操作将保存更新的 YAML 文件并将其提交到 GitHub 存储库。此提交将触发您的管道,您应该会看到一个作业排队。此作业的结果如何并不重要,因为我们还没有向存储库提交任何代码,但我们创建了作业这一点很重要。

这完成了 Azure 配置。

将 eGit 添加到您的 Eclipse 应用程序

现在我们有了正常运行的管道,我们必须设置 Eclipse,以便我们可以添加 Azure 函数的代码。

如果您已安装并配置了 eGit,请跳过此步骤。如果没有,请从安装 eGit开始。然后,要配置 eGit,您需要添加一些属性。

从菜单中选择“窗口”>“首选项”以打开“首选项”对话框。在过滤器中键入“eGit”。从列表中选择“配置”。在“配置”窗格中选择“用户设置”选项卡。

如果未显示下面的选项,请添加它们,然后设置这些值

  • 电子邮件是您的 GitHub 用户 ID
  • 名称是与您的提交更改关联的名称

创建一个 Azure 函数

每次创建新函数时都使用此过程。有关更多信息,请参阅:使用 Java 和 Eclipse 创建您的第一个函数

有几项重要的先决条件

Maven 原型提供了一个最小但功能齐全的 Azure 函数。文章使用 Java 和 Eclipse 创建您的第一个函数解释了如何在本地运行它,但在此教程中我们将跳过此步骤,因为我们知道代码可以构建并且会产生有效的结果。

在 Eclipse 中,从菜单中选择“文件”>“新建”>“项目”。在“新建项目”对话框中,选择“创建 Maven 项目”>“Maven 项目”。

接受默认值。点击“新建 Maven 项目”对话框底部的“下一步”。

输入“com.microsoft.azure”以过滤列表。选择 azure-functions-archetype。

在顶部设置 Group Id 和 Artifact Id 字段,以及下图所示的“groupId”、“artefactId”和“appName”属性。向下滚动到“javaVersion”并将值设置为 11。

现在您已经拥有了一个功能齐全的 Azure 函数的源代码。让我们为它创建一个本地存储库,然后将其保存在 GitHub 上。

添加本地存储库

要打开“Git Repositories”视图,请从菜单中选择“窗口”>“显示视图”>“其他”。选择“Git Repositories”。

右键单击项目以显示上下文菜单。选择“Team”>“Share Project”以显示“Share Project”对话框。

在“Share Project”对话框中,点击“Repository”字段右侧的“Create”以显示“Create a Git Repository”对话框。将名称设置为下图所示。点击“Finish”。

确保“Share Project”对话框中的字段具有下图所示的值。您的路径会有所不同,但请确保所有字段都引用“AzureFunctionHelloWorld”目录。点击“Finish”。

创建本地存储库后,您将在“Repositories”视图中看到它,如下所示。

添加常规操作

您将在以下各节中执行提交、拉取和推送操作,每次成功完成单元测试后都会执行。

提交新代码

在提交更改之前,从菜单中选择“窗口”>“显示视图”>“其他”以打开“Git Staging”对话框。

在“Git Staging”视图中,点击“双加号”图标将您的更改从“Unstaged Changes”移到“Staged Changes”。添加提交消息。点击“Commit”。

推送前拉取

如果本地存储库与远程存储库不同步,Git 无法将您的更改推送到远程存储库。我们知道我们将 Pipeline YAML 文件推送到了远程存储库,这意味着本地存储库与远程存储库不同步。要解决此问题,我们需要在推送更改之前拉取远程存储库。

右键单击项目以显示上下文菜单。选择“Team”>“Pull”。

在“Pull”对话框中,在“URI”字段中输入 GitHub 存储库的 URL。这将自动完成“Host”和“Repository path”字段。确保您选择了“https”协议并填写了“Authentication”字段。点击“Next”。

添加远程存储库链接。

如果一切正常,当您在“Reference”字段中键入“m”时,Eclipse 会联系 GitHub 并查找所有以字母“m”开头的分支。它还会显示警告消息,表明远程存储库与本地存储库不同步。点击“main”分支进行选择。

选择分支后,“Reference”字段将更新。

选择“Configure upstream for push and pull”,这将节省您为推送操作再次输入所有这些数据。点击“Finish”以执行“Pull”操作。

您的“Pull”操作的结果如下所示。

点击“Close”以完成“Pull”操作。

将新代码推送到 GitHub

右键单击项目以显示上下文菜单。选择“Team”>“Push Branch "master"”。

在“Push Branch master”对话框中,点击“Preview”。

点击“Push”以确认您要将提交的代码推送到 GitHub 存储库并完成操作。

点击“Confirmation”对话框中的“Close”以确认操作已完成。

确认推送和函数更新

通过检查 GitHub 来确认推送操作已成功。

这应该会触发管道开始一个新作业。

作业完成后,点击它以查看结果。

您将在函数应用中看到已安装的函数。

验证构建和更新

最后但同样重要的是,您可以使用应用概述中显示的基 URL 在浏览器中运行 Azure 函数。

URL 的其余部分是“api/HttpExample”,因为这是 Maven 模板中提供的函数名称。

要测试该函数,请打开浏览器并检索此 URL
https://azurefunctionhelloworld.azurewebsites.net//api/HttpExample?name=ExamplePollingCorp

Azure 函数运行方法

Microsoft 提供的示例代码在使用 Java 和 Eclipse 创建您的第一个函数中,但有三点我们想指出。这些在下一篇文章中会有用。

第一点是 `@FunctionName` 装饰器中设置的函数名称。默认名称是“HttpExample”。如上所示,此名称以及包含它的 Azure 函数应用的名称都会出现在调用 HttpExample 函数的 URL 中。

https:// <Function App Name> .azurewebsites.net//api/ <@Name Decorator> ?

第二点是 HTTP 请求方法由 `methods` 属性启用。示例同时支持 `GET` 和 `POST` 方法。您可以根据需要添加或删除方法。

    @FunctionName("HttpExample")
    public HttpResponseMessage run(
            @HttpTrigger(
                name = "req",
                methods = {HttpMethod.GET, HttpMethod.POST},
                authLevel = AuthorizationLevel.ANONYMOUS)
                HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {

最后,`authLevel` 设置为“ANONYMOUS”。我们之所以这样做,是因为我们启用了使用 Azure Active Directory 进行身份验证,它会过滤掉大多数攻击。我们希望允许该函数使用提供的标识来确定为用户授权哪些操作。

后续步骤

您现在拥有了一个完整、完全集成的云原生 CI/CD 流程来创建 Azure 函数,以及一个工作的无服务器函数。我们将在下一篇文章中使用它们来构建一个完整的应用程序。由于这里所做的工作,我们将能够专注于构建应用程序,而不是讨论我们必须做什么来测试和部署它。

如果您想了解有关 Azure 平台上的 CI/CD 工具的更多信息,这些文章为您提供了很好的概述

现在您已经准备好了流程,请查看本系列最后一篇文章,构建一个功能齐全的微服务。

© . All rights reserved.