尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

从浏览器输入 URL 到页面显示:DNS、Nginx、后端与 CDN 全链路解析

从浏览器输入 URL 到页面显示:DNS、Nginx、后端与 CDN 全链路解析 从浏览器输入 URL 到页面显示DNS、Nginx、后端与 CDN 全链路解析前言1. 一次请求的整体地图2. DNS把域名变成可访问地址2.1 为什么浏览器不能只拿域名建立连接2.2 DNS 查询如何逐层找到答案3. TCP 与 HTTPS先连通再安全传输3.1 TCP 三次握手解决什么问题3.2 TLS 为 HTTP 加上一层保护4. Nginx统一入口与反向代理4.1 为什么这叫反向代理4.2 Nginx 在请求链路中还会做什么5. 服务器集群与负载均衡5.1 反向代理与负载均衡不是一回事6. NestJS真正处理业务请求的地方6.1 两个典型 API 请求7. MySQL 与 Redis一个保存事实一个加速访问7.1 以文章详情为例理解缓存8. 静态资源为何应走独立链路9. OSS让大体积对象有合适的存放位置9.1 上传与访问的常见分工10. CDN把静态资源更快地送到用户附近10.1 缓存命中与回源11. 两条完整请求链路11.1 动态 API 请求需要业务判断与数据访问11.2 静态资源请求优先由 CDN 与对象存储服务总结前言刚开始接触 Web 开发时一个接口看起来往往很直接浏览器调用GET /api/posts/42后端返回一段 JSON。但把域名放进地址栏后请求并不是瞬间抵达某个 Controller。它会先找到可连接的地址建立安全连接经过接入层转发再由业务服务读取数据如果页面还包含图片、脚本和字体这些资源通常走的是另一条更适合分发的链路。理解这条路径的价值不在于背下每个网络术语而在于建立一张清晰的“分工图”谁负责定位、谁负责接入、谁负责业务、谁负责保存数据、谁负责分发大体积资源。排查“页面打不开”“接口很慢”“图片加载慢”时也就知道该从哪一层入手。可以把一次访问理解为一次协作DNS 负责找到入口Nginx 负责接待并分流NestJS 负责办理业务MySQL 和 Redis 提供数据OSS 与 CDN 负责高效送达静态资源。1. 一次请求的整体地图先看最常见的动态请求主干。这里的“服务器/接入层 IP”不一定是某台 NestJS 机器的地址也可能是负载均衡器或 CDN 的入口地址这是现代部署中非常常见的设计。浏览器输入域名 ↓ DNS 解析 ↓ 获得服务器/接入层 IP ↓ TCP 三次握手 ↓ HTTPS 场景下进行 TLS 握手 ↓ Nginx / 负载均衡层 ↓ NestJS 后端服务器集群 ↓ MySQL / Redis ↓ 返回数据以访问https://api.example.com/api/posts/42为例浏览器先通过 DNS 找到api.example.com对应的可访问地址连接建立后请求到达 NginxNginx 选择一台健康的 NestJS 实例该实例读取文章数据必要时优先从 Redis 获取缓存未命中再查询 MySQL最后将 JSON 沿原路返回浏览器。层次主要职责初学者最应记住的一点DNS域名解析为可连接地址域名是便于记忆的名称网络连接需要地址TCP / TLS建立可靠、安全的传输通道先连通再安全地传数据Nginx统一接入、转发、分流它通常不处理具体业务规则NestJSAPI 与业务编排Controller、Service、鉴权通常在这里发生MySQL / Redis数据持久化与高速访问两者解决的问题不同常常配合使用OSS / CDN存储与加速静态资源大资源不应挤进业务接口链路2. DNS把域名变成可访问地址2.1 为什么浏览器不能只拿域名建立连接人更擅长记住www.example.com这样的名称网络设备建立连接时却需要知道目标在哪里。IP 地址就是网络中的寻址信息。**DNSDomain Name System域名系统**承担的工作正是将便于记忆的域名转换为可用于连接的 IP 地址或先转换为另一个域名记录再继续查询。这个机制还带来一个实际好处应用可以迁移机器、扩容接入层或切换服务商而用户继续访问同一个域名即可。变更的是 DNS 记录及后端部署用户使用的入口名称不必改变。2.2 DNS 查询如何逐层找到答案一次查询不一定每次都要从最上层开始。浏览器、操作系统和递归 DNS 都可能保存过往结果并且记录带有TTL缓存有效期。缓存仍有效时查询可以很快结束缓存失效或没有记录时才需要继续向下查找。浏览器 / 操作系统缓存 ↓ 递归 DNS ↓ 根 DNS ↓ 顶级域 DNS ↓ 权威 DNS ↓ IP 地址其中各角色的关系可以这样理解本地缓存浏览器和操作系统会暂存近期结果减少重复查询。递归 DNS通常由网络运营商、公共 DNS 服务或企业网络提供。它替用户完成后续查询并会缓存答案。根 DNS知道顶级域 DNS 的入口在哪里不直接保存所有具体域名的最终地址。顶级域 DNS管理如.com、.cn这类顶级域的委派信息告诉查询方某个域名应去找哪组权威 DNS。权威 DNS保存某个域名实际配置的 DNS 记录是最终答案的权威来源。例如查询api.example.com时递归 DNS 可能先向根 DNS 询问.com的去向再向.com的顶级域 DNS 询问example.com的权威 DNS最后从权威 DNS 获取api.example.com的A或AAAA记录。A通常对应 IPv4AAAA通常对应 IPv6。实际服务也可能通过CNAME指向另一个域名递归 DNS 会继续完成解析。DNS 的职责是“找到可访问的入口”并不等同于承诺“必然返回物理距离最近的一台业务机器”。是否就近、如何调度取决于 DNS 配置、CDN、负载均衡和网络策略等多种因素。常见现象更可能优先检查的位置刚改域名解析部分用户仍访问旧地址TTL 与各级缓存是否尚未过期域名无法解析权威 DNS 记录、域名委派、拼写与记录类型同一域名解析出多个地址可能用于高可用、流量分配或多入口部署3. TCP 与 HTTPS先连通再安全传输拿到 IP 后浏览器才知道该向哪里发起连接。对于传统的 HTTPS 网站可以先把连接过程压缩成下面三步DNS ↓ TCP 三次握手 ↓ TLS 握手 ↓ HTTP 请求3.1 TCP 三次握手解决什么问题TCP 是面向连接的传输协议。所谓三次握手可以先理解为客户端和服务端在正式传数据之前彼此确认“我能发到你”“我能收到你”“我们准备好了”。这个过程帮助双方建立一条可靠的连接状态之后 HTTP 请求和响应才能稳定地在这条连接上收发。不必在初学阶段纠结序列号、窗口大小等实现细节。工程上更有用的认识是DNS 成功只说明找到了地址TCP 成功才说明目标端口可以建立连接。如果握手失败可能是服务未监听、端口被防火墙拦截或者网络路由不可达。3.2 TLS 为 HTTP 加上一层保护当地址以https://开头时TCP 建立后通常还要进行TLS 握手。浏览器会校验证书并与服务端协商后续通信所需的加密参数。握手完成后HTTP 请求内容才在加密通道中传输。TLS 的关键收益是三件事验证访问对象的身份、保护传输内容不被轻易窥视、降低内容在传输中被篡改的风险。证书过期、域名与证书不匹配、接入层未正确配置证书都会让浏览器在 HTTP 请求前就提示安全问题。阶段解决的问题失败时常见表现DNS 解析域名对应什么地址域名找不到、解析超时TCP 握手能否与目标端口建立连接连接超时、连接被拒绝TLS 握手能否建立可信的加密通道证书告警、HTTPS 连接失败HTTP 传输请求能否被正确处理4xx、5xx或响应慢4. Nginx统一入口与反向代理浏览器通常不直接访问某台具体的 NestJS 实例。因为业务服务可能有多台会扩缩容、发布和故障切换把它们的真实地址直接暴露给客户端管理和安全都会变得困难。实践中外部请求经常先到Nginx或云负载均衡等接入层再由接入层将请求转发给内部业务服务。用户 ↓ Nginx ↓ NestJS Server4.1 为什么这叫反向代理代理的核心是“代替一方发起或接收请求”。正向代理靠近客户端客户端把访问外部站点的请求先交给代理由代理代为访问目标。它主要服务于客户端侧的访问控制、网络出口等场景。反向代理靠近服务端用户只知道一个统一入口反向代理在后面代表服务端接收请求并将请求交给合适的业务服务。用户无需知道 NestJS 实例的数量、地址和变化。类型代理站在哪一侧客户端通常是否知道真实目标正向代理客户端一侧通常知道要访问的外部站点反向代理服务端一侧通常只需要知道统一服务入口4.2 Nginx 在请求链路中还会做什么Nginx 常见职责包括 TLS 证书终止、域名与路径路由、请求转发、压缩、访问日志、限流以及静态资源直接响应。例如/api/前缀转发给 NestJS而/assets/则可以由 Nginx 或 CDN 直接服务。这种划分避免所有资源请求都进入业务框架。下面是便于理解的配置片段server { listen 443 ssl; server_name api.example.com; location /api/ { proxy_pass http://nestjs_cluster; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }这段配置表达的重点是收到api.example.com的/api/请求后Nginx 将其转发给名为nestjs_cluster的后端集群。真实项目还会补充超时、跨域、限流和日志等配置但“统一入口再转发”的主线不变。5. 服务器集群与负载均衡单台后端服务容易遇到两个问题访问量上来后性能有限机器故障或发布重启时服务可能整体不可用。因此大型网站通常会让多台机器运行同一套 NestJS 程序形成后端集群。对外仍保持一个域名和一个接入入口对内则把请求分配给多个实例。→ NestJS A 用户 → Nginx → NestJS B → NestJS C → NestJS D5.1 反向代理与负载均衡不是一回事二者经常都由 Nginx 承担因此容易混淆。反向代理回答的是“请求由接入层代为转给后端”负载均衡进一步回答“这一次具体转给哪一台后端”。反向代理请求转发给真正后端 负载均衡决定具体转发给哪一台后端能力核心问题例子反向代理请求是否经过统一入口转发/api/转给 NestJS 服务负载均衡多个后端中选择哪一个本次转给 A下次转给 B健康检查某个实例是否还能接收流量B 异常后暂时不再分配请求常见分配策略包括轮询按顺序依次分配适合实例规格和请求耗时比较接近的场景。加权轮询性能更高的实例获得更高权重从而承担更多流量。最少连接优先选择当前连接数较少的实例对请求耗时差异较大的场景更有帮助。健康检查是可用性的另一层保障。接入层会通过探测接口、连接状态或云平台健康检查判断实例是否异常某个实例无法正常服务时会被暂时摘除恢复健康后再加入流量分配。需要注意负载均衡并不能自动让业务变正确登录状态、临时数据和幂等等问题仍需在应用设计中处理。6. NestJS真正处理业务请求的地方Nginx 关心的是“把请求交给谁”NestJS 关心的是“这个请求该怎么处理”。NestJS 是 Node.js 生态中的后端框架常用于构建结构化 API。它通常负责接收请求、校验参数、登录鉴权、执行业务逻辑、调用数据层最后返回 JSON。Nginx决定请求交给谁 NestJS决定这个请求具体怎么处理6.1 两个典型 API 请求登录接口通常是一个写操作。NestJS 接收到POST /api/login后先校验账号和密码是否完整再查询用户信息、比对凭证成功后生成访问令牌或建立会话最后返回登录结果。文章详情接口则通常是读操作GET /api/posts/:id先从路径中读取id校验格式并查询文章再返回相应 JSON。POST /api/login GET /api/posts/:id下面用简化的 NestJS Controller 展示路由入口。重点不是记住装饰器而是看清每个 HTTP 请求会被路由到对应的业务方法。Controller(api)exportclassAppController{constructor(privatereadonlyauthService:AuthService){}Post(login)asynclogin(Body()dto:LoginDto){returnthis.authService.login(dto);}Get(posts/:id)asyncgetPost(Param(id)id:string){returnthis.postService.findById(id);}}一次请求在 NestJS 中常见的执行顺序是路由匹配到 ControllerPipe 完成参数转换与校验Guard 判断是否有权限Service 组织业务规则并调用 Repository 或其他服务最终由 Controller 返回结果。出现错误时Exception Filter 可以把异常转换成统一的 HTTP 响应格式。NestJS 不应承担所有工作。连接接入、静态资源分发和海量二进制对象传输交给更擅长的组件业务服务才能保持专注、易扩展。7. MySQL 与 Redis一个保存事实一个加速访问NestJS 处理业务时通常需要数据支撑。MySQL是关系型数据库适合保存需要长期保留、结构明确、可关联查询的业务事实例如用户文章评论点赞收藏Redis是内存型键值存储读写很快常用于缓存、Session、验证码、热点数据和计数器。它的价值在于减少重复计算和重复查询快速应对高频访问但它通常不能替代 MySQL 作为关键业务事实的长期唯一来源。Nginx ↓ NestJS ↓ MySQL / Redis7.1 以文章详情为例理解缓存当大量用户同时浏览热门文章时如果每次都查询 MySQL数据库会承担大量相同读取。一个常见做法是NestJS 先查询 Redis若缓存命中直接返回若未命中再查询 MySQL把结果写入 Redis 并设置合适过期时间。GET /api/posts/42 ↓ NestJS 查询 Redis ├─ 命中直接返回文章详情 └─ 未命中查询 MySQL → 写入 Redis → 返回文章详情存储更适合保存设计时要注意MySQL用户、订单、文章等核心业务数据表结构、索引、事务与一致性Redis缓存、会话、验证码、计数器过期策略、缓存更新与内存容量缓存并非“加上就一定更快”。数据更新后如何让缓存同步失效是常见难点。例如文章编辑成功后可以删除对应缓存让下一次读取重新从 MySQL 构建缓存。对于点赞数这样的热点计数器也要结合业务容忍度设计异步汇总和最终一致性策略。8. 静态资源为何应走独立链路页面中的图片、CSS、JavaScript、字体和视频等都属于静态资源。它们的共同特点是内容通常不会因每个用户而频繁变化且单个对象可能很大、请求数量也多。若每一次请求都进入 NestJS 的 Controller、鉴权和业务逻辑会消耗本不必要的计算资源也让业务服务承担了不擅长的传输工作。更合理的分工是动态 API 走 Nginx 与 NestJS静态资源由 Nginx 直接响应或进一步交给 OSS 与 CDN。浏览器仍然只是在请求一个 URL但服务端内部走的是更合适的通道。请求类型示例通常处理者动态请求GET /api/posts/42Nginx → NestJS → 数据存储静态资源GET /assets/logo.svgCDN / Nginx / OSS上传请求POST /api/uploadsNestJS 负责鉴权与生成上传凭证对象存储承接内容这种拆分还会让扩容更精准接口压力高时扩 NestJS图片访问量高时提高 CDN 覆盖和缓存策略大体积对象存储增长时扩展 OSS 容量而不必让所有压力都落在同一类机器上。9. OSS让大体积对象有合适的存放位置图片、附件、音视频等二进制对象通常不直接存进 MySQL 的业务表。对象存储服务如OSS、S3、COS更适合保存这类内容容量扩展方便可通过 URL 访问也能和 CDN 更自然地协同。MySQL 更适合保存与业务相关的元数据例如对象名称、访问 URL、大小、媒体类型、上传者和关联文章。一个概念上的记录可以是filename URL size mimetype userId postId9.1 上传与访问的常见分工上传时NestJS 可以先验证用户身份、校验类型和大小限制再把内容写入对象存储或签发短时有效的直传凭证让浏览器直接上传。上传完成后业务服务将 URL 和关联信息写入 MySQL。读取文章详情时NestJS 返回图片 URL浏览器随后根据该 URL 从 CDN 或对象存储获取资源实体。这种设计避免让 MySQL 承担大对象传输也让数据库备份、查询和迁移更可控。对于私有资源还可以使用签名 URL 或访问控制策略避免仅凭一个公开地址就能长期访问。OSS 的重点是可靠存放对象MySQL 的重点是保存对象与业务之间的关系。二者不是替代关系而是分层协作。10. CDN把静态资源更快地送到用户附近CDNContent Delivery Network内容分发网络的核心作用是缓存和就近分发静态资源。CDN 在不同地区部署边缘节点用户请求图片、脚本等资源时DNS 或 CDN 调度系统会引导请求到合适的节点。若节点已缓存所需内容就可以直接返回减少回到源站的距离与压力。这里的“合适”不只是地理距离还会综合网络质量、节点健康和调度策略。因此可以把 CDN 理解为提升资源获取效率的分发网络而不是一个简单的“永远最近节点”承诺。10.1 缓存命中与回源当 CDN 节点中已经有当前版本的资源且仍在有效期内称为缓存命中节点直接响应用户。当节点没有该资源、缓存已过期或策略要求校验源站内容时称为需要回源CDN 向 OSS 或源站请求资源拿到后按策略缓存再返回用户。用户 ↓ CDN ↓ 缓存命中 → 直接返回 ↓ 未命中 ↓ OSS / 源站 ↓ CDN 缓存 ↓ 返回用户概念含义对用户与源站的影响缓存命中边缘节点已有可用资源返回更快源站压力更小回源节点从 OSS 或源站获取资源首次或失效后可能更慢会增加源站请求缓存过期缓存控制时间结束需要按策略重新校验或获取资源资源更新时CDN 缓存策略尤为重要。工程上常用带版本号或内容哈希的 URL例如app.8f3a2c.js。内容改变时 URL 同时改变浏览器与 CDN 可以安全地长时间缓存旧版本而新版本通过新 URL 获取减少“用户看到旧资源”的问题。紧急更新时也可以使用 CDN 刷新或预热能力但要了解其生效范围与成本。11. 两条完整请求链路11.1 动态 API 请求需要业务判断与数据访问以用户查看文章详情为例浏览器访问https://api.example.com/api/posts/42。DNS 将域名解析为接入层地址浏览器完成 TCP 和 TLS 握手Nginx 接收请求并根据负载策略选择一台 NestJS 实例NestJS 校验参数后先查 Redis未命中则查询 MySQL最后组装 JSON 返回。浏览器 ↓ DNS ↓ TCP / TLS ↓ Nginx ↓ NestJS ↓ MySQL / Redis这个过程中每一层都可以独立观测DNS 看解析结果与 TTLNginx 看访问日志和上游耗时NestJS 看接口日志和错误率MySQL 看慢查询Redis 看命中率。这样定位性能问题时不必笼统地说“后端慢”。11.2 静态资源请求优先由 CDN 与对象存储服务同一篇文章返回的 JSON 中可能包含封面图 URL。浏览器随后请求该图片时一般不会再进入文章详情的 NestJS 业务流程而是通过 CDN 获取节点缓存未命中时CDN 再向 OSS 或源站回源。浏览器 ↓ DNS ↓ CDN ↓ OSS / 源站这两条链路相互配合动态 API 保证内容和权限正确静态资源链路保证图片、脚本等高效交付。它们不是谁取代谁而是在不同类型的请求上各司其职。总结从地址栏输入域名到页面呈现内容是一条由多个组件接力完成的路径。DNS 将好记的名称转换为可访问地址TCP 与 TLS 让通信通道可靠且安全Nginx 提供统一入口并将流量代理、分配给健康的 NestJS 实例NestJS 承载鉴权、校验和业务规则MySQL 保存长期业务事实Redis 缓解热点访问OSS 存放大体积对象CDN 通过边缘缓存加速静态资源。掌握这种边界感比孤立记住某个组件的命令更重要当请求出现异常或性能下降时可以顺着链路分层定位也能在系统增长时有针对性地扩展。DNS域名 → IP Nginx代理 负载均衡 NestJS业务逻辑 MySQL持久化业务数据 Redis缓存和高速数据 OSS存对象 CDN加速静态资源访问
返回列表