从只懂 A 记录,到重新理解 DNS:普通解析、泛域名和证书验证

最近在折腾 frp、Caddy、内网穿透和域名分流的时候,我突然发现一个问题:

我以前对 DNS 的理解其实挺片面的。

以前我理解 DNS,大概就是:

域名 -> IP

比如:

weini.xin -> 服务器 IP
www.weini.xin -> 服务器 IP

也就是说,我过去主要只知道 A 记录

A 记录确实是 DNS 里最常见、最直观的一种记录,但这次深入折腾之后,我发现 DNS 远不只是“域名转 IP”这么简单。

它其实同时参与了:

域名寻址
服务入口命名
泛域名管理
证书验证
权属证明
公网入口治理

这次算是对 DNS 的理解上了一层楼。


一、我以前理解的 DNS:域名指向 IP

最普通的 DNS 使用方式,就是添加一条 A 记录。

比如:

abc.weini.xin A 123.123.123.123

意思是:

访问 abc.weini.xin 的时候,去 123.123.123.123 这台服务器

这就是最常见的 DNS 解析。

如果我在浏览器访问:

http://abc.weini.xin

大概流程是:

浏览器要访问 abc.weini.xin
        ↓
查询 DNS
        ↓
DNS 返回 123.123.123.123
        ↓
浏览器连接这台服务器

这个过程很好理解。

所以我以前一直觉得:

DNS 不就是把域名解析成 IP 吗?

这个理解没错,但只是 DNS 的第一层。


二、普通 DNS 解析:一个名字对应一个目标

普通解析通常是这种形式:

abc.weini.xin -> 服务器 IP
api.weini.xin -> 服务器 IP
www.weini.xin -> 服务器 IP

也就是你每需要一个明确的域名,就添加一条记录。

比如:

abc.weini.xin A 123.123.123.123
api.weini.xin A 123.123.123.123
www.weini.xin A 123.123.123.123

这很好理解,也很适合正式服务。

比如:

weini.xin       主站
www.weini.xin   主站
api.weini.xin   正式 API
blog.weini.xin  博客

这些域名比较稳定,单独配置 A 记录完全没问题。

但是如果我有很多开发服务、测试服务、临时服务,就会变麻烦。

比如:

mcp.dev.weini.xin
api.dev.weini.xin
demo.dev.weini.xin
ghost-test.dev.weini.xin
test-api.dev.weini.xin

如果每一个都手动添加 DNS 记录,会很烦。

这时候就引出了泛域名解析。


三、泛域名解析:一次配置,覆盖一批子域名

泛域名解析就是:

*.dev.weini.xin A 123.123.123.123

它的意思是:

所有 xxx.dev.weini.xin 都解析到 123.123.123.123

比如:

mcp.dev.weini.xin
api.dev.weini.xin
demo.dev.weini.xin
abc.dev.weini.xin
anything.dev.weini.xin

这些都会自动解析到同一台服务器。

这个体验非常爽。

以前新增一个服务,我要想:

我要不要去 DNS 控制台加一条记录?
我要不要配置新域名?
我要不要记住这个端口?

有了泛域名之后,我只要提前配置:

*.dev.weini.xin A 服务器 IP
*.test.weini.xin A 服务器 IP

后面所有开发和测试服务都可以直接挂进去。

比如:

mcp.dev.weini.xin
api.dev.weini.xin
demo.test.weini.xin
client-a.test.weini.xin

DNS 层不用再改。

这个时候我第一次明显感觉到:

DNS 不只是域名解析,它还能帮我规划服务入口的命名空间。


四、普通解析和泛域名解析的区别

普通解析更像是:

我明确指定某一个名字去哪

比如:

api.weini.xin -> 123.123.123.123

泛域名解析更像是:

我指定一整片名字都去哪

比如:

*.dev.weini.xin -> 123.123.123.123

对比一下:

普通解析:
api.weini.xin
www.weini.xin
blog.weini.xin
每个名字单独配置

泛域名解析:
*.dev.weini.xin
*.test.weini.xin
一整片子域名统一配置

所以我现在更倾向于这样规划:

weini.xin              正式主站
www.weini.xin          正式入口
api.weini.xin          正式 API,单独配置

*.dev.weini.xin        开发服务,泛域名
*.test.weini.xin       测试服务,泛域名

这样既不会污染主域名空间,又能让开发测试环境足够灵活。

这个分层我觉得很重要:

一级子域名留给正式服务
二级命名空间留给开发测试

也就是说,不一定要直接搞:

*.weini.xin

因为这会让所有一级子域名都进入泛解析范围,比如:

mail.weini.xin
admin.weini.xin
cdn.weini.xin
random.weini.xin

这有点太大了。

更稳的是:

*.dev.weini.xin
*.test.weini.xin

这样边界更清晰。


五、DNS 只负责“找到服务器”,不负责“服务分流”

这是这次很重要的一个认知。

比如我配置了:

*.dev.weini.xin A 123.123.123.123

那么:

mcp.dev.weini.xin
api.dev.weini.xin
demo.dev.weini.xin

都会到同一台服务器。

但是 DNS 只负责把它们都带到服务器。

它不负责判断:

mcp.dev.weini.xin 应该去 8120
api.dev.weini.xin 应该去 8122
demo.dev.weini.xin 应该去 8080

这个分流不是 DNS 做的。

真正分流的是服务器上的 Caddy、Nginx,或者 frp 的 HTTP Host 分流。

比如 Caddy 可以根据 Host 头判断:

Host: mcp.dev.weini.xin -> 转发到服务 A
Host: api.dev.weini.xin -> 转发到服务 B
Host: demo.dev.weini.xin -> 转发到服务 C

所以这句话很关键:

DNS 负责让请求找到服务器,Caddy/frp 负责让请求找到具体服务。

这也是我之前容易混的地方。


六、A 记录和 TXT 记录:一个负责 IP,一个负责字符串

这次还有一个很大的收获,就是理解了 TXT 记录。

以前我只熟悉 A 记录:

abc.weini.xin A 123.123.123.123

A 记录返回的是 IP。

但 TXT 记录返回的是一段字符串。

比如:

_acme-challenge.dev.weini.xin TXT "abcdefg"

它不是告诉浏览器访问哪台服务器。

它只是说:

_acme-challenge.dev.weini.xin 这个 DNS 名字下面,有一段文本 abcdefg

也就是说:

A 记录:某个名字 -> IP 地址
TXT 记录:某个名字 -> 一段字符串

这让我突然意识到,DNS 不只是能返回 IP。

它还能公开地返回各种信息。

比如 TXT 记录经常用于:

证书验证
域名所有权验证
邮箱 SPF
DKIM
DMARC
各种平台的域名认证

这一下我对 DNS 的理解就打开了。


七、普通 HTTPS 证书是怎么验证的?

以前我只知道 Caddy 可以自动申请 HTTPS 证书。

但我没认真想过:

证书机构凭什么相信这个域名是我的?

普通证书的验证方式大概是这样。

比如我要申请:

abc.weini.xin

的证书。

前提是 DNS 里有:

abc.weini.xin A 123.123.123.123

然后 Caddy 向证书机构申请证书。

证书机构会给 Caddy 一个随机字符串,比如:

xyz987

然后要求 Caddy 在这个地址返回它:

http://abc.weini.xin/.well-known/acme-challenge/某个路径

接着证书机构自己访问这个 URL。

访问过程是:

证书机构访问 abc.weini.xin
        ↓
DNS 把 abc.weini.xin 解析到服务器 IP
        ↓
请求到达 Caddy
        ↓
Caddy 返回刚刚那个随机字符串
        ↓
证书机构确认字符串正确
        ↓
签发证书

所以普通证书的关键不是:

证书机构看 A 记录里的 IP 是不是对的

而是:

证书机构通过 DNS 找到你的服务器,然后看你的服务器能不能返回正确验证码

换句话说:

普通证书验证的是:你能控制这个具体域名当前指向的 Web 服务。

DNS 在这里负责带路。

Caddy 在 HTTP 响应里交验证码。

证书机构负责检查验证码对不对。


八、通配证书是怎么验证的?

通配证书就不一样了。

比如我要申请:

*.dev.weini.xin

这张证书可以覆盖:

mcp.dev.weini.xin
api.dev.weini.xin
demo.dev.weini.xin
anything.dev.weini.xin

但是问题来了:

证书机构没法访问:

http://*.dev.weini.xin/.well-known/acme-challenge/xxx

因为 * 不是一个具体的域名。

它代表无限多个可能的子域名。

所以通配证书不能用普通 HTTP 路径验证。

它需要 DNS 验证。

流程大概是:

Caddy 申请 *.dev.weini.xin 通配证书
        ↓
证书机构生成一个随机字符串,比如 abcdefg
        ↓
证书机构要求添加:
_acme-challenge.dev.weini.xin TXT "abcdefg"
        ↓
Caddy 或者人手动去 DNS 里添加这条 TXT
        ↓
证书机构查询 DNS
        ↓
发现 TXT 里的字符串和自己给的一样
        ↓
证明你能控制 dev.weini.xin 这片 DNS
        ↓
签发 *.dev.weini.xin 通配证书

所以通配证书验证的是:

你能控制这个域名的 DNS。

不是验证某一台服务器。

这点很关键。


九、为什么 TXT 记录不能自己永久写死?

一开始我有个疑问:

既然通配证书需要:

_acme-challenge.dev.weini.xin TXT "某个字符串"

那我自己在阿里云 DNS 里写一个固定字符串,不就完了吗?

后来才理解,这个不行。

因为这个字符串不是我自己定的。

它是证书机构每次临时生成的随机验证码。

这就像短信验证码。

网站让你输入:

839201

你不能说:

我自己设一个 123456,以后你都认这个不就行了吗?

不行。

因为验证码必须是对方临时出的。

证书验证也是一样。

这次申请时,证书机构可能要求:

_acme-challenge.dev.weini.xin TXT "abc123"

下次续期时,可能变成:

_acme-challenge.dev.weini.xin TXT "xyz789"

它不是永久固定值。

所以手动添加 TXT 可以完成一次申请,但以后续期时还得再改。

这就是为什么通配证书要想自动续期,Caddy 需要 DNS 服务商的 API 权限。


十、阿里云 API Key 不是为了 DDNS,而是为了自动改 TXT 验证

这里也容易误会。

一开始听到 Caddy 需要阿里云 API Key,我下意识以为:

这不是变成 DDNS 了吗?我不是已经有 *.dev.weini.xin 泛解析了吗?

后来才明白不是一回事。

我已经配置好的:

*.dev.weini.xin A 服务器 IP

负责的是流量入口。

它可以长期固定。

而 Caddy 需要 DNS API,是为了在申请或续期通配证书时,自动创建或更新:

_acme-challenge.dev.weini.xin TXT "本次随机值"

也就是说,API Key 不是为了新增:

mcp.dev.weini.xin
api.dev.weini.xin
demo.dev.weini.xin

这些业务域名已经由泛解析覆盖了。

API Key 只是为了自动完成证书机构要求的 TXT 验证。

可以这么理解:

*.dev.weini.xin A 记录:
长期固定,负责所有 dev 子域名流量进入服务器

_acme-challenge.dev.weini.xin TXT 记录:
临时变化,负责通配证书申请和续期验证

这是两件完全不同的事。


十一、普通证书和通配证书的核心区别

现在我终于能把这两个东西分清楚了。

普通证书:

申请对象:abc.weini.xin
验证方式:HTTP 验证
验证内容:服务器能不能返回正确验证码
证明的是:你能控制这个具体域名对应的 Web 服务

通配证书:

申请对象:*.dev.weini.xin
验证方式:DNS TXT 验证
验证内容:DNS 里能不能写入正确验证码
证明的是:你能控制这个域名的 DNS

一句话总结:

普通证书:
DNS 负责带路,Caddy 在 HTTP 里交验证码。

通配证书:
不访问具体服务器,直接用 DNS TXT 交验证码。

这下就清楚了。


十二、结合 frp 和 Caddy 后,DNS 的价值一下子变大了

这次之所以对 DNS 有新理解,是因为它和 frp、Caddy 结合起来之后,价值变得很明显。

我的目标是:

内网服务很多
每个服务有自己的端口
我想通过公网域名访问它们
但不想每次都开端口、改 DNS、登录服务器

最开始的方式是:

公网服务器:18120 -> 内网服务:8120
公网服务器:18122 -> 内网服务:8122

这能用,但端口多了很乱。

后来改成:

mcp.dev.weini.xin -> Caddy -> frp -> 内网服务
api.dev.weini.xin -> Caddy -> frp -> 内网服务

再加上泛域名:

*.dev.weini.xin -> 公网服务器
*.test.weini.xin -> 公网服务器

DNS 这一层就变成了服务入口命名空间。

之后如果再配合 Caddy 通配入口和 frp HTTP Host 分流,就可以做到:

DNS 不用改
Caddy 不用改
安全组不用开新端口
新增服务只改 frpc

这个体验就非常优雅。


十三、我现在对 DNS 的新理解

以前我理解 DNS 是:

DNS = 域名转 IP

现在我觉得更准确的是:

DNS = 互联网服务的命名、寻址、验证和治理系统

A 记录解决:

这个名字应该去哪个 IP?

泛域名解决:

这一整片名字都应该去哪里?

TXT 记录解决:

这个名字下面公开声明了什么字符串?

证书验证利用 TXT 记录解决:

你是否真的控制这个域名?

Caddy 和 frp 利用 Host 解决:

这个请求到了服务器后,应该交给哪个服务?

所以整个链路变成:

DNS:负责名字和入口
证书机构:负责信任验证
Caddy:负责 HTTPS 和网关入口
frp:负责把请求带回内网服务
业务服务:只负责自己的功能

这比单纯“域名指向 IP”的理解要完整很多。


十四、这次最大的收获

这次最大的收获不是学会了怎么添加一条 TXT 记录,也不是学会了泛域名怎么配。

而是理解了:

DNS 不只是访问入口,也是信任体系的一部分。

普通访问时,DNS 负责告诉用户去哪里。

申请证书时,DNS 还可以用来证明你是不是有资格拥有这个域名。

尤其是通配证书:

*.dev.weini.xin

它不是靠访问某一台服务器来验证,而是靠 DNS TXT 来证明你控制整个命名空间。

这个认知对我很重要。

以前我只知道 A 记录。

现在至少我知道了:

A 记录:负责寻址
泛域名:负责批量命名空间
TXT 记录:负责字符串信息和验证
普通证书:HTTP 验证
通配证书:DNS TXT 验证

这次算是真正从“会配 DNS”往“理解 DNS”走了一步。

Read more

Mac 上 Skill CLI 无法执行的坑:最后其实一条命令就够了

我在做 Amazon skills 的过程中,逐步把本地 CLI 从 Python 脚本切到 Go 二进制。这样做的好处很明显:用户不用装 Python、不用配依赖,解压 skill 后直接运行。但在 macOS 上,我们反复遇到一个看起来很玄的问题:同一个二进制,在 Linux/Windows 上正常,在 Mac 上就是执行不了。 当时遇到的现象 常见报错大概有几类: * 双击或 agent 调用 CLI 时,系统提示文件来自未知开发者,无法打开。 * 终端里执行时提示 Permission denied。 * 已经 chmod +x 了,仍然被 macOS 拦截。 * Apple

By ladydd

当我把全世界人群的基因 PCA 跑出来后,看见了一个倒 L 型

最近我把之前学的一些分子人类学知识,终于真正落地了。 不是停留在看论文、看别人画图、看别人解释“人群结构”这些概念,而是自己把数据处理完,自己跑 PCA,自己把全世界不同人群放到一张图上。 然后那一刻,我真的被击中了。 图上出现了一个非常漂亮的倒 L 型。 一端是非洲,另一端逐渐拉向东亚,中间有中东、欧洲、南亚、欧亚大陆上的各种过渡人群。它不是那种随机散点图,而是有方向、有骨架、有历史感的结构。 我第一眼看到的时候,脑子里直接冒出一句话: 这不像是一张普通统计图,这像是人类迁徙史在二维空间里留下的影子。 当然,后来我也提醒自己,PCA 不能被过度浪漫化。它不是地图,也不是时间轴,更不是“谁从哪里走到哪里”的直接证据。PCA 本质上是把高维基因差异压缩到几个主成分上,用最大方差方向把样本摊开。它可以帮助我们观察人群结构、相似性、分化和混合,但不能单独承担全部历史解释。PCA 在群体遗传学里常用于观察 population structure

By ladydd

吞吐与延迟:一个厨房比喻讲透性能压测

写于 2026-06-26。背景: MCP 服务 跑在 3 台 ClickHouse(每台 16 核 / 64G,1 分片 3 副本)上。 我们花了一整轮做公网压测,把这套系统的极限、天花板和杠杆全摸清了。这篇把"吞吐 / 延迟 / 排队"这三个最容易混的概念讲透,配我们自己的真实实测数据。 一句话结论 我们这套系统的吞吐天花板 ≈ 76 req/s。 往里塞再多并发(100、200、300、500),每秒"做完"的还是大约 76 个,多出来的全在排队。系统不会崩,只会让每个人等得更久。 天花板能不能抬?

By ladydd

四卡 3090 本地模型部署复盘:Ollama 跑通 35B,以及 GPU0 掉卡问题

这次做的是一轮真实的本地模型部署摸底。 目标不是搭一个临时 Demo,而是把一台四卡 3090 GPU 机器接进自己的日常 AI 使用环境:本机跑 Open WebUI,负责账号、会话和前端配置;GPU 机器只负责模型推理。这样以后换模型、换推理框架、重启服务,都尽量不影响本机的使用入口。 最后结论比较清楚:qwen3.5:35b 的 GGUF Q4_K_M 量化版已经通过 Ollama 跑通,本机 Open WebUI 可以接入,热加载后的聊天速度也能用;但 GPU0 存在明显稳定性问题,重启后能短暂恢复,跑过负载后又会掉到 NVML 异常状态。 状态快照 当前能用的部分: * 本机 Open WebUI 已部署,

By ladydd
陕公网安备61011302002223号 | 陕ICP备2025083092号