虚拟等候室

更新时间:2024-09-03 17:00:41

本示例展示如何使用 Edge Cloud Apps函数创建单节点虚拟等候室,控制用户对网站特定页面的访问流量。当您预计网站会迎来流量高峰,例如电商促销、新品发布、演唱会抢票等场景时,可以使用虚拟等候室来管理用户访问,防止突发流量造成源站过载。

示例模拟了一个宠物商店网站的 “团队” 页面,并为其设置了虚拟等候室。该等候室最多允许 1 位 用户同时访问(访问成功后有 15 秒 连接时间),最多允许 2 位 访问者同时排队等候。
为了简化单机测试,本示例使用 “客户端 IP + User Agent” 作为客户唯一标识。

详细代码

import { waitingRoomSingle } from "./wslib-waiting-room-single"

async function handleRequest(request) {
    const headers = request.headers
    const url = new URL(request.url)
    const clientID = headers.get("cdn-src-ip") + headers.get("user-agent") // 由客户端决定识别访问终端的方式
    if (!clientID) {
        return fetch(request)                           // 没有终端标识符,无法应用等候室逻辑
    }
    const roomID = url.hostname                         // 由客户端决定以确定哪些URL范围共享一个等候室
    const args = {
        connectedTimeout: 15,                           // 数据插入连接池后自动删除的持续时间
        connectedMax: 1,                                // 允许的最大连接客户端数量
        waitingTimeout: 30,                             // 数据插入等待池后自动删除的持续时间
        waitingMax: 2,                                  // 允许的最大等待客户端数量
        waitingPageMaxRefreshInterval: 3,               // 刷新等待页的最大时间间隔
        generateWaitingPage: null,                      // 自定义生成等待页;如果未提供,将使用默认页面
        generateBusyPage: null,                         // 自定义生成繁忙页;如果未提供,将使用默认页面
    }

    const resp = await waitingRoomSingle(request, roomID, clientID, args)
    // 为了测试方便,禁用浏览器缓存
    resp.headers.delete('ETag')
    resp.headers.delete('Last-Modified')
    return resp
}
                    
addEventListener("fetch", event => {
    return event.respondWith(handleRequest(event.request))
})

说明

  • Edge Cloud Apps 函数提供的虚拟等候室功能需要结合Edge KV才能实现。Edge KV存储了两个关键数据池:“连接池” 和 “等候池”,分别记录已连接到目标页面和正在排队等候的客户端信息。函数通过 “客户端 IP + User Agent” 等信息标识客户端,并结合访问时间戳作为键值存储在Edge KV中。客户端访问时,函数会检查其携带的 Cookie 值,判断其是新访问者还是已在等候队列中的访问者。利用Edge KV的键值存储、自动过期机制和排序功能,函数可以实现客户端排队、超时控制和并发访问限制等功能,确保虚拟等候室的正常运作,并根据预设规则,将用户引导至目标页面或等待页面。
  • 您可以根据实际需求调整等候室参数,例如最大并发访问人数、等待时间、等待页面刷新间隔等。
  • 您可以自定义 generateWaitingPagegenerateBusyPage,生成个性化的等待页面,提升用户体验。
本篇文档内容对您是否有帮助?
有帮助
我要反馈
提交成功!非常感谢您的反馈,我们会继续努力做到更好!