资源成本双优化!看Serverless颠覆编程教育的创新实践

本文涉及的产品
函数计算FC,每月15万CU 3个月
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
简介: 说起 Serverless 这个词,我想大家应该都不陌生,那么 Serverless 这个词到底是什么意思?Serverless 到底能解决什么问题?可能很多朋友还没有深刻的体会和体感。这篇文章我就和大家一起聊聊 Serverless 。

说起 Serverless 这个词,我想大家应该都不陌生,那么 Serverless 这个词到底是什么意思?Serverless 到底能解决什么问题?可能很多朋友还没有深刻的体会和体感。这篇文章我就和大家一起聊聊 Serverless 。

什么是 Serverless

我们先将 Serverless 这个词拆开来看。Server,大家都知道是服务器的意思,说明 Serverless 解决的问题范围在服务端。Less,大家肯定也知道它的意思是较少的。那么 Serverless 连起来,再稍加修饰,那就是较少的关心服务器的意思。

Serverfull 时代

我们都知道,在研发侧都会有研发人员和运维人员两个角色,要开发一个新系统的时候,研发人员根据产品经理的 PRD 开始写代码开发功能,当功能开发、测试完之后,要发布到服务器。这个时候开始由运维人员规划服务器规格、服务器数量、每个服务部署的节点数量、服务器的扩缩容策略和机制、发布服务过程、服务优雅上下线机制等等。这种模式是研发和运维隔离,服务端运维都由专门的运维人员处理,而且很多时候是靠纯人力处理,也就是 Serverfull 时代。

DevOps 时代

互联网公司里最辛苦的是谁?我相信大多数都是运维同学。白天做各种网络规划、环境规划、数据库规划等等,晚上熬夜发布新版本,做上线保障,而且很多事情是重复性的工作。然后慢慢就有了赋能研发这样的声音,运维同学帮助研发同学做一套运维控制台,可以让研发同学在运维控制台上自行发布服务、查看日志、查询数据。这样一来,运维同学主要维护这套运维控制台系统,并且不断完善功能,轻松了不少。这就是研发兼运维的 DevOps 时代。

Serverless 时代

渐渐的,研发同学和运维同学的关注点都在运维控制台了,运维控制台的功能越来越强大,比如根据运维侧的需求增加了自动弹性扩缩、性能监控的功能,根据研发侧的需求增加了自动化发布的流水线功能。因为有了这套系统,代码质量检测、单元测试、打包编译、部署、集成测试、灰度发布、弹性扩缩、性能监控、应用防护这一系列服务端的工作基本上不需要人工参与处理了。这就是 NoOps,Serverless 时代。

Serverless 在编程教育中的应用

2020 年注定是不平凡的一年,疫情期间,多少家企业如割韭菜般倒下,又有多少家企业如雨后春笋般茁壮成长,比如在线教育行业。

没错,在线教育行业是这次疫情的最大受益者,在在线教育在这个行业里,有一个细分市场是在线编程教育,尤其是少儿编程教育和面向非专业人士的编程教育,比如编程猫、斑马AI、小象学院等。这些企业的在线编程系统都有一些共同的特点和诉求:

  • 屏幕一侧写代码,执行代码,另一侧显示运行结果。
  • 根据题目编写的代码都是代码块,每道题的代码量不会很大。
  • 运行代码的速度要快。
  • 支持多种编程语言。
  • 能支撑不可预计的流量洪峰冲击。

image.png

例如小象学院的编程课界面:

结合上述这些特点和诉求,不难看出,构建这样一套在线编程系统的核心在于有一个支持多种编程语言的、健壮高可用的代码运行环境。

那么我们先来看看传统的实现架构:

image.png

从 HighLevel 的架构来看,前端只需要将代码片段和编程语言的标识传给 Server 端即可,然后等待响应展示结果。所以整个 Server 端要负责对不同语言的代码进行分类、预处理然后传给不同编程语言的 Runtime 。这种架构有以下几个比较核心的问题。

工作量大,灵活性差

首先是研发和运维工作量的问题,当市场有新的需求,或者洞察到新业务模式时需要增加编程语言,此时研发侧需要增加编程代码分类和预处理的逻辑,另外需要构建对应编程语言的 Runtime 。在运维侧需要规划支撑新语言的服务器规格以及数量,还有整体的 CICD 流程等。所以支持新的编程语言这个需求要落地,需要研发、运维花费不少的时间来实现,再加上黑/白盒测试和 CICD 流程测试的时间,对市场需求的支撑不能快速的响应,灵活性相对较差。

高可用自己兜底

其次整个在线编程系统的稳定性是重中之重。所以所有 Server 端服务的高可用架构都需要自己搭建,用以保证流量高峰场景和稳态场景下的系统稳定。高可用一方面是代码逻辑编写的是否优雅和完善,另一方面是部署服务的集群,无论是 ECS 集群还是 K8s 集群,都需要研发和运维同学一起规划,那么对于对编程语言进行分类和预处理的服务来讲,尚能给定一个节点数,但是对于不同语言的 Runtime 服务来讲,市场需求随时会变,所以不好具体衡量每个服务的节点数。另外很重要的一点是所以服务的扩容,缩容机制都需要运维同学来实时手动操作,即便是通过脚本实现自动化,那么ECS弹起的速度也是远达不到业务预期的。

成本控制粒度粗

再次是整个 IaaS 资源的成本控制,我们都知道这种在线教育是有明显的流量潮汐的,比如上午 10 点到 12 点,下午 3 点到 5 点,晚上 8 点到 10 点这几个时段是流量比较大的时候,其他时间端流量比较小,而且夜晚更是没什么流量。所以在这种情况下,传统的部署架构无法做到 IaaS 资源和流量的贴合。举个例子,加入为了应对流量高峰时期,需要 20 台 ECS 搭建集群来承载流量冲击,此时每台 ECS 的资源使用率可能在 70% 以上,利用率较高,但是在流量小的时候和夜晚,每台 ECS 的资源使用率可能就是百分之十几甚至更低,这就是一种资源浪费。

Serverless 架构

那么我们来看看如何使用 Serverless 架构来实现同样的功能,并且解决上述几个问题。在选择 Serverless 产品时,在国内自然而然优先想到的就是阿里云的产品。阿里云有两款 Serverless 架构的产品 Serverless 应用引擎和函数计算,这里我们使用函数计算来实现编程教育的场景。

函数计算(FunctionCompute)是事件驱动的全托管计算服务,简称FC。使用函数计算,我们无需采购与管理服务器等基础设施,只需编写并上传代码。函数计算为您准备好计算资源,弹性地、可靠地运行任务,并提供日志查询、性能监控和报警等功能。

这里不对FC的含义做过多赘述,只举一个例子。FC 中有两个概念,一个是服务,一个是函数。一个服务包含多个函数:

image.png

这里拿 Java 微服务架构来对应,可以理解为,FC 中的服务是Java中的一个类,FC 中的函数是 Java 类中的一个方法:

image.png

但是 Java 类中的方法固然只能是 Java 代码,而 FC 中的函数可以设置不同语言的 Runtime 来运行不同的编程语言:

image.png

这个结构理解清楚之后,我们来看看如何调用 FC 的函数,这里会引出一个触发器的概念。我们最常使用的 HTTP 请求协议其实就是一种类型的触发器,在 FC 里称为 HTTP 触发器,除了 HTTP 触发器以外,还提供了 OSS (对象存储)触发器、SLS(日志服务)触发器、定时触发器、MNS 触发器、 CDN 触发器等。

image.png

从上图可以大概理解,我们可以通过多种途径调用 FC 中的函数。举例两个场景,比如每当我在指定的 OSSBucket 的某个目录下上传一张图片后,就可以触发 FC 中的函数,函数的逻辑是将刚刚上传的图片下载下来,然后对图片做处理,然后再上传回 OSS 。再比如向 MNS 的某个队列发送一条消息,然后触发FC中的函数来处理针对这条消息的逻辑。

最后我们再来看看 FC 的高可用。每一个函数在运行代码时底层肯定还是 IaaS 资源,但我们只需要给每个函数设置运行代码时需要的内存数即可,最小 128M ,最大 3G ,对使用者而言,不需要考虑多少核数,也不需要知道代码运行在什么样的服务器上,不需要关心启动了多少个函数实例,也不需要关心弹性扩缩的问题等,这些都由 FC 来处理。

image.png

从上图可以看到,高可用有两种策略:

  • 给函数设置并发实例数,假如设置为 3 ,那么有三个请求进来时,该函数只启一个实例,但是会启三个线程来运行逻辑。
  • 线程数达到上限后,会再拉起一个函数实例。

大家看到这里,可能已经大概对基于 FC 实现在线编程教育系统的架构有了一个大概的轮廓。

image.png

上图是基于 FC 实现的在线编程教育系统的架构图,在这个架构下来看看上述那三个核心问题怎么解:

  • 工作量和灵活性:我们只需要关注在如何执行代码的业务逻辑上,如果要加新语言,只需要创建一个对应语言 Runtime 的 FC 函数即可。
  • 高可用:多线程运行业务逻辑和多实例运行业务逻辑两层高可用保障,并且函数实例的扩缩完全都是 FC 自动处理,不需要研发和运维同学做任何配置。
  • 成本优化:当没有请求的时候,函数实例是不会被拉起的,此时也不会计费,所以在流量低谷期或者夜间时,整个 FC 的成本消耗是非常低的。可以做到函数实例个数、计费粒度和流量完美的贴合。

image.png

Python 编程语言示例

下面以运行 Python 代码为例来看看如何用 FC 实现 Python 在线编程 Demo 。

创建服务和函数

打开函数计算(FC)控制台,选择对应的 Region ,选择左侧服务/函数,然后新建服务:
https://fc.console.aliyun.com/fc/overview/cn-hangzhou

image.png

输出服务名称,创建服务。

image.png

进入新创建的服务,然后创建函数,选择HTTP函数,即可配置HTTP触发器的函数:

image.png

设置函数的各个参数:

image.png

几个需要的注意的参数这里做以说明:

  • 运行环境:这个很好理解,这里选择 Python3 。
  • 函数实例类型:这里有弹性实例和性能实例两种,前者最大支持 2C 3G 规格的实例,后者支持更大的规格,最大到 8C 16G 。
  • 函数入口:详细参见文档-HTTP 触发器认证方式:anonymous 为不需要鉴权, function 是需要鉴权的:

https://help.aliyun.com/document_detail/74756.html?spm=a2c4g.11186623.6.572.195359cdselnzR

代码解析

函数创建好,进入函数,可以看到概述、代码执行、触发器、日志查询等页签,我们先看触发器,会看到这个函数自动创建了一个 HTTP 触发器,有调用该函数对应的 HTTP 路径:

image.png

然后我们选择代码执行,直接在线写入我们的代码:

image.png

具体代码如下:

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

import logging
import urllib.parse
import time
import subprocess

def handler(environ, start_response):
    context = environ['fc.context']
    request_uri = environ['fc.request_uri']
    for k, v in environ.items():
      if k.startswith('HTTP_'):
        pass
    try:        
        request_body_size = int(environ.get('CONTENT_LENGTH', 0))    
    except (ValueError):        
        request_body_size = 0   
    # 获取用户传入的code
    request_body = environ['wsgi.input'].read(request_body_size)  
    codeStr = urllib.parse.unquote(request_body.decode("GBK"))
    # 因为body里的对象里有code和input两个属性,这里分别获取用户code和用户输入
    codeArr = codeStr.split('&')
    code = codeArr[0][5:]
    inputStr = codeArr[1][6:]
    # 将用户code保存为py文件,放/tmp目录下,以时间戳为文件名
    fileName = '/tmp/' + str(int(time.time())) + '.py'
    f = open(fileName, "w")
    # 这里预置引入了time库
    f.write('import time \r\n')
    f = open(fileName, "a")
    f.write(code)
    f.close()
    # 创建子进程,执行刚才保存的用户code py文件
    p = subprocess.Popen("python " + fileName, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, encoding='utf-8')
    # 通过标准输入传入用户的input输入
    if inputStr != '' :
        p.stdin.write(inputStr + "\n")
        p.stdin.flush()
    # 通过标准输出获取代码执行结果
    r = p.stdout.read()
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    return [r.encode('UTF-8')]

整个代码思路如下:

  • 从前端传入代码片段,格式是字符串。
  • 在 FC 函数中获取到传入的代码字符串,截取 code 内容和 input 的内容。因为这里简单实现了 Python 中 input 交互的能力。
  • 将代码保存为一个 Python 文件,以时间戳为文件名,保存在 FC 函数的 /tmp 目录下。(每个FC函数都有独立的 /tmp 目录,可以存放临时文件)
  • 然后在文件中追加了引入 time 库的代码,应对 sleep 这种交互场景。
  • 通过 subprocess 创建子进程,以 Shell 的方式通过 Python 命令执行保存在 /tmp 目录下的 Python 文件。如果有用户输入的信息,则通过标准输入输出写入子进程。
  • 最后读取执行结果返回给前端。

前端代码

前端我使用 VUE 写了简单的页面,这里解析两个简单的方法:

image.png

页面加载时初始化 HTTP 请求对象,调用的 HTTP 路径就是方才函数的 HTTP 触发器的路径。

image.png

这个方法就是调用 FC 中的 PythonRuntime 函数,将前端页面的代码片段传给该函数。这里处理 input 交互的思路是,扫描整个代码片段,以包含 input 代码为标识将整个代码段分成多段。没有包含 input 代码的直接送给 FC 函数执行,包含 input 代码的,请求用户的输入,然后代码片段带着用户输入的信息一起送给 FC 函数执行。

演示如下:

lagoudemo.gif

结束语

这篇文章洋洋洒洒给大家介绍了 Serverless ,阿里云的 Serverless 产品函数计算(FC)以及基于函数计算(FC)实现的在线编程系统的Demo。大家应该有所体感,基于函数计算(FC)实现在线编程系统时,研发同学只需要专注在如何执行由前端传入的代码即可,整个 Server 端的各个环节都不需要研发同学和运维同学去关心,基本体现了 Serverless 的精髓。

基于 Serverless 还有很多其他的应用场景,之后我会一一分享给大家,大家如果有任何疑问也可以扫码加入钉钉群(群号:35712134)来寻找答案,我们不见不散!

test

作者:计缘
来源:阿里巴巴中间件 微信公众号
原文链接:https://mp.weixin.qq.com/s/007Wy1AdQh21Q3nsBPk5lw

相关实践学习
【AI破次元壁合照】少年白马醉春风,函数计算一键部署AI绘画平台
本次实验基于阿里云函数计算产品能力开发AI绘画平台,可让您实现“破次元壁”与角色合照,为角色换背景效果,用AI绘图技术绘出属于自己的少年江湖。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
相关文章
|
1月前
|
运维 监控 Cloud Native
【云故事探索】NO.17:国诚投顾的云原生 Serverless 实践
国诚投顾携手阿里云,依托Serverless架构实现技术全面升级,构建高弹性、智能化技术底座,提升业务稳定性与运行效率。通过云原生API网关、微服务治理与智能监控,实现流量精细化管理与系统可观测性增强,打造安全、敏捷的智能投顾平台,助力行业数字化变革。
【云故事探索】NO.17:国诚投顾的云原生 Serverless 实践
|
1月前
|
运维 监控 Cloud Native
【云故事探索】NO.17:国诚投顾的云原生 Serverless 实践
通过与阿里云深度合作,国诚投顾完成了从传统 ECS 架构向云原生 Serverless 架构的全面转型。新的技术架构不仅解决了原有系统在稳定性、弹性、运维效率等方面的痛点,还在成本控制、API 治理、可观测性、DevOps 自动化等方面实现了全方位升级。
|
5月前
|
数据采集 运维 Serverless
云函数采集架构:Serverless模式下的动态IP与冷启动优化
本文探讨了在Serverless架构中使用云函数进行网页数据采集的挑战与解决方案。针对动态IP、冷启动及目标网站反爬策略等问题,提出了动态代理IP、请求头优化、云函数预热及容错设计等方法。通过网易云音乐歌曲信息采集案例,展示了如何结合Python代码实现高效的数据抓取,包括搜索、歌词与评论的获取。此方案不仅解决了传统采集方式在Serverless环境下的局限,还提升了系统的稳定性和性能。
155 0
|
8月前
|
消息中间件 存储 弹性计算
云端问道13期方案教学-告别资源瓶颈,函数计算驱动多媒体文件处理
《云端问道13期方案教学》由阿里云技术团队周博宇主讲,聚焦如何使用函数计算突破资源瓶颈,高效处理多媒体文件。方案涵盖六大要点:寻找云需求解决方案、选择函数计算的原因、对比不同文件处理方式、实现多媒体文件处理、应用场景广泛性及优惠购买推荐。通过将文件处理从主应用拆分,利用函数计算的按需扩展和自动弹性特性,确保核心业务稳定,并大幅降低成本。适用于图片、视频处理等多种场景。
103 1
云端问道13期方案教学-告别资源瓶颈,函数计算驱动多媒体文件处理
|
5月前
|
存储 运维 Serverless
千万级数据秒级响应!碧桂园基于 EMR Serverless StarRocks 升级存算分离架构实践
碧桂园服务通过引入 EMR Serverless StarRocks 存算分离架构,解决了海量数据处理中的资源利用率低、并发能力不足等问题,显著降低了硬件和运维成本。实时查询性能提升8倍,查询出错率减少30倍,集群数据 SLA 达99.99%。此次技术升级不仅优化了用户体验,还结合AI打造了“一看”和“—问”智能场景助力精准决策与风险预测。
496 69
|
5月前
|
Cloud Native Serverless 流计算
云原生时代的应用架构演进:从微服务到 Serverless 的阿里云实践
云原生技术正重塑企业数字化转型路径。阿里云作为亚太领先云服务商,提供完整云原生产品矩阵:容器服务ACK优化启动速度与镜像分发效率;MSE微服务引擎保障高可用性;ASM服务网格降低资源消耗;函数计算FC突破冷启动瓶颈;SAE重新定义PaaS边界;PolarDB数据库实现存储计算分离;DataWorks简化数据湖构建;Flink实时计算助力风控系统。这些技术已在多行业落地,推动效率提升与商业模式创新,助力企业在数字化浪潮中占据先机。
337 12
|
7月前
|
Kubernetes 监控 Serverless
基于阿里云Serverless Kubernetes(ASK)的无服务器架构设计与实践
无服务器架构(Serverless Architecture)在云原生技术中备受关注,开发者只需专注于业务逻辑,无需管理服务器。阿里云Serverless Kubernetes(ASK)是基于Kubernetes的托管服务,提供极致弹性和按需付费能力。本文深入探讨如何使用ASK设计和实现无服务器架构,涵盖事件驱动、自动扩展、无状态设计、监控与日志及成本优化等方面,并通过图片处理服务案例展示具体实践,帮助构建高效可靠的无服务器应用。
|
2天前
|
存储 人工智能 Serverless
函数计算进化之路:AI 应用运行时的状态剖析
AI应用正从“请求-响应”迈向“对话式智能体”,推动Serverless架构向“会话原生”演进。阿里云函数计算引领云上 AI 应用 Serverless 运行时技术创新,实现性能、隔离与成本平衡,开启Serverless AI新范式。
|
5月前
|
SQL 分布式计算 Serverless
鹰角网络:EMR Serverless Spark 在《明日方舟》游戏业务的应用
鹰角网络为应对游戏业务高频活动带来的数据潮汐、资源弹性及稳定性需求,采用阿里云 EMR Serverless Spark 替代原有架构。迁移后实现研发效率提升,支持业务快速发展、计算效率提升,增强SLA保障,稳定性提升,降低运维成本,并支撑全球化数据架构部署。
520 56
鹰角网络:EMR Serverless Spark 在《明日方舟》游戏业务的应用

相关产品

  • 函数计算