开发一个Serverless应用

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
函数计算FC,每月15万CU 3个月
简介: 当我们通过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架构下,我们即便开发、测试完项目,他也会处于一个静默状态,只有当请求到来的时候,函数被触发的时候,系统才会进行计费,也就是说只有使用才有费用,不使用无费用产生,这对于整个资源成本的压缩,具有极大的帮助和促进作用。

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
目录
打赏
0
0
0
0
1882
分享
相关文章
云大使 X 函数计算 FC 专属活动上线!享返佣,一键打造 AI 应用
如今,AI 技术已经成为推动业务创新和增长的重要力量。但对于许多企业和开发者来说,如何高效、便捷地部署和管理 AI 应用仍然是一个挑战。阿里云函数计算 FC 以其免运维的特点,大大降低了 AI 应用部署的复杂性。用户无需担心底层资源的管理和运维问题,可以专注于应用的创新和开发,并且用户可以通过一键部署功能,迅速将 AI 大模型部署到云端,实现快速上线和迭代。函数计算目前推出了多种规格的云资源优惠套餐,用户可以根据实际需求灵活选择。
Serverless + AI 让应用开发更简单,加速应用智能化
Serverless + AI 让应用开发更简单,加速应用智能化
云原生应用实战:基于阿里云Serverless的API服务开发与部署
随着云计算的发展,Serverless架构日益流行。阿里云函数计算(Function Compute)作为Serverless服务,让开发者无需管理服务器即可运行代码,按需付费,简化开发运维流程。本文从零开始,介绍如何使用阿里云函数计算开发简单的API服务,并探讨其核心优势与最佳实践。通过Python示例,演示创建、部署及优化API的过程,涵盖环境准备、代码实现、性能优化和安全管理等内容,帮助读者快速上手Serverless开发。
阿里云 EMR Serverless Spark 在微财机器学习场景下的应用
面对机器学习场景下的训练瓶颈,微财选择基于阿里云 EMR Serverless Spark 建立数据平台。通过 EMR Serverless Spark,微财突破了单机训练使用的数据规模瓶颈,大幅提升了训练效率,解决了存算分离架构下 Shuffle 稳定性和性能困扰,为智能风控等业务提供了强有力的技术支撑。
173 15
基于阿里云 EMR Serverless Spark 版快速搭建OSS日志分析应用
基于阿里云 EMR Serverless Spark 版快速搭建OSS日志分析应用
7分钟玩转 AI 应用,函数计算一键部署 AI 生图大模型
人工智能生成图像(AI 生图)的领域中,Stable Diffusion WebUI 以其强大的算法和稳定的输出质量而闻名。它能够快速地从文本描述中生成高质量的图像,为用户提供了一个直观且高效的创作平台。而 ComfyUI 则以其用户友好的界面和高度定制化的选项所受到欢迎。ComfyUI 的灵活性和直观性使得即使是没有技术背景的用户也能轻松上手。本次技术解决方案通过函数计算一键部署热门 AI 生图大模型,凭借其按量付费、卓越弹性、快速交付能力的特点,完美实现低成本,免运维。
尽享红利,Serverless构建企业AI应用方案与实践
本次课程由阿里云云原生架构师计缘分享,主题为“尽享红利,Serverless构建企业AI应用方案与实践”。课程分为四个部分:1) Serverless技术价值,介绍其发展趋势及优势;2) Serverless函数计算与AI的结合,探讨两者融合的应用场景;3) Serverless函数计算AIGC应用方案,展示具体的技术实现和客户案例;4) 业务初期如何降低使用门槛,提供新用户权益和免费资源。通过这些内容,帮助企业和开发者快速构建高效、低成本的AI应用。
126 12
探索Serverless架构:开发实践与优化策略
本文深入探讨了Serverless架构的核心概念、开发实践及优化策略。Serverless让开发者无需管理服务器即可运行代码,具有成本效益、高可扩展性和提升开发效率等优势。文章还详细介绍了函数设计、安全性、监控及性能和成本优化的最佳实践。
Serverless架构通过提供更快的研发交付速度、降低成本、简化运维、优化资源利用、提供自动扩展能力、支持实时数据处理和快速原型开发等优势,为图像处理等计算密集型应用提供了一个高效、灵活且成本效益高的解决方案。
Serverless架构通过提供更快的研发交付速度、降低成本、简化运维、优化资源利用、提供自动扩展能力、支持实时数据处理和快速原型开发等优势,为图像处理等计算密集型应用提供了一个高效、灵活且成本效益高的解决方案。
138 1
"揭秘D2终端大会热点技术:Serverless架构最佳实践全解析,让你的开发效率翻倍,迈向技术新高峰!"
【10月更文挑战第23天】D2终端大会汇聚了众多前沿技术,其中Serverless架构备受瞩目。它让开发者无需关注服务器管理,专注于业务逻辑,提高开发效率。本文介绍了选择合适平台、设计合理函数架构、优化性能及安全监控的最佳实践,助力开发者充分挖掘Serverless潜力,推动技术发展。
234 1

相关产品

  • 函数计算
  • AI助理

    你好,我是AI助理

    可以解答问题、推荐解决方案等