Serverless
2024年6月22日 更新
开启更多功能,提升办公效能

Description

Serverless 服务遵循 Node.js 的约定和规范,保持 Node.js 项目风格的一致性。

模板代码

Serverless

    Serverless(简称 sls) 是一个构建和管理无服务架构服务的框架,Serverless 服务将使用 sls 构建、管理、部署无服务项目。

Config

    使用 config 包管理配置。在项目根目录建创建 config 文件夹,并在该文件夹放置不同环境的配置文件。

config
- default.js
- development.js
- production.js
- staging.js
- test.js

   为了易于控制 sls 配置,使用 serverless.js 作为 sls 的配置。

ENV

    NODE_ENV 是 Node.js 的运行环境,stage 表示 serverless 的环境。

    每个 stage 对应一个 NODE_ENV 环境,也就是 serverless 代码的运行环境,使用 NODE_ENV 运行代码的时候会自动根据 NODE_ENV 选择对应的 stage。

stage

NODE_ENV

description

dev

development

开发环境

test

test

测试环境

staging

staging

测试环境

prod

production

生产环境

    在 serverless.js 文件中引用配置文件,并完成 NODE_ENV 到 stage 的映射。

const env = config.util.getEnv('NODE_ENV');

const stage = ({
development: 'dev',
test: 'test',
staging: 'staging',
production: 'prod'
})[env];


Deploy

    在使用 sls 部署 serverless 服务的时候需要使用对应的 Node 环境。

    使用 sls deploy 部署,根据 NODE_ENV 会自动选择对应的 stage,NODE_ENV=envName sls deploy,比如开发环境:NODE_ENV=development sls deploy,。

    使用 sls remove 取消部署,根据 NODE_ENV 会自动选择对应的 stage,NODE_ENV=envName sls remove,比如开发环境:NODE_ENV=development sls deploy。

Package

    出于性能考虑,需要尽可能的减小 serverless 项目的体积,特别是 λ。使用 sls 部署的时候,sls 会自动打包 serverless 项目成压缩包并上传 AWS。

    尽可能减少不必要的包的使用,并把 aws-sdk 包作为测试包,因为 AWS 默认提供。

"devDependencies": {
  "aws-sdk": "^2.529.0"
}

把和运行无关的代码去除,比如测试代码。

// serverless.js

module.exports = {
  package: {
    exclude: [
      '.nyc_output/**',
      'bin/**',
      'coverage/**',
      'test/**',
      '.eslintignore',
      '.eslintrc',
      '.nycrc',
      'README.md',
      'test.js',
      'tables/**',
      '.dynamodb/**'
    ]
  }
};

如果有必要,可以把不同的 λ 分开打包。

Resource

    Serverless 中使用的的 λ、API Gateway、DynamoDB 等称为资源,使用 sls 管理这些资源:创建、修改和销毁等。

   比如 SQS。

const config = require('config');

module.exports = {
  resources: {
      pigQueue: {
        Type: 'AWS::SQS::Queue',
        Properties: {
          QueueName: config.sqs.pig
        }
      }
    }
  }
};

如果是 DynamoDB,需要把表的定义单独管理。比如放在 src/table/index.js。

const config = require('config');

module.exports = {
  pigTable: {
    TableName: config.table.pig,
    AttributeDefinitions: [{
      AttributeName: 'id',
      AttributeType: 'S'
    }],
    KeySchema: [{
      AttributeName: 'id',
      KeyType: 'HASH'
    }],
    ProvisionedThroughput: {
      ReadCapacityUnits: 1,
      WriteCapacityUnits: 1
    }
  }
};

然后在 serverless.js 中配置。

const config = require('config');
const tables = require('./src/table');

module.exports = {
    Resources: {
      ...Object.keys(tables).reduce((obj, name) => (Object.assign(obj,
        {
          [name]: {
            Type: 'AWS::DynamoDB::Table',
            Properties: tables[name]
          }
        })), {})
};

Test

    Serverless 服务遵循 Node.js 测试规范

    Serverless 服务分为单元测试(包括 λ 的测试)、集成测试(包括接口测试)。

Local Test & development

    Serverless 服务需要依赖云服务的资源,比如 λ、DynamoDB 等。为了方便本地开发和测试,需要在本地构建这些资源环境。

    通过使用 sls 插件的方式,在本地构建这些资源的环境,然后进行自动化测试。比如 API Gateway & Lambda

Serverless-localstack

    A fully functional local AWS cloud stack.

Serverless-offline

    Serverless-offline 是一个 λ 和 API Gateway 本地化的一个 sls 插件。

Serverless-dynamodb-local

    Serverless-dynamodb-local 是一个 DynamoDB 本地化的一个 sls 插件。

Mongodb-memory-server

    Spinning up mongod in memory for fast tests.

API Gateway & Lambda

    在 serverless.js 配置插件。

module.exports = {
  plugins: ['serverless-dynamodb-local', 'serverless-offline']
};

使用子进程构建所需资源的环境,然后测试代码就可以使用这些资源进行测试。

const { spawn } = require('child_process');

before(function (done) {
  this.timeout(30000);

  console.log('[Test Bootstrap] Start');

  this.slsOfflineProcess = spawn('sls', ['offline', 'start']);
  console.log(`Serverless: Offline started with PID : ${this.slsOfflineProcess.pid}`);

  this.slsOfflineProcess.stdout.on('data', (data) => {
    if (data.includes('Offline listening on')) {
      console.log(data.toString().trim());
      console.log('[Test Bootstrap] Done');
      done();
    } else {
      console.log(data.toString());
    }
  });

  this.slsOfflineProcess.stderr.on('data', (data) => {
    console.error(`Error starting Serverless Offline:\n${data}`);
    console.error('[Test Bootstrap] Done');

    done(data);
  });
});

after(function () {
  console.log('[Test Teardown] Start');

  this.slsOfflineProcess.kill();
  console.log('Serverless Offline stopped');
  console.log('[Test Teardown] Done');
});

Unit Test

Integration Test

Lambda

Log

    在 λ 页面或 Cloudwatch Insights 页面,可以找到对应的 λ 日志数据。可以找到最耗费资源的请求并进行优化。


Metric

    在 λ 页面或 Cloudwatch Metrics 页面,可以找到对应的 λ metric 数据。


API Gateway

Log

    stage 为 prod 需要开启日志服务。


Metric

    在 Gateway 的 Dashboard 页面也看到接口的大概 metric 数据。

    如果需要看 metric 的详细,可以到 Metrics 页面(可以在 Dashboard 点击对应的图表)。

Monitoring

Tool

Pipeline

  1. Local:develop & local test
  1. Gitlab:Serverless Repository
  1. CI:Run Lint & Unit Test
  1. CD:Deploy to staging / prod

Lifestyle

CI

CD

参考