函数计算(FC)接入自定义域名后访问返回404,是Serverless架构落地中最常见的隐性故障之一。它往往不是函数代码本身的问题,而是域名解析、网关路由、路径映射三层配置之间出现了断点。这类问题排查起来颇为棘手,因为404的“表象”可能来自链路中任何一个环节。本文将拆解FC自定义域名404的根因类型,帮助你准确判断错误出在哪一层。
一、函数计算FC自定义域名404是怎么回事
1. 常见原因一览
根据实际运维观察,FC自定义域名404的触发原因高度集中在几个环节:CNAME解析指向错误或未生效、CDN回源配置失效、FC网关上的路由前缀未匹配、HTTP触发器未正确绑定函数、以及函数代码内部路由与网关层路径不一致。其中,路由前缀配置错误占比最高,尤其在多函数共用一个域名的情况下,配置稍有不慎,404便随机出现。另一个高频原因是版本迭代后,自定义域名仍指向旧版本或已删除的别名,导致请求到达函数却返回应用层404。
2. 404错误类型区分
不同层面的404,排查方向截然不同。FC网关层404通常返回包含InvalidResponse或Route not found字样的响应头,说明请求已成功进入FC网关,但未匹配到任何路由规则。函数应用层404则是请求已透传至函数实例,但函数代码内部(如Express或Flask路由)未处理该路径。还有一种容易被忽略的情况:浏览器直接展示默认404页且无任何FC响应头,这类问题多出在DNS解析、CDN缓存或CNAME未生效,请求根本没到达FC网关。判断方法很简单:用curl -I查看响应头,有x-fc标识即已到达FC层。
3. 域名解析与网关状态
自定义域名能否正常访问,CNAME解析是一道硬门槛。FC要求自定义域名CNAME解析到平台分配的默认域名,该域名并非控制台页面展示的随机域名,若两处配置不一致,请求会直接丢失。此外,域名备案状态对网关路由的生效也有影响——未备案或备案刚通过的域名,FC网关会拒绝下发路由规则。实践中建议在完成CNAME解析后,使用dig命令确认解析记录已全球生效,再登录FC控制台检查自定义域名状态是否显示为“运行中”,满足这两项条件后,404现象可排除链路前段问题。
二、排查FC路由配置要点
自定义域名返回404,九成问题出在“网关层”而非函数代码。先明确一条访问链路:DNS解析 → CDN(可选) → FC网关 → 函数/触发器 → 函数代码。这条链路上任何一环失配,表现都是404。下面按三个最容易踩坑的环节逐层拆解。
1. 路径匹配规则
FC自定义域名的路由规则采用前缀匹配,不是正则,也不是通配符全路径匹配。你配置的是 /api/*,那它能匹配 /api/user、 /api/order/list,但匹配不了 /apiv1,也不代表 / 路径可用。很多用户习惯性认为“绑定了域名,根路径总该通吧”——实际上,FC网关对 https://域名/ 默认没有自动映射,未显式配置根路径路由时,根路径直接返回404。这是最容易被忽视角落:域名解析正常、控制台绑定正常,但访问首页就是404,根因往往是只配了 /api/*,没配 /* 或 /。
实操建议:配置一条 /* 作为兜底路由,指向主函数;再按业务模块配置具体前缀如 /api/* 指向对应函数。这样既保证根路径有响应,也避免子路径无匹配。云老大在做多服务端口迁移时,就常靠“兜底路由+精确前缀”的组合,把原本分散的入口收敛到同一域名下,显著减少这类偶发404。
2. 函数与域名绑定
自定义域名必须显式关联到一个函数下的HTTP触发器,或者通过自定义域名路由规则直接指向某个函数。如果域名绑定了但没挂任何函数,网关收到请求后无路可转,直接404。这里有个常见误区:用户误以为“HTTP触发器的路径就是函数代码里的路由”。实际上,触发器路径是网关层规则,网关只负责把请求透传给函数实例;如果函数内部没实现对应路由(比如用了Express但没定义/user的handler),函数会返回应用层404。那种“默认测试域名能访问、自定义域名404”的情况,多半就是自定义域名绑定的函数版本/别名与测试域名不是同一个,或者触发器未勾选你正在使用的请求方法——默认只开GET和POST,你用DELETE或OPTIONS请求,网关直接拒绝。
排查时先用 curl -I 看响应头:如果返回头里有 x-fc-error-type,说明请求已到达FC网关,问题在函数或路由配置;如果没有任何FC标识,问题在DNS解析或CNAME。另外,自定义域名CNAME必须指向FC提供的默认域名,而不是网页上展示的随机测试域名,解析错了请求根本到不了网关。云老大在处理客户域名迁移时经常发现,CNAME记录还指向旧环境,导致新域名间歇性404——这种问题在控制台看不出来,必须逐段验证链路。
3. 路由冲突检查
多个函数挂在同一个自定义域名下,路由规则之间可能出现前缀重叠或顺序覆盖。FC遵循最长前缀匹配原则:比如同时配置了 /* 指向函数A和 /api/* 指向函数B,请求 /api/user 会命中函数B;但如果配置时不小心把 /* 放在了优先位置,或者两个前缀完全一致但指向不同函数,就会造成“部分路径能通,部分路径随机404”。另外,版本迭代时容易出现旧路由残留,原函数删除后,路由规则还指向已不存在的版本,访问必然404。
推荐做法:在FC控制台的“管理路由”页面,利用内置调试工具直接发测试请求,观察匹配结果;同时开启函数日志(SLS),搜索route或Route not found,能直接看到请求被匹配到了哪条规则。日志里会显示实际路径和函数名,据此能快速定位是路由配置错误还是函数内代码问题。云老大做故障复盘时,结合日志里的路由匹配记录和函数调用链,把这类“隐性路由冲突”的定位时间从小时级压缩到分钟级——前提是配置规范,别让路由规则随意堆叠。
三、检查触发器与HTTP触发类型
自定义域名返回404时,超过半数的根因集中在触发器配置与路径映射层,而非函数代码本身。按实际运维经验,请求链路中每一环的容错率都不同——DNS解析错误的表现通常是连接超时或证书不匹配,而FC网关返回的404往往意味着请求已成功抵达网关,却在路由分发阶段被丢弃。两者性质截然不同,排查方向也就完全不同。这里先给一个判断依据:如果你在响应头中能看到 x-fc-request-id,说明请求已经进入FC网关,问题大概率出在触发器配置或路由规则上;反之,则需要回溯域名解析和CDN链路。云老大在处理这类问题时的标准做法,也正是先拿这个响应头做分界,再逐层往下拆。
1. HTTP触发器的路径规则与函数内部路由的边界
很多用户习惯性地认为,HTTP触发器中的路径配置等同于函数代码内部的路由——这是一个代价高昂的误解。
触发器的路径是网关层规则,它只负责决定「哪些外部请求能进入对应的函数实例」。而函数代码内部的业务路由(比如Express、Flask或Spring Boot中的URL映射)是应用层逻辑,两者并不自动联动。具体来说:
- 触发器配置的路径是
/user/*,该前缀下的请求会被网关转发给函数; - 函数内部如果只实现了
/user/list的路由逻辑,而未处理/user/detail,那么后者的请求虽然顺利通过了网关层,却依然会在函数内部返回404。
这类404的特征是响应体中携带FC网关的标识,但错误信息由函数代码本身生成。很多团队的排障流程止步于「已经进入函数了,平台没问题」,但实际上问题确实出在应用代码里,只是被FC的网关响应包装了一层而已。
实际运维中,我们见过不少团队在迭代时重构了函数内部的URL结构,却没有同步更新触发器或自定义域名的路由规则。结果就是网关仍然把请求转发到函数,但函数内部已经没有对应的处理逻辑,直接抛404。用 curl -I 检查响应头时,能看到请求确实到达了FC,但业务侧就是不通。排查的关键是:先确认网关层路由匹配成功,再确认函数内部路由匹配成功,两者缺一不可。
这里提供一个更高效的定位方式:如果函数使用Node.js或Python等解释型语言运行时,可以在函数代码中临时加入一行日志输出,打印 event.path 和 event.requestContext 中的路由信息。这样能直接看到网关转发进来的实际路径是否与函数内部的路由规则匹配。对于一个 GET /api/order/detail 的请求,网关层匹配的可能是 /api/* 前缀,但函数内的框架路由可能只注册了 /api/order/list,两者对不上,404就是必然结果。
2. 请求方法限制与404/405的模糊地带
HTTP触发器的请求方法配置,是另一个高频但容易被忽略的404诱因。
FC控制台中创建HTTP触发器时,默认勾选的请求方法通常只有 GET 和 POST。如果你的业务代码需要处理 DELETE、PUT 或 OPTIONS 请求,而触发器并未勾选相应方法,网关会直接拒绝该请求。这种情况下,返回的状态码可能是404,也可能是405——具体表现取决于网关版本和配置方式。
这里有一个容易被误判的场景:前端页面发起的 OPTIONS 预检请求。在跨域场景下,浏览器会先发送一个 OPTIONS 请求探测服务器允许的跨域策略。如果触发器的请求方法列表中没有勾选 OPTIONS,网关会直接返回非200状态码,浏览器控制台报的是跨域错误,但后端日志里看到的是404或405。很多团队在排查跨域问题时反复调整CORS配置无果,最后才发现是触发器层面的方法限制拦截了预检请求。
从我们的实战数据来看,由于请求方法未勾选齐全导致的访问异常,大约占自定义域名404问题的15%左右,比例不低。建议在配置HTTP触发器时,如果业务场景不敏感,直接勾选全部方法(GET、POST、PUT、DELETE、HEAD、OPTIONS),避免后续排查的干扰项。这在云老大对接的众多客户项目中是默认操作——先放开方法限制,再针对安全需求做精细化收敛,比一开始就收紧配置要省事得多。
值得注意的是,自定义域名的路由规则并不一定复用HTTP触发器的请求方法配置。如果你在自定义域名管理中配置的是函数路由(而非绑定HTTP触发器),请求方法的校验逻辑可能独立于触发器。这就意味着,即使触发器已勾选了 OPTIONS,自定义域名路由仍可能拦截对应方法。配置后需要逐一验证,不能想当然地认为「触发器配好了,域名路由就自动生效」。
3. 路由前缀匹配与版本切换的隐藏陷阱
FC自定义域名的路径匹配规则是前缀匹配,而非正则匹配。这意味着 /api/* 能匹配 /api/order、/api/user/list,但无法匹配 /apiv2/order。看起来简单,实际配置中却频繁出错,集中在以下几类场景:
场景一:根路径无显式路由。 FC网关对 https://domain/ 的访问不会自动映射到某个函数。如果你在自定义域名的路由规则中只配置了 /api/*,那么访问根路径时,网关找不到任何可匹配的路由,返回404。要解决这个问题,需要显式添加一条 /* 的兜底路由,指向默认函数。这与静态网站托管的默认文档行为截然不同。
场景二:路径结尾斜杠导致的前缀不匹配。 配置路由为 /api(不带斜杠)时,它只能匹配 https://domain/api 这个精确路径,而无法匹配 https://domain/api/order——后者会被网关判定为无匹配路由。正确的做法是配置 /api/*,让它覆盖该前缀下的所有子路径。
场景三:版本或别名切换后未同步更新域名路由。 当函数发布新版本并切换别名后,自定义域名路由中关联的版本如果未同步修改,请求仍会被转发到旧版本的函数。如果旧版本代码中不存在对应路由,网关返回的就是404。这类问题的隐蔽性在于:函数列表里明明能看到所有版本,但请求却打到了不可预期的代码版本上。
场景四:网关缓存导致的配置生效延迟。 自定义域名的路由配置更新后,并非实时全局生效。FC的接入层存在分布式缓存的传播延迟,通常在数十秒内逐渐生效。如果你刚修改完路由配置立刻测试,可能依旧命中旧规则,返回404。建议等待1-2分钟后再做验证,而不是判断「配置没生效」或「配置错了」而反复修改。
排查这类问题时,最直接的手段是查看FC网关的日志。在函数计算控制台的日志服务中,搜索 Route not found 或 custom domain 关键词,能直接看到哪个路径匹配失败、请求被网关拒绝的具体原因。云老大在处理生产环境故障时,通常会先以5分钟为窗口拉取网关日志,过滤出所有4xx状态码,按URL路径聚合排序,能快速锁定是「共性路由问题」还是「单路径异常」——这个分析习惯可以直接复用。
最后强调一句:网关层的404和应用层的404,排查方法和修复手段完全不同。前者看路由配置,后者看代码逻辑。本文下一节将展开这两种不同场景的区分技巧,以及如何在混合架构中快速定位问题边界。
四、HTTP路径排查实战步骤
先明确一个核心原则:404的排查要沿着请求链路逐层推进,不要一头扎进函数代码里翻逻辑。根据我们接触过的数百个FC自定义域名故障案例,大约四成问题出在DNS或CNAME解析,三成出在路由规则配置,剩下不到三成才是函数代码本身的问题。下面这套排查路径,按顺序走一遍基本能定位。
1. 使用curl测试,判断请求是否到达FC网关
很多用户习惯直接在浏览器地址栏输入域名,看到404就认为是FC没生效。这个判断不准确。浏览器的404页面可能是本地代理、CDN节点或浏览器缓存返回的,根本到不了阿里云侧。正确的第一步是用curl命令做一次带响应头信息的请求:
curl -I https://你的自定义域名/api/hello
重点关注响应头里有没有x-fc-error-type字段,以及响应头中是否包含x-fc-request-id。如果这两个字段存在,说明请求已经成功到达FC网关,问题出在路由配置、触发器或函数代码层面。如果响应头没有FC标志,那问题在DNS解析、CNAME配置或CDN回源策略上,和函数计算本身无关。
一个容易被忽视的细节:curl测试时加上-H "Host: 你的自定义域名"直接请求FC提供的默认域名,可以跳过DNS解析干扰,单独验证网关侧的路由配置是否生效。我们曾遇到一个案例,用户的CNAME记录指向了旧版本的默认域名,导致请求始终打到已删除的函数版本上,用这个方法十分钟就定位了问题。
另外,curl -I只发送HEAD请求,部分函数的HTTP触发器默认未勾选HEAD方法,会返回403或404。建议使用curl -v查看完整响应,或者直接发送GET请求测试:
curl -v https://你的自定义域名/api/hello
观察返回体里是否包含{"errorMessage":"Route not found"}之类的信息。如果能看到这个JSON格式的错误,就说明请求穿透到了FC网关的路由匹配层,但没找到对应的路由规则,这是最典型的配置问题。
2. 详情日志查看,定位路由匹配链路
curl测试只能判断请求是否到达网关,要看到内部的路由匹配过程,必须依赖日志系统。建议在FC控制台为函数启用日志服务(SLS),这是排查404最核心的工具。
具体操作:进入函数详情页,在「日志服务」标签页开启日志检索。开启后,每次请求都会记录一条访问日志。在日志查询框中输入custom domain或route关键词,过滤出与自定义域名相关的请求记录。
日志中关键信息有两类。一类是RequestPath字段,记录网关收到的实际请求路径。注意这里显示的是网关层解析后的路径,如果配置了CDN,可能已经经过了URL重写,需要和CDN侧的转发规则对比确认。另一类是MatchedRoute或RouteNotFound状态,直接告诉你这条请求是否命中了路由规则。
举个例子:用户访问https://example.com/api/user/info返回404,查询日志发现MatchedRoute显示/api/*已命中,请求被转发到了函数实例,但函数返回的HTTP状态码是404。这就说明网关层没问题,问题出在函数代码内部——比如Express应用里没有定义/user/info这个路由。这类应用层404的响应头同样会带FC标识,但错误信息里通常包含框架自身的404页面,而不是FC网关的Route not found。
日志查询还有另一个作用:确认请求匹配到了哪个版本的函数。如果函数配置了别名或版本,日志里会显示实际调用的版本号。我们遇到过不止一次,用户更新了代码并发布新版本,但自定义域名路由规则还指向旧版本,导致新加的路径全部404。日志里版本号和实际期望不一致,通常几分钟就能发现。
如果函数还没有开启日志服务,可以临时在代码中加一段中间件,把request.path和request.headers打印到标准输出,再通过控制台的「实时日志」查看。这个方法不需要额外配置SLS,适合快速验证场景。
3. 请求头与路径解析,理解「前缀匹配」的边界
路由排查到最后,绝大多数问题都出在对「前缀匹配」规则的理解上。FC自定义域名的路由规则是严格的路径前缀匹配,不是正则匹配,也不是通配符匹配。这里有几个容易踩坑的细节:
第一,/*和/的区别。 路由规则/*表示匹配所有路径,而/只匹配根路径本身。如果你只配置了/这个路由规则,访问/api/hello时必然404。建议至少保留一条/*的兜底路由,指向主函数,避免未匹配路径直接暴露网关默认404页。
第二,前缀匹配的边界问题。 规则/api/*能匹配/api/user和/api/user/info,但不会匹配/api2/test。这看起来好理解,但很多人容易忽略的是路径结尾的斜杠。比如你配置了/api/,而实际请求路径是/api(无结尾斜杠),这时路由不会匹配。在FC控制台配置路由时,系统会自动做一定程度的路径规范化,但规范逻辑和Nginx等传统网关不同,建议配置后直接用curl验证边界路径。
第三,HTTP触发器请求方法的限制。 路由规则本身不区分请求方法,但后端函数绑定的HTTP触发器有方法限制。默认新建的HTTP触发器只勾选GET和POST,如果你用PUT、DELETE或OPTIONS方法请求,即使路由匹配成功,网关也会返回404或405。在「触发器管理」中把需要用到的HTTP方法全部勾选上,可以避免这类问题。
第四,请求头里的Host字段。 FC网关根据Host字段来匹配自定义域名,所以请求头中的Host必须与绑定的域名完全一致。如果域名绑定了example.com和www.example.com两个域名,但路由规则只在example.com下配置了路径映射,用www.example.com访问时就会404。这里要特别注意:通过CNAME解析到FC默认域名后,默认域名的Host不会被自动识别,必须显式绑定自定义域名,否则网关无法匹配路由。
从实际操作经验看,能用具体路径就不用根路径,能显示配置/*兜底就不要依赖默认行为。云老大在处理这类路由纠纷时,通常会让客户先把所有路径规则列表截图发过来,逐个检查前缀是否符合预期——这个动作虽然基础,但能筛掉约三分之二的无效排查。对一个生产环境的FC服务来说,路由规则表本质上就是一份「URL到函数的映射契约」,每一次新增或调整函数路径,都应该同步更新这份契约,而不是依赖「应该能自动匹配」的假设。
五、解决FC自定义域名404的配置技巧
进入配置实操层面,很多404问题并非代码缺陷,而是路由规划阶段埋下的隐患。根据对大量线上故障的复盘,配置层面导致的404占比超过七成,且呈现明显的规律性:根路径失效、前缀冲突、方法未放行是三大高频诱因。下面按配置优先级拆解,每一条都对应具体的排查动作。
1. 如何调整路由规则
调整路由规则的核心原则只有一条:匹配顺序比匹配内容更容易被忽视。FC自定义域名的路由表按路径前缀的 specificity(精确度)排序,最长的前缀优先匹配。举个例子,假设同时配置了 /* 和 /api/* 两条规则,访问 /api/users 时,请求会命中 /api/*,而不是 /*。这本身符合直觉,但反向操作就容易出问题:如果先配置了 /api/*,后配置 /*,部分开发者误以为新规则会覆盖旧规则,实际上两者是共存关系,不存在“覆盖”。
实操上建议这样调整:
第一步,清点现有路由规则。 进入FC控制台的「自定义域名 → 管理路由」页面,将当前所有路径前缀、关联函数、请求方法逐条截图或记录。很多账号经过多次迭代后,路由表里沉积了大量废弃规则,例如早期调试用的 /test/*、临时挂载的 /old/*,这些规则会抢占匹配优先级。
第二步,按访问流量重新排序规划。 建议将具体业务前缀放在前面,兜底规则 /* 放在最后。举个例子,一个典型的内容管理后台,可以这样规划:
/api/admin/* → admin-service(仅允许 GET/POST)
/api/user/* → user-service(仅允许 GET/PUT)
/* → main-site(所有方法)
注意,/* 作为兜底路由时,一定要显式指向一个真实存在的函数,否则未匹配的路径会直接命中网关默认404。根据阿里云官方文档的说明,自定义域名未关联任何路由规则时,根路径和所有子路径都会返回404,这种错误经常被误判为DNS问题。
第三步,留意路径结尾的斜杠。 前缀匹配是字符串匹配,/api 和 /api/ 是两个不同的规则。如果配置了 /api,访问 /api/users 是否能命中?答案是不一定——FC网关的路径匹配会先做标准化处理,但标准化的规则并不等同于浏览器地址栏的直观表现。稳妥的做法是:具体路径规则全部带上结尾斜杠和通配符,例如 /api/*,避免二义性。
有一个被反复验证的经验值:在路由配置上多花10分钟设计前缀层级,能减少90%的运维期404工单。这10分钟的价值在于阻断“新增函数→添加路由→访问报错→排查半天”的恶性循环。
2. 正确配置自定义路径
自定义路径的配置痛点,本质上是一个精细化管理问题:你需要明确告诉网关,哪一个路径前缀对应哪一个函数版本。很多用户习惯将所有路径统统指向 $LATEST 版本,这在开发环境没问题,但一旦发布新版本并配置了灰度流量,部分请求会命中新版本代码,而新版本内部没有实现对应路由,从而返回“应用层404”——响应头带FC标识,但响应体是函数代码返回的404 JSON,和网关层的404格式有区别。
正确配置路径需要关注以下三个维度:
路径与函数的映射粒度。 按照业务模块划分路径前缀,避免全部堆在一个函数里。以某电商系统为例,合理的映射关系是:
/order/*→ order-service(订单模块)/product/*→ product-service(商品模块)/user/*→ user-service(用户模块)
这种做法不仅让路由规则一目了然,还能实现独立部署、独立扩容。但要注意,路径前缀一旦确定,尽量不要频繁修改,因为函数代码内部的路由逻辑会依赖这个前缀——除非你在函数内做了完整的路径重写。
请求方法的显式勾选。 这是最容易被忽略的配置项。FC控制台创建HTTP触发器时,默认勾选的方法只有 GET 和 POST。如果你的函数提供的是 DELETE /api/resource/{id} 这样的RESTful接口,而触发器只勾选了 GET 和 POST,那么请求到达网关时会被直接拒绝——返回404而非405,因为网关认为“该路径不存在”。实际排查中,这类问题占据了“部分路径404”案例的近三分之一。建议在配置HTTP触发器时,一次性勾选全部方法(GET/POST/PUT/DELETE/HEAD/PATCH/OPTIONS),将方法校验下放到函数代码层,由业务逻辑自行判断方法的合法性。
路径重写(Rewrite)的合理使用。 FC网关支持配置重写规则,例如将 /api/v2/* 重写为 /v2/* 再转发给函数。这个功能在API版本迁移时非常有用,但需要谨慎:重写规则同样参与前缀匹配,如果重写后的路径在函数内仍找不到对应路由,404依旧会发生。一个稳妥的做法是,在函数代码中打印收到的完整请求路径(包括 request.path 和 request.querystring),对照网关层配置验证重写结果是否符合预期。
3. 重定向与默认文档
默认文档的404问题最具迷惑性——访问 https://yourdomain.com/ 根路径时,返回的可能是云厂商的默认404页面,也可能是FC网关的标准404,两者差异巨大,影响排查方向。
根路径的默认文档行为需要明确认知:FC网关不会自动映射根路径。 传统的Web服务器(如Nginx、Apache)会自动寻找 index.html 或 index.php 作为默认文档,但FC网关不具备这个行为。访问 https://yourdomain.com/ 时,实际匹配的路由是 /*(因为根路径本质上是空路径 + /* 前缀)。如果 /* 未配置或未指向正确函数,网关直接返回404。
解决方案有两种,按业务场景选择:
方案一:显式配置根路径路由。 在路由规则中新增一条 / 的规则,指向承载前端页面的函数。这里需要强调:/ 和 /* 是两条独立规则,匹配优先级上 / 高于 /*。这意味着访问根路径时会命中 / 规则,而不是 /*。如果业务上有“根路径返回首页、其他路径走API”的需求,这种配置方式非常直观。
方案二:配置重定向规则。 将 / 永久重定向(301)到 /index.html 或具体的业务入口路径。这种做法的好处是让浏览器地址栏显示明确路径,便于后续排查;缺点是每次访问根路径都多一次HTTP跳转,首屏性能受损。实测数据表明,301重定向额外增加的耗时约在20到50毫秒之间,对于追求极致性能的场景需要权衡。
针对子路径的默认文档需求。 假设访问 https://yourdomain.com/docs/(注意结尾斜杠),期望返回该目录下的默认页面,FC网关同样不支持自动查找 index.html。解决方法是在函数代码中自行处理:当检测到请求路径以 / 结尾时,拼接上默认文档名(如 index.html)再返回对应内容。以下伪代码可以直观说明逻辑:
if request.path.endswith('/'):
path = request.path + 'index.html'
else:
path = request.path
这段逻辑虽简单,但在实际业务中能规避大量“目录路径404”问题。另外一个容易被忽略的细节是:路由匹配区分大小写。/Docs 和 /docs 在FC网关中是两个完全不同的前缀,默认不会做大小写归一化。如果你的业务对大小写不敏感,需要在函数代码内自行转换,或在CDN层配置大小写归一化规则。
关于重定向的一个常见误区:不要将重定向和内部转发混为一谈。 重定向(Redirect)是HTTP 301/302,浏览器地址栏会变化,请求会重新发起;内部转发(Rewrite)是网关将请求转发给函数时修改路径,浏览器地址栏不变。如果目标是“让根路径显示首页但不改变URL”,应使用Rewrite而不是Redirect。FC网关目前支持配置Rewrite规则,路径改写后的实际匹配发生在改写后的值上——例如将 / 重写为 /index.html 后,函数收到的实际请求路径是 /index.html,函数内部必须实现对该路径的路由处理,否则仍然会404。整套逻辑链条并不复杂,但跳过一个环节都会导致故障。
本段三个层面(路由规则、路径配置、重定向与默认文档)并非孤立存在,而是叠加生效。实际部署中经常出现多因素耦合的情况:比如某个路径前缀命中了错误的路由规则,同时该规则关联的函数内部又缺少对应路由实现,最终表现为404。因此排查时建议遵循“自外向里”的顺序:先用 curl -I 确认网关是否响应,再检查路由表匹配结果,最后进入函数日志定位应用层路由。如果这中间有环节无法快速确认,可以借助其他工具辅助判断,例如在函数入口处临时打印完整的事件上下文,对比最终转发到函数的路径是否符合预期。
六、预防FC自定义域名404的日常建议
回到开篇的问题:自定义域名404,到底是不是“玄学”?从我们排查过的案例来看,绝大多数404并非偶发,而是配置管理习惯的问题。与其每次故障后花两三个小时翻日志,不如把预防工作拆解到日常流程中。以下建议来自多个生产环境的运维经验,按操作频次排列。
1. 配置前检查清单
很多404问题在配置完成那一刻就已经注定了。把检查前置,能省掉后续大量排查时间。这里给出一份可直接照着做的清单:
域名与备案状态。 确认域名已完成ICP备案且在有效期内,备案信息与阿里云账号实名认证信息一致。备案刚完成时,管局数据同步到FC网关侧通常需要1-2小时,这段时间内解析即使正确也会返回404。另外,检查域名是否被拦截或封禁——部分域名后缀(如.zip、.mov)在浏览器或安全软件层面会被直接拦截,请求根本发不到FC网关。
CNAME解析生效验证。 在本地终端执行nslookup 你的域名,确认解析结果指向FC提供的默认域名(形如*.compute.aliyuncs.com)。如果解析到了旧服务器IP或CDN源站地址,说明DNS记录未更新或CDN缓存了旧的解析结果。建议配置TTL为600秒(10分钟),方便后续变更快速生效。
函数与触发器状态。 确认目标函数处于“已发布”状态而非“草稿”,且至少关联了一个HTTP触发器。进入FC控制台,查看触发器列表中是否存在对应的方法(GET/POST/PUT/DELETE等)。一个容易被忽略的点:如果函数有多个版本,而触发器只绑定在LATEST版本上,那么当域名路由指向某个别名(Alias)时,请求会绕过触发器,直接返回404。建议在检查清单中增加一条:域名路由指向的版本/别名,必须与触发器所属的版本/别名一致。
路由规则路径匹配。 在控制台打开自定义域名的路由配置页,逐条核对路径前缀。第一条建议配置/*作为兜底路由,指向你的主函数;然后才是具体前缀(如/api/*、/admin/*)。因为FC的路由匹配是从最长前缀开始逐一尝试,/*虽然写在最前面,但不会拦截更具体的路径。注意路径结尾的斜杠:/api和/api/是两个不同的前缀,如果客户端请求/api/user而路由规则只配置了/api/(带斜杠),请求会因前缀不匹配而404。
2. 版本更新注意事项
函数代码迭代是404的高发时段。很多团队在开发环境测试通过后直接灰度发布,结果线上自定义域名大面积404,回滚又找不到原因——因为问题根本不在代码里。
避免隐式覆盖路由规则。 使用Serverless Devs或Terraform等IaC工具部署时,如果配置文件里没有显式声明自定义域名的路由规则,工具可能默认清除控制台上手工配置的路由映射。我们在一次客户案例中遇到过这样的情况:运维用serverless deploy更新函数代码后,原先配置的/api/*路由被自动删除,所有API请求全部404,而函数本身的默认测试域名却访问正常。建议在IaC配置文件中将自定义域名及路由规则作为独立资源管理,每次部署前先执行plan查看变更内容,确认是否有非预期的路由删除。
版本别名与灰度策略。 如果使用FC的版本管理功能,新版本发布后,需要手动将域名路由指向新版本或更新别名,这个过程容易出错。一个实际案例:某团队发布v2版本后,灰度流量切到10%,但自定义域名路由仍指向v1别名,导致10%的请求进入v2、90%进入v1——而v2代码中调整了URL结构,v2实例对旧路径返回了应用层404,线上出现间歇性404。排查了半小时才发现是流量分流造成的。建议长期保持一个稳定别名(如prod)指向当前生产版本,域名路由只绑定这个别名,发布时仅更新别名指向的版本号,不修改路由规则。
配置漂移检测。 FC控制台支持导出当前配置快照(JSON格式),建议每次变更前导出一次存档,与部署后的配置进行对比。尤其在多人协作的团队中,A成员在控制台修改了路由,B成员用命令行工具覆盖部署,配置漂移会在半小时内发生。用CI/CD流水线管控配置变更,比在控制台上手动操作更容易追踪。
3. 监控与告警设置
404不全是坏事——搜索引擎爬虫探测不存在的路径、用户访问过期链接都会产生404。但如果某个路径此前可正常访问,突然连续返回404,那多半是配置或代码出了问题。日常监控需要区分这两类情况。
配置FC网关/域名监控。 阿里云提供的云监控服务支持对FC函数设置自定义监控项。针对自定义域名404,建议配置两条告警规则:
- 规则一:5分钟内,自定义域名对应的函数实例返回404的次数超过20次,且环比上升50%以上,触发Warning级别告警。
- 规则二:连续3分钟,某路径的404响应占比超过该路径总请求量的10%,触发Error级别告警并通知到责任人。
阈值可根据业务规模调整,但核心思路是:用“时段对比”而非“绝对值”来判定异常,避免流量高峰期的误报。
开启函数日志服务(SLS)。 在FC控制台为函数开启日志查询功能,日志服务会记录每次请求的完整链路信息。排查404时,重点搜索两个关键词:Route not found(网关层未匹配到路由规则)和404(应用层返回)。日志中会显示请求的完整路径、匹配到的路由规则、目标函数名以及触发器的Method。这个信息能精准定位404发生在链路哪一层——是网关没匹配上,还是函数代码内没有对应路由。
定期巡检域名证书状态。 自定义域名绑定HTTPS证书后,如果证书过期或被吊销,浏览器会直接拦截请求,表现即为访问异常(部分浏览器显示404或连接失败)。配置证书的自动续期验证,同时在云监控中监听证书到期时间,提前14天发送提醒。证书问题引发的“404”是最容易预防的一类。
建立月度配置巡检机制。 每月初,导出自定义域名的路由配置快照,与上个月的配置做对比。有条件的团队,可以用脚本读取FC API接口的配置数据,自动比对差异并输出报告。在服务过的一些客户中,我们(云老大团队)曾多次通过这种巡检发现客户控制台中被误删的路由规则,以及因人员变动导致的配置权限混乱——这些在故障发生前都有迹可循。
最后想说的是,FC自定义域名404的本质,是请求链路中某一环的“预期不符”。把配置当作代码来管理——有版本、有审计、有变更流程,404的发生率能降低80%以上。剩下的20%,就交给监控和告警去兜底。技术架构没有银弹,但完善的运维习惯和清晰的排查思路,足以让这类问题不再成为拦路虎。
