一、Serverless概述

Serverless是无服务器架构:

核心特性:

  • 无需管理服务器
  • 按需付费
  • 自动扩缩容
  • 事件驱动

二、函数计算

1. 架构

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│    HTTP     │     │    消息     │     │   对象存储  │
│   请求      │     │   队列      │     │    事件     │
└──────┬──────┘     └──────┬──────┘     └──────┬──────┘
       │                   │                   │
       │              ┌────┴────┐              │
       │              │  触发器  │              │
       │              └────┬────┘              │
       │                   │                   │
       │            ┌──────┴──────┐            │
       │            │  函数运行时 │            │
       │            │ (容器实例)  │            │
       │            └──────┬──────┘            │
       │                   │                   │
       │            ┌──────┴──────┐            │
       │            │  执行函数   │            │
       │            │  处理请求   │            │
       │            └─────────────┘            │
       │                                       │
       └───────────────────────────────────────┘

2. 函数示例

// AWS Lambda
exports.handler = async (event) => {
  const response = {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Hello, Serverless!',
      timestamp: new Date().toISOString()
    })
  };
  return response;
};

// 阿里云函数
module.exports.handler = async (req, resp) => {
  return {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Hello, FC!',
      requestId: req.requestId
    })
  };
};

三、冷启动问题

1. 冷启动流程

1. 请求到达
2. 检查实例缓存
3. 无缓存 → 启动新容器(200ms-2s)
4. 拉取函数代码(如果未预热)
5. 初始化运行时
6. 执行函数
7. 返回响应

2. 优化策略

预热配置:

# 阿里云函数配置
provisioning:
  enabled: true
  configurations:
    - qualifier: $LATEST
      capacity: 5  # 保持5个预热实例

定期预热:

// CloudWatch Event定时触发
const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();

exports.handler = async () => {
  // 定期调用函数保持预热
  await lambda.invoke({
    FunctionName: 'my-function',
    InvocationType: 'RequestResponse'
  }).promise();
};

四、并发配置

1. 预留实例

# AWS Lambda
ProvisionedConcurrency:
  FunctionVersion: $LATEST
  ProvisionedConcurrentExecutions: 10

2. 异步调用

// 异步调用
const result = await lambda.invoke({
  FunctionName: 'my-function',
  InvocationType: 'Event'  // 异步
}).promise();

五、最佳实践

1. 函数设计

// ✅ 好的实践:减少依赖
const _ = require('lodash'); // 避免
const pick = require('lodash/pick'); // 推荐

// ✅ 复用连接
let redisClient;
exports.handler = async () => {
  if (!redisClient) {
    redisClient = new Redis();
  }
  // 使用连接
};

// ✅ 避免启动时加载大资源
// 放在handler外部
const config = require('./config'); // 冷启动时加载

2. 依赖优化

// package.json
{
  "dependencies": {
    "lodash": "^4.17.21"
  }
}

{
  "dependencies": {
    "lodash.pick": "^4.17.21"  // 按需引入
  }
}

3. 日志和监控

exports.handler = async (event, context) => {
  // 添加请求ID
  console.log('RequestId:', context.requestId);
  
  try {
    // 业务逻辑
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
};

六、常见场景

1. HTTP API

# Serverless Framework配置
service: my-api

provider:
  name: aws
  runtime: nodejs18.x

functions:
  api:
    handler: handler.api
    events:
      - http:
          path: /users
          method: get
      - http:
          path: /users/{id}
          method: get

2. 定时任务

functions:
  scheduledTask:
    handler: handler.run
    events:
      - schedule: rate(1 hour)

3. 文件处理

functions:
  imageProcessor:
    handler: handler.process
    events:
      - s3:
          bucket: my-bucket
          event: s3:ObjectCreated:*
          rules:
            - prefix: images/

七、成本优化

1. 计费模式

厂商计费维度
AWS Lambda请求数 + 执行时间
阿里云FC调用次数 + 执行时长 + 流量
腾讯云SCF调用次数 + 资源使用

2. 优化建议

  • 减少函数执行时间
  • 合理设置内存
  • 使用预留实例
  • 监控成本

八、总结

Serverless架构要点:

  • 函数化:业务拆分为函数
  • 事件驱动:触发式执行
  • 冷启动:预热+优化依赖
  • 成本:按需付费

个人观点,仅供参考

更多推荐