Serverless 中怎么创建一个短网址服务

发布时间:2021-07-28 15:30:15 作者:Leah
来源:亿速云 阅读:281
# Serverless 中怎么创建一个短网址服务

## 引言

在当今互联网时代,短网址服务已成为分享长链接的必备工具。传统短网址服务需要维护服务器和基础设施,而Serverless架构的出现彻底改变了这一模式。本文将详细介绍如何利用Serverless技术栈(AWS Lambda + API Gateway + DynamoDB)构建一个高可用、低成本的短网址服务。

## 一、Serverless架构概述

### 1.1 什么是Serverless

Serverless是一种云计算执行模型,其核心特点是:
- **无需管理服务器**:云服务商自动分配计算资源
- **事件驱动**:通过特定事件触发代码执行
- **按使用付费**:只对实际消耗的资源计费
- **自动弹性伸缩**:根据负载自动调整资源

### 1.2 为什么选择Serverless构建短网址服务

传统架构痛点:
- 需要预置服务器资源
- 流量突增时需手动扩容
- 存在资源闲置浪费

Serverless优势:
- 零基础设施管理
- 毫秒级自动扩容
- 成本效益显著(百万次调用约需$0.20)

## 二、技术选型与架构设计

### 2.1 核心组件

| 服务          | 作用                          |
|---------------|-----------------------------|
| AWS Lambda    | 处理URL转换的业务逻辑          |
| API Gateway   | 提供RESTful接口               |
| DynamoDB      | 存储原始URL与短码的映射关系     |
| Route53       | 域名解析(可选)              |

### 2.2 数据流示意图

用户请求 -> API Gateway -> Lambda -> DynamoDB ↑ ↓ 响应生成 <- 错误处理


### 2.3 短码生成算法比较

| 算法           | 优点                  | 缺点                  |
|----------------|----------------------|----------------------|
| 自增ID+Base62  | 无冲突、有序          | 需维护计数器          |
| 哈希截断       | 分布式友好            | 可能冲突需重试        |
| UUID           | 唯一性保证            | 长度较长(8字符以上) |

推荐实现(Python示例):
```python
import hashlib
import base64

def generate_short_code(url, length=6):
    md5 = hashlib.md5(url.encode()).digest()
    b64 = base64.urlsafe_b64encode(md5).decode()
    return b64[:length].replace('_', 'x').replace('-', 'y')

三、详细实现步骤

3.1 环境准备

  1. 安装AWS CLI并配置凭证
    
    aws configure
    
  2. 安装Serverless Framework
    
    npm install -g serverless
    

3.2 项目初始化

serverless create --template aws-python3 --path url-shortener
cd url-shortener

目录结构:

.
├── handler.py    # Lambda函数代码
├── serverless.yml # 资源配置文件
└── requirements.txt # Python依赖

3.3 DynamoDB表设计

serverless.yml资源配置片段:

resources:
  Resources:
    ShortUrlsTable:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: short-urls
        AttributeDefinitions:
          - AttributeName: shortCode
            AttributeType: S
        KeySchema:
          - AttributeName: shortCode
            KeyType: HASH
        BillingMode: PAY_PER_REQUEST
        TimeToLiveSpecification:
          AttributeName: expiryTime
          Enabled: true

3.4 Lambda函数实现

handler.py核心代码:

import os
import boto3
from datetime import datetime, timedelta
from urllib.parse import urlparse

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(os.environ['TABLE_NAME'])

def create_short_url(event, context):
    body = json.loads(event['body'])
    original_url = body['url']
    
    if not urlparse(original_url).scheme:
        original_url = 'https://' + original_url
    
    short_code = generate_short_code(original_url)
    
    table.put_item(
        Item={
            'shortCode': short_code,
            'originalUrl': original_url,
            'createdAt': datetime.utcnow().isoformat(),
            'expiryTime': int((datetime.now() + timedelta(days=365)).timestamp(),
            'clickCount': 0
        }
    )
    
    return {
        'statusCode': 200,
        'body': json.dumps({
            'shortUrl': f"https://{event['headers']['Host']}/{short_code}"
        })
    }

def redirect_short_url(event, context):
    short_code = event['pathParameters']['code']
    
    response = table.update_item(
        Key={'shortCode': short_code},
        UpdateExpression='ADD clickCount :incr',
        ExpressionAttributeValues={':incr': 1},
        ReturnValues='UPDATED_NEW'
    )
    
    return {
        'statusCode': 301,
        'headers': {'Location': response['Item']['originalUrl']}
    }

3.5 API Gateway配置

serverless.yml中的事件定义:

functions:
  create:
    handler: handler.create_short_url
    events:
      - http:
          path: /url
          method: post
          cors: true
  redirect:
    handler: handler.redirect_short_url
    events:
      - http:
          path: /{code}
          method: get

3.6 部署与测试

部署命令:

serverless deploy

测试创建短链:

curl -X POST https://xxx.execute-api.region.amazonaws.com/dev/url \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/very/long/url"}'

访问短链:

curl -v https://xxx.execute-api.region.amazonaws.com/dev/abc123

四、高级功能实现

4.1 自定义域名

  1. 在API Gateway控制台配置自定义域名
  2. 添加ACM证书
  3. 修改Route53记录

4.2 访问统计

增强DynamoDB项:

{
    'shortCode': 'abc123',
    'originalUrl': 'https://example.com',
    'analytics': {
        'lastAccessed': '2023-07-20T08:00:00Z',
        'referrers': {
            'direct': 42,
            'twitter': 15
        },
        'deviceTypes': {
            'mobile': 30,
            'desktop': 27
        }
    }
}

4.3 过期自动清理

利用DynamoDB TTL特性: 1. 设置expiryTime属性 2. 配置Lambda处理过期项:

resources:
  Resources:
    CleanupRule:
      Type: AWS::Events::Rule
      Properties:
        ScheduleExpression: 'rate(1 day)'
        Targets:
          - Arn: !GetAtt CleanupFunction.Arn

五、性能优化与安全

5.1 缓存策略

添加Redis缓存层(AWS ElastiCache):

import redis
cache = redis.Redis(host=os.environ['REDIS_HOST'])

def redirect_short_url(event, context):
    short_code = event['pathParameters']['code']
    
    # 先查缓存
    original_url = cache.get(f"url:{short_code}")
    if original_url:
        return {'statusCode': 301, 'headers': {'Location': original_url}}
    
    # 缓存未命中则查数据库
    response = table.get_item(Key={'shortCode': short_code})
    ...

5.2 安全防护

  1. 防滥用

    • 实现API密钥认证
    • 限制创建频率(AWS WAF Rate-based rules)
  2. 内容过滤: “`python BLACKLIST_DOMNS = [‘malware.com’, ‘phishing.site’]

def validate_url(url): domain = urlparse(url).netloc return not any(bad in domain for bad in BLACKLIST_DOMNS)


## 六、成本估算

假设每月100万次请求:
| 服务           | 单价               | 月成本   |
|----------------|-------------------|---------|
| Lambda         | $0.20/百万请求     | $0.20   |
| API Gateway    | $1.00/百万请求     | $1.00   |
| DynamoDB       | $0.25/百万读写单位 | $0.50   |
| **总计**       |                   | **$1.70** |

## 七、替代方案比较

### 7.1 其他云服务商实现

| 平台       | 等效服务组合               | 特点                     |
|------------|--------------------------|-------------------------|
| Azure      | Functions + CosmosDB      | 与Microsoft生态集成度高  |
| GCP        | Cloud Functions + Firestore | 实时数据库能力突出        |

### 7.2 开源框架方案

使用Serverless Framework插件:
```yaml
plugins:
  - serverless-dynamodb-local
  - serverless-offline

本地开发命令:

serverless dynamodb install
serverless offline start

结语

通过本文的实践,我们完成了: 1. 完全Serverless的短网址服务搭建 2. 实现了核心的创建/跳转功能 3. 添加了访问统计等高级特性 4. 确保了系统的安全性和经济性

Serverless架构使得个人开发者也能轻松构建高可用的生产级服务。读者可以在此基础上继续扩展: - 添加用户系统 - 实现可视化数据看板 - 开发浏览器插件等客户端

资源推荐: - AWS Serverless 官方文档 - Serverless Framework 示例库 - 短链接算法研究论文 “`

(注:实际字符数约3100字,此处显示为缩略版本,完整实现需包含更多错误处理和边界情况处理代码)

推荐阅读:
  1. Serverless 实战——使用 Rendertron 搭建 Headless Chrome 渲染
  2. 快速搭建 Serverless 在线图片处理应用

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

serverless

上一篇:Nexus OSS 3.x中怎么创建一个Docker私有仓库

下一篇:Circuitjs中怎么创建一个自定义逻辑器件

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》