阿里云 ESA 函数和Pages 深度实战

简介: 创建函数、绑定触发器、写业务逻辑、灰度发布,一次讲透 ESA 函数和Pages 全流程

阿里云 ESA 函数和Pages 深度实战:用边缘函数实现毫秒级请求转发与重定向

背景:为什么传统重定向方案撑不住了

做过 Web 服务迭代的同学大概都遇到过这些场景:域名迁移、接口版本升级、多地域流量调度。传统方案要么在 Nginx 层写一堆 rewrite 规则,要么依赖 CDN 控制台的静态重定向配置,但这两种方式都有明显短板:

传统方案的瓶颈 边缘函数的优势
单台 Nginx 在高并发压力下,重定向延迟会随流量陡增,还要额外承担计算压力 通过全球 3200+ 边缘节点并行处理,离用户最近的节点直接响应
只支持基础字符串替换,没有正则捕获和动态决策能力 支持完整 JavaScript ES6 语法,可写正则、条件判断等复杂逻辑
修改配置后生效延迟高,回滚困难,没有环境隔离 版本化发布,支持测试环境、灰度环境、生产环境分级验证
逻辑集中在源站服务器,源站压力和带宽消耗大 请求在边缘节点直接被处理或转发,有效降低源站带宽和计算资源消耗

阿里云边缘安全加速(ESA)最近把原来的"边缘函数"能力全面升级为函数和Pages,深度集成了 Git 工作流、全球边缘网络和智能构建系统,不仅能跑 JS 边缘函数,还能直接托管静态站点、SPA、SSR 应用。这篇文章就用"请求转发 + 重定向"这个最常见的场景,带你走一遍从零到上线的完整流程,把控制台里每一个容易踩坑的细节都讲清楚。

准备工作:开通 ESA 并接入站点

把域名接入 ESA:

  1. 登录 ESA 控制台,进入站点管理,单击新增站点,输入你的域名(比如 example.com)。
  2. 选择获得加速与保护的区域,接入方式选择 CNAME
  3. 选择套餐类型——如果是第一次使用,可以在阿里云官网试用中心搜索 "ESA" 领取试用资格,先跑通流程再决定要不要长期使用。
  4. 完成域名归属权验证:控制台会给一条 TXT 记录,你需要去云解析 DNS 控制台,在权威域名解析里添加一条主机记录为 _esaauth 的 TXT 记录,值填控制台给出的验证码,等待解析生效后点击点击验证即可。
  5. 建议顺手在SSL/TLS > 边缘证书里开启 SSL/TLS 功能(可以直接申请免费证书),后续无论是访问函数域名还是站点本身,都推荐走 HTTPS,一是安全性有保障,二是现在浏览器对 HTTP 明文站点的提示越来越不友好。

另外要注意:记录生效有延迟,通常几分钟内会完成,如果验证一直失败,先检查记录是否添加到了正确的域名上。

核心实现:创建函数并编写转发/重定向逻辑

第一步:创建函数

在 ESA 控制台左侧导航栏找到边缘计算和AI > 函数和Pages,点击创建,创建方式选择函数模板(如果你想从零写,也可以选择自定义函数,后续自行编写全部逻辑)。

创建时需要注意几个容易被忽略的限制:

  • 函数名称必须以小写英文字母开头,只能包含小写字母、数字和中划线,且不能以中划线结尾,长度限制在 2~41 个字符之间,一旦创建完成就无法修改,起名字的时候最好提前规划好命名规范。
  • 规格决定了函数单次执行最多可用的 CPU 时间(不含等待网络请求响应的 I/O 时间),目前提供 5ms(默认)、50ms、100ms 三档,可用内存固定 128MB,RT(响应时间)最大值都是 120 秒。如果你的函数逻辑比较简单(比如纯字符串匹配和跳转),默认的 5ms 规格完全够用;但凡涉及稍复杂的计算或者多次数据处理,建议直接选 50ms 起步,避免函数因为 CPU 时间片耗尽被强制中断。

填写函数名称、描述并预览代码详情后单击提交,系统会自动生成一个临时公共域名,有效期 60 分钟,方便你先预览效果,不用等域名绑定完成就能看到函数是否跑得通。

第二步:配置触发器

触发器决定了什么样的请求会被转发给这个函数,ESA 提供两种绑定方式,很多教程只讲域名绑定,但路由方式其实更灵活,值得展开讲清楚。

域名绑定:把某个域名的全部流量都转发到函数。比如你已经在 ESA 添加了站点 example.com,想通过 function.example.com 访问函数,操作是:

  1. 进入函数详情页,切换到触发器页签,选择域名绑定,点击添加域名,填入 function.example.com
  2. 绑定完成后 ESA 会自动在 DNS 记录里加一条 CNAME,不需要你手动去云解析控制台添加——这一点和很多人的直觉相反,如果你手动又加了一条同名记录反而可能导致解析冲突。
  3. 绑定后,function.example.comfunction.example.com/userfunction.example.com/login 等所有路径的请求都会进函数处理。

路由:只把某个域名下特定路径的流量转发到函数,其余路径继续走正常的加速回源或缓存流程。这对已经在线上跑的站点更实用,不需要单独占用一个子域名:

  1. 触发器页签选择路由,点击添加路由,选择目标站点。
  2. 填写路由规则,支持用通配符 * 匹配零个或多个字符,但只支持在开头或结尾加通配符,不支持中间通配符,也不支持 ?param=1 这种参数匹配。几个实际例子:
    • example.com/a* 会匹配 example.com/aexample.com/a1example.com/api 等,但不会匹配 example.com/b
    • *.example.com/* 会匹配任何发到 www.example.com/example.com/ 的请求。
    • www.example.com/api/* 会匹配 www.example.com/api/userswww.example.com/api/products/123 这类子路径请求。
  3. 路由规则区分大小写,example.com/aexample.com/A 会被当成两条完全不同的规则;如果业务本身路径不区分大小写,建议在函数代码里对 pathname 统一做一次 .toLowerCase() 处理,避免因为大小写不一致导致规则漏判。
  4. 如果多条规则都能匹配同一个请求,会优先命中更早配置的那条。
  5. 如果路由里填的是带前缀的域名(比如 *.example.comwww.example.com),这种情况下需要你手动去添加一条对应的解析记录,否则访问会失败——这正好和域名绑定的自动添加行为相反,很容易搞混。

第三步:编写真正的业务逻辑

需求场景设定成这样:

  • 如果请求路径以 /esa/ 开头、以 .html 结尾,直接转发到目标页面(不改变浏览器地址栏)。
  • 如果请求路径以 /product 开头,301 重定向到产品列表页。
  • 其他情况一律重定向到首页。

代码用 JavaScript ES6 语法编写,直接粘贴到控制台的代码页签:

// 定义正则表达式:Path部分以"/esa/"开头,以".html"结尾,用于命中"转发"规则
const esaPageRegex = /^\/esa\/.*\.html$/;

function handleRequest(request) {
   
  const url = new URL(request.url);
  const pathName = url.pathname.toLowerCase();

  // 命中转发规则:直接fetch目标地址,地址栏不变
  if (esaPageRegex.test(pathName)) {
   
    const newUrl = 'https://www.aliyun.com/product/esa';
    return fetch(new Request(newUrl, request));
  }

  // 命中重定向规则:返回301跳转
  if (pathName.startsWith('/product')) {
   
    const newUrl = 'https://www.aliyun.com/product/list';
    return Response.redirect(newUrl, 301);
  }

  // 兜底规则
  const newUrl = 'https://www.aliyun.com/';
  return Response.redirect(newUrl, 301);
}

export default {
   
  fetch(request) {
   
    return handleRequest(request);
  }
}

逐行拆解一下这段逻辑:new URL(request.url) 把原始请求地址解析成结构化对象,方便拿到 pathname 单独做判断,这里额外调用了 .toLowerCase() 统一大小写,避免路由规则的大小写敏感特性影响判断结果;两个 if 分支分别对应转发和重定向两种处理方式,顺序很关键——因为判断是按代码执行顺序走的,如果把兜底逻辑写在最前面,后面的判断分支永远不会被执行到。

转发(fetch)重定向(Response.redirect) 是两种完全不同的处理方式:前者是服务端代理,函数发起一次新的请求去拿目标内容再原样返回给客户端,用户感知不到地址变化;后者是标准的 HTTP 30x 跳转,由客户端浏览器自己发起第二次请求,地址栏会变。选型时一定要想清楚业务到底需要哪种——如果是想做隐藏真实来源的内容聚合,用转发;如果是纯粹的地址迁移,重定向更省资源也更符合 SEO 规范。

这里还要提前留意一个和转发场景强相关的限制:函数单次执行最多只能发起 4 次 fetch 子请求,如果你的转发逻辑需要串联多个上游服务,4 个请求很快就会用完,需要提前规划好调用链路。

第四步:调试、生成版本、分环境发布

控制台右侧自带一套调试工具,可以直接构造 HTTP 请求方法、请求头、请求体来测试函数逻辑,不需要真的发到线上就能看到返回结果。完整流程是:

  1. 代码写完后先点击保存到调试环境,然后在右侧工具栏构造请求方法、请求头、请求体,点击请求按钮,控制台会直接返回函数处理后的响应结果,方便反复调整。
  2. 调试通过后点击发布到测试环境——测试环境是独立的边缘测试节点,你可以通过绑定 Host 的方式,用真实客户端发请求验证效果,这一步不会影响任何线上流量。
  3. 测试环境验证没问题后,点击生成正式版本,进入版本发布页签,选择目标版本,点击发布,可选发布到测试环境灰度环境生产环境

这里有个官方建议的发布顺序很容易被忽略:先逐个发布到各个灰度环境,所有灰度环境都验证通过之后,再发布到生产环境,而不是测试完直接全量上线。灰度环境本质上是拿一小部分真实边缘节点先跑新版本,能在真正影响全量用户之前再拦一道风险。

效果验证

浏览器直接访问 https://function.example.com/esa/info.html,地址栏不变但显示的是转发后的内容,说明转发生效。也可以用命令行更直观地验证:

curl -I https://function.example.com/product

正常情况下应该能在返回头里看到 HTTP/1.1 301 Moved PermanentlyLocation: https://www.aliyun.com/product/list,如果状态码不对,大概率是路由规则没匹配上,回去检查路由的通配符写法和大小写。

使用限制一览

正式上线前,建议对照官方限制表逐条检查自己的业务场景会不会踩线:

限制项 限制值 影响说明
响应时间(RT) 120 秒 函数单次执行的响应时间上限,等待 I/O 的时间也算在内
网关等待时间 10 秒 网关等待函数返回数据的超时时间,超时会主动断开连接并返回 504
代码包大小 4 MB 每个函数的 JavaScript 代码文件体积上限
子请求数量 4 个 单次函数执行允许发起的 fetch 请求数量上限
开发语言 JavaScript(ES6 语法) 目前仅支持 JS,暂不支持其他语言
每账号函数数量 免费模式 20 个 / 付费模式 100 个 超出需要考虑切换模式或合并函数逻辑
每函数版本数量 免费模式 5 个 / 付费模式 20 个 版本数量达到上限后需要清理旧版本才能继续生成新版本

其中网关等待时间 10 秒子请求数量 4 个这两项和本文的转发/重定向场景关系最直接:如果转发的目标源站响应慢,超过 10 秒会被网关直接掐断连接返回 504;如果一次请求里需要串行调用多个上游接口,超过 4 次子请求同样会失败,写业务逻辑时要提前把这两条线摸清楚。

踩坑记录

实际操作中容易踩的几个坑,提前列出来省得你走弯路:

  • 函数名称创建后不可修改:起名字务必提前规划好,尤其是团队协作场景,建议提前约定命名规范(比如按业务模块+功能前缀)。
  • 规格选错导致执行中断:默认的 5ms CPU 时间片对纯转发/重定向这种逻辑够用,但如果代码里有额外的字符串处理或多重判断,建议直接上 50ms 规格,避免线上偶发被截断。
  • 域名绑定和路由的 DNS 处理方式完全相反:域名绑定会自动加 CNAME,你不需要手动操作;路由如果用了带前缀的域名匹配,则需要你自己手动去加解析记录,搞反了两种情况会导致要么解析冲突,要么访问不通。
  • 路由不支持中间通配符:example.com/*/path 这种写法是不合法的,只能在开头或结尾用 *
  • 多条路由规则冲突时优先匹配更早配置的规则:如果发现新加的路由规则没有生效,先看看是不是被一条更早配置的规则抢先命中了。
  • 子请求数量和等待时间容易被忽略:4 个子请求、10 秒网关等待,这两条限制在做多接口聚合或者转发慢速源站时特别容易踩雷,提前设计好降级逻辑。
  • CNAME 生效有延迟:域名绑定后的 DNS 记录生效通常要几分钟,遇到访问不通先别急着改配置,等等看。

总结

这套方案的核心价值在于把原本要靠 Nginx 或应用层代码处理的转发逻辑下沉到了边缘节点,既减少了源站压力,又把延迟降到了最低。从这次实战看,ESA 函数和Pages 在触发器配置(域名绑定/路由两种方式)、调试环境、版本管理、灰度发布这几个环节上的设计已经相当完整,细节抠得越仔细,线上踩坑的概率就越低。如果业务逻辑更重、需要更大算力,ESA 的边缘容器会是更合适的选择;如果需要在边缘做有状态的判断(比如灰度名单、简单鉴权),可以进一步了解边缘存储(EdgeKV)如何和函数配合使用。

目录
相关文章
|
安全 关系型数据库 MySQL
Docker 进阶 发布自己的Docker镜像 将镜像上传到阿里云和Docker Hub
上传自己制作的docker镜像的方法,将docker镜像上传到Docker Hub,阿里云的两种方法,以及上传镜像时可能遇见的问题和解决办法,每一步的详解和上传镜像时的规范。
10493 0
Docker 进阶 发布自己的Docker镜像 将镜像上传到阿里云和Docker Hub
|
2月前
|
人工智能
Qwen3.8抢先体验!正式版即将发布并开源!
千问Qwen3.8即将开源,参数达2.4T,进化速度以“天”计,实力媲美Fable 5。预览版Qwen3.8-Max已上线阿里Token Plan等平台,限时优惠:日间Credits低至1折,夜间更优,个人/团队版月付仅35元起!
4285 147
|
29天前
|
Kubernetes 应用服务中间件 nginx
Kubernetes (K8s) 从入门到实战:命名空间、Pod、Controller、Service,图文并茂
本文是K8s初学者的实战笔记,系统讲解命名空间(隔离资源、环境划分、权限控制)、Pod(最小调度单元、多容器、标签、生命周期、探针、资源限制)、控制器(Deployment灰度发布/回滚、StatefulSet/Job/DaemonSet)及Service(ClusterIP/NodePort、负载均衡、多端口)等核心概念与操作,附带丰富命令示例和原理剖析。
Kubernetes (K8s) 从入门到实战:命名空间、Pod、Controller、Service,图文并茂
|
1月前
|
缓存 JSON JavaScript
3天7个步骤,基于 AgentLoop 的游戏 Agent 效果优化实践
UGC 游戏行业 Agent 评测优化最佳实践指南。
|
28天前
|
数据采集 存储 算法
聊聊数据的"冷热分离":如何对历史爬虫数据进行合理的归档与压缩存储?
本文是面向爬虫工程师的冷热分离实战指南:直击数据堆积痛点,详解如何用隧道代理高效采集,并通过SQLite(热层)+Parquet/zstd(冷层)实现低成本、高效率的数据分层存储与归档,附完整可运行代码及中文注释。(239字)
|
29天前
|
人工智能 API 知识图谱
GEO优化采样系统的工程模式与我踩过的坑
成都GEO优化专家王涛于2026年构建多平台AI采样器,提炼出四条核心工程纪律:结果冻结不可重算、比较前须验可比性、缺数据不补零、文案严分“未判断”与“零结果”。本文面向GEO采样与AI检索诊断工程师,厘清数据可比性边界与结论书写规范。(239字)
|
2月前
|
消息中间件 算法 Java
百炼网关实践:用 RocketMQ LiteTopic 让限流比降了 10 倍
LiteTopic 提供的 “轻量队列 + 差异化订阅 + Suspend 控速” 三件套,让百炼网关的限流比降低了 10 倍。
319 11
|
28天前
|
存储 安全 网络安全
企业通讯录数据泄露衍生定向钓鱼攻击机理与全域防御研究
本文以泽西岛通讯录泄露引发的区域性定向钓鱼事件为实证,系统剖析其攻击链路、社会工程机理与多维风险,指出传统邮件过滤失效根源。提出“数据管控—邮件认证—终端拦截—公众宣教—应急处置”五位一体闭环防御体系,为中小政企及区域网安机构提供可落地的风险治理方案。(239字)
65 0
|
28天前
|
人工智能 安全 API
DeepSeek V4 Pro暴涨近50分,我却更想押GLM-5.3
DeepSeek V4 Pro正式版和GLM-5.3前后脚上线。一个把Agent成绩拉得像换了一代模型,一个连基座都没换,只靠后训练继续往前拱。老金来给你详细说说。
|
5月前
|
人工智能 监控 Kubernetes
LoongCollector + ACS Agent Sandbox:构建 AI Agent 生产级运行平台
文章介绍了阿里云ACSAgentSandbox与LoongCollector协同构建的AIAgent生产级运行平台,通过沙箱隔离保障运行时安全,并以高性能、全链路可观测能力解决Agent行为不可预测和执行风险难题。
2736 84

热门文章

最新文章