人人都是Serverless架构师之传统内容管理系统改造实战一[开篇]

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
函数计算FC,每月15万CU 3个月
简介: 内容管理系统是很常见的一种web应用场景,可以用到个人独立站,企业官网展示等场景,具有很高的实用价值,一个标准的内容管理系统主要由三个部分组成 主站展示部分、后台管理系统、API接口服务,本系列文章会以一个已有内容管理系统的Serverless架构重构展开,介绍改造的基本思路,改造细节,以及性能优化业务可观测设计等。涉及大家关心的Serverless生产遇到的一些问题,比如数据库、日志、动静态分离、调试、维护、灰度方案等。最真实的展现Serverless架构的实施落地细节。本篇章作为系列文章的开篇,大致讲解一下将传统前端应用重构成Serverless架构的架构设计方案,工程改造思路,以及部署

本次改造的项目题材取自GiiBee CMS
Serverless架构改造的仓库地址

项目改造后预览地址 SSR方案地址SSG方案地址

1. 题材选择

最初的动机是想针对传统的项目做一个完整的Serverless架构重构,并且想找一些有一定复杂度能够展示Serverless架构分布式特色的项目,GiiBee CMS的项目结构比较符合预期。整个项目采用的技术栈是前端js全栈,Api服务使用了 NestJS, 管理后台是标准的 Vue + Element UI 的单页面应用形式,展示首页则是用了Nuxtjs这个既可作 SSR 也可作SSG 的前端渲染框架,三个部分各自独立又有联系,整体看是一个项目,非常契合Serverless架构的分布式结构。

2. 架构设计

这套CMS系统的三个部分在部署部分是独立的,但在访问侧却应该是统一的,首页,后台管理,OpenApi 服务需要共用同一个域名,这个时候需要有个前置网关入口来做相应的分流处理。这里提供两套方案,一套是以阿里云ApiGateway为入口流量处理的方案,另外一个则是以阿里云DCDN边缘应用程序为入口流量处理的方案,两个方案都有各自的优劣,后面会详细展开。并且为了能够将项目的完整功能呈现出来,首页的渲染方式准备使用SSR,整个的架构设计方案如下。

方案一:ApiGateway

方案二:DCDN边缘应用程序


3. 工程改造

对整个工程源码进行解读后,将需要改造的部分进行如下罗列:

3.1 前端静态资源

主要包括网站首页图片,产品图片等,原项目中静态资源存放在server/public/uploads 目录下,跟服务端的耦合度比较高,而服务端最终需要运行到函数计算FAAS服务中,无写权限,这部分需要做一些处理。有两种方案可以参考:

  1. 将目录映射到Nas上,利用Nas进行读写,这种改造成本较低,不过缺点是依然依赖主业务服务。
  2. 单独将静态资源文件存储到 OSS,实现跟业务服务的解耦,缺点就是改造成本比第一个方案要高。

3.2 日志

后端服务的日志写入同样会受限,与静态资源不同的是日志服务可以单独写到专业的日志存储服务上不如SLS。

3.3 数据库

数据库部分也要单独准备可访问的链接地址,账号,密码等,这些同样需要改动源码。

3.4 配置项

比如上面提到的数据库信息,日志地址信息,静态资源地址信息等,这些配置项在Serverless架构模式下都需要单独抽离出来,以环境变量的方式替换存在于源码中的位置,以便安全和灵活的设置。

3.5 其他

除了上面几个基本项外,剩下的就是根据业务功能做适当的调整了,实践中比如路径的改动,功能性增加等。此外部署配置部分的内容也需要在源代码中体现,比如使用函数计算Customer Runtime 部署后端Api服务,就需要准备好bootstrap入口文件。

3.6 部署方案

其实就是如何配置ServerlessDevs  s.yaml,  我们需要先配置 Api服务的配置项,将Nestjs的后端项目部署到函数计算,将后端管理系统的前端静态资源上传到OSS对象存储,将主站内容做SSR的构建,然后同样以部署函数的方式部署到函数计算上,最后还要配置网关及路由关系映射,增加DNS解析等。理想的状态是,所有这些操作都可以用统一工程化的方式一键处理,具体实施的环节我将在后面的文章中做详细介绍。

s.yaml的基本信息展示如下:

edition: 1.0.0
name: modern-app-new
access: hanxie
vars:
  region: cn-hangzhou
  fc: 
    serviceName: 'modern-app-new'
    functionName: 'modern-app-new'
    triggers: 'modern-web-api'
    staticPath: '/mnt/auto/modern-app-new/public'
    logPath: '/mnt/auto/modern-app-new/logs/application.log'
  oss:
    bucketName: 'hanxie-modernweb-registery'
    bucketObject: 'admin'
    bucketObject2: 'portal'
services:
  www-admin: # 静态资源
    component: oss
    props:
      region: ${vars.region}
      bucket: ${vars.oss.bucketName} # OSS bucket 自动生成
      subDir: ${vars.oss.bucketObject}
      acl: public-read # 读写权限
      codeUri: ./admin/dist # 指定本地要上传目录文件地址
      website: # OSS 静态网站配置
        index: index.html # 默认首页
        error: 404.html # 默认 404 页
        subDirType: redirect # 子目录首页 404 规则
      # customDomains: # OSS 绑定域名
      #   - domainName: auto
      #     protocol: HTTP
  api-server:
    component: fc
    actions:
      post-deploy: # 在deploy之后运行
      - plugin: keep-warm-fc
        args:
          url: http://modern-app-new.modern-app-new.1611387345152601.cn-hangzhou.fc.devsapp.net
    # actions:
    #   post-deploy:
    #     - component: fc nas upload -r ./server/logs /mnt/auto/modern-app-new
    #     - component: fc nas upload -r ./server/public /mnt/auto/modern-app-new
    props:
      region: ${vars.region}
      service:
        name: ${vars.fc.serviceName}
        description: Aliyun RAM Role
        internetAccess: true
        nasConfig: auto
      function:
        name: ${vars.fc.functionName}
        description: Native recording handler
        timeout: 3000
        memorySize: 1024
        runtime: custom
        environmentVariables:
          NODE_ENV: production
          dbHost: 
          dbPort: 3306
          dbPassword: 
          dbUserName: 
          staticPath: ${vars.fc.staticPath}
          logPath: ${vars.fc.logPath}
        codeUri: ./server
        caPort: 3000
      triggers:
        - name: ${vars.fc.triggers}
          type: http
          config:
            authType: anonymous
            methods:
              - GET
              - POST
              - PUT
              - DELETE
              - HEAD
              - OPTIONS
      customDomains:
        - domainName: auto
          protocol: HTTP
          routeConfigs:
            - path: /*
              serviceName: ${vars.fc.serviceName}
              functionName:  ${vars.fc.functionName}
  ssr-portal:
    component: fc
    actions:
      post-deploy: # 在deploy之后运行
      - plugin: keep-warm-fc
        args:
          url: http://modern-app-portal.modern-app-portal.1611387345152601.cn-hangzhou.fc.devsapp.net
    # actions:
    #   post-deploy:
    #     - component: fc nas upload -r ./server/logs /mnt/auto/modern-app-new
    #     - component: fc nas upload -r ./server/public /mnt/auto/modern-app-new
    props:
      region: ${vars.region}
      service:
        name: modern-app-portal
        description: Aliyun RAM Role
        internetAccess: true
        nasConfig: auto
      function:
        name: modern-app-portal
        description: Native recording handler
        timeout: 3000
        memorySize: 1024
        runtime: custom
        codeUri: ./web
        caPort: 3001
      triggers:
        - name: modern-app-portal
          type: http
          config:
            authType: anonymous
            methods:
              - GET
              - POST
              - PUT
              - DELETE
              - HEAD
              - OPTIONS
      customDomains:
        - domainName: auto
          protocol: HTTP
          routeConfigs:
            - path: /*
              serviceName: modern-app-portal
              functionName:  modern-app-portal

4. 总结

上面介绍了对传统前端应用做Serverless架构重构的基本思路,从设计到工程改造到部署方案都有涉及,单单是内容的罗列就有很多内容,真实的改造中遇到的问题更多,也曾一度有打退堂鼓的想法,怀疑过Serverless改造的投入产出是否合理,但当真正完成后又会有非常大的成就感,在后续对项目的逐渐完善中进一步体会到Serverless架构的魅力所在,相信各位小伙伴在跟随笔者完成这个Serverless架构改造系列文章后也会有相同的感觉,接下来我们一起探索!

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
目录
相关文章
|
11天前
|
运维 监控 负载均衡
深入理解无服务器架构:优势与挑战
【10月更文挑战第6天】深入理解无服务器架构:优势与挑战
|
18天前
|
分布式计算 大数据 Serverless
云栖实录 | 开源大数据全面升级:Native 核心引擎、Serverless 化、湖仓架构引领云上大数据发展
在2024云栖大会开源大数据专场上,阿里云宣布推出实时计算Flink产品的新一代向量化流计算引擎Flash,该引擎100%兼容Apache Flink标准,性能提升5-10倍,助力企业降本增效。此外,EMR Serverless Spark产品启动商业化,提供全托管Serverless服务,性能提升300%,并支持弹性伸缩与按量付费。七猫免费小说也分享了其在云上数据仓库治理的成功实践。其次 Flink Forward Asia 2024 将于11月在上海举行,欢迎报名参加。
113 1
云栖实录 | 开源大数据全面升级:Native 核心引擎、Serverless 化、湖仓架构引领云上大数据发展
|
3天前
|
运维 监控 Serverless
利用Serverless架构优化成本和可伸缩性
【10月更文挑战第13天】Serverless架构让开发者无需管理服务器即可构建和运行应用,实现成本优化与自动扩展。本文介绍其工作原理、核心优势及实施步骤,探讨在Web应用后端、数据处理等领域的应用,并分享实战技巧。
|
5天前
|
运维 Serverless 数据处理
Serverless架构通过提供更快的研发交付速度、降低成本、简化运维、优化资源利用、提供自动扩展能力、支持实时数据处理和快速原型开发等优势,为图像处理等计算密集型应用提供了一个高效、灵活且成本效益高的解决方案。
Serverless架构通过提供更快的研发交付速度、降低成本、简化运维、优化资源利用、提供自动扩展能力、支持实时数据处理和快速原型开发等优势,为图像处理等计算密集型应用提供了一个高效、灵活且成本效益高的解决方案。
24 3
|
5天前
|
存储 消息中间件 人工智能
ApsaraMQ Serverless 能力再升级,事件驱动架构赋能 AI 应用
本文整理自2024年云栖大会阿里云智能集团高级技术专家金吉祥的演讲《ApsaraMQ Serverless 能力再升级,事件驱动架构赋能 AI 应用》。
|
7天前
|
运维 Serverless 数据处理
Serverless架构在图像处理等计算密集型应用中展现了显著的优势
Serverless架构在图像处理等计算密集型应用中展现出显著优势,包括加速研发交付、降低成本、零运维成本、高效资源利用、自动扩展、实时数据处理及快速原型开发,为高并发、动态需求场景提供高效解决方案。
19 1
|
11天前
|
运维 Serverless 数据处理
Serverless架构在图像处理等计算密集型应用中展现出显著优势
【10月更文挑战第6天】Serverless架构在图像处理等计算密集型应用中展现出显著优势,包括加速研发交付、成本效益、零运维成本、高效资源利用、自动扩展能力、实时数据处理及快速原型开发,为高并发、动态需求场景提供高效、灵活的解决方案。
28 4
|
12天前
|
监控 Serverless 云计算
探索Serverless架构:开发的未来趋势
【10月更文挑战第5天】Serverless架构,即无服务器架构,正逐渐成为云计算领域的热点。它允许开发者构建和运行应用程序而无需管理底层服务器。本文介绍了Serverless架构的基本概念、核心优势及挑战,并展示了其在事件驱动编程、微服务架构和数据流处理等场景中的应用。通过优化冷启动、使用外部存储等实战技巧,开发者可以更好地利用Serverless架构提升开发效率和应用性能。随着技术的成熟,Serverless将在未来软件开发中扮演重要角色。
|
16天前
|
缓存 前端开发 Serverless
前端技术新趋势:从PWA到Serverless架构
【10月更文挑战第1天】前端技术新趋势:从PWA到Serverless架构
30 3
|
18天前
|
监控 Serverless 云计算
探索Serverless架构:无服务器计算的新纪元
Serverless架构作为云计算的新范式,让开发者无需管理服务器即可构建和运行应用,从而专注于代码开发。其核心优势包括成本效益、自动扩展及高效部署。通过事件驱动模型和微服务部署,开发者按需付费,减少了资源浪费。尽管面临冷启动、状态管理和调试等挑战,Serverless架构仍凭借其高效性与可扩展性展现出广阔的应用前景。流行平台如AWS Lambda、Azure Functions等使其实施更为便捷。

相关产品

  • 函数计算