Duoyun Cloud
返回博客
tutorials2026-04-18

腾讯云SCF构建Serverless API实战

腾讯云SCFServerlessAPI

腾讯云SCF构建Serverless API实战

Serverless架构让开发者无需管理服务器即可运行代码,按实际调用计费,冷启动快,弹性无限。腾讯云SCF(Serverless Cloud Function)是国内最成熟的Serverless平台之一。本文将通过一个完整的RESTful API项目,带你实战SCF的开发与部署。

一、Serverless架构概述

1.1 核心理念

Serverless并非"无服务器",而是将服务器管理完全交给云平台:

| 传统架构 | Serverless架构 | |---------|--------------| | 需要购买/租用服务器 | 无需管理服务器 | | 持续运行,持续计费 | 按调用次数和执行时间计费 | | 需要处理扩缩容 | 自动弹性伸缩 | | 需要运维OS和运行时 | 只关注业务代码 | | 固定成本 | 可变成本(接近零空闲成本) |

1.2 SCF与其他平台对比

| 特性 | 腾讯云SCF | 阿里云 FC | AWS Lambda | |------|----------|-----------|------| | 运行时 | Node.js/Python/Go/Java/PHP | Node.js/Python/Go/Java/PHP | Node.js/Python/Go/Java/.NET | | 最大执行时间 | 900秒 | 600秒 | 900秒 | | 内存 | 128MB-3GB | 128MB-3GB | 128MB-10GB | | 冷启动时间 | 100-300ms | 100-500ms | 50-200ms | | 免费额度 | 100万次/月 | 100万次/月 | 100万次/月 | | 预置并发 | 支持 | 支持 | 支持(Provisioned Concurrency) |

二、项目设计

我们将构建一个Todo管理API,包含以下接口:

| 方法 | 路径 | 功能 | |------|------|------| | GET | /api/todos | 获取所有待办 | | GET | /api/todos/:id | 获取单个待办 | | POST | /api/todos | 创建待办 | | PUT | /api/todos/:id | 更新待办 | | DELETE | /api/todos/:id | 删除待办 |

架构设计

客户端 → API网关 → SCF函数 → 云数据库MongoDB
                         ↓
                      云监控/日志

三、函数开发

3.1 创建函数

  1. 登录 腾讯云SCF控制台
  2. 点击「新建」→ 选择「从头开始」
  3. 配置:

| 配置项 | 值 | 说明 | |-------|-----|------| | 函数名 | todo-api | 项目名称 | | 运行环境 | Node.js 18 | LTS版本 | | 执行方法 | index.main | 入口函数 | | 内存 | 256MB | 中等配置 | | 超时时间 | 30秒 | API响应要求 |

3.2 代码实现

'use strict';

const MongoClient = require('mongodb').MongoClient;
const MONGO_URI = process.env.MONGO_URI;
let cachedDb = null;

async function connectToDatabase() {
  if (cachedDb) return cachedDb;
  const client = await MongoClient.connect(MONGO_URI);
  const db = client.db('todo_app');
  cachedDb = db;
  return db;
}

exports.main = async (event) => {
  const db = await connectToDatabase();
  const collection = db.collection('todos');
  const method = event.httpMethod || event.requestContext?.httpMethod;
  const path = event.path || event.requestContext?.path;
  const body = event.body ? JSON.parse(event.body) : {};

  let response;

  // 路由匹配
  if (method === 'GET' && path === '/api/todos') {
    const todos = await collection.find({}).toArray();
    response = { code: 0, data: todos };
  }
  else if (method === 'GET' && path.match(/^\/api\/todos\/[a-f0-9]+$/)) {
    const id = path.split('/').pop();
    const todo = await collection.findOne({ _id: new require('mongodb').ObjectId(id) });
    response = todo ? { code: 0, data: todo } : { code: 404, message: 'Not found' };
  }
  else if (method === 'POST' && path === '/api/todos') {
    const result = await collection.insertOne({
      title: body.title,
      completed: false,
      createdAt: new Date()
    });
    response = { code: 0, data: { id: result.insertedId } };
  }
  else if (method === 'PUT' && path.match(/^\/api\/todos\/[a-f0-9]+$/)) {
    const id = path.split('/').pop();
    await collection.updateOne(
      { _id: new require('mongodb').ObjectId(id) },
      { $set: { title: body.title, completed: body.completed, updatedAt: new Date() } }
    );
    response = { code: 0, message: 'Updated' };
  }
  else if (method === 'DELETE' && path.match(/^\/api\/todos\/[a-f0-9]+$/)) {
    const id = path.split('/').pop();
    await collection.deleteOne({ _id: new require('mongodb').ObjectId(id) });
    response = { code: 0, message: 'Deleted' };
  }
  else {
    response = { code: 404, message: 'Route not found' };
  }

  return {
    statusCode: response.code === 404 ? 404 : 200,
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(response)
  };
};

3.3 依赖管理

创建 package.json

{
  "name": "todo-api",
  "version": "1.0.0",
  "dependencies": {
    "mongodb": "^6.3.0"
  }
}

在SCF控制台上传代码时,需先在本地安装依赖并一起打包:

npm install
zip -r todo-api.zip . -x "node_modules/.cache/*"

四、API网关配置

API网关是SCF对外暴露HTTP接口的桥梁:

4.1 创建API服务

  1. 进入 API网关控制台
  2. 创建服务 → 选择「与SCF同地域」
  3. 创建API:

| 配置 | 值 | 说明 | |------|-----|------| | API名称 | TodoAPI | 标识 | | 前端类型 | HTTP | HTTP协议 | | 路径 | /api/todos | 资源路径 | | 方法 | GET/POST/PUT/DELETE | 支持多方法 | | 后端类型 | 云函数SCF | 关联SCF函数 | | 函数名 | todo-api | 目标函数 |

4.2 启用CORS

如果前后端分离部署,需要启用CORS:

  • Access-Control-Allow-Origin: https://your-frontend.com
  • Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
  • Access-Control-Allow-Headers: Content-Type, Authorization

4.3 鉴权配置

API网关支持多种鉴权方式:

| 鉴权方式 | 适用场景 | 配置复杂度 | |---------|---------|----------| | 密钥对 | 服务间调用 | 低 | | OAuth 2.0 | 第三方授权 | 中 | | 自定义鉴权 | JWT等Token验证 | 中 | | 无鉴权 | 公开API | 无 |

推荐使用自定义鉴权函数验证JWT Token:

// 鉴权函数
exports.main = async (event) => {
  const token = event.headers?.authorization?.replace('Bearer ', '');
  try {
    const decoded = require('jsonwebtoken').verify(token, process.env.JWT_SECRET);
    return {
      isAuthorized: true,
      context: { userId: decoded.userId }
    };
  } catch (e) {
    return { isAuthorized: false };
  }
};

五、数据库集成

5.1 云数据库MongoDB

腾讯云提供完全托管的MongoDB服务:

| 规格 | 存储 | 月费参考 | 适用场景 | |------|------|---------|---------| | 1C2G | 20GB SSD | ¥320 | 开发测试 | | 2C4G | 50GB SSD | ¥650 | 小型生产 | | 4C8G | 100GB SSD | ¥1,200 | 中型生产 |

5.2 连接优化

SCF冷启动时建立数据库连接较慢,建议:

  1. 连接复用:将数据库连接对象存储在全局变量中
  2. 内网访问:MongoDB实例与SCF在同一VPC内
  3. 连接池:配置合理的连接池大小(10-20个连接)

5.3 替代方案:云开发TCB

如果不想管理MongoDB,可使用腾讯云开发(TCB):

const cloudbase = require('@cloudbase/node-sdk');
const app = cloudbase.init();
const db = app.database();

// 无需连接字符串,自动鉴权
const result = await db.collection('todos').get();

TCB提供免费额度,适合MVP和轻量级应用。

六、部署与CI/CD

6.1 Serverless Framework部署

# 安装Serverless Framework
npm install -g serverless

# 创建serverless.yml
cat > serverless.yml << 'EOF'
component: scf
name: todo-api
inputs:
  src:
    src: ./
    exclude:
      - node_modules/**
  functionName: todo-api
  runtime: Nodejs18
  handler: index.main
  memorySize: 256
  timeout: 30
  environmentVariables:
    MONGO_URI: mongodb://...
  events:
    - apigw:
        name: todo-api-gw
        parameters:
          protocols:
            - http
            - https
          serviceName: todo-api-service
          endpoints:
            - path: /api/todos
              method: ANY
EOF

# 部署
serverless deploy

6.2 GitHub Actions自动部署

name: Deploy SCF
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 18
      - run: npm install
      - run: npm install -g serverless
      - run: serverless deploy
        env:
          TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
          TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}

七、性能与成本分析

7.1 性能指标

| 指标 | 预期值 | 优化后 | |------|-------|-------| | 冷启动延迟 | 200-500ms | <200ms(预置并发) | | 热启动延迟 | 10-50ms | <10ms | | 并发处理 | 自动弹性 | 无上限 | | 单次执行时间 | 20-100ms | 优化数据库查询 |

7.2 费用计算

以月调用100万次、平均执行时间100ms、256MB内存为例:

| 计费项 | 用量 | 月费 | |-------|------|------| | 调用次数 | 100万次 | ¥1.33(超出免费额度部分) | | 执行时间 | 100万×100ms×0.25GB | ¥2.33 | | 免费额度 | 抵扣 | -¥1.33 | | API网关 | 100万次 | ¥7.00 | | 合计 | | ¥9.33/月 |

GCP Cloud Functions相比,SCF在国内访问延迟更低,且免费额度覆盖了更多低流量场景。

7.3 预置并发配置

冷启动是Serverless最大的痛点。SCF预置并发保持函数实例常驻:

# 配置预置并发
tccli scf PutProvisionedConcurrentConfig \
  --FunctionName todo-api \
  --VersionValue '{"VersionProvisionedConcurrentNums": [{"Version": "1", "Capacity": 5}]}'

| 配置 | 费用影响 | 效果 | |------|---------|------| | 预置并发=0 | 最低成本 | 有冷启动 | | 预置并发=5 | 增加约¥50/月 | 消除前5个并发冷启动 | | 预置并发=10 | 增加约¥100/月 | 适合稳定流量 |

八、最佳实践

  1. 单一职责:一个函数处理一个API端点,或使用路由分发
  2. 冷启动优化:减小包体积、使用预置并发、保持函数精简
  3. 错误处理:统一错误格式、重试机制、死信队列
  4. 日志规范:使用结构化日志,关联requestId
  5. 安全:环境变量存储密钥、启用函数鉴权、限制调用来源
  6. 监控告警:配置错误率>5%告警、P99延迟>500ms告警

总结

腾讯云SCF让API开发摆脱了服务器管理的负担,从开发到上线只需关注业务代码。结合API网关和云数据库,一个完整的Serverless API月成本可低至几十元,是中小项目和MVP的最佳选择。

多云(Duoyun Cloud) 作为腾讯云合作伙伴,提供SCF和API网关的架构咨询和专属折扣。通过多云采购腾讯云资源,可享受更优的价格和专业的中文技术支持,帮你以最低成本构建Serverless应用。访问 duoyun.io 了解详情。

需要专业云服务咨询?

我们的云架构师团队免费为你定制最优方案

免费咨询

相关文章

news

主要云厂商边缘计算趋势

2026-04-23
optimization

云账单告警与预算管理配置

2026-04-22
news

腾讯云AI新服务发布

2026-04-22