Serverless 工程实践 | 传统 Web 框架迁移

本文涉及的产品
可观测监控 Prometheus 版,每月50GB免费额度
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
可观测可视化 Grafana 版,10个用户账号 1个月
简介: 在 Serverless 这种新的架构或者说是新的编程范式下,使用全新的思路来做 Serverless 应用是再好不过的了,但实际并非如此。原生的 Serverless 开发框架是非常少的。以 Web 框架为例,目前主流的 Web 框架均不支持 Serverless 部署,所以将传统框架更简单、更快速、更科学地部署到 Serverless 架构上就是一个值得探讨的问题。

作者 | 刘宇


前言:与其说 Serverless 架构是一个新的概念 / 架构,不如说它是一个全新的思路、一种新的编程范式。


在 Serverless 这种新的架构或者说是新的编程范式下,使用全新的思路来做 Serverless 应用是再好不过的了,但实际并非如此。原生的 Serverless 开发框架是非常少的。以 Web 框架为例,目前主流的 Web 框架均不支持 Serverless 部署,所以将传统框架更简单、更快速、更科学地部署到 Serverless 架构上就是一个值得探讨的问题。


请求集成方案


请求集成方案实际上就是把真实的 API 网关请求直接传递给 FaaS 平台,而不在中途增加任何转换逻辑。以阿里云函数计算的 HTTP 函数为例,当想要把传统框架(例如 Django、Flask、Express、Next.js 等)部署到阿里云函数计算平台上,并且享受 Serverless 带来的按量付费、弹性伸缩等红利时,得益于阿里云函数计算的 HTTP 函数和 HTTP 触发器,使用者不仅可以快速、简单地将框架部署到阿里云函数计算上,还可以保持和传统开发一样的体验。以 Python 的 Bottle 框架为例,开发一个 Bottle 项目:


# index.py
import bottle
@bottle.route('/hello/<name>')
def index(name):
   return "Hello world"
if __name__ == '__main__':
   bottle.run(host='localhost', port=8080, debug=True)


当想要把该项目部署到阿里云函数计算上时,只需要增加一个 default_app 对象即可:


app = bottle.default_app()


整个项目实现如下:


# index.py
import bottle
@bottle.route('/hello/<name>')
def index(name):
   return "Hello world"
app = bottle.default_app()
if __name__ == '__main__':
   bottle.run(host='localhost', port=8080, debug=True)


当想在阿里云函数计算平台创建函数时,将函数入口设置为 index.app 即可。除了 Bottle 框架之外,其他的 Web 框架的操作方法是类似的。再以 Flask 为例:


# index.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
   return 'Hello, World!'
if __name__ == '__main__':
   app.run(
       host="0.0.0.0",
       port=int("8001")
   )


在配置函数的时候设置入口函数为 index.app,即可保证该 Flask 项目运行在函数计算平台上。


当然,除了使用已有的语言化的 Runtime,还可以考虑使用 Custom Runtime 和 Custom Container 来实现。例如,一个 Web 项目完成之后,我们可以编写一个 Bootstrap 文件(在 Bootstrap 文件中写一些启动命令即可),要启动一个 Express 项目,把 Express 项目准备好之后,直接通过 Bootstrap 实现:


#!/usr/bin/env bash
export PORT=9000
npm run star


除了上面的方法,其实阿里云函数计算还提供了更简单的 Web 框架迁移方案,即直接将传统 Web 框架迁移到函数计算中。我们在函数计算控制台找到应用中心,可以看到 Web 应用框架,如下图所示:


1.png

image.gif阿里云函数计算应用中心


选择好对应的环境之后,只需要上传代码、做好简单的配置,即可让传统 Web 项目运行在阿里云函数计算平台上。如果通过开发者工具进行部署,以 Serverless Devs 为例,可以先创建 index.py:


# -*- coding: utf-8 -*-
from bottle import route, run
@route('/')
def hello():
    return "Hello World!"
run(host='0.0.0.0', debug=False, port=9000)


然后编写资源和行为描述文件:


edition: 1.0.0          
name: functionApp      
access: defaule  
services:
   bottleExample:                                            #服务名称
       component: devsapp/bottle                             #组件名称
       actions:
           pre-deploy:                                       #在deploy之前运行
               - run: pip3 install -t . -r requirements.txt  #要运行的命令行
                   path: ./src                               #命令行运行的路径
       props:                                                #组件的属性值
           region: cn-shenzhen
           service:
               name: serverless-devs-bottle
               description: Serverless Devs示例程序
           function:
               name: bottle
               description: bottle项目
               memorySize: 256
               code:
                   src: ./src
               customContainerConfig:
                   command: '["python3"]'
                   args: '["./bottle/index.py"]'                                        #服务名称       component: devsapp/bottle                             #组件名称       actions:           pre-deploy:                                       #在deploy之前运行               - run: pip3 install -t . -r requirements.txt  #要运行的命令行                   path: ./src                               #命令行运行的路径       props:                                                #组件的属性值           region: cn-shenzhen           service:               name: serverless-devs-bottle               description: Serverless Devs示例程序           function:               name: bottle               description: bottle项目               memorySize: 256               code:                   src: ./src               customContainerConfig:                   command: '["python3"]'                   args: '["./bottle/index.py"]'


完成之后,执行 deploy 指令:


s deploy


部署如图所示:


2.png

image.gif在 Serverless Devs 上部署 bottle 框架


根据返回的网址,可以看到如下图所示的结果:image.gif

3.png

Serverless Devs 部署结果预览


综上所述,通过阿里云函数计算进行传统 Web 框架的部署和迁移是相对方便的,并且得益于 HTTP 函数与 HTTP 触发器,整个过程侵入性非常低。当然,将传统 Web 框架部署到阿里云函数计算时,可选方案也是比较多的。


  • 编程语言化的 Runtime:只需要写好函数入口即可。
  • Custom Runtime:只需要写好 Bootstrap 即可。
  • Custom Container:直接按照规范上传镜像文件即可。


部署途径也是多种多样的,具体如下。

  • 直接在控制台创建函数。
  • 在应用中心处创建 Web 应用。
  • 使用开发者工具直接部署。



其它方案


相对于阿里云的 HTTP 函数以及 HTTP 触发器而言,AWS、华为云、腾讯云等 FaaS 平台需要借助 API 网关以及转换层来实现将传统 Web 框架部署到 FaaS 平台。


如图所示,通常情况下使用 Flask 等框架实际上要通过 Web Server 进入下一个环节,而云函数更多是一个函数,本不需要启动 Web Server,所以可以直接调用 wsgi_app 方法。


4.png

传统WSGI Web Server工作原理示例


这里的 environ 就是需要对 event/context 等进行处理的对象,也就是所说的转换层要做的工作;start_response 可以认为是一种特殊的数据结构,例如 response 结构形态等。以 Flask 项目为例,在腾讯云云函数上,转换层结构如下:


import sys
import json
from urllib.parse import urlencode
from flask import Flask
try:
   from cStringIO import StringIO
except ImportError:
   try:
       from StringIO import StringIO
   except ImportError:
       from io import StringIO
from werkzeug.wrappers import BaseRequest
def make_environ(event):
   environ = {}
   for hdr_name, hdr_value in event['headers'].items():
       hdr_name = hdr_name.replace('-', '_').upper()
       if hdr_name in ['CONTENT_TYPE', 'CONTENT_LENGTH']:
           environ[hdr_name] = hdr_value
           continue
       http_hdr_name = 'HTTP_%s' % hdr_name
       environ[http_hdr_name] = hdr_value
   apigateway_qs = event['queryStringParameters']
   request_qs = event['queryString']
   qs = apigateway_qs.copy()
   qs.update(request_qs)
   body = ''
   if 'body' in event:
       body = event['body']
   environ['REQUEST_METHOD'] = event['httpMethod']
   environ['PATH_INFO'] = event['path']
   environ['QUERY_STRING'] = urlencode(qs) if qs else ''
   environ['REMOTE_ADDR'] = 80
   environ['HOST'] = event['headers']['host']
   environ['SCRIPT_NAME'] = ''
   environ['SERVER_PORT'] = 80
   environ['SERVER_PROTOCOL'] = 'HTTP/1.1'
   environ['CONTENT_LENGTH'] = str(len(body))
   environ['wsgi.url_scheme'] = ''
   environ['wsgi.input'] = StringIO(body)
   environ['wsgi.version'] = (1, 0)
   environ['wsgi.errors'] = sys.stderr
   environ['wsgi.multithread'] = False
   environ['wsgi.run_once'] = True
   environ['wsgi.multiprocess'] = False
   BaseRequest(environ)
   return environ
class LambdaResponse(object):
   def __init__(self):
       self.status = None
       self.response_headers = None
   def start_response(self, status, response_headers, exc_info=None):
       self.status = int(status[:3])
       self.response_headers = dict(response_headers)
class FlaskLambda(Flask):
   def __call__(self, event, context):
       if 'httpMethod' not in event:
           return super(FlaskLambda, self).__call__(event, context)
       response = LambdaResponse()
       body = next(self.wsgi_app(
           make_environ(event),
           response.start_response
       ))
       return {
           'statusCode': response.status,
           'headers': response.response_headers,
           'body': body
       }


当然,转换在某些情况下还是比较麻烦的,所以在很多时候,我们可以借助常见的开发者工具进行传统 Web 框架的部署,例如借助开源的开发者工具 Serverless Devs、Serverless Framework 等。


关于作者:

image.gif

刘宇(江昱)国防科技大学电子信息专业在读博士,阿里云 Serverless 产品经理,阿里云 Serverless 云布道师,CIO 学院特聘讲师。


新书推荐


IMG_9633.jpeg


本书会通过多个开源项目、多个云厂商的多款云产品,以及多种途径向读者介绍什么是 Serverless 架构、如何上手 Serverless 架构、不同领域中 Serverless 架构的应用以及如何从零开发一个 Serverless 应用等。本书可以帮助读者将 Serverless 架构融入到自己所在的领域,把 Serverless 项目真实落地,获得 Serverless 架构带来的技术红利。


Serverless 工程系列文


第一篇:Serverless 工程实践 | 从云计算到 Serverless

第二篇:Serverless 工程实践 | 细数 Serverless 的配套服务


相关实践学习
【AI破次元壁合照】少年白马醉春风,函数计算一键部署AI绘画平台
本次实验基于阿里云函数计算产品能力开发AI绘画平台,可让您实现“破次元壁”与角色合照,为角色换背景效果,用AI绘图技术绘出属于自己的少年江湖。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
相关文章
|
12天前
|
运维 监控 Cloud Native
【云故事探索】NO.17:国诚投顾的云原生 Serverless 实践
国诚投顾携手阿里云,依托Serverless架构实现技术全面升级,构建高弹性、智能化技术底座,提升业务稳定性与运行效率。通过云原生API网关、微服务治理与智能监控,实现流量精细化管理与系统可观测性增强,打造安全、敏捷的智能投顾平台,助力行业数字化变革。
【云故事探索】NO.17:国诚投顾的云原生 Serverless 实践
|
14天前
|
运维 监控 Cloud Native
【云故事探索】NO.17:国诚投顾的云原生 Serverless 实践
通过与阿里云深度合作,国诚投顾完成了从传统 ECS 架构向云原生 Serverless 架构的全面转型。新的技术架构不仅解决了原有系统在稳定性、弹性、运维效率等方面的痛点,还在成本控制、API 治理、可观测性、DevOps 自动化等方面实现了全方位升级。
|
5月前
|
存储 运维 Serverless
千万级数据秒级响应!碧桂园基于 EMR Serverless StarRocks 升级存算分离架构实践
碧桂园服务通过引入 EMR Serverless StarRocks 存算分离架构,解决了海量数据处理中的资源利用率低、并发能力不足等问题,显著降低了硬件和运维成本。实时查询性能提升8倍,查询出错率减少30倍,集群数据 SLA 达99.99%。此次技术升级不仅优化了用户体验,还结合AI打造了“一看”和“—问”智能场景助力精准决策与风险预测。
436 69
|
3月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:路由、中间件、参数校验
Gin框架以其极简风格、强大路由管理、灵活中间件机制及参数绑定校验系统著称。本文详解其核心功能:1) 路由管理,支持分组与路径参数;2) 中间件机制,实现全局与局部控制;3) 参数绑定,涵盖多种来源;4) 结构体绑定与字段校验,确保数据合法性;5) 自定义校验器扩展功能;6) 统一错误处理提升用户体验。Gin以清晰模块化、流程可控及自动化校验等优势,成为开发者的优选工具。
|
3月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:使用 Gin 快速构建 Web 服务
Gin 是一个高效、轻量级的 Go 语言 Web 框架,支持中间件机制,非常适合开发 RESTful API。本文从安装到进阶技巧全面解析 Gin 的使用:快速入门示例(Hello Gin)、定义 RESTful 用户服务(增删改查接口实现),以及推荐实践如参数校验、中间件和路由分组等。通过对比标准库 `net/http`,Gin 提供更简洁灵活的开发体验。此外,还推荐了 GORM、Viper、Zap 等配合使用的工具库,助力高效开发。
|
5月前
|
人工智能 自然语言处理 JavaScript
测试工程师要失业?Magnitude:开源AI Agent驱动的端到端测试框架,让Web测试更智能,自动完善测试用例!
Magnitude是一个基于视觉AI代理的开源端到端测试框架,通过自然语言构建测试用例,结合推理代理和视觉代理实现智能化的Web应用测试,支持本地运行和CI/CD集成。
647 15
测试工程师要失业?Magnitude:开源AI Agent驱动的端到端测试框架,让Web测试更智能,自动完善测试用例!
|
5月前
|
Cloud Native Serverless 流计算
云原生时代的应用架构演进:从微服务到 Serverless 的阿里云实践
云原生技术正重塑企业数字化转型路径。阿里云作为亚太领先云服务商,提供完整云原生产品矩阵:容器服务ACK优化启动速度与镜像分发效率;MSE微服务引擎保障高可用性;ASM服务网格降低资源消耗;函数计算FC突破冷启动瓶颈;SAE重新定义PaaS边界;PolarDB数据库实现存储计算分离;DataWorks简化数据湖构建;Flink实时计算助力风控系统。这些技术已在多行业落地,推动效率提升与商业模式创新,助力企业在数字化浪潮中占据先机。
309 12
|
7月前
|
Kubernetes 监控 Serverless
基于阿里云Serverless Kubernetes(ASK)的无服务器架构设计与实践
无服务器架构(Serverless Architecture)在云原生技术中备受关注,开发者只需专注于业务逻辑,无需管理服务器。阿里云Serverless Kubernetes(ASK)是基于Kubernetes的托管服务,提供极致弹性和按需付费能力。本文深入探讨如何使用ASK设计和实现无服务器架构,涵盖事件驱动、自动扩展、无状态设计、监控与日志及成本优化等方面,并通过图片处理服务案例展示具体实践,帮助构建高效可靠的无服务器应用。
|
10月前
|
开发框架 搜索推荐 数据可视化
Django框架适合开发哪种类型的Web应用程序?
Django 框架凭借其强大的功能、稳定性和可扩展性,几乎可以适应各种类型的 Web 应用程序开发需求。无论是简单的网站还是复杂的企业级系统,Django 都能提供可靠的支持,帮助开发者快速构建高质量的应用。同时,其活跃的社区和丰富的资源也为开发者在项目实施过程中提供了有力的保障。
355 67

相关产品

  • 函数计算