构建完整的微服务(三)

目录

创建Cosmos数据库帐户

使用输出绑定插入

修复我们的TypeScript

使用输入绑定读取

修复我们的发布

部署基础设施

部署Cosmos DB

部署DTAP

下一步


本系列的第二部分中,我们使用默认的Visual Studio Code模板在Node.jsTypeScript中创建了一个Azure函数。我们还创建了一个构建管道来构建和测试代码并将TypeScript转换为JavaScript。通过发布管道,我们自动将功能部署到Azure

在本文中,我们将向我们的函数添加一个数据库,然后将我们的函数(包括所需的基础设施)部署到开发、测试、验收和生产 (DTAP)。在本文结束时,我们将创建一个微服务,并带有一个数据库,可以部署到DTAP

创建Cosmos数据库帐户

让我们从在我们的函数中添加一个数据库开始。我们将Azure Cosmos DBSQL API结合使用。我们有充分的理由使用SQL API,稍后您会看到。对于JavaScriptTypeScript开发人员,使用MongoDB API可能是有意义的。这意味着,尽管我们正在运行Cosmos DB,但我们可以使用任何MongoDB库(例如Mongoose)连接到它。但是,对于我们接下来向您展示的内容,SQL API将完成。

转到Azure门户并查找Cosmos DB。将它放在与您的函数相同的资源组中,以便以后轻松清理。选择一个独特的名称和您附近的地区。除此之外,保留所有默认设置。

创建可能需要几分钟,在我们的例子中是14分钟。同时,我们可以专注于我们函数的代码。

使用输出绑定插入

为了从Cosmos DB中获取数据,我们使用Azure函数绑定。例如,如果我们将输入参数绑定到MongoDB查询,我们将自动获取一条记录。同样,我们可以添加一个输出绑定来返回一个对象,它会自动添加到Cosmos DB中。有不同的绑定,例如Blob、表和队列存储、服务总线和事件中心,但我们将使用Cosmos DB绑定。

您的函数在您的项目中有自己的文件夹,该文件夹包含一个function.json文件。当您打开此文件时,您会看到两个绑定,输入输出绑定。这实际上是您的HTTP触发请求和响应。您还将看到您的函数当前允许使用GETPOST方法。

让我们从将文档插入我们的数据库开始。为此,我们将只使用POST,因此从配置中删除GET方法。为我们的函数添加一个路由也很好,使我们能够在以后添加其他函数。因此,将值为“person”的路由属性添加到输入绑定。此外,向您的配置添加额外的输出绑定。

{
   "bindings": [
      {
         "authLevel": "function",
         "type": "httpTrigger",
         "direction": "in",
         "name": "req",
         "methods": [
            "post"
         ],
         "route": "person"
      },
      {
         "type": "http",
         "direction": "out",
         "name": "res"
      },
      {
         "name": "personOut",
         "databaseName": "mydb",
         "collectionName": "person",
         "createIfNotExists": true,
         "connectionStringSetting": "CosmosDBConnString",
         "partitionKey": "/partitionKey",
         "direction": "out",
         "type": "cosmosDB"
      }
   ],
   "scriptFile": "../dist/HttpTrigger1/index.js"
}

Cosmos DB使用分区键对数据进行分区。该字段是必填字段,但您可以将其留空或使用常量字符串值。我们使用一个人的姓名首字母作为分区键。我们需要在这里指定分区键,因为我们告诉我们的函数创建数据库和集合,如果它们不存在。

此外,转到您的local.settings.json文件并添加CosmosDBConnString设置。在Cosmos DB帐户的密钥选项卡中的Azure门户中查找连接字符串。

修复我们的TypeScript

我们现在可以更改我们的函数,使其返回到运行时。对于此人的ID,我们将使用GUID,因此首先运行npm install guid-typescript 然后,添加import { Guid } from "guid-typescript";TypeScript文件的顶部。

对于人,我们定义了一个接口。

interface Person {
   id: string,
   email: string;
   partitionKey: string;
   firstName: string;
   lastName: string;
}

然后,在我们的函数中,我们创建一个人并将其添加到上下文绑定中,以便函数运行时知道它应该将此人添加到Cosmos DB。我们用:

context.bindings.[name you entered in your out binding configuration]

最后,我们将这个人返回给调用者,以便他们可以存储生成的ID

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
   let p: Person = {
      id: Guid.create().toString(),
      email: req.body.email,
      partitionKey: req.body.firstName[0],
      firstName: req.body.firstName,
      lastName: req.body.lastName,
   };

   context.bindings.personOut = p;

   context.res = {
      // status: 200, /* Defaults to 200 */
      body: p
   };
};

现在,启动PostmancURL或任何其他工具,使您能够向HTTP服务发出POST请求。启动您的函数并将URL(应该类似于https://localhost[:port]/api/person复制到您选择的工具。然后,然后给它一个像这样的身体:

{
   "email": "john.smith@contoso.com",
   "firstName": "John",
   "lastName": "Smith"
}

如果一切顺利,它应该返回200状态和您的人的副本。由于我们不验证John Smith是否已经存在,我们可以继续添加John Smith,但我们每次都应该获得一个唯一的ID

通过在Azure门户中查找Cosmos DB帐户并转到数据资源管理器选项卡来确认它确实有效。

使用输入绑定读取

现在,创建第二个函数以从Cosmos DB读取人员。在VS Code中,转到Azure选项卡,单击创建函数并选择HTTP触发器。这将在单独的文件夹中创建HttpTrigger2

再次打开function.json文件,但这次删除POST方法并添加一个值为person/{partitionKey}/{id}的路由。Cosmos DB输入绑定看起来有点像输出绑定,只是我们需要指定ID和分区键。我们在这里使用我们的路由参数。

{
   "bindings": [
      {
         "authLevel": "function",
         "type": "httpTrigger",
         "direction": "in",
         "name": "req",
         "methods": [
            "get"
         ],
         "route": "person/{partitionKey}/{id}"
      },
      {
         "name": "personIn",
         "databaseName": "mydb",
         "collectionName": "person",
         "connectionStringSetting": "CosmosDBConnString",
         "id": "{id}",
         "partitionKey": "{partitionKey}",
         "direction": "in",
         "type": "cosmosDB"
      },
      {
         "type": "http",
         "direction": "out",
         "name": "res"
      }
   ],
   "scriptFile": "../dist/HttpTrigger2/index.js"
}

这一次,我们可以从context.bindings.[name of the binding]中读取这个人。分区键和ID取自您的URL,因此我们可以通过浏览到https://[your URL]/api/person/[initial]/[ID]来获取一个人。TypeScript非常简单。

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
   context.res = {
      // status: 200, /* Defaults to 200 */
      body: context.bindings.personIn
   };
};

因此,无需为Cosmos DB编写任何代码,我们就能够在数据库中插入和读取文本。

修复我们的发布

不幸的是,此更改破坏了我们的发布。如果您推送您的更改,您会看到一切都已发布并且似乎可以正常工作,直到您实际向URL发出请求。

这是因为local.settings.json文件不在源代码管理中,但我们向其中添加了连接字符串。要确认这确实是您的问题,请转到Azure门户中的Function App,然后转到配置并添加“CosmosDBConnString”和您的连接字符串作为值。该应用程序将重新启动,它应该会再次运行。

我们实际上可以将此解决方案添加到我们的版本中。在Azure DevOps发布管道中,将其添加到部署Azure Function App任务。

在任务中,找到App Settings然后添加-CosmosDBConnString $(CosmosDBConnString)

现在,添加CosmosDBConnString变量并设置值,将范围设置为开发,并通过单击锁将其设为机密。连接字符串将添加到您的函数应用程序中,并且没有人能够看到该值(他们只能设置一个新值)。通过创建新版本来确认它有效。

部署基础设施

现在一切正常。如果您对TypeScript进行更改并将其推送到您的存储库,它将被自动构建、测试和部署。但是,如果我们要创建另一个环境,则必须手动创建一个Function App和一个Cosmos DB,这既耗时又容易出错。

我们可以使用Azure资源管理模板(也称为 ARM 模板)、PowerShellPowerShell CoreBashShellAzure中创建资源。向管道添加新任务并查找Azure CLI任务。将它放在Azure Functions任务之前。设置连接并选择脚本类型Shell和位置内联脚本。

我们现在可以将Azure CLI命令添加到我们的构建中。您可能希望将一些脚本添加到您的存储库并使用它们,但为简单起见,我们使用内联脚本。

我们先创建一个资源组,然后我们可以添加Function App,它也需要一个存储帐户。

az group create --name $(ResourceGroupName) --location $(Location)

az storage account create --resource-group $(ResourceGroupName) --name $(StorageAccountName) --location $(Location) --sku Standard_LRS

az functionapp create --resource-group $(ResourceGroupName) --name $(AppServiceName) --storage-account $(StorageAccountName) --consumption-plan-location $(Location) --functions-version 3 --os-type Linux --runtime node

现在,进入变量并添加ResourceGroupNameLocationStorageAccountName。将位置设置为“westeurope”“westus”或您附近的任何内容。

您可以使用资源组的名称作为ResourceGroupName或使用新的名称,最好以“-dev”结尾,以便您知道这是您的开发环境。如果为资源组使用其他名称,则还必须为函数应用使用新名称,为存储帐户使用新名称。

存储帐户名称在所有Azure中必须是唯一的,只能包含字母,并且不得超过24个字符。这是一个严格的命名策略,但这就是Azure的工作方式。

确保除位置外的所有变量都适用于开发。填写完空格后,保存并运行部署并检查您是否没有收到错误。此部署可能需要几分钟时间,因为它会在您的Azure帐户中创建新资源。

部署Cosmos DB

如果一切顺利,请将另一个Azure CLI任务添加到管道中,并将其放在Azure Functions任务之后。在此CLI中,我们将创建Cosmos DB帐户,读取连接字符串,并将其放置在应用服务的配置中。如果我们一直手动添加连接字符串,我们需要做一次发布,手动获取和设置连接字符串,最后再做一次发布。但是,我们希望这一切同时生效。

az cosmosdb create --resource-group $(ResourceGroupName) --name $(CosmosDBAccountName) --locations regionName=$(Location) failoverPriority=0 isZoneRedundant=False

CONN_STRING=$(az cosmosdb keys list --name $(CosmosDBAccountName) --resource-group $(ResourceGroupName) --type connection-strings --query "connectionStrings[0].connectionString" -o tsv)

az webapp config appsettings set --resource-group $(ResourceGroupName) --name $(AppServiceName) --settings "CosmosDBConnString=$CONN_STRING"

Cosmos DB成功部署后,查询连接字符串并将其存储在脚本变量中。最后,添加CosmosDBConnString到我们的函数应用程序的配置中。通过在脚本中执行此操作,我们可以部署我们想要的任何内容、更改名称、更改环境等等,并且我们将始终拥有连接字符串。

现在可以从Azure Functions任务和变量中删除连接字符串。

部署DTAP

现在,转到您的管道概览,您可以在其中查看工件和阶段。将鼠标悬停在您的开发阶段,然后单击出现的克隆按钮。这将创建阶段开发副本,您可以将其重命名为测试。两个阶段之间有一条线,这意味着测试将在开发之后部署。单击测试阶段上的闪电按钮将触发器更改为仅手动。这将阻止您的代码在推送到您的存储库后自动进入您的测试环境。如果需要,您可以设置部署前批准。如果您进行了大量推送,但又不想在测试人员进行测试时打扰他们,则您可能更喜欢手动方法。

所以,很酷的是,你的整个开发阶段都被复制了,包括你的变量。但是,您的变量现在设置为测试范围。这意味着您只需要更改这些变量,就可以部署一个全新的环境!

由于我们没有在脚本中使用任何硬命名,我们甚至不必查看它们。因此,在您的变量中,在作用域为Test的变量上输入一个新名称。只有您的位置保持不变,因为它的作用域是整个版本。

设置变量后,保存,创建新版本,触发测试阶段,然后转到Azure门户以确认一切正常。尝试使用Postman触发您的Azure函数来插入和读取一个人。

下一步

在本文中,我们向Azure函数添加了Cosmos DB输入和输出绑定。当然,您可以像往常一样使用npm包连接到任何数据库。通过将我们的基础设施添加到上一篇文章的发布管道中,我们能够快速轻松地启动新环境,无需人工干预,也无需追踪错误。

正如您在本系列中学到的,通过一些设置,您可以自动执行以前手动执行的任务。这让您有时间专注于更重要的项目,例如创建新功能来让您的客户惊叹,同时根据需要轻松扩展以支持您不断增长的客户群。

恭喜!完成本教程后,您现在正式成为云原生。如果您准备了解更多信息,请查看以您在此处开发的技能为基础的中级云原生系列。

要了解有关在Azure上使用Kubernetes的更多信息,请浏览Kubernetes Bundle | Microsoft AzureAzure上的动手Kubernetes | 微软Azure

Build a Complete Microservice - CodeProject

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值