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

本文涉及的产品
可观测可视化 Grafana 版,10个用户账号 1个月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
简介: 在 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 的配套服务


相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
3月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
66 4
|
3月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
217 3
|
3月前
|
SQL 安全 PHP
PHP 自发布以来一直在 Web 开发领域占据重要地位,PHP 8 更是带来了属性、刚性类型等新特性。
【10月更文挑战第1天】PHP 自问世以来,凭借其易用性和灵活性,在 Web 开发领域迅速崛起。从简单的网页脚本语言逐步演进为支持面向对象编程的现代语言,尤其自 PHP 5.3 引入命名空间后,代码组织和维护变得更加高效。PHP 7 的性能优化和 PHP 8 的新特性(如属性和刚性类型)进一步巩固了其地位。框架如 Laravel、Symfony、Yii2 和 CodeIgniter 等简化了开发流程,提高了效率和安全性。
69 2
|
2月前
|
开发框架 搜索推荐 数据可视化
Django框架适合开发哪种类型的Web应用程序?
Django 框架凭借其强大的功能、稳定性和可扩展性,几乎可以适应各种类型的 Web 应用程序开发需求。无论是简单的网站还是复杂的企业级系统,Django 都能提供可靠的支持,帮助开发者快速构建高质量的应用。同时,其活跃的社区和丰富的资源也为开发者在项目实施过程中提供了有力的保障。
138 62
|
1月前
|
消息中间件 人工智能 Kubernetes
解密开源Serverless容器框架:事件驱动篇
Knative是一款基于Kubernetes的开源Serverless框架,提供了云原生、跨平台的Serverless编排标准。作为Serverless中必不可少的事件驱动能力,Knative Eventing提供了云原生的事件驱动能力。
|
2月前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
237 45
|
2月前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
53 2
|
2月前
|
中间件 Go API
Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架
本文概述了Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架。
176 1
|
2月前
|
SQL 安全 PHP
探索PHP的现代演进:从Web开发到框架创新
PHP是一种流行的服务器端脚本语言,自诞生以来在Web开发领域占据重要地位。从简单的网页脚本到支持面向对象编程的现代语言,PHP经历了多次重大更新。本文探讨PHP的现代演进历程,重点介绍其在Web开发中的应用及框架创新,如Laravel、Symfony等。这些框架不仅简化了开发流程,还提高了开发效率和安全性。
42 3
|
2月前
|
前端开发 JavaScript 开发工具
从框架到现代Web开发实践
从框架到现代Web开发实践
53 1

相关产品

  • 函数计算