Microsoft Azure Functions

Microsoft Azure Functions 是 Microsoft Azure 平台上，提供无服务器计算架构 (Serverless Computing) 的服务，允许开发人员在不用接触与管理服务器的情况下，编写小型的处理程式以处理云端上的讯息或事件。

Azure Functions 于微软 Build 2016 大会上宣布，于同年11月15日正式 GA (General Availability)。

Azure Functions 已广泛于用如 Azure Bot Services、Azure IoT Suite、Azure Logic App 等服务串联。

## 简介

Azure Functions 是以 Azure Web App 开发时所建立的 Microsoft Azure Azure Web Jobs 为基础所开发的一个服务，Web Jobs 在开发时就已经支援多语言 (包含 Bash, 批次档, C#, node.js, PowerShell, F#, Python 与 PHP 等) 的执行环境，因此在发展 Azure Functions 时，也将 Web Jobs 的多语言能力移植到 Azure Functions，同时基于无服务器的架构，Azure Functions 只要求开发人员在 Azure 的管理界面上撰写程式码，即可立即测试与执行，不必担心背后的资源分配与服务器管理的问题。

Azure Functions 在设计上以函数 (function) 会有的特性来规划，一个函数本身会有输入 (input)、处理 (process) 与输出 (output) 三个部分，微软将输入和输出进行抽象化的处理，以系结 (binding) 来替代。

- 输入系结 (input binding) 表示函数会于系结指定的条件发生时触发，并将条件所需的参数传到函数作为输入的参数 (argument)。
- 输出系结 (output binding) 表示函数会输出成指定的格式，通常作为回传值 (return value)。

Azure Functions 如同其他 Azure应用服务 一般，执行于 App Service Plan (应用服务计划) 之上，不过为了要达到无服务器架构的目标，Azure Functions 还多了一个使用模式，称为消费计划 (Consumption Plan)，以执行次数 (Executions) 和执行时的资源耗用量 (Resource Consumption) 为计费基础，但使用者可选择要用原始的 App Service Plan 还是要使用计量级的 Consumption Plan 作为计费单位。

## 功能

Azure Functions 基于无服务器管理架构，因此其功能大多数都落在程式码的开发、系结的设定与安全金钥的管理，当然也可以依需求进一步的设定其所处的 App Service Plan (即使是 Consumption Plan 也有) 的进阶设定，例如加上 SSL 或增修应用程序组态档的设定等等。

### 程式码管理

Azure Functions 允许开发人员直接编写函数的程式码，也就是处理 (Process) 这个部分，基于与函数的系结的整合，微软提供了数个样板 (template) 给开发人员选用，每个支援的系结都会有一个样板，开发人员不需费心于思考如何在函数中使用系结，只要在函数的本体中编写处理的程式码即可。

例如使用 HTTP 触发 (即送 HTTP 要求给该函数) 的 C# 程式码如下：

```csharp
public static Task<HttpResponseMessage> Run(HttpRequestMessage request, string category, int? id, TraceWriter log)
    {
        if (id == null)
           return  req.CreateResponse(HttpStatusCode.OK, $"All {category} items were requested.");
        else
           return  req.CreateResponse(HttpStatusCode.OK, $"{category} item with id = {id} has been requested.");
    }
```

而同样功能的 node.js 程式码如下：

```javascript
module.exports = function (context, req) {

        var category = context.bindingData.category;
        var id = context.bindingData.id;

        if (!id) {
            context.res = {
                // status: 200, /* Defaults to 200 */
                body: "All " + category + " items were requested."
            };
        }
        else {
            context.res = {
                // status: 200, /* Defaults to 200 */
                body: category + " item with id = " + id + " was requested."
            };
        }

        context.done();
    }
```

范本会先为开发人员设定好参数，开发人员只要填入处理的程式即可。

另外，Azure Functions 也支援由 git 部署，然而若使用 git 部署时，Azure Portal 上的程式码编辑器会强制停用。

### 系结

系结决定了函数的输入、触发时间与输出，Azure Functions 支援了下列的触发程序、输入与输出。由于触发程序和输入参数可以不同，因此下表中无输入但有触发支援时，触发的参数会作为输入的参数。

类型｜触发｜输入｜输出

排程｜支援 (设定的时间或周期到时)

HTTP｜支援 (接到由 REST 或 WebHook 发送的 HTTP 要求时)｜支援

Blob｜支援 (Azure Storage Blob 监控的容器有资料新增或更新时)｜支援｜支援

事件｜支援 (EventHub 有事件进入时)｜支援

伫列｜支援 (Azure Storage Queue 伫列内有讯息时)｜支援

伫列和主题｜支援 (Azure Service Bus Queue 伫列或 Topic 主题内有讯息时)｜支援

储存体资料表｜支援｜支援

SQL 资料表｜支援｜支援

NoSQL 数据库｜支援｜支援

通知讯息｜支援

Twilio SMS 服务｜支援

SendGrid｜支援

每个输入、输出系结与触发程序也会有必要的参数设定 (例如排程需要设定执行周期、Blob 需要设定监控的储存体账户与容器等等)。

系结的设定除了可在使用者界面上设定外，也可使用每个函数都有的 function.json 档案设定，例如下列设定表示了监控 blob 的输入，如果有输入就触发函数，并且将函数的输出指定为另一个 blob 的系结。

```json
{
  "bindings": [
    {
      "name": "image",
      "type": "blobTrigger",
      "path": "sample-images/{filename}",
      "direction": "in",
      "connection": "MyStorageConnection"
    },
    {
      "name": "imageSmall",
      "type": "blob",
      "path": "sample-images-sm/{filename}",
      "direction": "out",
      "connection": "MyStorageConnection"
    }
  ],
}
```

### 存取控制

使用 HTTP 系结作为输入的函数 (通常用于 REST 与 WebHook)，Azure Functions 会另外提供金钥 (Key) 给开发人员使用，以作为存取控制的方法。

金钥预设有两种：

- 主机金钥 (master key)：所有建于此应用程序内的所有函数都可使用。
- 函数金钥 (function key): 只有金钥所属的函数可使用。

除了上面两个预设的金钥外，开发人员也可建立自己的金钥，并决定存取权限是限制于函数，还是要支援所有的函数。

## 开发人员支援

Azure Functions 除了提供 Azure Portal 上的程式码编修，以及采用 git 的持续整合的程式码管理方式外，也为开发人员在地端的作业提供了 Azure Function Runtime，以加速开发人员在地端的开发与测试。

Visual Studio Code 也有套件支援 Azure Functions 的开发。

## 外部链接

- Introducing Azure Functions
- Azure Functions Overview