Skip to content

第三章 开始部署项目-Serverless

Serverless

image-20240223212953491

缺陷:

性能浪费严重,早期用户量不大,服务器只使用了很少的性能。

image-20240223213145149

image-20240223213351716

好处:

相比自建机房资源的利用率更高。

缺陷:

购买虚拟机,价格依然很昂贵。

利用率依然不够高。

image-20240223213808240

好处:

ServerLess 最核心的价值在于,按量计费。

收费模式:

部署的内容是一个一个可执行的函数,按照函数的使用量付费。

CPU的占用率 + CPU使用时长

5s * CPU 1%

1s * CPU 100%

计费的依据:

  • CPU的使用
  • 网络带宽

阿里云的ServerLess

搜索:函数计算

image-20240223214313104

创建应用:

image-20240223214751231

选择【web框架】,选择对应的技术栈:

image-20240223214921936

创建应用,点击【创建并部署默认环境】:

image-20240223221614948

创建执行中:

image-20240223221714898

构建详情界面展示:

image-20240223221910245

部署成功:

image-20240223222002176

访问域名:

image-20240223222108114

image-20240223222154080

去gitee仓库中下载代码:

image-20240223222507319

安装依赖:

image-20240223222910572

运行:npm run start

image-20240223223117049

更改代码,提交仓库,自动构建:

image-20240224113935176

注意:package-lock.json会导致部署失败

json
"dependencies": {
  "@type/node": "^8.0.33"
}

原因:本地构建的版本不一定跟线上匹配,所以不上传本地构建的package-lock.json,让线上自主选择插件版本构建环境

~和^的区别

  • ~会匹配最近的小版本依赖包,比如~1.2.3会匹配所有1.2.x版本,但是不包括1.3.x的版本
  • ^会匹配最新的大版本依赖包,比如^1.2.3会匹配所有1.x.x的包,包括1.3.0,但是不包括2.0.0

那么该如何选择呢?

当然可以指定特定的版本号,直接写1.2.3,前面什么前缀都没有,这样固然没问题,但是如果依赖包发布新版本修复了一些小bug,那么需要手动修改 package.json文件;~^则可以解决这个问题。但是需要注意^版本更新可能比较大,会造成项目代码错误,所以建议使用~来标记版本号,这样可以保证项目不会出现大的问题,也能保证包中的小bug可以得到修复。

而使用package-lock.json可以把项目版本号固定,避免版本不一致导致问题。

将静态资源和后端服务放在同一个工程下

前端更改:

image-20240224114438870

后端服务:

image-20240224114514229

效果:

image-20240224114546730

如何让前端页面可以自动更新?

目前存在Node服务需要手动获取html页面模板

image-20240224191141395

解决手动关联html的思路两种:

  • 在流水线中解决问题
  • 在控制器中解决问题

image-20240224221357943

在控制器中解决手动关联html的问题

image-20240224225818813

新增Node服务控制器:

shell
# 依赖安装
npm i superagent -S

image-20240225085607268

image-20240225085631572

修改静态资源网页:

image-20240225085955078

效果:

image-20240225095434971

脚本解决html关联问题

新建js脚本:build_html.js

js
// 下载 https://react-web-static-1258508006.cos.ap-nanjing.myqcloud.com/index.html 内容
// 然后复制到public文件夹下

const superAgent = require('superagent');
const path = require('path');
const fs = require('fs');

// 定义目标文件路径
const view_path = path.join(__dirname, './public/index.html');

// 创建html文件
async function create_html() {
  const res = await superAgent.get(
    'https://react-web-static-1258508006.cos.ap-nanjing.myqcloud.com/index.html',
  );
  fs.writeFileSync(view_path, res.text);
  console.log('创建html文件成功');
}

create_html();

package.json 更改执行脚本命令:

json
  "scripts": {
    "build": "node .build_html.js && nest build",
  },

修改静态资源网页:

image-20240225105754000

效果:

image-20240225105820148

总结:两种关联html方式

在流水线中解决问题,构建过程中拉取html下载到public目录中

  • 缺点:每次前端更新,后端即使没有改代码,也要重新进行发布

在控制器中解决问题,nodejs路由中,当用户访问时,动态拉取html的内容

  • 缺点:每次用户访问的时候,服务器都要拉取下载一次html,网络链路变长了。

到底选择哪种方式:

首选方案二:

  • 开发方便
  • 性能影响并没有想象的那么大

方案一场景:

  • 项目对网络加载速度要求极高。
  • 后端构建无阻断

项目中的 s.yaml 的作用

参考链接:客户端交互各大厂商的serverless产品

详细内容:

yaml
edition: 3.0.0
name: web-framework-app
access: 'undefined'
vars:
  region: 'cn-hangzhou'
  functionName: 'aliyun-nest-devops-fn'
resources:
  framework:
    component: fc3
    actions:
      pre-deploy:
        - run: npm install --registry=https://registry.npmmirror.com
          path: ./code
        - run: npm run build
          path: ./code
    props:
      region: ${vars.region}
      description: Serverless Devs Web Framework Function
      runtime: custom
      memorySize: 512
      timeout: 6
      customRuntimeConfig:
        command:
          - ./bootstrap # 启动服务
        port: 9000
      functionName: ${vars.functionName}
      code: ./code
      triggers:
        - triggerName: http-trigger # HTTP 触发器
          triggerType: http
          triggerConfig:
            authType: anonymous
            methods:
              - GET
              - POST
  fc3_domain_0:
    component: fc3-domain
    props:
      region: ${vars.region}
      domainName: auto
      protocol: HTTP
      routeConfig:
        routes:
          - path: /*
            functionName: ${vars.functionName}

triggers 触发器:

参考链接:阿里云链接

  • http[主要]
  • 事件

自定义域名访问ServerLess服务

image-20240225113900748

前置条件:

  • 注册域名
  • 域名必须备案
  • 添加DNS解析

Released under the MIT License.