从输入网址到看见博客——我的网络基础设施全揭秘

经常有同学问我:“你的博客是怎么搭的?”“为什么输入域名就能访问?”“你本地写的文章怎么发布到网上?”

这篇文章用跟随一个真实请求的旅程的方式,把这些问题的答案一次性说清楚。


第 1 章:前置知识——三种"地址" {#basics}

在正式开始 "跟着请求走" 之前,我们需要先认识四个基础概念。这些概念就像是网络世界的 "路牌" 和 "门牌号",理解它们之后,后面每一站的故事你都能轻松看懂。

IP 地址 = 互联网上的门牌号

你家有门牌号,快递员才能找到你;在互联网上,每一台联网的设备也有一个独一无二的 "门牌号"——IP 地址。它的样子像这样:192.168.5.8(我的 NAS)或者 101.133.128.193(我的阿里云服务器),由四组数字组成,中间用点隔开。

无论是你的手机、电脑,还是远在千里之外的云服务器,只要连上网,就会有一个 IP 地址。有了这个地址,别人的电脑才能知道把数据发到哪儿去——就像快递小哥看着门牌号,才能准确地把包裹送到你家门口。

公网 IP vs 内网 IP —— 城市街道和小区楼号的区别

然而,并不是所有的 "门牌号" 外面的人都能找到。

公网 IP 就像城市里的街道地址——比如 "北京市海淀区中关村大街 1 号",全世界的人都知道这是什么位置,任何人都可以按这个地址找过来。阿里云、腾讯云这些云服务器给你分配的就是公网 IP。

内网 IP 就不一样了。它更像是小区内部的楼号——“3 号楼 2 单元 501”。你小区里的人当然能找到你,但小区外面的人拿着 "3 号楼" 这个地址就傻眼了,因为他根本不知道是哪个小区的 3 号楼。你家里的电脑、NAS、手机,连 WiFi 时拿到的都是内网 IP(一般以 192.168.x.x 开头)。

核心矛盾就在这里:你的博客跑在家里的电脑上,它的 "门牌号" 是内网 IP。外面的人拿着这个地址,找不到你的小区在哪里。这就是我们后面要重点解决的问题。

域名 + DNS = 手机通讯录

现在我们已经有了 "门牌号" 的概念,但问题又来了——没人能记住一串数字。你会记住所有亲朋好友的电话号码吗?当然不会。你打开手机通讯录,看到 "妈妈",点一下,手机自动拨出 138xxxx1234

在互联网上,DNS(域名系统) 扮演的就是这个 "通讯录" 的角色。你在浏览器里输入 blog.liuhangyv.top 这样一个好记的名字(这叫域名),DNS 会帮你查通讯录,然后告诉你:“这个域名对应的 IP 地址是 101.133.128.193,去找他吧。”

整个过程你完全无感——和你在通讯录里点 "妈妈" 一样,根本不用关心背后的号码是多少。

端口 —— 同一栋楼的不同房间门

一台服务器(一个 IP 地址)上往往跑着几十个不同的服务:博客、Git 仓库、管理面板、数据库……浏览器怎么知道你找的是哪个服务?

这就需要一个额外的标识——端口号。如果说 IP 是楼号,那端口就是这栋楼里不同的房间门号。举个例子,同一台阿里云服务器上:

  • **HTTPS(网页)**用 443 号门
  • Git SSH222 号门
  • 管理面板8090 号门

当你访问 https://blog.liuhangyv.top 时,浏览器默认就去敲 443 这个门——这是网页服务的 "固定房间号"。

但问题再次浮现:家庭网络中,运营商的宽带不仅给你的是内网 IP,还默认把大部分端口都锁死了。你连 "开门" 的资格都没有,外面的人再怎么能敲门也进不来。


总结一下:别人的浏览器想访问你电脑上的应用,必须知道两样东西——你在互联网上的门牌号(公网 IP)+ 你开了哪个房间门(端口)。而大多数人家里的电脑只有内网 IP——这就是后面要解决的问题。


第 2 章:第一站——DNS 把域名变成 IP {#dns}

好了,前置知识已经就位。现在让我们化身小明,真的在浏览器地址栏里敲下 blog.liuhangyv.top,然后按下回车——亲自走一遍第一个环节。


小明在浏览器地址栏输入了 blog.liuhangyv.top,敲下回车。

浏览器看了一眼这个地址,心想:“blog.liuhangyv.top……这是一个域名,人类认得,但我只认 IP 地址。”

就像你在手机上点 "妈妈",手机必须先去通讯录里查出那串电话号码才能拨号一样——浏览器也需要先去查 "通讯录"。这一步,就是第 1 章里讲过的 DNS

浏览器转身去问 DNS 服务器:“你好,请帮我查一下,blog.liuhangyv.top 这个域名对应的 IP 是多少?”

DNS 服务器翻了翻记录,很快给出回答:“找到了,它的 IP 是 101.133.128.193。这是阿里云上的一台服务器,去吧。”

整个过程快到小明完全无感——从敲下回车到拿到 IP 地址,通常只需要几十毫秒。

不止一个域名指向这里

如果你接着问 DNS:" 那 lhy-git.liuhangyv.top 呢?" 它给你同一个答案:101.133.128.193

再问 gitea.liuhangyv.top 呢?还是 101.133.128.193

没错——我的博客、个人 Git 仓库、协会 Git 仓库,三个域名,全部指向同一台阿里云服务器。同一个门牌号,同一栋楼。

拿到地址,出发

浏览器现在有目标了。既然小明访问的是 https://blog.liuhangyv.top,浏览器就直奔这个 IP 的 443 端口——也就是 HTTPS 网页服务的 "标准房门号"。

它敲敲门:“你好,101.133.128.193 的 443 号房,我想看 blog.liuhangyv.top 的网页。”

但这里浮现出一个有意思的问题:三个域名都指向同一个 IP、同一个 443 端口,服务器收到请求后,怎么知道小明到底想看博客、Git 仓库,还是别的什么?

这个悬念,我们留给下一章揭晓。


第 3 章:第二站——OpenResty 按域名分流 {#reverse-proxy}

上一章留了一个悬念:三个域名都指向同一个 IP、同一个 443 端口,服务器怎么知道小明到底想看什么?

答案就在这里揭晓。阿里云服务器上跑着一个叫 OpenResty 的软件,它扮演的角色,用一句话就能说清楚:写字楼的前台

想象一下这个场景——小明走进一栋写字楼(阿里云服务器),大楼里有很多家公司:一家博客公司、一家 Git 仓库公司、一家管理面板公司。但小明手里只有写字楼的统一地址(IP),没有具体公司名称。他走到一楼前台,前台姑娘问他:“您好,您找谁?”

小明说:“我找 blog.liuhangyv.top。”

前台查了一下登记表:"好的,blog 公司在这边,请跟我来。" 然后把他带到了正确的房间。

这就是 OpenResty 每天在做的事情——它就是这个 "前台"。

Host 头部:前台凭什么知道你找谁?

你可能会问:小明没有亲口说 "blog.liuhangyv.top" 啊?他只是输入了这个网址然后按了回车。前台是怎么听到这个信息的?

答案是——每个 HTTP 请求的 "头顶" 上,都死死地贴着一个标签,上面写着请求的域名。这个标签叫 Host 头部字段。当小明的浏览器向 101.133.128.193:443 发送请求时,请求包里就带着一句话:

“Host: blog.liuhangyv.top”

哪怕三个域名的请求都走到同一台服务器,OpenResty 看一眼这个 Host,立刻就知道:哦,你是来找 blog 的;你是来找 lhy-git 的;你是来找 gitea 的。

然后,它按照预先设定好的分流规则,把访客带到各自对应的目的地。这个过程在技术上就叫反向代理——浏览器是 "正向" 地发请求,而 OpenResty 站在服务器的立场 "反向" 地把请求分发给内部真正的服务。

真实的"登记表"

打开我的 OpenResty 配置,它的分流规则大概长这样(简化版):

# 博客 → 转发到腾讯云的 Halo(端口 8090)
if ($host = "blog.liuhangyv.top") {
    转发("http://127.0.0.1:8090");
}

# 个人 Git → 转发到腾讯云的 Gitea(端口 3000)
if ($host = "lhy-git.liuhangyv.top") {
    转发("http://127.0.0.1:3000");
}

# 协会 Git → 转发到阿里云本地的 Gitea(端口 3000)
if ($host = "gitea.liuhangyv.top") {
    转发("http://127.0.0.1:3001");
}

你看,前两条规则里有 "转发到腾讯云"——这不是打错字了。博客和 Git 仓库虽然域名解析到了阿里云,但真正的后端服务其实是跑在另一台腾讯云的服务器上。阿里云这边只是负责 "接客",接完客再通过一条秘密通道把请求送过去——这条秘密通道就是下一章的主角 FRP 隧道

一张嘴喂饱三个服务

到这里,反向代理的核心价值就一目了然了:

你只需要一台服务器、一个公网 IP,就能在外面挂上几十个不同的域名,每个域名背后连接不同的服务。 不需要给每个网站单独买一台云服务器——写字楼一栋就够了,前台会帮你把客人带到对的房间。

小明现在已经顺利来到了 "前台" 面前。对于 blog 和 lhy-git 的请求,前台要做的事不是直接带到楼上的房间,而是——走一条秘密通道,把请求送到千里之外的腾讯云。这条通道是怎么挖通的?我们进入下一章。


第 4 章:第三站——FRP 隧道穿透内网 {#frp}

等等——你可能会问:“腾讯云不是也有公网 IP 吗?为什么不让用户直接访问腾讯云,还要经阿里云绕一圈?”

好问题。事实上,腾讯云确实有自己的公网 IP(124.221.93.161),技术上完全可以让 DNS 直接把 blog.liuhangyv.top 指向腾讯云,省略阿里云这个中间环节。

那为什么我没有这样做?三个理由:

第一,统一入口。 我的所有域名——博客、个人 Git、协会 Git——只需要指向一个 IP(阿里云),就像所有快递只需送到一栋写字楼。如果哪天我在腾讯云上新加了一个服务,不需要去改 DNS 记录,也不用等 DNS 全球生效——在 OpenResty 里加一行转发规则就够了,秒级生效。

第二,SSL 证书统一管理。 HTTPS 需要 SSL 证书来加密通信。如果每个服务都直接暴露公网,我得在每台服务器上分别配置证书、分别续期。而把 OpenResty 放在阿里云做统一入口,我只需要在一处管理所有域名的证书——OpenResty 自动帮你完成 HTTPS 加密和续期,省心省力。

第三,安全隔离。 腾讯云上的 Halo 博客和 Gitea 仓库,它们的服务端口(8090、3000)并不直接暴露在公网上。外人访问这些服务的唯一路径,就是先到阿里云的 OpenResty 前台,再通过一条加密隧道中转过去。没有隧道的另一端,就算你知道腾讯云的公网 IP,敲这些端口也没人应门。

这第三条,引出了本章真正的主角——FRP 隧道

FRP 的工作原理:总机接线员 + 内部电话

要理解 FRP,最好的比喻是一栋写字楼的电话系统:

FRP 服务端(frps 跑在阿里云上,它就像写字楼一楼前台的总机接线员。所有外面打来的电话,第一个接起来的一定是它。

FRP 客户端(frpc 跑在腾讯云上,它就像藏在各个房间里的内部电话。它的工作方式很特别——不是被动地等着前台呼叫,而是主动打电话给前台报到:“喂,总机你好,我是腾讯云上的 Halo 博客,我在这边 8090 号房间,如果有人来找博客,麻烦帮我转过来。”

这条报到电话一旦接通,就变成了一条持续保持的长连接——客户端和总机之间始终有一条话线通着。外部访客(比如小明的浏览器)来到写字楼前台,告诉总机 "我要找 blog.liuhangyv.top"→ 总机看了一眼登记表 → 通过那条已经保持着的内部电话线,把请求转发到腾讯云上对应的房间。

从外面的角度看,整栋楼只有一个入口(阿里云),一个前台(OpenResty),一个总机(frps)。但实际上,这栋楼的地下连着一条秘密隧道,直通另一栋楼(腾讯云)的内部房间。外人完全看不到这条隧道的存在,更不知道后面还藏着另一个数据中心。

一句金句总结

FRP 就是在两台服务器之间打了一条加密隧道,让藏在腾讯云上的服务能被阿里云上的请求访问到。你可以把它想象成一根只有你自己知道的水管——外面的人只看到阿里云,但水管的另一头连着腾讯云。

补充:你的本地电脑呢?

聪明的你可能会想到另一个问题:“你肯定是在本地电脑上写文章的对吧?那你本地电脑是不是也要装 FRP,也要有公网 IP?”

完全不需要。

我写这篇文章用的是 Obsidian 编辑器,搭配一个自己写的 Halo 发布插件。当我写完之后,在 Obsidian 里点一下 "发布",插件直接通过 HTTPS API 把文章内容发到 https://blog.liuhangyv.top——和普通读者访问博客走的是同一条路。请求先到阿里云 OpenResty,再通过 FRP 隧道转到腾讯云的 Halo 服务,Halo 收到文章后存进数据库。

我的 Windows 电脑既没有公网 IP,也没有装任何 FRP 客户端——它只是这条管道另一端的一个 "普通访客" 而已。


到这里,小明从输入网址到看见博客的完整旅程已经全部走完了。DNS → OpenResty → FRP → Halo,四个环节环环相扣。但读到这里你可能会觉得有点晕——这么多台服务器,这么多条隧道,它们之间到底是什么关系?最后这一章,我们用一张全景图把所有东西串起来。


第 5 章:全景回顾——一张图说清楚 {#overview}

好了,我们从第 1 章一路走到了第 4 章,每一站都讲清楚了。现在让我们退后一步,用三个层次把整件事印进脑子里。

一句话走完全程

把小明从输入网址到看见博客的完整链路,用一句话就能说完:

小明输入 blog.liuhangyv.top 回车 → DNS 告诉浏览器去 101.133.128.193 → 阿里云 OpenResty 前台看了一眼 Host 头部,发现是博客域名 → 通过 FRP 加密隧道转发请求 → 腾讯云上的 Halo 收到请求、渲染博客页面 → 原路返回小明浏览器,小明看到博客。

这一秒不到的旅程里,数据跑过了三座城市(本地浏览器、阿里云杭州、腾讯云广州)、穿过了两条加密隧道、被四个软件组件接力传递——而你全程只需要输入一个域名。


全景架构图

用一张 ASCII 图把所有主角画出来:

                    👤 你的同学 / 朋友
               输入 blog.liuhangyv.top
                         │
                   ① DNS 解析(域名 → IP)
                         │
                         ▼
         ☁️ 阿里云 101.133.128.193(唯一对外入口)
   ┌─────────────────────────────────────────┐
   │     OpenResty(反向代理 / 写字楼前台)     │
   │                                         │
   │  blog.liuhangyv.top     ──→  FRP 隧道 →  腾讯云 Halo
   │  lhy-git.liuhangyv.top  ──→  FRP 隧道 →  腾讯云 Gitea
   │  gitea.liuhangyv.top    ──→  本地转发 →  协会 Gitea
   │                                         │
   │     frps(FRP 服务端 / 总机接线员)        │
   └────────────┬────────────────────────────┘
                │ ② FRP 加密隧道
                ▼
         ☁️ 腾讯云 124.221.93.161
   ┌─────────────────────────────────────────┐
   │  frpc(FRP 客户端 / 内部电话)            │
   │  📝 Halo 博客 :8090                     │
   │  📦 Gitea 个人仓库 :3000                 │
   └─────────────────────────────────────────┘

   💻 本地 Windows(Obsidian + 发布插件)
      → 通过 HTTPS API 发布文章
      → 和普通读者走同一条路

给想自己搭建的同学

如果你也想让别人访问你电脑上的应用,你只需要这四样东西:

  1. 一个域名 — 让你有一个好记的名字,不用每次说 IP 地址。几十块钱一年,建议去 Cloudflare 或腾讯云买。
  2. 一台云服务器 — 作为对外入口。阿里云、腾讯云、AWS 都可以——我选择阿里云的原因是网络稳定,低配学生价一年不到一百块。
  3. 一个反向代理 — 让一台服务器能服务多个域名。Nginx、OpenResty、Caddy 都可以。OpenResty 本质上就是 Nginx 的超集,配置逻辑完全一样。
  4. 一个 FRP 隧道 — 如果你不想把服务直接放在公网服务器上,或者有两台服务器需要打通。开源免费,GitHub 上直接下载,配置十几行就搞定。

这四样东西配齐之后,你的电脑就不再是一座孤岛。全世界任何一个浏览器,都能通过你精心铺设的这条数据高速公路,敲开你的门。

下次有人问你 "你博客咋搭的",你就把这篇丢给他 😄