函数计算再升级,脱胎换骨出新意

本文涉及的产品
云服务器 ECS,每月免费额度200元 3个月
云服务器ECS,u1 2核4GB 1个月
简介: 作为一个解决方案架构师,我每天的工作几乎都会用到函数计算,用其来自动检测Web应用的一些页面数据、定时任务、视频转换等等。那么说到函数计算,大家是否能够清晰的说出函数计算是什么,用其来做什么呢?首先让我们首先来明确一下函数计算的概念,按照阿里云官方网站对于函数计算3.0的一个个产品简介:“函数计算是事件驱动的全托管计算服务。使用函数计算,您无需采购与管理服务器等基础设施,只需编写并上传代码或镜像。函数计算为您准备好计算资源,弹性地、可靠地运行任务,并提供日志查询、性能监控和报警等功能。”

FC3.0.jpg

作为一个解决方案架构师,我每天的工作几乎都会用到函数计算,用其来自动检测Web应用的一些页面数据、定时任务、视频转换等等。那么说到函数计算,大家是否能够清晰的说出函数计算是什么,用其来做什么呢?

首先让我们首先来明确一下函数计算的概念,按照阿里云官方网站对于函数计算3.0的一个个产品简介:

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

这里我们提取关键点:无需管理基础设施,专注于代码、业务

那么,在阿里云官网也提供了这样一个步骤图例用以说明,这5个步骤很清晰的描述出了,开发者使用函数计算的一个流程。


图片援引于阿里云函数计算帮助文档



解说视频(更精彩更细致更丰富)



从新出发,特性一览

特性研究(关键点)

一级实体不套娃

因为作者本人是亚马逊云科技合作伙伴的SA,那么在工作和日常生活中会经常用到函数计算,在亚马逊云科技的Lambda服务(函数计算),函数就直接是一个实体。反观阿里云方面,在函数计算3.0以前,咱们使用函数计算是需要先创建服务,然后再去服务中创建函数,一个服务中可容纳多个函数,函数并非一级实体。那么本次函数计算3.0的一个更新,可以说是在一定程度上真正的达到了函数计算的一个点。

全村希望:FAAS-->角色和工作负载绑定

还记得我第一次使用阿里云函数计算的时候,因为自己的云技术栈主要是在亚马逊云科技,对于函数计算的授权这块习惯了直接将函数和相关权限的角色绑定,在使用阿里云函数计算的时候,查阅了文档比较惊讶的就是并不支持,于是就直接在函数计算的代码中定义AK、SK,那么这样我觉得在云上来做这种操作是有点难受了,从另一个角度来分析,就是云平台的服务并没有很好的一个整合。那么现如今函数计算3.0终究是弥补上这个缺点,函数计算3.0现已支持SLR(服务关联角色),让开发者可以在使用函数计算服务的时候更好的去调用阿里云的其他服务。

说到这里,也是在无意间看到一篇文章《云厂商眼中的客户:又穷又闲又缺爱》,个人感觉得到似乎作者是将国内的云厂商骂了各遍,当然重点不在于此,重要的是文中提到的【阿里云不支持角色和工作负载绑定】,我发现文章这里有写错,在观察到阿里云函数计算3.0的帮助文档更新时间为2023年10月7日,而这里提到的文章发布时间为2023年11月6日,其间一个月的时间,还出现这样的错误,确实是有点。。。。

截图来自文章【云厂商眼中的客户:又穷又闲又缺爱

案例分享

多线程解压OSS大文件

当发布网页游戏、静态资源时,通常会使用OSS来存放游戏中的静态资源。这些静态资源数量可达成千上万,如果直接从本地同步这么多文件到OSS,势必会花费较长的时间。

为了优化这个过程,我们可以考虑先将所有静态资源打包成一个 ZIP 文件,然后上传到OSS。ZIP 文件体积较小,上传速度会快很多。上传完成后,我们可以触发函数计算服务,自动解压该 ZIP 文件,并将文件上传回指定的 OSS。这种方式可以大大缩短整体的一个业务流程。

在阿里云官方案例提供的一个《使用函数计算实现自动解压上传到OSS的ZIP文件》,我觉得这个可以拿出来讲讲,官方提供的一个案例,我感觉是有一点缺陷的

下面分别为阿里云和亚马逊云提供的一个方案,两者的差异就在于,函数计算解压后,对加压后的数据是否利用了函数多线程的一个形式传递给存储桶。

阿里云方案

亚马逊云科技方案

加入多线程后代码(也许有瑕疵)

# -*- coding: utf-8 -*-
'''
声明:
这个函数针对文件和文件夹命名编码是如下格式:
1. mac/linux 系统, 默认是utf-8
2. windows 系统, 默认是gb2312, 也可以是utf-8
对于其他编码,我们这里尝试使用chardet这个库进行编码判断,但是这个并不能保证100% 正确,
建议用户先调试函数,如果有必要再改写函数,并保证调试通过。
Statement:
This function names and encodes files and folders as follows:
1. MAC/Linux system, default is utf-8
2. For Windows, the default is gb2312 or utf-8
For other encodings, we try to use the chardet library for coding judgment here, 
but this is not guaranteed to be 100% correct. 
If necessary to rewrite this function, and ensure that the debugging pass
'''
import helper
import oss2
import json
import os
import time
import logging
import chardet
import concurrent.futures
"""
When a source/ prefix object is placed in an OSS, it is hoped that the object will be decompressed and then stored in the OSS as processed/ prefixed.
For example, source/a.zip will be processed as processed/a/... 
"Source /", "processed/" can be changed according to the user's requirements.
"""
# Close the info log printed by the oss SDK
logging.getLogger("oss2.api").setLevel(logging.ERROR)
logging.getLogger("oss2.auth").setLevel(logging.ERROR)
LOGGER = logging.getLogger()
# a decorator for print the excute time of a function
def print_excute_time(func):
    def wrapper(*args, **kwargs):
        local_time = time.time()
        ret = func(*args, **kwargs)
        LOGGER.info('current Function [%s] excute time is %.2f' %
                    (func.__name__, time.time() - local_time))
        return ret
    return wrapper
def get_zipfile_name(origin_name):  # 解决中文乱码问题
    name = origin_name
    try:
        name_bytes = origin_name.encode(encoding="cp437")
    except:
        name_bytes = origin_name.encode(encoding="utf-8")
    # the string to be detect is long enough, the detection result accuracy is higher
    detect = chardet.detect(name_bytes)
    confidence = detect["confidence"]
    detect_encoding = detect["encoding"]
    if confidence > 0.75 and (detect_encoding.lower() in ["gb2312", "gbk", "gb18030", "ascii", "utf-8"]):
        try:
            if detect_encoding.lower() in ["gb2312", "gbk", "gb18030"]:
                detect_encoding = "gb18030"
            name = name_bytes.decode(detect_encoding)
        except:
            name = name_bytes.decode(encoding="gb18030")
    else:
        try:
            name = name_bytes.decode(encoding="gb18030")
        except:
            name = name_bytes.decode(encoding="utf-8")
    # fix windows \\ as dir segment
    name = name.replace("\\", "/")
    return name
@print_excute_time
def handler(event, context):
    """
    The object from OSS will be decompressed automatically .
    param: event:   The OSS event json string. Including oss object uri and other information.
        For detail info, please refer https://help.aliyun.com/document_detail/70140.html?spm=a2c4g.11186623.6.578.5eb8cc74AJCA9p#OSS
    param: context: The function context, including credential and runtime info.
        For detail info, please refer to https://help.aliyun.com/document_detail/56316.html#using-context
    """
    evt_lst = json.loads(event)
    creds = context.credentials
    auth = oss2.StsAuth(
        creds.access_key_id,
        creds.access_key_secret,
        creds.security_token)
    evt = evt_lst['events'][0]
    bucket_name = evt['oss']['bucket']['name']
    endpoint = 'oss-' + evt['region'] + '-internal.aliyuncs.com'
    bucket = oss2.Bucket(auth, endpoint, bucket_name)
    object_name = evt['oss']['object']['key']
    if "ObjectCreated:PutSymlink" == evt['eventName']:
        object_name = bucket.get_symlink(object_name).target_key
        if object_name == "":
            raise RuntimeError('{} is invalid symlink file'.format(
                evt['oss']['object']['key']))
    file_type = os.path.splitext(object_name)[1]
    if file_type != ".zip":
        raise RuntimeError('{} filetype is not zip'.format(object_name))
    LOGGER.info("start to decompress zip file = {}".format(object_name))
    lst = object_name.split("/")
    zip_name = lst[-1]
    PROCESSED_DIR = os.environ.get("PROCESSED_DIR", "")
    RETAIN_FILE_NAME = os.environ.get("RETAIN_FILE_NAME", "")
    if PROCESSED_DIR and PROCESSED_DIR[-1] != "/":
        PROCESSED_DIR += "/"
    if RETAIN_FILE_NAME == "false":
        newKey = PROCESSED_DIR
    else:
        newKey = PROCESSED_DIR + zip_name
    zip_fp = helper.OssStreamFileLikeObject(bucket, object_name)
    newKey = newKey.replace(".zip", "/")
    with helper.zipfile_support_oss.ZipFile(zip_fp) as zip_file:
        with concurrent.futures.ThreadPoolExecutor() as executor:
            futures = []
            for name in zip_file.namelist():
                with zip_file.open(name) as file_obj:
                    name = get_zipfile_name(name)
                    new_object_key = newKey + name
                    futures.append(executor.submit(bucket.put_object, new_object_key, file_obj))
            # 等待所有任务完成
            concurrent.futures.wait(futures)

总结

先说优点,自古以来都说伸手不打笑脸人

  • 有实例的概念,我认为萝卜白菜各有所爱,利好--方便调试
  • IDE有Terminal提供,在调试的时候不用层就可以很方便的调试代码
  • 函数运行资源更大。环比友商亚马逊云科技的Lambda服务,那么阿里云函数计算3.0能提供最大32GB单个函数的内存量,亚马逊云科技的lambda服务单个函数最大10GB,三倍还多的一个差距,没得说的完胜

建议

在试用函数计算3.0的过程中,我的确感受到了函数计算3.0的一些便捷之处,但是从个人角度和使用习惯上来看,存在一些问题,也是可以在对比友商方面来讲,咱们阿里云是否可以基于以下提出的建议来改进?

  • 云平台服务的配套时效性。就拿负载均衡器来讲,是有函数计算可以作为目标组,但是在实际使用中仍旧保持使用函数计算2.0。(亦或者是因为函数计算3.0在测试中?)
  • 实例可见性。对于函数计算-Serverless,不再关心底层基础设施,应该是不可见实例,也应该淡化实例的概念。
  • 函数域名。这块应该在3.0中单独呈现出来,在每个函数中设置一个类似于“函数URL”的一个样子。当然也许函数域名在高级功能中统一设置是为了便捷性。
  • 成本方面。我相信有一部分客户是对于成本较为敏感的,亦或者是就是为了成本才选择使用函数计算服务,那么我们如何去把控成本,或者是说我们如何去从业务方面选择/计算最佳的一个CPU、内存,以达到性价比最高的一个状态,在友商亚马逊云科技方面,有一个叫做“Lambda power tuning”的方案,可以帮助客户找到运行函数最佳性价比。那么阿里云方面是否也可以对标亚马逊云科技为客户推出同类或者更优质的功能/方案?
  • 函数并发。跟阿里云函数计算的工程师了解后,函数计算3.0对于并发量是针对于单个函数按量和预留合并,这点和2.0不同,但是地域总量仍旧是300。如果客户的一个场景是小规格大并发呢?是否默认的300其实并不合理?
  • 日志调试。是否也可以参照友商给日志这块较大的一个麻烦额度,在调试函数计算3.0的时候更加的方便?
相关实践学习
基于函数计算一键部署掌上游戏机
本场景介绍如何使用阿里云计算服务命令快速搭建一个掌上游戏机。
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
目录
相关文章
|
1天前
|
人工智能 弹性计算 Serverless
函数计算 3.0 版本升级
【4月更文挑战第2天】函数计算 3.0 版本升级
12 2
|
1天前
|
Java Serverless 测试技术
Serverless 应用引擎问题之镜像升级报错如何解决
在进行Serverless应用开发和部署时,开发者可能会遇到不同类型的报错信息;本合集着重收录了Serverless环境中常见的报错问题及其解决策略,以助于开发者迅速诊断和解决问题,保证服务的连续性和可用性。
402 0
|
1天前
|
消息中间件 BI Serverless
消息队列推出serverless版、Quick BI升级至5.0……阿里云近期产品动态汇总
消息队列推出serverless版、Quick BI升级至5.0……阿里云近期产品动态汇总
482 1
|
1天前
|
人工智能 弹性计算 自然语言处理
函数计算 3.0 版:重大升级带来的优势与应用场景
近年来,随着云计算和服务化架构的快速发展,使得函数计算成为了一种备受技术圈关注的技术。而且最近函数计算有了新的重大升级更新,也就是函数计算 3.0 版是函数计算产品的一次重大升级,对函数管理、函数执行引擎、自定义域名、函数授权及弹性伸缩规则等方面进行了多项改进。新版本函数计算具备了极简体验、技术升级以及简化 AI 应用开发等优点,作为一名开发者,我有幸亲身体验了函数计算 3.0 版本后的变化,并在这篇文章中分享一下我的感想,接下来让我们来看看这次升级对开发者意味着什么吧。
477 1
函数计算 3.0 版:重大升级带来的优势与应用场景
|
1天前
|
消息中间件 存储 Cloud Native
阿里云消息产品全面升级为 ApsaraMQ,并发布 Serverless 版,助力企业降本
阿里云消息产品全面升级为 ApsaraMQ,并发布 Serverless 版,助力企业降本
62345 1
|
6月前
|
SQL 人工智能 关系型数据库
重磅|Serverless与AI驱动,阿里云瑶池数据库核心能力全面升级!
阿里云瑶池数据库全面Serverless化,智能助手全新亮相!
|
8月前
|
运维 Cloud Native Serverless
全面 Serverless 化,阿里云微服务引擎 MSE 重磅升级
全面 Serverless 化,阿里云微服务引擎 MSE 重磅升级
|
9月前
|
人工智能 弹性计算 运维
阿里云宣布 Serverless 应用引擎 SAE2.0 将公测上线,多款产品全新升级
阿里云宣布 Serverless 应用引擎 SAE2.0 将公测上线,多款产品全新升级
66100 53
|
9月前
|
人工智能 弹性计算 运维
阿里云容器服务 Serverless 版(ACK Serverless)全新升级
阿里云容器服务 Serverless 版(ACK Serverless)全新升级
1521 10
|
11月前
|
人工智能 运维 Kubernetes
阿里云 Serverless 容器服务全面升级:新增组件全托管、AI 镜像秒级拉取能力
阿里云 Serverless 容器服务全面升级:新增组件全托管、AI 镜像秒级拉取能力
http://www.vxiaotou.com