CloudBluePrint-Chapter 1.7 : 云上应用技术架构-函数计算、Serverless、小程序

2023-09-07 10:07:19 浏览数 (2)

概述

FaaS(函数即服务)、Serverless、小程序和弹性云计算的诞生可以归因于云计算发展的趋势和应用架构的演变。

云服务技术趋势

  • 可扩展性:随着对可扩展和灵活解决方案需求的增加,传统基于服务器的架构在有效管理资源方面面临挑战。FaaS和Serverless通过提供按需可扩展性来解决这个问题,允许应用根据工作负载自动进行扩展。
  • 成本优化:云服务提供商引入了按使用量付费的定价模型,使企业能够通过仅支付所消耗的资源来优化成本。FaaS和Serverless进一步增强了成本优化,通过按实际执行函数的时间计费,而不是持续使用服务器。
  • 简化开发:开发人员希望更多地专注于应用逻辑而不是基础架构管理。FaaS和Serverless抽象了基础架构管理的复杂性,使开发人员能够快速轻松地编写和部署代码。

应用架构演变

  • 微服务:应用越来越多地以松耦合的微服务集合形式开发。FaaS和Serverless与这种架构相契合,因为它们允许开发人员独立部署单个函数或微服务,促进模块化和灵活性。
  • 事件驱动架构:许多现代应用程序是事件驱动的,即特定的函数或工作流由操作或事件触发。FaaS和Serverless在事件驱动场景中表现出色,因为它们可以轻松地被事件触发,如API调用、数据库更新或消息队列。
  • 轻量级应用:用户希望获得轻量级、便捷的体验,无需下载或安装单独的应用程序。小程序通过在类似微信或支付宝等大型平台内提供特定功能来满足这一需求。

弹性云计算

  • 工作负载灵活性:弹性云计算允许企业根据需求动态调整资源规模。这种灵活性确保应用能够高效处理不同的工作负载,避免资源过度配置或利用不足。
  • 成本效益:通过根据需求动态分配资源,弹性云计算有助于优化成本。企业只需支付所需的资源,避免了维护闲置资源所带来的不必要开销。

函数计算的关联性

FaaS(Function as a Service)、Serverless、小程序和弹性计算之间的关联性可以简要概述如下:

  • FaaS是Serverless计算的一个子集,开发人员可以在不管理底层基础架构的情况下部署和运行单个函数或代码片段。
  • Serverless计算是一个更广泛的概念,包括FaaS在内。它指的是在云环境中执行代码而无需管理服务器,使开发人员可以专注于编写代码而不是基础架构管理。
  • 小程序是轻量级应用程序,运行在较大的平台或生态系统中。可以利用Serverless计算来开发和部署小程序,为用户提供特定的功能,无需单独安装应用程序。
  • 弹性计算指的是根据需求动态扩展计算资源的能力。Serverless计算天然支持弹性,根据工作负载要求自动调整资源规模,确保资源分配高效和成本优化。

FaaS、Serverless计算、小程序和弹性计算之间存在关联性,它们都利用云计算的优势为开发人员和用户提供可扩展、经济高效和灵活的解决方案。

函数计算的局限性

尽管函数计算(FaaS)具有许多优点,但它也存在一些局限性。这些包括执行时间限制、冷启动延迟、资源限制、状态管理挑战、厂商锁定、调试复杂性和可伸缩性限制。

  • 执行时间限制:函数计算平台通常对函数设置执行时间限制。例如,AWS Lambda的最大执行时间为5分钟。长时间运行或资源密集型任务可能不适合使用函数计算,可能需要其他解决方案。
  • 冷启动延迟:当一个函数首次被调用或在一段时间不活动后再次被调用时,函数计算平台可能会出现“冷启动”延迟。这是初始化函数的运行时环境所需的时间,导致初始请求的响应时间增加。
  • 资源限制:函数计算平台通常对每个函数可用的内存、CPU和存储量设置限制。这可能会限制可以有效部署在函数计算平台上的应用程序类型。
  • 状态管理:函数计算的设计理念是无状态的,意味着它们在调用之间不保留任何持久状态。虽然这简化了开发过程,但在需要维护状态或在函数调用之间共享数据的场景下可能会带来挑战。
  • 厂商锁定:每个云提供商都提供自己的函数计算平台,具有自己的功能和限制。这可能导致锁定厂商,使得在不进行重大修改的情况下难以将函数迁移到不同的提供商之间。
  • 调试和监控:与传统基于服务器的应用程序相比,在无服务器环境中调试和监控函数运行更具挑战性。对基础架构的可见性有限,这使得更难以识别和解决问题。
  • 可伸缩性限制:虽然函数计算平台提供自动扩展功能,但可能存在最大并发函数调用数或最大实例数的限制。这可能会影响处理突发流量或大规模并行处理的能力。

在决定是否在特定用例中使用函数计算时,需要考虑这些限制,并在这些限制可能带来挑战时探索替代解决方案。

函数计算模式的实现

函数计算,Serverless,小程序的差异

服务/平台

支持的语言

不支持的语言

FaaS(如AWS Lambda,Google Cloud Functions,Azure Functions等)

Python, Node.js, Java, C#, Go, Ruby(具体支持的语言取决于具体的云服务提供商)

冷门或特定领域的语言,如Rust, Erlang, Haskell等

Serverless

Node.js, Python, Java, Go, C#, Swift, Kotlin等

可以通过插件扩展对其他语言的支持

小程序(如微信小程序,阿里小程序,百度小程序等)

JavaScript, TypeScript

不支持除JavaScript和TypeScript之外的其他编程语言

开源社区函数计算的实现

OpenFaaS

OpenFaaS(Functions as a Service)是一个使用Docker和Kubernetes构建无服务器函数的开源框架。它允许您将函数打包为容器,并在任何Kubernetes集群上部署它们。它支持多种编程语言,包括Node.js、Python、Go和Java。

Kubeless

Kubeless是一个针对Kubernetes的开源无服务器框架。它允许您在Kubernetes集群上部署和运行函数,无需管理底层基础设施。它支持多种编程语言,包括Node.js、Python、Ruby和PHP。

OpenWhisk

OpenWhisk是一个开源的无服务器平台,支持多种编程语言,并可在各种云平台或本地部署。它为运行无服务器函数提供了灵活且可扩展的环境。

Knative

Knative是一个建立在Kubernetes之上的开源无服务器平台, 支持多种编程语言,并与流行的开发工具和框架集成。它提供了一组中间件组件,使开发人员能够在Kubernetes上部署、运行和管理无服务器工作负载。Knative旨在提供一个更高级的抽象,用于构建和部署无服务器应用程序,使开发人员更专注于编写代码而不是管理基础设施。Knative包括三个主要组件: Serving(服务)、Eventing(事件)和Build(构建)

  • Serving负责运行和扩展无服务器应用程序
  • Eventing支持事件驱动的架构
  • Build自动化从源代码构建容器镜像

云厂商函数计算托管服务

云服务提供商

产品与服务

特性

典型应用场景

支持的语言

AWS

Lambda

自动扩展,无服务器,事件驱动计算

实时文件处理,数据转换,后端API

Node.js, Java, C#, Go, PowerShell, Ruby, Python

GCP

Cloud Functions

事件驱动,自动扩展,无服务器

数据处理,实时分析,后端服务

Node.js, Python, Go

Microsoft Azure

Azure Functions

事件驱动,无服务器,支持多种触发器

实时流分析,数据处理,IoT后端

C#, JavaScript, F#, Java, PowerShell, Python, TypeScript

Alibaba Cloud

Function Compute

事件驱动,自动扩展,无服务器

日志处理,图片处理,大数据分析

Python, Java, Node.js, PHP

Tencent Cloud

SCF (Serverless Cloud Function)

事件驱动,自动扩展,无服务器

实时文件处理,数据清洗,后端API

Node.js, Python, PHP, Java, Go

函数计算的未来趋势

以下是一些函数计算和Serverless架构应用,可能的未来发展趋势:

  • 更广泛的采用:随着开发者和企业更加了解和信任无服务器技术,无服务器计算和函数计算的采用率将大幅度提高。
  • 混合云和多云环境:随着混合云和多云环境的流行,无服务器技术将更加灵活地适应不同的云环境。这意味着开发者可以在任何云平台上使用相同的无服务器框架和工具,使得跨云部署和管理变得更加简单。
  • eBPF的整合:eBPF(扩展的伯克利数据包过滤器)是一种新兴的技术,它允许开发者在Linux内核中运行自定义的安全、网络和性能分析程序。通过整合eBPF,无服务器平台可以提供更高级的观察性、安全性和性能优化。
  • AI和机器学习的集成:随着AI和机器学习的发展,我们预计无服务器平台将提供更多集成这些技术的工具和服务。例如,开发者可以使用无服务器函数来处理机器学习模型的训练和推理。
  • 更丰富的开发者工具:随着无服务器计算的复杂性增加,我们预计将出现更多的工具来帮助开发者编写、测试和部署无服务器应用。这可能包括更好的本地测试工具、更强大的部署和监控工具,以及更多的教育资源。
  • 标准化:随着无服务器计算的发展,行业内可能会形成一些标准,以解决目前存在的互操作性问题。例如,开发者可能会推动创建一个标准的函数签名,使得在不同的无服务器平台之间迁移变得更容易。

开源社区示例代码

OpenFaaS

假设我们有一个简单的Python函数,它接受一个字符串并返回反转后的字符串。在OpenFaaS中,我们可以创建一个名为handler.py的文件,并在其中定义这个函数:

代码语言:python代码运行次数:0复制
def handle(req):
    """handle a request to the function
    Args:
        req (str): request body
    """
    return req[::-1]

Kubeless

在Kubeless中,我们可以创建一个名为reverse.py的文件,并在其中定义一个类似的函数:

代码语言:python代码运行次数:0复制
def reverse(event, context):
    return event['data'][::-1]

然后,我们可以使用Kubeless CLI将这个函数部署到Kubernetes集群:

代码语言:shell复制
kubeless function deploy reverse --runtime python3.7 --from-file reverse.py --handler reverse.reverse

OpenWhisk

在OpenWhisk中,我们可以创建一个名为reverse.js的文件,并在其中定义一个类似的函数:

代码语言:javascript复制
function main(params) {
    return {payload: params.payload.split("").reverse().join("")};
}

然后,我们可以使用OpenWhisk CLI将这个函数部署到OpenWhisk平台:

代码语言:shell复制
wsk action create reverse reverse.js

Knative

在Knative中,我们可以创建一个名为reverse.go的文件,并在其中定义一个HTTP处理函数:

代码语言:go复制
package main

import (
	"fmt"
	"net/http"
)

func reverseHandler(w http.ResponseWriter, r *http.Request) {
	msg := []rune(r.URL.Query().Get("msg"))
	for i, j := 0, len(msg)-1; i < j; i, j = i 1, j-1 {
		msg[i], msg[j] = msg[j], msg[i]
	}
	fmt.Fprint(w, string(msg))
}

func main() {
	http.HandleFunc("/", reverseHandler)
	http.ListenAndServe(":8080", nil)
}

然后,我们可以创建一个Knative服务来部署这个应用:

代码语言:yaml复制
apiVersion: serving.knative.dev/v1 # The version of the Knative API to use
kind: Service
metadata:
  name: reverse # The name of the app
  namespace: default # The namespace the app will use
spec:
  template:
    spec:
      containers:
        - image: gcr.io/my-project/reverse # The URL to the image of the app
          ports:
            - containerPort: 8080

按照云服务提供商分类

以下是各大云服务提供商的函数计算、Serverless和小程序的示例代码:

AWS

  • Lambda函数计算(Python):
代码语言:python代码运行次数:0复制
def lambda_handler(event, context):
    message = event['message'][::-1]
    return {
        'message' : message
    }
  • Serverless(Node.js):
代码语言:javascript复制
module.exports.hello = async event => {
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: 'Go Serverless v1.0! Your function executed successfully!',
        input: event,
      },
      null,
      2
    ),
  };
};
  • 小程序(AWS Amplify与JavaScript):
代码语言:javascript复制
import Amplify from 'aws-amplify';
import awsconfig from './aws-exports';

Amplify.configure(awsconfig);

// 在应用中使用 AWS 服务

GCP

  • Cloud Functions(Node.js):
代码语言:javascript复制
exports.helloWorld = (req, res) => {
  res.send('Hello, World');
};
  • Serverless(Python):
代码语言:python代码运行次数:0复制
def hello_http(request):
    return 'Hello World!'
  • 小程序(Firebase与JavaScript):
代码语言:javascript复制
var firebaseConfig = {
  // ...
};
firebase.initializeApp(firebaseConfig);

Azure

  • Azure Functions(JavaScript):
代码语言:javascript复制
module.exports = async function (context, req) {
    context.res = {
        body: "Hello, World"
    };
}
  • Serverless(C#):
代码语言:c#复制
public static class Function1
{
    [FunctionName("Function1")]
    public static async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req)
    {
        return new OkObjectResult("Hello, World");
    }
}
  • 小程序(Azure Mobile Apps与JavaScript):
代码语言:javascript复制
var client = new WindowsAzure.MobileServiceClient('https://your-service.azurewebsites.net');

阿里云

  • 函数计算(Python):
代码语言:python代码运行次数:0复制
def handler(event, context):
  print("hello world")
  return 'hello world'
  • Serverless(Node.js):
代码语言:javascript复制
exports.handler = function(event, context, callback) {
  callback(null, 'hello world');
};
  • 小程序(阿里云SDK与JavaScript):
代码语言:javascript复制
var client = new OSS({
  region: '<Your region>',
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>',
});

腾讯云

  • 云函数(Node.js):
代码语言:javascript复制
exports.main = async (event, context) => {
  return event
}
  • Serverless(Node.js):
代码语言:javascript复制
module.exports.hello = async (event, context) => {
  return {
    message: 'Hello, Tencent Cloud!'
  }
}
  • 小程序(微信小程序与JavaScript):
代码语言:javascript复制
wx.cloud.init({
  env: 'my-env-id',
  traceUser: true,
})

按照常见的业务场景分类

实时文件处理

例如,用户在小程序中上传图片,可以通过函数计算进行实时的图片处理,如压缩、裁剪等,并将处理后的图片保存到云存储中。

代码语言:python代码运行次数:0复制
import os
from PIL import Image

def handle(event, context):
  # 获取上传的文件信息
  bucket_name = event['oss']['bucket']['name']
  object_key = event['oss']['object']['key']
  
  # 打开图片并进行处理
  with Image.open('/tmp/'   object_key) as img:
    # 进行图片压缩、裁剪等操作
    img.thumbnail((800, 800))
    img.save('/tmp/'   object_key)

  # 将处理后的图片上传到云存储
  s3_client.upload_file('/tmp/'   object_key, bucket_name, object_key)

日志处理和实时分析

例如,小程序产生的用户行为日志可以通过Serverless实时推送到日志服务,然后通过函数计算进行实时分析,生成用户行为报告。

代码语言:python代码运行次数:0复制
import json
import boto3

def handle(event, context):
  # 获取日志事件
  log_events = event['awslogs']['data']

  # 对日志事件进行解析和处理
  for log_event in log_logs:
    # 进行实时分析,如用户行为统计等
    analysis_result = analyze(log_event)

  # 将分析结果保存到数据库或发送报告
  db_client.put_item(
    TableName='analysis_result',
    Item=analysis_result
  )
  1. 定时任务:例如,每天定时清理过期的数据,或者定时发送用户活跃度报告等。
代码语言:python代码运行次数:0复制
import boto3

def handle(event, context):
  # 获取当前时间
  current_time = context['time']

  # 清理过期数据
  db_client.delete_items(
    TableName='user_data',
    KeyConditionExpression='expire_time < :current_time',
    ExpressionAttributeValues={':current_time': current_time}
  )

  # 或者定时发送用户活跃度报告
  report = generate_report()
  email_client.send_email(
    Subject='Daily Active User Report',
    Body=report,
    ToAddresses=['admin@example.com']
  )

IoT 数据处理

例如,设备发送的数据可以通过函数计算进行实时处理,比如温度传感器发送的数据可以用来实时监控和报警。

代码语言:python代码运行次数:0复制
def handle(event, context):
  # 获取设备数据
  device_data = event['device_data']

  # 对设备数据进行处理,如温度监控和报警
  if device_data['temperature'] > THRESHOLD:
    send_alert(device_data['device_id'], 'Temperature is too high!')

视频流处理

例如,用户上传的视频可以通过函数计算进行实时转码或者内容审核。

代码语言:python代码运行次数:0复制
def handle(event, context):
  # 获取上传的视频信息
  bucket_name = event['oss']['bucket']['name']
  object_key = event['oss']['object']['key']

  # 对视频进行处理,如转码或内容审核
  transcode_video(bucket_name, object_key)

AI 模型预测

例如,用户在小程序中上传图片,可以通过函数计算调用 AI 模型进行预测,如图像分类或人脸识别。

代码语言:python代码运行次数:0复制
import boto3

def handle(event, context):
  # 获取上传的图片信息
  bucket_name = event['s3']['bucket']['name']
  object_key = event['s3']['object']['key']

  # 调用 AI 模型进行预测
  prediction = predict_image(bucket_name, object_key)

  # 返回预测结果
  return {
    'statusCode': 200,
    'body': json.dumps(prediction)
  }

消息队列处理

例如,用户下单后,订单信息会被放入消息队列,然后通过函数计算进行处理,如库存检查和订单确认。

代码语言:python代码运行次数:0复制
import boto3

def handle(event, context):
  # 获取订单信息
  order_info = event['Records'][0]['body']

  # 对订单进行处理,如库存检查和订单确认
  check_stock(order_info)
  confirm_order(order_info)

这些示例代码主要是伪代码,并没有具体的实现细节。在实际使用时,你需要根据具体的云服务提供商的 SDK 和 API 进行具体的实现。

相关文档资源

1. OpenFaaS

  • 官方文档:docs.openfaas.com
  • GitHub:github.com/openfaas/faas
  • 社区:community.openfaas.com

2. Kubeless

  • 官方文档:kubeless.io/docs
  • GitHub:github.com/kubeless/kubeless
  • 社区:kubeless.io/community

3. OpenWhisk

  • 官方文档:openwhisk.apache.org/documentation.html
  • GitHub:github.com/apache/openwhisk
  • 社区:openwhisk.apache.org/community.html

4. Knative

  • 官方文档:knative.dev/docs
  • GitHub:github.com/knative
  • 社区:knative.dev/community

0 人点赞