写点什么

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

作者:深蓝
  • 2023-11-20
    北京
  • 本文字数:6648 字

    阅读完需:约 22 分钟

链接:https://github.com/svc-design/ebooks


概述

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,小程序的差异

开源社区函数计算的实现

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 自动化从源代码构建容器镜像

云厂商函数计算托管服务

函数计算的未来趋势

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

  • 更广泛的采用:随着开发者和企业更加了解和信任无服务器技术,无服务器计算和函数计算的采用率将大幅度提高。

  • 混合云和多云环境:随着混合云和多云环境的流行,无服务器技术将更加灵活地适应不同的云环境。这意味着开发者可以在任何云平台上使用相同的无服务器框架和工具,使得跨云部署和管理变得更加简单。

  • eBPF 的整合:eBPF(扩展的伯克利数据包过滤器)是一种新兴的技术,它允许开发者在 Linux 内核中运行自定义的安全、网络和性能分析程序。通过整合 eBPF,无服务器平台可以提供更高级的观察性、安全性和性能优化。

  • AI 和机器学习的集成:随着 AI 和机器学习的发展,我们预计无服务器平台将提供更多集成这些技术的工具和服务。例如,开发者可以使用无服务器函数来处理机器学习模型的训练和推理。

  • 更丰富的开发者工具:随着无服务器计算的复杂性增加,我们预计将出现更多的工具来帮助开发者编写、测试和部署无服务器应用。这可能包括更好的本地测试工具、更强大的部署和监控工具,以及更多的教育资源。

  • 标准化:随着无服务器计算的发展,行业内可能会形成一些标准,以解决目前存在的互操作性问题。例如,开发者可能会推动创建一个标准的函数签名,使得在不同的无服务器平台之间迁移变得更容易。

开源社区示例代码

OpenFaaS

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

def handle(req):    """handle a request to the function    Args:        req (str): request body    """    return req[::-1]
复制代码

复制

Kubeless

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

def reverse(event, context):    return event['data'][::-1]
复制代码

复制

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

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

复制

OpenWhisk

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

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

复制

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

wsk action create reverse reverse.js
复制代码

复制

Knative

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

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 服务来部署这个应用:

apiVersion: serving.knative.dev/v1 # The version of the Knative API to usekind: Servicemetadata:  name: reverse # The name of the app  namespace: default # The namespace the app will usespec:  template:    spec:      containers:        - image: gcr.io/my-project/reverse # The URL to the image of the app          ports:            - containerPort: 8080
复制代码

复制

按照云服务提供商分类

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

AWS

  • Lambda 函数计算(Python):

def lambda_handler(event, context):    message = event['message'][::-1]    return {        'message' : message    }
复制代码

复制

  • Serverless(Node.js):

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):

import Amplify from 'aws-amplify';import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
// 在应用中使用 AWS 服务
复制代码

复制

GCP

  • Cloud Functions(Node.js):

exports.helloWorld = (req, res) => {  res.send('Hello, World');};
复制代码

复制

  • Serverless(Python):

def hello_http(request):    return 'Hello World!'
复制代码

复制

  • 小程序(Firebase 与 JavaScript):

var firebaseConfig = {  // ...};firebase.initializeApp(firebaseConfig);
复制代码

复制

Azure

  • Azure Functions(JavaScript):

module.exports = async function (context, req) {    context.res = {        body: "Hello, World"    };}
复制代码

复制

  • Serverless(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):

var client = new WindowsAzure.MobileServiceClient('https://your-service.azurewebsites.net');
复制代码

复制

阿里云

  • 函数计算(Python):

def handler(event, context):  print("hello world")  return 'hello world'
复制代码

复制

  • Serverless(Node.js):

exports.handler = function(event, context, callback) {  callback(null, 'hello world');};
复制代码

复制

  • 小程序(阿里云 SDK 与 JavaScript):

var client = new OSS({  region: '<Your region>',  accessKeyId: '<Your AccessKeyId>',  accessKeySecret: '<Your AccessKeySecret>',});
复制代码

复制

腾讯云

  • 云函数(Node.js):

exports.main = async (event, context) => {  return event}
复制代码

复制

  • Serverless(Node.js):

module.exports.hello = async (event, context) => {  return {    message: 'Hello, Tencent Cloud!'  }}
复制代码

复制

wx.cloud.init({  env: 'my-env-id',  traceUser: true,})
复制代码

复制

按照常见的业务场景分类

实时文件处理

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

import osfrom 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 实时推送到日志服务,然后通过函数计算进行实时分析,生成用户行为报告。

import jsonimport 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. 定时任务:例如,每天定时清理过期的数据,或者定时发送用户活跃度报告等。

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 数据处理

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

def handle(event, context):  # 获取设备数据  device_data = event['device_data']
# 对设备数据进行处理,如温度监控和报警 if device_data['temperature'] > THRESHOLD: send_alert(device_data['device_id'], 'Temperature is too high!')
复制代码

复制

视频流处理

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

def handle(event, context):  # 获取上传的视频信息  bucket_name = event['oss']['bucket']['name']  object_key = event['oss']['object']['key']
# 对视频进行处理,如转码或内容审核 transcode_video(bucket_name, object_key)
复制代码

复制

AI 模型预测

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

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) }
复制代码

复制

消息队列处理

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

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

用户头像

深蓝

关注

还未添加个人签名 2018-08-28 加入

还未添加个人简介

评论

发布
暂无评论
云上应用技术架构-函数计算、Serverless、小程序_深蓝_InfoQ写作社区