三十分钟快速搭建serverless网盘服务

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
函数计算FC,每月15万CU 3个月
简介: 前言 函数计算支持以无服务器架构快速构建企业和开发者的软件系统,以其全托管事件触发模式、超弹性伸缩以及低廉的计费方式,相对于传统服务器架构,在开发效能和运维模式上都取得了明显优势。另外还提供了各种服务间的触发功能,作为云端各种产品的黏合剂,适用于各种应用场景。

前言

函数计算支持以无服务器架构快速构建企业和开发者的软件系统,以其全托管事件触发模式、超弹性伸缩以及低廉的计费方式,相对于传统服务器架构,在开发效能和运维模式上都取得了明显优势。另外还提供了各种服务间的触发功能,作为云端各种产品的黏合剂,适用于各种应用场景。

本节,将带领大家利用函数计算,快速搭建一个功能完整的网盘服务。网盘服务的项目见(即将开源):

网盘服务简介

功能

网盘服务功能详细介绍请参考文章网盘服务系统和相应的项目 repo

本文重点不是介绍网盘功能,所以,请大家通过已经搭建好的网盘 demo 自行体验,这里不做过多赘述。

网盘系统无服务器架构

image.png

网盘服务功能集较多,这里就以上传文件功能为例,展现其网盘的实现架构。

网盘服务自身模块以及资源依赖

网盘服务的模块实现分为三个部分,如下图所示:

image.png

  • apis : 提供了网盘的 API 接口功能,这部分功能是 serverless 架构实现的核心,使用 FC+API Gateway 架构模式实现主体功能,如上图无服务器架构图中展现的。
  • Site : 提供了网盘实例的管理控制台,还有对应的网盘宣传、使用文档以及 api 文档等。
  • UI : 提供用户使用和维护网盘的客户端。

这里,Site 和 UI 这两个子模块的实现都是静态网站模式,可以直接使用 OSS bucket 的 website 特性实现。为了简化整个部署流程和自动化资源编排过程,将 Site 和 UI 的部署方式也整合到 FC 中统一维护,见下面的详细的部署流程描述。

网盘服务功能后台依赖资源罗列如下:

image.png

fun 介绍

funhave Fun with Serverless 的缩写,是一款 Serverless 应用开发的工具,可以帮助用户定义函数计算、API 网关、日志服务等资源,旨在与阿里云 ROS 兼容(尽管到目前为止 ROS 还不支持函数计算。但是,fun 作为 ROS 的子集是我们的目标)。

使用 fun 能够解决复杂服务的资源依赖维护问题,能够快速部署、更新,简化资源编排运维。针对该网盘服务的众多资源依赖,使用 fun 能够很方便、迅速的解决各种资源的搭建和维护过程。下面我们将演示如何使用 fun 部署网盘服务系统。

具体部署过程

网盘服务目前实现了三种身份登录验证功能: 钉钉、支付宝和特殊账号密码(用于测试)。
因为钉钉、支付宝登录方式需要走一些申请流程获取对应的 appID 和 appSecret ,这里为了简化流程,我们仅仅使用特殊账号密码方式。

部署的具体步骤如下:

  1. 准备工作:

    • 云账号准备
    • 代码准备
    • fun 下载和配置
  2. 配置 fun 的 template.yml
  3. 部署 template.yml 定义资源,获取二级域名等信息
  4. 更新 apis function
  5. 部署 Site ,创建 groupID 实例
  6. 部署 UI,配置 storage 实例

准备工作

云账号准备

首先,准备一个能够登录阿里云官网的云账号, 登录控制台获取这个账号的 UID ( accountID )、 accessKeyID 和 accessKeySecret 。部署演示使用的资源全部在华东 2 ( cn-shanghai )。也可以使用其他 region 资源,但是必须保证所有的服务都在同一个 region 中。

然后开通如下服务:
image.png

代码准备

函数计算支持多种代码上传方式,这里统一打包成 zip 文件,并上传到该云账号的某个 bucket 上(用户自行在华东 2 创建即可)。参考代码如下连接:

  • apis.zip

    • 注意: apis 使用 nodejs 实现,在打包之前需要执行 tnpm i 命令安装项目依赖。
    • 解压后目录结构如下:

        |-- controllers # 控制层,主要逻辑
        |-- routes        # api路由
        |-- services     # 公共方法,包含调用各个云产品的方法
        |-- utils    
        |-- models
        |-- node_modules   # 项目依赖
        |-- index.js     # 服务入口
        |-- conf.js       # config 配置
        |-- package.json 
  • site.zip

    • 解压后文件结构如下:
        |-- deploy.py   # 部署函数
        |-- site             # site代码目录
        |-- 404.html  
        |-- index.html    
        |-- docs
        |-- static   
  • ui.zip

    • 解压后文件结构如下:
        |-- deploy.py   # 部署函数
        |-- ui                # ui代码目录
        |-- 404.html  
        |-- index.html    
        |-- static   

fun 下载和配置

如果您的系统已经安装有 node 8 及以上的环境配置,那么可以直接执行如下命令进行 fun 的安装

npm install @alicloud/fun -g

如果您不想安装 node 运行环境,那么可以直接下载 fun 的 binary 执行,参考各种环境 fun 的 release binary

然后设置 accountID、accessKeyID 和 accessKeySecret 以及 region,请使用准备步骤中的已经申请的云账号的参数进行配置,本示例中 region 选择 cn-shanghai :

# 如果是 binary ,执行 ./${binary_name} config
fun config

template.yml 配置

template.yml 模板配置是本部署中最重要的部分,因为网盘服务依赖的资源项比较多(主要是 API网关资源和表格存储资源), 建议下载参考模板直接修改,需要修改的内容已经使用 "TODO" 标识。

template.yml 的语法规范参考 fun 规范文档

这面具体介绍配置中的相关部分:

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
  apsaradrivefc:
    Type: 'Aliyun::Serverless::Service'
    Properties:
      Description: apsara drive
      Policies:
        - AliyunOTSFullAccess
        - AliyunSTSAssumeRoleAccess
        - AliyunOTSFullAccess
        - AliyunLogFullAccess
        - AliyunFCInvocationAccess
      LogConfig:
        Project: log-yunpan # TODO replace sls project name
        Logstore: fclog
    apis:
      Type: 'Aliyun::Serverless::Function'
      Properties:
        Description: apis
        Runtime: nodejs8
        Timeout: 30
        MemorySize: 128
        Handler: index.handler
        CodeUri: oss://apsaradrive-ui/download/apis.zip # TODO replaced the code location
        EnvironmentVariables: # TODO replace all the values which has 'TODO' tag
          ENV_CONFIG: '...'
    DeploySite: # function name which deploys site
         Type: 'Aliyun::Serverless::Function'
         Properties:
            Handler: 'deploy.my_handler'
            Runtime: 'python2.7'
            Description: 'function to deploy site'
            MemorySize: 128
            Timeout: 30
            CodeUri: 'oss://apsaradrive-ui/download/site.zip' # TODO replaced by the code location
    DeployUI: # function name witch deploys ui
         Type: 'Aliyun::Serverless::Function'
         Properties:
            Handler: 'deploy.my_handler'
            Runtime: 'python2.7'
            Description: 'function to deploy ui'
            MemorySize: 128
            Timeout: 30
            CodeUri: 'oss://apsaradrive-ui/download/ui.zip' # TODO replaced by the code location
  apsaradriveapis:
    Type: 'Aliyun::Serverless::Api'
    ...

  ts-yunpan: # TODO replace ots instance name
    Type: 'Aliyun::Serverless::TableStore'
    Properties:
      ClusterType: HYBRID
      Description: for apsaradrive
     ...
  log-yunpan: # TODO replace sls project name
    Type: 'Aliyun::Serverless::Log'
    Properties:
      Description: log
    fclog:
      Type: 'Aliyun::Serverless::Log::Logstore'
      Properties:
        TTL: 10
        ShardCount: 1

上面定义的 yaml 文件主要做了以下几件事情:

  1. 创建一个名为 'apsaradrivefc' 的 Service , 并且为这个 Service 创建一个具有 AliyunOTSFullAccessAliyunSTSAssumeRoleAccessAliyunOTSFullAccessAliyunLogFullAccessAliyunFCInvocationAccess 这几大权限的 Service Role。然后在这个 Service 下面创建三个 Function ,分别名为 'apis', 'DeploySite' 和 'DeployUI' 。
  2. 创建一个 LOG Project名为 'log-yunpan' , 然后在这个LOG Project 下面创建一个名为 'fclog' 的 Logstore ,作为 apsaradrivefc 这个 Service 下 Function 执行的日志收集 store 。
  3. 创建一个名为 'ts-yunpan' 的 OTS Instance , 并且在这面生成各种 Table 。
  4. 创建一个 API 网关分组: apsaradriveapis ,以及其下的各种 API 定义。

需要修改的内容:

  1. OTS Instance name: 全局有三处地方需要修改,请统一,因为 OTS Instance 在 region 范围全局唯一,尽量保持命名唯一性,注意: OTS Instance 命名规范
  2. LOG Project name: 全局有两处地方需要修改,请统一,因为 LOG Project在region范围全局唯一,尽量保持命名唯一性,注意: LOG Project 命名规范
  3. 三处 CodeUri ,分别是 apis ,Site 和 UI 三个模块的代码位置,目前 template.yml 中的默认配置可用,可以不修改。
  4. apis 这个 Function 中的 EnvironmentVariables 属性内部需要配置 API 网关分组的二级域名,因为当前步骤还没有生成这个参数,这里先不修改。

部署 template.yml 定义资源

直接执行如下命令:

# 在 template.yml 所在目录执行
# 如果是 binary ,执行 ./${binary_name} config
fun deploy

这个时候,你可以在 OTS、SLS、RAM、API 网关和 FC 的控制台上分别看到 fun 为网盘服务创建的各种资源,如下图:

image.png

image.png

image.png

image.png

更新 apis function

从上一步 fun 的部署输出日志中可以找到对应的 API 网关分组的二级域名,如下:
image.png

修改 apis 这个 Function 中的 EnvironmentVariables 属性内部需要配置 API 网关分组的二级域名,如下图位置:

image.png

仍然执行如下命令,进行function的环境变量更新

fun deploy

至此,apis 模块部署完毕。

部署 Site ,创建 groupID 实例

Site 模块的实现其实就是一个静态网站,我们可以利用 OSS 的静态网站功能实现,步骤如下:

  1. 修改 static/global.js 中的 endpoint ( apis 的二级域名)和 ui_endpoint (如果在华东2, 那么就是 ${uid}-ui.oss-cn-shanghai.aliyuncs.com )
  2. 创建 ${uid}-site 这个 bucket ,并设置为 public-read ACL
  3. 设置这个 bucket 的 website 的默认首页和 404 页面
  4. 上传整个代码目录

将所有的步骤按照函数计算编程模型封装如下,并创建为 Function: DeploySite 。封装的 Function 实现如下所示:

import oss2
import logging
import json
import shutil
import os
import sys

reload(sys)
sys.setdefaultencoding('utf8')

from oss2.models import BucketWebsite

def delete_file(filePath):
    if os.path.exists(filePath):
        for fileList in os.walk(filePath):
            for name in fileList[2]:
                os.remove(os.path.join(fileList[0],name))
        shutil.rmtree(filePath)


def my_handler(event, context):
    # event is json string, parse it
    evt = json.loads(event)
    logger = logging.getLogger()
    endpoint = 'oss-cn-shanghai-internal.aliyuncs.com'
    creds = context.credentials
    auth = oss2.StsAuth(creds.accessKeyId, creds.accessKeySecret, creds.securityToken)

    # create bucket for site named ${uid}-site, and set the ACL to public read
    bucket_name = '%s-site' % (evt['uid'])
    bucket = oss2.Bucket(auth, endpoint, bucket_name)
    try:
        bucket.create_bucket(permission=oss2.BUCKET_ACL_PUBLIC_READ)
    except oss2.exceptions.BucketAlreadyExists:
        logger.info("Bucket %s is already exist" % bucket_name)

    # set static website
    bucket.put_bucket_website(BucketWebsite('index.html', '404.html'))
   # modify the config for site
    code_dir = '/tmp/site/'
    delete_file(code_dir)
    shutil.copytree('/code/site/', code_dir)
    data = u''
    with open(os.path.join(code_dir, 'static/global.js')) as f:
        for line in f.readlines():
            if line.startswith('var endpoint = '):
                line = u'var endpoint = \'%s\';\n' % (evt['endpoint'])
            elif line.startswith('var ui_endpoint = '):
                line = u'var ui_endpoint = \'http://%s.oss-cn-shanghai.aliyuncs.com\';\n' % (bucket_name)
            data += line
    with open(os.path.join(code_dir, '/tmp/site/static/global.js'), "w") as f:
        f.writelines(data)

    # put all the static code to the bucket
    for root,dirs,files in os.walk(code_dir):
        for filespath in files:
            full_file_name = os.path.join(root,filespath)
            bucket.put_object_from_file(full_file_name[len(code_dir):], full_file_name)

所以,只需要 Invoke 这个 Function 就能够完成 Site 模块的部署。接下来演示一下 Invoke 的过程。

登录函数计算控制台,找到对应的 Function: DeploySite ,修改触发事件,然后点击执行:

image.png

{
  "uid": "replace with you accountID",
  "endpoint": "replace with the SLD"
}

然后打开 Site 页面(如果 uid 为 apsaradrive 的话,那么 Site 的 URL 为: http://apsaradrive-site.oss-cn-shanghai.aliyuncs.com ),登录之后(使用默认的 username: admin, password: 1234 登录),创建 group 实例。

image.png

部署 UI,配置 storage 实例

部署 UI 的过程和 Site 类似,同样在控制台上找到 DeployUI,修改触发事件,注意事件格式定义如下:

{
  "uid": "replace with you accountID",
  "group_id": "replace with the group_id you just create in the Site web"
  "endpoint": "replace with the SLD"
}

点击执行之后,就可以通过刚刚 Site 页面的 Group 入口进入 UI 页面:
image.png

在 UI 页面配置相关的 Storage :

image.png

接下来,您就可以对您的网盘进行各种文件操作了。
image.png
image.png

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
8天前
|
存储 Serverless 数据库
科普文:云计算服务类型IaaS, PaaS, SaaS, BaaS, Faas说明
本文介绍了云计算服务的几种主要类型,包括IaaS(基础设施即服务)、PaaS(平台即服务)、SaaS(软件即服务)、BaaS(后端即服务)和FaaS(函数即服务)。每种服务模式提供了不同的服务层次和功能,从基础设施的提供到应用的开发和运行,再到软件的交付使用,满足了企业和个人用户在不同场景下的需求。文章详细阐述了每种服务模式的特点、优势和缺点,并列举了相应的示例。云计算服务的发展始于21世纪初,随着互联网技术的普及,这些服务模式不断演进,为企业和个人带来了高效、灵活的解决方案。然而,使用这些服务时也需要注意服务的稳定性、数据安全性和成本等问题。
182 3
|
4月前
|
分布式计算 运维 Serverless
EMR Serverless Spark服务和EMR Serverless StarRocks服务的比较
**EMR Serverless Spark** 以其出色的稳定性、高效性能、减轻运维负担及成本优化著称,适合大规模数据处理。**EMR Serverless StarRocks** 则以高速查询、存算分离架构和灵活扩缩容见长,侧重企业级功能。两者在不同应用场景中有各自优势,选择应基于具体需求。更多详情,参考阿里云官方资源。
|
7天前
|
机器学习/深度学习 监控 物联网
函数即服务(FaaS)
函数即服务(FaaS)
|
2天前
|
弹性计算 人工智能 自然语言处理
魔搭社区与函数计算:高效部署开源大模型的文本生成服务体验
在数字化时代,人工智能技术迅速发展,开源大模型成为重要成果。魔搭社区(ModelScope)作为开源大模型的聚集地,结合阿里云函数计算,提供了一种高效、便捷的部署方式。通过按需付费和弹性伸缩,开发者可以快速部署和使用大模型,享受云计算的便利。本文介绍了魔搭社区与函数计算的结合使用体验,包括环境准备、部署应用、体验使用和资源清理等步骤,并提出了改进建议。
|
3月前
|
消息中间件 关系型数据库 Serverless
【阿里云】一键部署创建函数计算服务以处理多媒体文件
通过阿里云的一键部署功能,轻松创建函数计算服务以处理多媒体文件。首先选择地域并配置资源栈名称及其他必要参数,如登录凭证、实例类型及数据库配置。过程中可能需开通相关服务如消息服务MNS,并确保账户有足够的余额。完成配置后,系统自动创建资源栈。当状态显示“创建成功”即部署完毕。最后,通过提供的URL及凭据访问应用,上传PPTX文件进行处理,并下载处理后的结果。
80 5
|
3月前
|
Kubernetes 安全 Serverless
Kubernetes 的架构问题之Serverless Container中提供对外服务如何解决
Kubernetes 的架构问题之Serverless Container中提供对外服务如何解决
71 5
|
4月前
|
Java Serverless Docker
函数计算产品使用问题之使用Docker镜像部署的Web服务如何获取客户端的真实IP
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
4月前
|
运维 Serverless API
Serverless 应用引擎使用问题之如何开发HTTP服务
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
3月前
|
存储 运维 安全
函数计算产品使用问题之如何获取到访问其他阿里云服务所需的AccessKey、SecretKey或STS Token
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
3月前
|
消息中间件 运维 Serverless
Serverless 支撑赛事转播问题之利用函数计算处理视频直播截帧服务如何解决
Serverless 支撑赛事转播问题之利用函数计算处理视频直播截帧服务如何解决

热门文章

最新文章

相关产品

  • 函数计算