2026-10-20 08:00:00
不用社交媒体的一个尴尬之处是这样的内容不知该往哪里放。前几天写的,在那个当下我觉得它们有趣,可其实我又不希望这样的文本长久存档在博客。Anyway,辛苦写了就还是发吧,大不了以后再删!
2026-10-20 08:00:00
来解决堆积的大量草稿,放弃详细写了。第一百次发誓,这个月度记录的模式真的要改,投入产出过于不均衡。
要是只给文字评分,估计只能 2.5 星,更何况真的有必要出一本书吗?一篇长报道就足够了。
我以为重点在抑郁症,可实际落点却是卖蛋糕。作者确实是抑郁症患者没错可对抑郁症的科学解释简直错得离谱。另外他的生意起步靠的岳母的蛋糕方子,甚至最开始完全是岳母付出劳动,最后作者的书后致谢列了一堆人名还包括大大表扬了自己,唯独没有岳母,这是否有点荒谬?
50% 弃。这么说显得我很冷酷,可是我不喜欢只让我反复咀嚼痛苦的书。
两星。
会读这本书是因为标题切中我心,而且会让我想起非常喜欢的《当我们点起火把》这个现场,开头说「这首歌关于一个庆祝,庆祝什么呢,庆祝我们的遗憾。此时此刻我们是被我们过往所有的经历堆叠而成的,包括艰难的时刻,所以让我们点起火把」。
但内容实在差劲。
狗屁鸡汤,用名人名言和一堆成功学事例把整本书填充起来,告诉你,这是在庆祝我们的失败。实质上庆祝的是什么呢?是失败过然而最终都取得世俗意义上成功的那些人。重点还是──他们的失败成就了成功。
还有拿来当做「成功」的例子也根本毫无说服力。
哦,乔布斯的伟大和成功是因为他之前失败了很多次,甚至被赶出了自己的公司;谷歌的伟大是因为谷歌失败了很多次,包括不吝啬承认失败──砍掉了 Google 眼镜,砍掉了 Google Reader 等等产品。
Come on!乔布斯反正在我这里永远算不上伟大和成功。至于 Google Reader 才不是失败好吗,杀死 Google Reader 才是 Google 真正的失败!杀死这些产品并不能证明谷歌的任何成功,更不值得任何庆祝!
以及另外一堆商业成就大大值得商榷的人,我都快被气笑了,这作者到底有没有点基本经济学和商业常识?是随便搜了几个人名就开始瞎写吗?
我不太喜欢,刻薄一点说的话,是段子上长出了本书,而这段子还不那么好笑。
我想读到的是,在历史和当下,真的涉及到人兽冲突时法律上是如何解决的。可这本书更像是作者搜罗了一堆荒谬示例然后用非常自我的方式描述它们,重点是作者的反应。作者的观察、作者的幽默、作者的冒险是整本书的中心。
而我不喜欢这种写法。
另外只是潦草翻完依然看到一堆翻译问题,brushtail possum 不是负鼠,更离谱的是 possum Merino 直接被翻成羊毛,只看上下文都知道这根本不通啊。
很普通,内容和我的期待有些偏离。原以为是分析日本低欲望社会的形成,没想到整本书是作者对安倍政府经济和政治政策的控诉。大量日本执政细节我真的毫不关心!
另外就是和大量日本人一样,作者对美国和北欧模式有异乎寻常的崇拜,而那其实许多都还值得商榷。
完全忘了为什么这本书会进入我的待读仓库。一个我完全不认识的什么人,写的对论语、老庄的再读感想。
主题确实是我有兴趣的,可是作者的解读太个人和太碎片化,不建议对孔子、老子、庄子一无所知的人读,会一头雾水加极其容易被作者带偏。随便看看吧,也算一种他山之石。
潮间带物种科普。
各章节之间没什么联系,介绍得也比较泛泛,只是这些描述的对象被讨论得太少,它们的外观、行为模式都十分新奇,配图也十分详尽,因此看起来还算有趣。
另外我不喜欢的一点是作者过于喜欢拿各种食物做比喻,太影响未来的食欲了。
四小时野外白噪音再加 Robert Macfarlane 的前言和 Jackie Morris 的采访然后就凑成了一本 audiobook 实在有点过分了吧?而且居然还要卖 15 刀?多亏我是 Libby 免费听的。
介绍发明了世界上第一个水族箱的女性。因为想更近、更久地观察海洋生物而设计出了水族箱,最后还解开了 argonauts 章鱼之谜。
PS 这种章鱼非常非常有意思,但展开讲实在是太费事儿了,有兴趣可自行查阅。


南极小百科。
在 Libby 借的电子版,字儿和图都实在是太密盯得我眼睛都快瞎了最后打开 accessibility 里的放大镜功能看完的。
和人有关的部分(比如探险队历史或者现今的考察队在南极吃啥用啥)我兴趣平平不想认真看字,扫完就算。动物部分有些很有意思,比如 giant squid 和 colossal squid 字面上都是「大」鱿鱼,但其实是两个完全不同的物种。



关于风的简单科普。很直观地用画面展示各种风力下环境的变化。深度不如之前读的另一本科普绘本 I Am Wind: An Autobiography,而图像虽然不差,可也没有辨识度。随便翻翻吧。

试图将诗歌形式介绍和太阳系星体科普结合的绘本。倒是也能说得通,每一个星体都用了不同的诗歌形式,但是诗歌本身写得并不那么出彩。

一本关于微小宇宙的摄影集。下图截自作者官网。至于详细内容我实在写不动了!看上面的简介吧(破罐破摔)。

之前读 Hello Lighthouse 还挺喜欢作者的风格,就顺便找来她另一本绘本读了。
一个小男孩和一只「negative」的猫咪的故事。
另外很惊喜的联动是提到了两本我读过的关于猫的绘本,2023 十一月读书记录 # Millions of Cats 和 2025 三月读书记录(一) # They All Saw a Cat 。


2026-10-13 08:00:00
作为十几年的重度 RSS 用户,使用伊始就留意到时不时有些文章会被重复推送,而某些站点还会几十上百篇旧文刷屏,被这么烦过几次我甚至会怒而取关。
等到自己也写博客,就额外注意不要出推送事故,但初期我只意识到是博文链接变动导致的,当时我的方法是如果改了文件名(Hugo 生成的 URL 也会随之变动),就对新文件加 rss_ignore 来避免内容重复。这带来的潜在问题是,之前推送的文章链接已经不存在了,从 RSS 跳转原站会 404。
最近买了域名涉及到了 Hugo 的 baseurl 变动和旧地址 vercel.app 301 redirect,个中详情不再赘述,但总之就是突然让我发现 RSS 的识别机制好像不是我原以为那样。
大概研究了下,各类 RSS 阅读器判定是否为新文章并不是靠文章链接而是靠识别参数。
TL;DR:让识别参数
guid不再依赖 URL,改用一串固定的自定义字符串;只对新文章启用,旧文保持原样。
Hugo 内置的
RSS Template,item 部分是 RSS 条目生成规则。看里面的组成,title 文章标题,link 文章链接,而 guid 才是识别参数,但它默认的是 {{ . Permalink }},导致的问题就是一旦 URL 有任何变动,RSS 阅读器就会认定这是未读内容再推送一次。
<item>
<title>{{ .Title }}</title>
<link>{{ .Permalink }}</link>
<pubDate>{{ .PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
{{- with $authorEmail }}<author>{{ . }}{{ with $authorName }} ({{ . }}){{ end }}</author>{{ end }}
<guid>{{ .Permalink }}</guid>
<description>{{ .Summary | transform.XMLEscape | safeHTML }}</description>
</item>
最根本的方案是把 guid 和 permalink 解耦。但问题在于,直接修改 Hugo 的 RSS 模版 guid 语法会导致之前的文章重新生成 guid,旧文会被再推送一遍。因此这个方法最好是在新建站还没有 RSS 输出时就使用。
而对于已经有文章的站点,首先,限制 RSS 输出条目数量,这样即使错误操作也不会刷屏得太过厉害。
在 Hugo 配置文件里加上(以 config.toml 为例,数值按需调整):
[services.rss]
limit = 10
早期版本使用顶层的
rssLimit,新版本已改为services.rss.limit,请以所用版本的文档为准。
接下来就是打补丁,三步走。补丁的关键在于:只对新文章启用自定义 guid,旧文没有 rss_guid 参数,仍然沿用 .Permalink,所以它们的 guid 不变,不会被重推。
guid 组成方式guid 并不要求一定是链接,而只是一串识别字符,重点是要唯一和固定。这篇文章
Be Unique And Use RSS Guid Like Everybody Else 介绍得挺清楚,也提供了一个 guid 的组成方案 TAG URI scheme,包含五个元素:
示例:
<guid isPermaLink="false">tag:rssboard.org,2006:weblog.217</guid>
我用的是站名+ filename + 时间戳(具体到秒)的组合,也几乎不可能出现重复了。这并不严格遵循 TAG URI 格式,但满足“唯一且固定”这两个核心要求。另外,guid 中含空格并不违反规范,但个别阅读器对空格的处理可能不一致,追求稳妥的话可以换成连字符或下划线。
Hugo 的 RSS 模版一般位于 /layouts/_default/index.xml,改文件的 guid 部分即可。(Hugo 版本不同模板目录结构有调整,旧路径可能不再适用,请以所用版本的文档为准。)
我的变动:
<guid isPermaLink="{{ if .Params.rss_guid }}false{{ else }}true{{ end }}">{{ if .Params.rss_guid }}{{ .Params.rss_guid }}{{ else }}{{ .Permalink }}{{ end }}</guid>
作用是,如果文章有自定义 rss_guid 参数就用它作为 RSS 的唯一标识,否则默认使用文章的 URL(.Permalink)作为 guid。
rss_guid 生成方式这一步取决于如何生成新的 markdown 文件。要是愿意完全手打也可以。
我所有博客内容都在 Obsidian 里生成,因此靠 Obsidian template 功能实现。
开启 Obsidian Settings -> Core Plugins -> Templates 功能并设定存放模版的文件夹。
新建一个 blog-template.md 文件,放入上一步的文件夹内。
内容供参考,重点看 rss_guid 部分。
---
title:
date: {{date}}
draft: true
tags:
categories:
rss_ignore: false
abstract: false
hide: false
rss_guid: "WanderingMargins {{title}} {{date:YYYYMMDDHHmmss}}"
---
其中 Obsidian 模板里的 {{title}} 取的是文件名(即 filename,不含扩展名),而不是 front matter 里的 title(比如我这篇的 markdown 文件是 how-to-avoid-duplicate-rss-entries.md);{{date}} 默认只到日,所以 rss_guid 里单独用 {{date:YYYYMMDDHHmmss}} 精确到秒。
在新文章里插入 blog-template 模版 (用 Ctrl + P 打开命令面板或自行绑定 hot key),以本篇为例,插入后的内容:
---
title:
date: 2026-10-10
draft: true
tags:
categories:
rss_ignore: false
abstract: false
hide: false
rss_guid: "WanderingMargins how-to-avoid-duplicate-rss-entries 20261010193503"
---
这样所有新文章都有 guid 参数而不依赖于 URL。
注意:模板只应在新建文章时插入一次。 rss_guid 在插入的那一刻就固定了,之后无论怎么改文件名、改链接都不会变;但如果重新插入模板,就会生成新的时间戳,也就是新的 guid,文章会再被推送一次。
如果想让旧文也摆脱 URL 的影响,可以给它们补上 rss_guid,值必须与它当前 guid 完全一致(即阅读器已经记录的那个 URL,包括协议、域名、末尾斜杠),这样阅读器看到的 guid 没有变化,就不会重推。之后即使 URL 再变,guid 也保持不动。建议先挑一两篇旧文,用上面的方法验证无误后再批量处理。
2026-10-08 08:00:00
简单来说,在写了快六年这个博客后,我终于买了域名。
原来的网址是随手打的,用了很喜欢的 wandering albatross + 自己的英文名凑出了站名,之后一直觉得把名字(哪怕是个英文名)挂在首页和 URL 里有点尴尬,可我又是个取名废就懒得换。加上不确定自己到底会写多久,买域名这件事就也一直搁置。
而最近莫名地非常想在网上花钱,和,vercel.app 持续在 Google 搜索结果里表现不佳,终于下定决心买了。
博客的新地址是
https://blog.wanderingmargins.fyi,RSS 也相应变成了
https://blog.wanderingmargins.fyi/rss.xml。之前用过的 github.io 和 vercel.app 我都设置了 301 redirect,用旧链接访问或在 RSS 阅读器里订阅暂时也不会有什么问题,但方便的话还是烦请有我友链或通过 RSS 阅读的朋友们更新一下地址。
还是取名苦手,就依然保留了 wandering 这个词。顶级域名看来看去,不太想要看上去太过正经的 .com、.net 或 .org 之类,.top、.icu、.xyz 则是又被滥用得太过厉害,最后挑中了这个不算太常见的 .fyi。私心里觉着它第一眼看起来很像 “fly”,和 wandering 倒也搭配。
只要不疯狂涨价我应该会留着它很久。希望再也不用烦域名的事儿了。
PS,标题有点文不对题,但是我脑子里第一时间蹦出的就是这个书名,不管了!
2026-10-02 08:00:00
九月阅读记录非常好写因为压根没看书!沉迷于其他罪恶且不健康的活动不可自拔。
非常可爱的关于云的科普。和之前读的 Cloud Spotting 以及 空气之海漫游指南 里的知识点也全关联起来了(不过这两本,我全部都还拖着没写记录……)。
此外也是看绘本才意识到,雨天和暴风雨前云之所以那么黑沉沉,是因为云里水滴数量浓度过大,阳光在云层顶部已经被大量散射和吸收,无法穿透云层到达底部,从地球上看云,就显得黑乎乎。明明是很简单的原理,居然之前从没认真想过!


有点年头的绘本,讲爱书和囤书成癖的主人公家中被书淹没,最后把书捐给社区建成了一个公共图书馆的故事。
不过,这个美国故事里却出现了 Eurasian Blue Tit(一个典型的欧亚物种)──没办法,观鸟人的关注点。
用某个洞穴里的钟乳石和石笋视角讲地球历史。
钟乳石和石笋在漫长的时间里极其缓慢地生长着,好像时间是停滞的,但不同的洞穴来客们却又不断暗示时间的尺度。尤其对地球生物演化历史有一定了解的话,从中辨认不同阶段也是极其有趣的。
下面的画面,我觉得还可以命名为《彗星(好吧其实是小行星)来的那一夜》。

久违地看了 BL 小说。由头是前阵子短暂上头了一个十八线明星,刷混剪时有评论说非常想让他去演张淮——就是入戏这本小说的主角,没控制住我的好奇就读了。
这本书在豆瓣评分相当高,我承认作者的意图是完成了,成功地让读者分不清究竟哪个是戏内还是戏外,可人物实在塑造的糟糕,几乎每一章都是色情戏,关系和感情全部靠肉贴肉完成,我觉得这并不能让我信服。
最后我甚至产生了无比的疲倦——究竟做到什么时候才能是个头?肉多到令人起腻,看不到人物只看见色欲。
在没有心力看书但又想看点东西的时候我就选择自然绘本,比看纪录片耗费时间少得多。
这本介绍了 bottlenose dolphin baby 时期的一些行为,内容挺浅,画面像是水粉,色彩和光晕很漂亮,还是令人愉悦的。

看上面的 NeoDB 简介吧。
评价是一面倒的好,图也确实极尽精美和科学,然而──几乎没有像样的文字解释,对我这种大幅依赖文字的人非常不友好。所以最后只是翻完了图片就当读完了。
2026-10-01 08:00:00
极简 Vultr + Hysteria2 + Clash Verge 搭建记录。连命令行都不需要打,顺利的话二十分钟不到就可以完成。得到的是一个可以在 Clash Verge 中使用的私人节点。
具体这些东西是什么也不在本篇解释范围内,若需要了解请自行检索。
注册 Vultr 账号,充值。
从侧边栏进入 Network → Firewall Groups 或访问
Firewall Groups 创建新的 Firewall Group。

添加规则:
Protocol: UDP
Port: 443
Source: 0.0.0.0/0
从侧边栏进入 Orchestration → Startup Scripts 或直接访问
Startup Scripts 创建新的 Boot Script。

Startup Script 会在 VPS 第一次启动时自动执行,用于自动安装和配置软件。
Config PASSWORD="password1234" 部分建议使用大小写字母、数字、特殊符号混合的随机密码,例如 PASSWORD="X7!kP9@v2Lm"。
完整脚本见下方。
#!/bin/bash
set -e
sleep 10
# ==================== config ====================
PASSWORD="password1234"
LISTEN_PORT="443"
MASQUERADE_URL="https://www.bing.com"
CERT_DAYS="365"
HY_VERSION="v2.12.3"
# ============================================================
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} Hysteria ${HY_VERSION} VPN Server Installation ${NC}"
echo -e "${GREEN} ${NC}"
echo -e "${GREEN}========================================${NC}"
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}Error: Please run this script as root user (sudo ./script.sh)${NC}"
exit 1
fi
echo -e "${YELLOW}[1/7] Updating system and installing dependencies...${NC}"
apt update -qq
apt install -y -qq wget curl openssl ufw
echo -e "${YELLOW}[2/7] Creating directory structure...${NC}"
mkdir -p /etc/hysteria /etc/ssl/hysteria
echo -e "${YELLOW}[3/7] Generating SSL certificate (valid for ${CERT_DAYS} days)...${NC}"
openssl req -x509 -newkey rsa:4096 -nodes \
-keyout /etc/ssl/hysteria/key.pem \
-out /etc/ssl/hysteria/cert.pem \
-days ${CERT_DAYS} \
-subj "/CN=www.bing.com"
chmod 644 /etc/ssl/hysteria/key.pem
chmod 644 /etc/ssl/hysteria/cert.pem
echo -e "${GREEN} Certificate permissions set to 644${NC}"
echo -e "${YELLOW}[4/7] Creating configuration file /etc/hysteria/config.yaml ...${NC}"
cat > /etc/hysteria/config.yaml << YAML
listen: :${LISTEN_PORT}
tls:
cert: /etc/ssl/hysteria/cert.pem
key: /etc/ssl/hysteria/key.pem
auth:
type: password
password: ${PASSWORD}
masquerade:
type: proxy
proxy:
url: ${MASQUERADE_URL}
rewriteHost: true
quic:
initStreamReceiveWindow: 8388608
maxStreamReceiveWindow: 8388608
initConnReceiveWindow: 20971520
maxConnReceiveWindow: 20971520
YAML
echo -e "${YELLOW}[5/7] Installing Hysteria ${HY_VERSION} using official script...${NC}"
bash <(curl -fsSL https://get.hy2.sh/) --version ${HY_VERSION}
echo -e "${YELLOW}[6/7] Configuring firewall (ufw)...${NC}"
ufw allow ${LISTEN_PORT}/udp
echo -e "${GREEN}UDP ${LISTEN_PORT} port has been allowed${NC}"
echo -e "${YELLOW}[7/7] Restarting Hysteria service and applying configuration...${NC}"
systemctl stop hysteria-server || true
systemctl start hysteria-server
systemctl enable hysteria-server
sleep 3
if systemctl is-active --quiet hysteria-server; then
SERVER_IP=$(curl -s ifconfig.me)
echo -e "\n${GREEN}========================================${NC}"
echo -e "${GREEN} Hysteria deployment completed successfully!${NC}"
echo -e "${GREEN}========================================${NC}"
echo -e "${YELLOW}Service status:${NC}$(systemctl status hysteria-server --no-pager | grep "Active:")"
echo -e "${YELLOW}Port listening status:${NC}"
ss -tulnp | grep ":${LISTEN_PORT}" | grep -v grep || echo " Waiting for port to listen..."
echo ""
echo -e "${GREEN}Client connection information:${NC}"
echo -e " Server address: ${SERVER_IP}:${LISTEN_PORT}"
echo -e " Protocol: Hysteria ${HY_VERSION}"
echo ""
echo -e "${YELLOW}Common management commands:${NC}"
echo -e " Check status: systemctl status hysteria-server"
echo -e " View logs: journalctl -u hysteria-server -f"
echo -e " Restart service: systemctl restart hysteria-server"
echo -e " Stop service: systemctl stop hysteria-server"
else
echo -e "${RED}Service failed to start! Check error logs:${NC}"
journalctl -u hysteria-server -n 20 --no-pager
exit 1
fi
这个是为了在自己电脑远程连接 VPS 更方便和安全,不是必须,但加上最好。
进入 Orchestration → SSH Keys 或
SSH Keys 添加 SSH Key。
在 Vultr Deploy 页面创建新 instance。

我这里选的是能用的套餐里最便宜的一档,Shared CPU,vc 2-1 c-0.5 gb, New York, US (AMER)。
几个注意点:
Image Version 就选默认的 Debian。接着在 Server Settings 里下拉添加上一步创建好的 Firewall Group,Startup Script,SSH(如有)。点击 Deploy 开始创建。

创建完成后等待安装,通常几分钟内完成。在 dashboard 看到 instance 的状态是 running 就说明安装好了。
可以在 Clash 的 GitHub 仓库下载最新版本软件。
在本地新建一个 config.yaml 文件,内容如下。
如果想要分流效果,比如大陆网站直连、海外网站走代理,可以去网上搜其他人的配置教程,我一向是全局模式,就省掉了规则集配置。
proxies:
- name: "VPS-Hysteria2"
type: hysteria2
server: Your-VPS-IPv4-Address
port: 443
password: "password1234"
sni: www.bing.com
skip-cert-verify: true
up: "20 Mbps"
down: "50 Mbps"
修改 server 为 VPS IPv4 地址(可在 Vultr dashboard 里查看),修改 password 为 Startup Script 中设置的密码。
在 Clash Verge 里选中 Profiles→ New→ Local→ CHOOSE FILE,选择上一步创建的 config.yaml 即可启用配置。连接成功就可以在 Clash Verge 中看到 VPS-Hysteria2 节点。

如果有多个设备,不希望每次复制 config.yaml 文件,可以生成一个订阅 URL,例如 https://xxxxx.workers.dev/token,Clash Verge,Clash Meta 手机端都可以直接通过 URL 更新配置。
创建 worker,具体代码:
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname !== "/" + env.SUB_TOKEN) {
return new Response("Not Found", {
status: 404
});
}
const config = `
proxies:
- name: NewYork-Vultr
type: hysteria2
server: ${env.SERVER}
port: 443
password: ${env.HY_PASSWORD}
sni: www.bing.com
skip-cert-verify: true
up: "20 Mbps"
down: "50 Mbps"
`;
return new Response(config, {
headers: {
"Content-Type": "text/yaml; charset=utf-8"
}
});
}
};
(我这里的 config 配置依然是省去了分流规则,有此需求的话请自行添加。)
接着在 Worker settings 里添加 variables。
| Key | Value |
|---|---|
| SERVER | VPS IP |
| HY_PASSWORD | Hysteria 密码 |
| SUB_TOKEN | 自行设定 Token |

完成之后就可以像市面上的机场一样通过 URL 订阅。假设 token 是 dg867dsgjklSH,订阅地址就是 https://xxxxx.username.workers.dev/dg867dsgjklSH。
以后如果换机房(IP 密码有变更),只要去 worker 设置里把 SERVER 和 HY_PASSWORD 的值变更即可,而不需要再写一遍 config.yaml 和重复配置。
用个人 VPS 搭建节点的优点是固定公网 IP,不会像商业 VPN 或者机场一样和大量用户共用 IP,访问 Gemini、ChatGPT 和 Claude 更稳定,也不太会触发各类验证。
而限制是只有个人服务器,没有多节点可切换,在流量高峰期可能出现网速缓慢或短暂断联。能否访问网络也取决于 IP 机房和 IP 本身,如果不可访问,可以在 Vultr 里换新 IP。
另外 Vultr 机房 IP 有个很离奇的 bug 是不能访问 Google Play Books 里自行上传的书籍──网页端能看到文字但看不到图,App 里则是用户自有图书全部无法下载。我查看了下发现都指向了一个特定的 CDN 地址,和 Play Books 里 Google 出售书籍不一样。所以如果是重度 Google Play Books 用户(比如我),还必须另备个梯子。