开发一个Serverless应用

简介: 当我们通过Serverless架构,建立了一个函数,并输出了Hello World之后,表明我们已经完成了Serverless架构的“初体验”,接下来,我们可以以其中一个云厂商为例(例如阿里云),进行基础的小工具开发和建设。

当我们通过Serverless架构,建立了一个函数,并输出了Hello World之后,表明我们已经完成了Serverless架构的“初体验”,接下来,我们可以以其中一个云厂商为例(例如阿里云),进行基础的小工具开发和建设。

在我们日常的生产中,需要获取客户端外网IP是一个非常常见的需求,但是在客户端直接获取外网IP实际上是一个比较困难的事情,这个时候就会有一个简单的方法:在服务端开一个接口来做这个事情,即当客户端请求该接口之后,该接口返回其IP地址。

如果我们选择用Python语言来开发这个项目,在传统的项目中,这个看似简单的应用,实际上并不简单,它通常需要我们有:

这里面包括Nginx,Python的环境,还要有我们所需要的Web Framework的框架(例如Django、Flask、Bottle、Web2py等),除此之外还要有我们的业务逻辑。在项目完成开发,上线之后,我们可能还需要对服务器的健康等进行持续关系和关注,必要时还要做一些高可用方案等。但是在Serverless架构下,这个过程将会变得非常简单:

在整个项目中,我们无需关注Nginx这些服务器软件,无需关注Python等环境的安装配置,更不用关心一些服务器的运维操作,在很多时候也无需关注高可用,我们关心的只是我们的函数代码,至于一些服务器软件全都交给云厂商来搞定,API网管等产品提供类似Nginx的能力,函数计算提供Python的运行环境,至于高可用、极致弹性则是函数计算所必备的“基础能力”。当然,让使用者更关注自身的业务逻辑,这也是Serverless的优势之一。

知识准备

为了更好的完成项目,以阿里云函数计算为例,在开始项目之前,需要进行一些概念的明确,基础知识的储备。

什么是Runtime

所谓的Runtime实际上就是所谓的运行时,可以认为是一种环境或者说是一种支持,例如阿里云函数计算提供了Python2.7的Runtime,可以认为你的Python2.7的应用是可以运行在这个环境下,针对不同的Runtime在文档中都会相关的描述,以Python相关的Runtime为例,在官网上,我们可以看到相关Runtime的描述信息,包括日志的输出方法,所支持的编程语言及版本,所运行的系统类型及版本,以及默认集成的工具/模块/依赖等。

什么是触发器

众所周知,函数计算是通过事件进行触发的,触发器是触发函数执行的方式。在事件驱动的计算模型中,事件源是事件的生产者,函数是事件的处理者,而触发器提供了一种集中、统一的方式来管理不同的事件源。在事件源中,当事件发生时,如果满足触发器定义的规则,事件源会自动调用触发器所对应的函数。

当然不同的事件源和函数进行一个事件的数据结构的规约,当事件源因为某些规则触发了函数,那么这个预先规约好的数据结构,将会作为参数之一传递给函数,例如阿里云对象存储与函数计算规约的事件数据结构:

{

 "events": [

   {

     "eventName": "ObjectCreated:PutObject",

     "eventSource": "acs:oss",

     "eventTime": "2017-04-21T12:46:37.000Z",

     "eventVersion": "1.0",

     "oss": {

       "bucket": {

         "arn": "acs:oss:cn-shanghai:123456789:bucketname",

         "name": "testbucket",

         "ownerIdentity": "123456789",

         "virtualBucket": ""

       },

       "object": {

         "deltaSize": 122539,

         "eTag": "688A7BF4F233DC9C88A80BF985AB7329",

         "key": "image/a.jpg",

         "size": 122539

       },

       "ossSchemaVersion": "1.0",

       "ruleId": "9adac8e253828f4f7c0466d941fa3db81161****"

     },

     "region": "cn-shanghai",

     "requestParameters": {

       "sourceIPAddress": "140.205.***.***"

     },

     "responseElements": {

       "requestId": "58F9FF2D3DF792092E12044C"

     },

     "userIdentity": {

       "principalId": "123456789"

     }

   }

 ]

}          

当用户的函数设置了OSS触发器,并绑定了某个对象存储的存储桶,当这个存储桶满足绑定操作时,即会生成一个事件,并触发函数。例如,我们可以为我们的函数计算设置一个OSS触发器,绑定存储桶“MyServerlessBook”(这个存储桶通常需要和用户的函数在同一个账号下,同一个地域下),设置了一个触发条件“oss:ObjectCreated:PutObject”(调用PutObject接口上传文件即会触发该函数),所以一旦该存储桶收到以PutObject接口上传的文件,就会按照之前规约好的数据结构生成一个事件,触发当前函数并将事件作为参数传递给函数的对方方法。

什么是函数入口

在我们学习C语言的时候,都会会知道一个叫main()的函数,main()函数称之为主函数,一个C程序总是从main()函数开始执行的,例如:

#include <stdio.h>

int main(void)

{

   printf("HelloWorld!\n");

   return 0;

}

其实在函数计算中也是这样,在我们创建函数的时候,我们也需要告知系统,我们的入口方法是什么。通常情况下,函数入口的格式为[文件名].[函数名]。以Python为例,创建函数时指定的Handler为index.handler,那么函数计算会去加载index.py中定义的handler函数。通常情况下一个函数计算的入口方法会有两个参数:

def handler(event, context):

   return 'hello world'

一个是event,一个是context:

event: 是用户自定义的函数入参,以字节流的形式传给函数,数据结构由您自行定义,它可以是一个简单的字符串 、一个JSON对象、一张图片(二进制数据)。函数计算不对event参数的内容进行任何解释。

对于不同的函数触发情况,event参数的值会有以下区别:

  • 事件源服务触发函数时,事件源服务会将事件以一种平台预定义的格式作为event参数传给函数,您可以根据此格式编写代码并从event参数中获取信息。例如使用OSS触发器触发函数时会将Bucket及文件的具体信息以JSON格式传递给event参数。
  • 函数通过SDK直接调用时,您可以在调用方和函数代码之间自定义event参数。调用方按照定义好的格式传入数据,函数代码按格式获取数据。例如定义一个JSON类型的数据结构{"key":"val"}作为event,当调用方传入数据{"key":"val"}时,函数代码先将字节流转换成JSON,再通过event["key"]来获得值val

context: context参数是函数计算平台定义的函数入参,它的数据结构由函数计算设计,包含函数运行时的信息,使用场景通常有两种,一种是用户的临时密钥信息可以通过context.credentials获取,通过context中的临时密钥去访问阿里云的其他服务(使用示例中以访问OSS为例),避免了在代码中使用密钥硬编码。另一种是在context中可以获取本次执行的基本信息,例如requestId、serviceName、functionName、qualifier等。在阿里云函数计算中,关于context的结构基本如下

{  

  requestId: '9cda63c3-1ac9-45ba-8a59-2593bb9bc101',  

  credentials: {    

     accessKeyId: 'xxx',    

     accessKeySecret: 'xxx',    

     securityToken: 'xxx'  

  },  

  function: {    

     name: 'xxx',    

     handler: 'index.handler',    

     memory: 512,    

     timeout: 60,    

     initializer: 'index.initializer',    

     initializationTimeout: 10  

  },  

  service: {    

     name: 'xxx',    

     logProject: 'xxx',    

     logStore: 'xxx',    

     qualifier: 'xxx',    

     versionId: 'xxx'  

  },  

  region: 'xxx',  

  accountId: 'xxx'

}


当然,在上一章中,细心的读者应该已经发现,阿里云的函数计算相对于其他云厂商的函数计算,在创建函数的时候多了一个选项:除了事件函数,还有一个选择叫HTTP函数。与普通的事件函数不同的是,HTTP函数更适合快速构建Web服务等场景。HTTP触发器支持HEAD、POST、PUT、GET和DELETE方式触发函数,同时与普通的事件函数不同的是,HTTP函数的入参和Response也略微不同,以官方例子为例:

# -*- coding: utf-8 -*-

import json

HELLO_WORLD = b"Hello world!\n"

def handler(environ, start_response):

   request_uri = environ['fc.request_uri']

   response_body = {

     'uri':environ['fc.request_uri'],

     'method':environ['REQUEST_METHOD']

   }

   # do something here

   status = '200 OK'

   response_headers = [('Content-type', 'text/json')]

   start_response(status, response_headers)

   # Python2

   return [json.dumps(response_body)]

   # Python3 tips: When using Python3, the str and bytes types cannot be mixed.

   # Use str.encode() to go from str to bytes

   # return [json.dumps(response_body).encode()]

当然,HTTP函数的一个优势是更加容易与传统的Web框架进行结合,以Python的轻量级Web框架Flask为例:

# index.py

from flask import Flask

app = Flask(__name__)

@app.route('/')

def hello_world():

   return 'Hello, World!'

此时,我们只需要将函数的入口方法设置为:index.app即可实现一个Flask项目运行在函数计算上。这个过程相对于很多在函数计算层面将JSON对象转换成Request对象的方案要方便得多。当然除了这一点之外,HTTP函数的优势还有:

  • 简化了开发人员的学习成本和调试过程,帮助开发人员快速使用函数计算搭建Web service和API。
  • 支持选择熟悉的HTTP测试工具验证函数计算侧的功能和性能。
  • 减少请求处理环节,HTTP触发器支持更高效的请求、响应格式,不需要编码或解码成JSON格式,性能更优。
  • 方便对接其他支持Webhook回调的服务,例如CDN回源、MNS等。

项目开发

原生FaaS开发

想要获得用户的IP地址,那么我们就要根据函数计算的特性,寻找到事件的数据结构,在这个数据结构中找到客户端IP的字段。我们可以先创建一个HTTP函数,输出environ:

# -*- coding: utf-8 -*-

import json

def handler(environ, start_response):

   print(environ)

   response_body = {}

   response_headers = [('Content-type', 'text/json')]

   start_response('200 OK', response_headers)

   return [json.dumps(response_body).encode()]

完成之后,我们执行该函数,可以看到输出的日志中有REMOTE_ADDR字段,存放的是客户端的IP地址:

所以此刻,我们可以通过environ['REMOTE_ADDR']来获得这个IP地址:

# -*- coding: utf-8 -*-

import json

def handler(environ, start_response):

   response_body = {

     'IP':environ['REMOTE_ADDR']

   }

   response_headers = [('Content-type', 'text/json')]

   start_response('200 OK', response_headers)

   return [json.dumps(response_body).encode()]

测试代码,可以看到已经正确输出我们的IP地址:

通过函数计算为我们生成的地址:

在客户端用命令行工具测试:

基于Web框架开发

首先在本地创建项目一个Flask项目,并且新建文件index.py:

from flask import Flask, request


app = Flask(__name__)



@app.route('/')

def index():

   return {"IP": request.remote_addr}



if __name__ == '__main__':

   app.run(

       host="0.0.0.0",

       port=int("8001")

   )


安装项目所需要的依赖到当前项目下,例如本项目只需要一个flask即可:

pip3 install flask -t ./

安装完成之后,我们可以本地启动该项目进行基本测试:

此时,我们在阿里云函数计算上创建一个HTTP函数,选择我们刚才的项目文件夹上传,同时函数入口要改成index.app:    

然后可以点击“新建”按钮,进行函数创建,创建完成之后,我们可以在控制台点击一下“测试”按钮,可以看到,已经成功输出我们的IP地址:

当然,我们也可以使用默认生成URL,在本地进行测试:

此时结果:


举一反三

AWS Lambda

上文是以阿里云函数计算为例,当然在其他云厂商中实现该服务的方法也是类似的,例如在AWS的Lambda中,代码可以为:

import json


def lambda_handler(event, context):

   return {

       'statusCode': 200,

       'body': json.dumps({"IP": event['requestContext']['http']['sourceIp']})

   }


腾讯云云函数

腾讯云云函数中,代码为:

# -*- coding: utf8 -*-

import json

def main_handler(event, context):

   response_body = {

     'IP': event['requestContext']['sourceIp']

   }

   return response_body

华为云函数工作流

华为云的可以是:

# -*- coding:utf-8 -*-

import json

def handler (event, context):

   return {

       "statusCode": 200,

       "isBase64Encoded": False,

       "body": json.dumps({"IP": event['headers']['x-real-ip']}),

       "headers": {

           "Content-Type": "application/json"

       }

   }


至此我们完成了一个简单的查询客户端IP的API服务的开发。相对于传统的自建服务器,安装各种软件,后期不断运维而言,Serverless架构的优势非常明显,它让我们仅关注自身的业务代码即可,无论是运行环境还是API网关等,都交给云厂商来统一管理和维护,这对研发效率的提升,人力资源投入的降低,是有巨大帮助和推进作用的。除此之外,传统云主机情况下,我们需要让我们的机器一直在运行,哪怕很长一段时间没有流量也要持续运行,而只要运行就会有费用的产生,就会有成本的产生,但是在Serverless架构下,我们即便开发、测试完项目,他也会处于一个静默状态,只有当请求到来的时候,函数被触发的时候,系统才会进行计费,也就是说只有使用才有费用,不使用无费用产生,这对于整个资源成本的压缩,具有极大的帮助和促进作用。

相关实践学习
【玩转ComfyUI】基于函数计算一键部署AI生图平台ComfyUI
本次实验将带大家通过使用阿里云产品函数计算FC,快速使用ComfyUI实现更高质量的图像生成。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
目录
相关文章
|
7月前
|
人工智能 运维 Kubernetes
Serverless 应用引擎 SAE:为传统应用托底,为 AI 创新加速
在容器技术持续演进与 AI 全面爆发的当下,企业既要稳健托管传统业务,又要高效落地 AI 创新,如何在复杂的基础设施与频繁的版本变化中保持敏捷、稳定与低成本,成了所有技术团队的共同挑战。阿里云 Serverless 应用引擎(SAE)正是为应对这一时代挑战而生的破局者,SAE 以“免运维、强稳定、极致降本”为核心,通过一站式的应用级托管能力,同时支撑传统应用与 AI 应用,让企业把更多精力投入到业务创新。
769 30
|
7月前
|
人工智能 运维 安全
加速智能体开发:从 Serverless 运行时到 Serverless AI 运行时
在云计算与人工智能深度融合的背景下,Serverless 技术作为云原生架构的集大成者,正加速向 AI 原生架构演进。阿里云函数计算(FC)率先提出并实践“Serverless AI 运行时”概念,通过技术创新与生态联动,为智能体(Agent)开发提供高效、安全、低成本的基础设施支持。本文从技术演进路径、核心能力及未来展望三方面解析 Serverless AI 的突破性价值。
|
8月前
|
存储 人工智能 Serverless
函数计算进化之路:AI 应用运行时的状态剖析
AI应用正从“请求-响应”迈向“对话式智能体”,推动Serverless架构向“会话原生”演进。阿里云函数计算引领云上 AI 应用 Serverless 运行时技术创新,实现性能、隔离与成本平衡,开启Serverless AI新范式。
815 12
|
SQL 分布式计算 Serverless
鹰角网络:EMR Serverless Spark 在《明日方舟》游戏业务的应用
鹰角网络为应对游戏业务高频活动带来的数据潮汐、资源弹性及稳定性需求,采用阿里云 EMR Serverless Spark 替代原有架构。迁移后实现研发效率提升,支持业务快速发展、计算效率提升,增强SLA保障,稳定性提升,降低运维成本,并支撑全球化数据架构部署。
1377 56
鹰角网络:EMR Serverless Spark 在《明日方舟》游戏业务的应用
|
人工智能 开发框架 安全
Serverless MCP 运行时业界首发,函数计算让 AI 应用最后一公里提速
作为云上托管 MCP 服务的最佳运行时,函数计算 FC 为阿里云百炼 MCP 提供弹性调用能力,用户只需提交 npx 命令即可“零改造”将开源 MCP Server 部署到云上,函数计算 FC 会准备好计算资源,并以弹性、可靠的方式运行 MCP 服务,按实际调用时长和次数计费,欢迎你在阿里云百炼和函数计算 FC 上体验 MCP 服务。
1030 31
|
11月前
|
存储 编解码 Serverless
Serverless架构下的OSS应用:函数计算FC自动处理图片/视频转码(演示水印添加+缩略图生成流水线)
本文介绍基于阿里云函数计算(FC)和对象存储(OSS)构建Serverless媒体处理流水线,解决传统方案资源利用率低、运维复杂、成本高等问题。通过事件驱动机制实现图片水印添加、多规格缩略图生成及视频转码优化,支持毫秒级弹性伸缩与精确计费,提升处理效率并降低成本,适用于高并发媒体处理场景。
1284 0
|
8月前
|
人工智能 运维 安全
聚焦 AI 应用基础设施,云栖大会 Serverless AI 全回顾
2025 年 9 月 26 日,为期三天的云栖大会在杭州云栖小镇圆满闭幕。随着大模型技术的飞速发展,我们正从云原生时代迈向一个全新的 AI 原生应用时代。为了解决企业在 AI 应用落地中面临的高成本、高复杂度和高风险等核心挑战,阿里云基于函数计算 FC 发布一系列重磅服务。本文将对云栖大会期间 Serverless+AI 基础设施相关内容进行全面总结。
|
8月前
|
人工智能 Kubernetes 安全
重塑云上 AI 应用“运行时”,函数计算进化之路
回顾历史,电网的修建,深刻地改变了世界的经济地理和创新格局。今天,一个 AI 原生的云端运行时的进化,其意义也远不止于技术本身。这是一次设计哲学的升华:从“让应用适应平台”到“让平台主动理解和适应智能应用”的转变。当一个强大、易用、经济且安全的 AI 运行时成为像水电一样的基础设施时,它将极大地降低创新的门槛。一个独立的开发者、一个小型创业团队,将有能力去创造和部署世界级的 AI 应用。这才是技术平权的真谛,是激发全社会创新潜能的关键。
|
Cloud Native Serverless 流计算
云原生时代的应用架构演进:从微服务到 Serverless 的阿里云实践
云原生技术正重塑企业数字化转型路径。阿里云作为亚太领先云服务商,提供完整云原生产品矩阵:容器服务ACK优化启动速度与镜像分发效率;MSE微服务引擎保障高可用性;ASM服务网格降低资源消耗;函数计算FC突破冷启动瓶颈;SAE重新定义PaaS边界;PolarDB数据库实现存储计算分离;DataWorks简化数据湖构建;Flink实时计算助力风控系统。这些技术已在多行业落地,推动效率提升与商业模式创新,助力企业在数字化浪潮中占据先机。
695 12
|
人工智能 开发框架 运维
Serverless MCP 运行时业界首发,函数计算让 AI 应用最后一公里提速
Serverless MCP 运行时业界首发,函数计算支持阿里云百炼 MCP 服务!阿里云百炼发布业界首个全生命周期 MCP 服务,无需用户管理资源、开发部署、工程运维等工作,5 分钟即可快速搭建一个连接 MCP 服务的 Agent(智能体)。作为云上托管 MCP 服务的最佳运行时,函数计算 FC 为阿里云百炼 MCP 提供弹性调用能力。
 Serverless MCP 运行时业界首发,函数计算让 AI 应用最后一公里提速

相关产品

  • 函数计算