业务背景和问题阿里云OSS服务 收费标准下行流量 OSS存储 https请求 流量支出是大头量化效果与验证方法流量成本(通过查询阿里云控制台)从 0.49/GB 降价到 0.08/GB每 GB 省下了0.49 - 0.13 0.36 节省的百分比0.36 ÷ 0.49 ≈73.47%图片加载速度我在本地写了一个 Shell 脚本利用curl -w命令定义了输出格式。针对同一张测试图片分别向 OSS 的直连域名和 CDN 域名发起了多次请求并打点了time_namelookupDNS 解析、time_connectTCP 建连耗时、time_starttransferTTFB 首字节时间以及time_total总耗时。对比数据发现CDN 的边缘节点调度把建连耗时和首字节时间极大地压缩了。总耗时从直连的 190 多毫秒稳定降到了 30 多毫秒绝对延迟降低了 160 毫秒左右算下来提升了 5 倍余。time_namelookup(DNS 解析)域名翻译成目标服务器 IP 地址所花的时间。time_connect(TCP 建连) 客户端和服务器完成“三次握手”建立可靠传输通道所花的时间。time_starttransfer(TTFB 首字节)从发出请求到收到服务器返回的第一点数据所花的时间反映了服务器的处理速度和网络往返延迟。time_total(总耗时) 从开始找地址直到图片完整下载完毕的总时间也就是用户感受到的白屏加载时间。引入CDN的收益就近接入所以极大缩短time_connect用户体验更丝滑缓存命中CDN 边缘节点会将热点资源直接缓存在自己的高速内存或 SSD 中。当请求打到边缘节点且缓存命中Cache Hit时节点直接把数据塞给用户省去了漫长的回源网络等待和源站处理时间TTFB首字节时间因此发生质的飞跃下行流量费用更低且回源走的公司内网不额外收费防止DDOS 负载均衡流量分散隐藏源站IPcdn是什么原理CDN加速访问怎么做的Content Distribution Network 内容分发网络顾名思义就是把静态资源比如图片分发到不同的地方以达到c端就近访问的目的——比如北京的用户就访问北京的CDN节点而不用访问可能物理距离很远的OSS源站。其实可以看作是对象存储层的特殊缓存服务既然是缓存就有一致性的问题如果用户访问的资源不在cdn边缘节点上它会自动回源而且因为回源走的阿里云内网不收费CDN工作原理简述如何找到最合适的 CDN 节点流程app向用户当前所处网络的本地 DNS 发起解析请求请求最终打到 CDN 的 GSLBDNS 的迭代查询过程GSLB 根据用户 IP 地址、CDN 节点状态负载、性能、响应时间、带宽等指标综合判断并返回最优 CDN 节点的 IP 地址。App 拿到最优节点 IP建立 TCP 连接带着你的objectKey和auth_key去拉取图片这里的关键全局负载均衡 GSLB将用户请求调度到最优的 CDN 节点GSLB 转发机制有三种实现DNS解析 主流实现DNS 有缓存功能和负载均衡能力能天然减轻 GSLB 的压力HTTP重定向IP路由简单举个例子比如之前网站网址是www.netitv.com.cn此时进行要 cdn 改造那么将之前的网站网址作为 GSLB 服务域名的 CNAME用户访问www.netitv.com.cn经过 CNAME 解析会映射到 GSLB 地址www.netitv.cdn.com.cn上然后 GSLB 基于 DNS 协议可以进行后续的负载均衡操作选择合适的 IP 返回给用户。静态资源是如何被缓存到 CDN 节点中的预热和回源节点上没有用户请求的资源或该资源的缓存已过期就得回源 运维侧在CDN控制台配置同账号下私有OSS bucket回源即可实现缓存未命中自动回源如何防止静态资源被盗用通过检查HTTP请求头中的Referer字段来判断请求来源是否合法 动态URL鉴权 服务器Token鉴权防盗链机制推荐采用Referer 防盗链 时间戳防盗链的组合方案平衡安全性与实现成本怎么用的 怎么实现的开发侧STAR法则1. 业务背景抛出痛点“改造之前我们的媒体资源链路比较粗暴数据库里直接存了完整的 OSS 直链前端展示的也是OSS直链并设置桶为公开读这不仅导致数据被严重污染、后续无法灵活更换 CDN 厂商还非常容易被恶意盗刷流量上传接口的鉴权做的不好,有水平越权的现象发生 为了解决这个问题我进行了全站媒体资源链路的重构核心思想就是遵循 KISS 原则实现存储与展现的解耦。2. 高度抽象数据链路分段阐述突出亮点“整个重构后的链路我按数据的流向分为上、中、下三段上传侧我废弃了传统的宽泛凭证新增了上传意图接口。App 必须先来后端申请后端校验合法后生成一个纯净的objectKey并动态签发一个只针对该文件的最小 STS 权限。App 拿到凭证后直传 OSS不占用服务器带宽。第二段是入库侧无论是发帖还是改头像写入链路都会强制经过我封装的MediaUrlService。它像一个漏斗会拦截掉所有的越权伪造和路径穿越最终 DB 和 Redis 里只落盘最纯净的objectKey。第三段是输出侧我在出参的视图层VO利用 Jackson 序列化做了切面。数据返回给前端的瞬间后端会在内存里把objectKey动态组装成带有Type A 过期时间签名的完整 CDN URL。”至于VO和DTO/POJO的转换和其必要,使用了MapStructURL 签名的流水线DB - POJO裸数据 MyBatis 从数据库中查出原生的实体类Entity/POJO如Comment。这时候像头像、图片这种字段里装的仅仅是纯文本的objectKey例如avatar/xxx.jpg没有任何域名和签名。POJO - VO挂载规则在 Controller 或 Service 返回之前调用了MediaResponseMapper由MapStruct自动生成的实现类把实体映射为 View Object如CommentResponseVO。注意在这一步objectKey本身的字符串并没有发生改变。转换的意义在于VO 对象的字段上挂载了特定的注解规则比如JsonSerialize(usingCdnUrlSerializer.class)privateStringauthorAvatar;这相当于给这个字段贴了一个标签“嘿一会儿谁要把我变成 JSON请用CdnUrlSerializer这个工具处理我”。VO - JSON动态触发签名你提到的“网关层”严格意义上来说其实是Spring MVC 的 Web 层HTTP 消息转换器。当 Controller 返回了ApiResponseVO后Spring Boot 准备把它写入 HTTP 响应体传给前端。这时候它会召唤默认的 JSON 序列化工具 ——Jackson。Jackson 开始遍历这个 VO 对象。当它扫描到authorAvatar字段时看到了上面贴的JsonSerialize标签。于是Jackson 放下了自己默认的字符串输出器转而实例化了你写的自定义拦截器CdnUrlSerializer。CdnUrlSerializer在内部调用了阿里云的 SDK通过MediaUrlService把裸的objectKey瞬间加上了https://cdn...域名并根据当前的服务器时间计算出了一个比如 1 小时后过期的auth_key签名参数。最后Jackson 把这个长长的、带签名的完整 URL 写进了最终的 JSON 字符串里输出给网络层。总结你的理解POJO 转 VO确实是ResponseMapperMapStruct做的主要是为了脱敏和贴序列化标签。签名转换确实是自定义的JacksonCdnUrlSerializer做的。发生的位置不是在独立部署的网关如 Nginx 或 Spring Cloud Gateway而是在Spring Boot 本身的响应序列化阶段即准备往浏览器吐 JSON 的那一刻。3. 用数据收尾证明价值并主动抛出诱饵“通过这套架构业务代码完全不需要关心图片链接是怎么拼的做到了高内聚低耦合。同时边缘的防盗刷加上源站的文件级鉴权帮我们把公网下行流量成本实打实地降低了 73.4%图片加载性能也提升了大概5倍。 在这个过程中为了保证新老版本的平滑过渡我也做了一些历史数据清洗和接口兼容的工作如果您感兴趣我可以展开讲讲。”运维侧这里跟着阿里云手册走即可不确定的问qwen助手他网站上面那个rag这里有个trick 如果你想快速测试而没有已备案的网站可以把cdn加速区域选择为非大陆。还有申请SSL证书为安全一般强制启用HTTPSHTTPS按每万次请求收费的。 配置过程略像ios app 强制拦截非https请求所以不得不申请CDN-OSS 鉴权防刷 架构OSS写鉴权后端下发STS临时访问凭证选择该方案理由适用性最广支持分片上传、断点续传等复杂场景特别适合仿小红书类项目中用户上传大文件如图片、视频的需求。安全性高临时凭证有效期通常为几分钟到几小时相比长期AccessKey更难泄露。可通过自定义策略进一步限制权限如仅允许上传到指定Bucket目录。性能优化空间服务端可对STS凭证进行缓存如Redis减少频繁调用STS服务导致的限流风险。其他方案对比PostPolicy 表单上传适用场景限制文件类型/大小且无需分片的小文件上传如网页表单。缺点不支持分片大文件上传易超时。实现服务端生成policy和signature客户端通过HTML表单提交。预签名URLPutObject适用场景简单的单文件上传且无需分片如小程序临时文件分享。缺点大文件需多次生成URL交互复杂不适合以后多图、弱网、分片、断点续传。客户端可篡改分片内容。实现简单服务端通过signUrl生成带时效的URL客户端直接PUT上传。总之仿小红书的APP项目应优先选择STS临时访问凭证方案其对大文件和复杂场景的支持、安全性及可扩展性均优于其他方案。STS动态policy此处涉密, 已自动脱敏删去不做的坏处读路径 流量防刷防盗链针对防刷我没有采用简单的 IP 限流因为在校园网环境下共用出口 IP很容易造成大面积误杀。我们采用的是阿里云 Type A 动态 URL 鉴权结合边缘频控的组合拳具体分为三个防御层级第一层无证拦截阻断直接盗链与遍历猜测我们的图片 URL 是动态生成的。当用户侧发起请求前后端的 Java 业务服务会使用URI Timestamp 随机数 预设密钥计算出一个 MD5 签名拼接在 URL 后面。 如果恶意爬虫直接构造 URL或者去遍历资源路径由于它没有我们的鉴权 Key算不出合法的 MD5CDN 边缘节点会直接校验失败并返回 403。这一步将 100% 的非法试探流量拦截在了边缘实现了零回源。第二层过期失效阻断长效重放攻击如果黑客通过抓包拿到了一个合法的、带有签名的 URL 怎么办 Type A 鉴权的 URL 中带有时间戳Timestamp。我们在生成时设置了合理的 TTL比如 30 分钟过期。黑客抓到的 URL 一旦过了这个时间窗口签名就自动失效了无法被长期作为盗链引用。第三层边缘高频限流阻断短时疯狂重放那么对于最极端的情况黑客写了脚本抓到一个合法 URL 后在过期前的这 30 分钟内发起高并发的疯狂请求怎么防 这时候我们的边缘限流规则就生效了。因为正常的客户端加载一张图片短时间内只会请求一次而‘刷子’会在极短时间内对同一个签名 URL 发起成百上千次请求。我们在 CDN 控制台配置了速率限制如果同一个 IP 针对同一个带 Token 的 URL在 10 秒内请求超过合理阈值例如 20 次CDN WAF 会直接进行 IP 封禁或连接阻断。通过这三层逻辑我们既避免了单纯 IP 限流的误杀又把恶意刷量流量彻底挡在了源站之外。URL 鉴权方案选择URL鉴权功能主要用于保护用户站点资源不被非法站点下载或盗用type a、b、c、d底层逻辑依然是 MD5 哈希校验 时间戳过期核心差异完全在于URL 的拼装格式和参数的灵活度这里没有孰优孰劣根据具体业务选择合适方案即可:按官方文档Type A 和 Type B都会在鉴权成功后还原成原始 URL 再做缓存键和回源所以“缓存命中”不是决定性差异。 区别是Type Aquery 参数式适合现在这种改造小、兼容 OSS 直链的方案。Type B路径前缀式更像内容站/图床风格适合你特别想要“无 query、像小红书”的外观。APP端演进App 上传链路统一迁移到新接口 POST /api/files/upload-intents。 App 不再本地拼 OSS 路径不再使用旧 GET /api/files/sts不再用 STS 做 OSS GetObject。 上传时 App 只把文件元信息交给后端使用后端返回的 objectKey 执行 PutObject业务接口统一提交 objectKey。 展示时 App 只使用后端业务接口返回的 CDN Type A 签名 URL。 图片缓存 key 改成稳定媒体 key 而不是旧版逻辑中完整的url避免 auth_key 每次变化导致缓存击穿。后续系统迭代的考量1. “垃圾数据”与孤儿文件问题 (Orphan Files)隐患现在的流程是App 拿到objectKey- 上传 OSS - 调用业务接口发帖落库。如果 App 上传完 OSS 后由于网络抖动、App 崩溃或用户直接杀后台导致业务接口没有被调用。这时 OSS 里就多了一个真实存在但数据库里没有记录的“孤儿文件”日积月累会浪费大量存储成本。大厂解法OSS 生命周期 (Lifecycle)规定所有客户端直传的文件默认放入一个临时目录如tmp/posts/{uid}/...该目录设置 1 天后自动删除。业务兜底/触发转移当 App 调用业务接口发帖成功落库后后端异步发起一个 OSS 的CopyObject请求将文件从tmp移动到正式目录或者通过修改文件的 Header/Tag 让其免于被清理。2. 图像处理与 CDN 边缘计算优化空间后端拼接 CDN URL 时还可以根据 App 端传来的参数动态追加 OSS 的图像处理参数?x-oss-processimage/resize,w_800/format,webp做到原图存储、多端按需裁剪。将裁剪和格式转换交由 CDN 边缘节点或 OSS 回源处理极大节省带宽并提升加载速度。3. 内容合规与风控 (Content Moderation)合规要求用户直传图片到 OSS如何防止上传涉黄、涉暴内容大厂解法通常会配置阿里云的内容安全绿网。当图片上传到 OSS 后自动触发 OSS 回调Callback或事件总线EventBridge推送到内容审核微服务。如果判定违规直接在后台将该objectKey标记为不可见或删除。原文地址OSSCDN实现快速稳定的图床实战本文持续更新最新内容及相关资料请访问原文。