2023-01-02 00:47:14
这一年我经历了很多,看到听到的更多。工作生活都没什么大的变化,但心情总是很差。21 年没有做合格的年终总结,23 年不一定会有总结,但 2022 这魔幻的一年不能没有一份详实的年度回顾记录。
《晚点 LatePost》在「中国十二大互联网公司年终盘点」一文中有这样一段话:
中国的互联网行业集体进入了一个新阶段 —— 不再寄望于无穷尽的增长,而是确保自己能在停止增长之后,通过提高管理和经营效率取得更高的利润。
这简直是对我 2022 工作体验的完美概括。过于关注局部的数据指标、外行领导内行盛行、向上管理几乎成了政治正确,即使没被裁员和降薪,我也要被迫体验到这些中高层老板从冲量到盈利过渡期对工作方向「艰难探索」所带来的副作用。不巧的是这些都是我所厌恶的东西,以至于时不时地我就会怀疑自己的工作到底能带来什么价值,全年可以说是毫无工作乐趣。而这令人沮丧的工作氛围也耗尽了我开拓副业的热情,甚至几度让我没了发言交流的欲望,如果你发现我几天都没在 Twitter 上瞎侃,那大概率我又因为工作的原因而怀疑人生了。
在工作内容方面,今年我的角色承担了更多的管理责任,一如《卓有成效的管理者》一书所言:
管理者的时间往往只属于别人,不属于自己。
无穷无尽的会议、代码及方案审核和各种花式汇报文档的编写,再加上前面所说的「艰难探索」带来的各种自上而下的奇葩指示中有不少还需要我来推动或落地,让我很少有时间能静下心来写代码。而又由于我对本组的项目实在过于熟悉,在架构和技术方案的设计上又很难遇到什么新的挑战,所以也谈不上什么技术成长。总体而言这一年我的时间和人基本是被事情推着走,所谓的管理大多也只是做了些顺水推舟的事情,好在有一些技术和业务层面的决策还算有少许价值,不然真可谓是在工作层面碌碌无为了一整年。
在主业之外,今年的内容和副业产出少得可怜。首先没能达成 21 年所设想的本年参与开源工作的目标,连小玩具都没动手做。其次博客也只写了三篇文章(把Notion变为个人网站、再见Hexo——从Hexo迁移至Hugo和旁路由的原理与配置一文通),虽然从搜索引擎排名情况来看文章质量应该还算可以,但三篇这个数量着实是太少了,而且基本都是我所熟悉的舒适区,可以概括为没有持续地用心写作。
最过分的是,Newsletter 被我鸽了一整年没更,鸽到平台 Revue 都倒闭了,实在是对不住 21 年以来订阅的这几十位读者了。不过下半年运营了下 Telegram Channel 并获得了一些关注,感谢各位的厚爱,这个应该不会再鸽了(吧)。Twitter 倒是说了不少话,涨了一点关注,但好像也没产出多少有价值的内容,惭愧惭愧。
从 21 年年末的西安封城开始,我的心情就一直很差。其中原因,一方面是我对同胞受苦的不忍,另一方面则是对方舱隔离和宠物无害化处理的恐惧。这一切愤恨、恐惧和绝望都在 22 年的年末戛然而止,我也不出意外地在放开后感染上了新冠病毒发了两天烧。
回看这一荒诞的一年,上海封城的乱象让我对其管理水平之低下有了新的认识,戾气日长的日常生活也让我看到了底层互害的可怕。我练出了进门前随手打开健康宝的扫码反射,也习惯了调低期望居家工作的生活。这些记忆既是历史的现身说法,也是对我认知的宝贵教训。我在自己的 Obsidian 知识库中整理了由新闻、图片和感想组成的 2022 清零防疫笔记图谱,以后每年都会翻出来看一看,提醒自己不要忘记这沉痛的一年中发生的骇人的事情。
由于电影院几乎歇菜了一整年,再加上我心情不好和工作内卷,这一年看的影视剧大部分都是以前看过内容的二刷、三刷,其中又以老港片为主。这些内容有情怀加持,剧情和桥段我又烂熟于心,看起来没有心理负担和理解成本,可以说是纯纯地摆烂了。
不过在状态好的时候我也延迟了几周到几月不等地看了一些热度比较高的新剧和新电影,这里列举下红黑榜。
不难看出,这又是我被 Netflix 「坑害」的一年,除了续集尚有些能保持水准,新剧有大量的平庸之作甚至烂片,电影就更差了。23 年真的要考虑换一家来订阅了。
今年读的书仍然是工具导向为主的技术或管理类书籍,而且数量不多,大多也是跳着读的,一般只有某几章是精读的,所以很难做出推荐和总结。不过在人文类书籍方面,22 年读的这本《午夜将至:核战边缘的肯尼迪、赫鲁晓夫与卡斯特罗》很有意思,联想今年国内的种种怪状和 21 年的一部我超爱的剧 Inside Job ,着实是让我重新审视了我对所谓高层的认知。
今年播客听得也少了很多,主力播客工具 Pocket Casts 的统计是 3days 9hours ,不过今年用有音转文功能的 Snipd 听了不少英文播客,所以这个统计有些失真。《忽左忽右》应该是我本年最爱的播客节目了,几乎每期必听,还会做很多的延伸阅读,新的一年要多多购买 JustPod 的周边产品和付费节目来做支持才行。
今年周杰伦听得少了很多,变得超级爱听伍佰的歌。以至于《再度重相逢》和《Last Dance》两首经典金曲在我的 Apple Music Replay 2022 中高居榜首,可见我的怀旧情绪有多高涨。我的年度歌曲是下面这两首:
年初时终于把《荒野大镖客2》的剧情通关了,好一部快意恩仇的西部史。是的你没看错,这样的大作我总是延迟几年才去玩,计划明年玩完《战神》。
今年机缘巧合间熬夜看了 CS:GO IEM 科隆总决赛,见证了 Faze Clan 的夺冠。后面又断断续续看了 Major 、Blast 等比赛,不得不说 CS:GO 比赛的观赏性是真的高。可惜入门和观赛门槛都挺高,所以国内外的人气都比较一般,这一点从与其他游戏的奖金池规模对比上也可见一斑。
题外话顺便聊两句足球。今年除了世界杯就没怎么看球,西甲和中超似乎都没看满整场的时候,欧冠由于巴萨早早出局也就看了个集锦。主队巴萨今年已经衰落成了标准的 1.5 流强队,并正在向二流继续滑坡,这几个赛季不因为杠杆和债务而破产或被私有化我就已经烧高香了,好在大连人今年终于不再在降级区苦苦挣扎了。足球在我生活中的比重越来越小,以前不理解我爸年轻时那么爱看球怎么中年之后就不太关注了,现在似乎逐渐领悟了一些。
今年的投资策略非常保守,股票、基金几乎完全不碰,更别提什么期货期权了。对这种经济下行状态下的认知不自信让我在今年变成了一个极端的风险厌恶者。
这样的好处是今年不仅没亏,而且还靠着美元升值和黄金价格波动取得了一些盈余。坏处是现在不抄底可能几年后肠子会悔青。不过我想这个时间点还是手握现金流更稳妥些,留得青山在不怕没柴烧,以后的悔就让以后的我品尝吧,不跟风不梭哈就不会破产。
我家小猫在 21 年做了个大手术,令人欣慰的是 22 年她活蹦乱跳瞎作了一整年什么事也没有,希望明年能继续作继续闹,铲屎官承受得起!
今年最大的成就可能就是把烟给戒掉了。我倒不是一个数年烟龄的老烟民,总计也就抽了两年左右,但后期随着工作和清零带来的沉闷心情,我的吸烟量达到了惊人的两包一天。Q4 在给自己重新灌输了一遍尼古丁不解决问题只会带来问题的理念后(其实就是《这本书能让你戒烟》一书的核心主旨),我趁着十一假期撑过了戒断反应的最高峰并彻底把烟戒掉了。
我的戒断反应主要集中在牙龈微痛和类似于醉氧的头晕,第一周还是挺难熬的,好在三周后就完全没有任何生理层面的不适和吸烟欲望了。不过,即使是在三个月后的今天,我也仍偶尔会产生想吸烟的情绪苗头。虽然比起戒烟时期,这些缺乏生理机制支撑的小火苗很容易就可以被扑灭,但我不知道这样的情况还会持续多久。所以尼古丁这类东西能不碰就不碰,不要迷信你所谓的意志力。
从下半年乌克兰变为优势方,到阿根廷在卡塔尔世界杯夺冠梅老板圆梦,再到清零政策的戛然而止,我的世界和生活似乎又有了些光明。我又想提起那句被说烂了的电影台词:
生活就像巧克力,你永远不知道下一颗是什么味道。
今年几乎所有的大件都是在春节期间买的,原因是那时还没对宏观经济情况的恶化作过多的思考。春节后就开始避免大额开销,非必要不购物了。所以比起 21 年,今年的购物清单算是寒酸了不少。
推荐指数:★★★★☆
买它是因为去环球影城前想到了在迪士尼乐园用手机录像的糟糕体验,就想购入一个更轻量的录像装备。在调研了 GoPro 、Insta360 和 DJI 的其它几款产品后,我最后选了这款没什么运动细胞、中规中矩的 Pocket 2 。除了价格不便宜、配件更贵外,整体能力很均衡,当然光线不佳时还是要用 iPhone 来补上。不过在去了一趟环球影城后因为封控的原因我就没再怎么出门游玩,希望明年可以让它发挥更大的价值吧。
推荐指数:★★★★☆
本想买了它再搭配 XGP 订阅能让我重新拾起玩游戏的心情,不曾想没玩几个 XGP 里的游戏,玩的时间最长的 FIFA 22 还是单独购买的,可谓是陪了夫人又折兵。不过对于喜欢宅在家玩主机游戏而家里又只有 1080P 电视的用户来说,Series S 绝对是最高性价比的选择,配合 XGP 整体的费用要比 NS 生态低不少。
推荐指数:★★★★★
没想到 2022 年了,小米贴牌在这类几百块价位的产品中仍然是性价比之选。简单、好看、小巧,不需要复杂的清洗。既然都喝胶囊咖啡了我想也就没必要追求各种咖啡机的高级功能了。
推荐指数:★★★★★
文石产品现在的文字渲染效果已经是一线水准了,今年用它搭配微信读书粗读了不少书。而作为曾经的 Kindle 用户,Android 系统之方便让我不禁怀疑此前我的 Kindle 吃灰是不是就是源自它封闭的生态而非我的问题(显然不是)。
推荐指数:★★★☆☆
可能是本年度最让我又爱又恨的一次购物选择。年初的时候,我手中那款做工极差的初代 AirPods Pro 又出现了各种奇怪的小毛病,忍无可忍的我在送修的同时,决定不再等待下半年大概率会出现的新款 AirPods Pro ,转投当时刚发布不久的 Beats Fit Pro 。说爱,是因为这款耳机完全没有 AirPods Pro 那些恼人的如单耳突然没声音、充不进电等问题,立体空间声等 AirPods Pro 有的功能它也都有,降噪能力我觉得也不输当时的同代产品。恨的是其通话能力很拉胯,那羸弱的麦克需要我保持静止才能较好地收音,再加上 Beats 产品发售即价格跳水的传统艺能,我很快就觉得它不香了。2023 年的各位如果想买新的入耳式降噪耳机,那还是考虑 AirPods Pro 2 吧。
推荐指数:★★★☆☆
买来替代我满身水渍的欧乐B牙刷,因为是便宜版本所以整体表现中规中矩吧。声音比欧乐B的安静不少,电量要更持久些,也没出现当年欧乐B把我牙龈刷出血的情况,无功无过的一次购物选择。分别使用过这两家的中低端产品后,我对于电动牙刷的购买建议是买个便宜的、电量持久的就行了,刷牙这件事情更重要的还是每天都刷且刷够时间。
在统计了我每年的软件和订阅开销上万后,去年的 flomo/秘塔写作猫/Bear/DigitalOcean Spaces 等产品的订阅都被我停掉了,替换为了免费产品或与其它平台型产品合并。这是一个开源节流的痛苦过程,但也是一个重新审视我真实软件需求的好机会。最后截至年末幸存的软件和服务清单如下。
服务 | 推荐指数 | 总结 |
---|---|---|
Apple Music 美区 | ★★★★☆ | 继续订阅的一年,只要 Spotify 不支持 Homepod 一天,我大概率就会一直订阅 |
Netflix | ★★☆☆☆ | 今年继续涨价+烂片更多,由于不怎么在电脑和 iPad 上看它了所以降级至了 1080P 版本,也算是省了点钱 |
Pocket Casts Plus | ★★★☆☆ | 继续订阅的一年,也继续没什么大的迭代。不过这家伙 23 年就要从 $9.99 涨价到 $14.99 了,加价不加量着实有些夸张,新的一年大概率是要被换掉了 |
iCloud 2TB | ★★★★★ | 今年拍猫的 4K 视频过多,以至于 200GB 版本已经不够用了,不得已只能升级到了 2TB 版本。好在 iCloud 的域名邮箱现在也勉强能用了,省了一笔 Google Workspace 的钱,正负得零,还算可以接受 |
Setapp | ★★★☆☆ | 这一年 Setapp 软件列表的扩充还是挺给力的,所以评价由去年的两星变为今年的三星。不过之前的优惠折扣结束了只能原价购买了,钱包有一点受伤 |
Grammarly | ★★★☆☆ | 因为几次偶然的正式英文使用场景头脑一热就订阅了一年。虽然功能还是挺好用的,但现在再看实在太冲动了,$12/month 的价格完全被我的低频使用浪费了,我想大部分在国内做代码开发工作的人可能都不需要订阅这款产品 |
TickTick | ★★★★☆ | 订阅了滴答清单的国际版用以替换 Microsoft To Do ,收集箱和四象限等接地气的功能大大缓解了我因堆积任务而产生的焦虑感,年末时我还用它替代了一众稍后读工具和随手记类型的笔记工具,这钱花得挺值 |
Craft | ★★★☆☆ | 受不了 Notion 的渲染和加载速度,再加上 Pro 版本支持使用 iCloud 存储才决定订阅这款 native 实现的笔记工具。然而重度使用后发现其对 CJK 的支持存在一些隐蔽的 Bug ,到了 Q4 加入 Setapp 的操作着实让我感觉交了两份钱。可能是本年度仅次于 Grammarly 的不值得订阅了 |
腾讯云香港轻量 VPS | ★★★★★ | 良心云今年风评不太良心,不过倒尚未影响我的使用,今年继续订阅 |
搬瓦工 SoftBank VPS | ★★★☆☆ | 今年莫名其妙被墙了一次,明年可能会改用中继方案而不再订阅了 |
Jetbrains 全家桶 | ★★★☆☆ | 去年忘记写这个收费大户了,今年依然继续订阅,不过新版本的卡顿问题比之前更严重了,评分一般 |
复制粘贴下上一年的个人 OKR ,把标题改成 23 年。内容变化不大,明年继续加油。
2022-08-15 12:43:11
「The all-in-one workspace」是 Notion 的自称,它肯定不是最优秀的笔记软件,但一定是当今最强大的内容生产工具之一。除了可玩性很高的数据库功能,Notion 还支持将页面对外公开,即可以通过简单地启用分享来获取到可在互联网上直接访问的链接。不过免费版不支持为被分享页面配置 SEO ,而且即使是付费版也尚未支持自定义域名。
如果想建立一个可高度自定义的个人网站,或希望把 Notion 的页面作为已有网站的附加内容,那就还是要基于 Notion 建立一个拥有独立域名、支持自定义设置的个人网站。本文就来聊聊基于 Notion 的个人网站有几样建法。
Notion 如今已经形成了生态,既然官方没提供完整的自定义个人网站方式,那各种 SaaS 产品就会补足市场的需求。当前已经出现了很多这类产品,通常是免费版提供另一个二级域名和自定义主题功能,付费订阅版才有自定义域名、支持 SEO 等高级功能。
这些产品的界面都很简洁,操作也简单易懂。以 Popsy 为例,选择新建站点:
最后填入站点名称和 Notion 页面的分享链接即可:
站点新建完成后,我们可以在左侧的导航栏里完成自定义设置,最后点击 Publish 完成发布即可。不过 Popsy 没有免费套餐,需要先在 Stripe 完成支付配置才可以试用 7 天。
SaaS 类产品的操作确实非常简单,功能上也可以满足用户大部分的自定义需求,很适合非技术人员或不愿意折腾的用户。唯一的缺点只有一个字,那就是「贵」,订阅价格通常在每月 $8~12 不等。贴几张不同产品价格功能表的截图,大家感受下:
除了付费产品,在流量不大时我们还可以借助 FaaS 产品的免费额度来实现建站。目前比较常见的思路分为 Cloudflare Workers 和 Vercel 两类,希望快速可用建议选 Workers ,打算通过开发来实现自定义的则可以使用 Vercel 方案。
这个方案的原理是通过 Workers 的转发和响应重写功能对 Notion 进行代理。由于这套逻辑大同小异,所以有网友开发了 Workers 代码的生成器。可视化界面的简单配置即可生成对应的代码,再拷贝到 Cloudflare Workers 中执行即可。
以最为著名的 Fruition 为例,我们首先完成 Step0 和 Step1 中的域名注册、Cloudflare 注册和 DNS 配置,随后在 Step2 中填写好期望的域名和 Notion 页面的分享链接,最后把生成的代码拷贝到新建的 Cloudflare Workers 函数中,再将该域名的路径设置为 Worker 的路由即可。官网的教程非常详细,按指导一步步执行即可。在 Step3 中我们可以做很多自定义工作,而由于该 Worker 的实现主要依赖重写响应,因此我们也可以对生成的代码进行深度修改以满足各种自定义需求。
不过我们从 Fruition 官网教程的截图也能看到,所使用的 Cloudflare 截图已经是改版前的页面了。无独有偶,该教程的细节也存在一些需要与时俱进的调整。在 Step1 的第 4 小节,教程中要求为目标域名添加 A 记录并将 IP 指向 1.1.1.1
:
If you don’t have any A records imported, add one with your root domain as the Name and 1.1.1.1 as the Content. Otherwise, click Continue on the DNS Record page.
但实际上如果你真的这样配置,那在当前的 Cloudflare 机制下会出现网页无法打开的问题。原因在于现在 Cloudflare 当前已经禁止了这种 DNS 配置方式,对应的 Workers 需要使用保留 IP 地址(Reserved address)比如 192.0.2.0
,CIDR 为 192.0.2.0/24
,这其后的技术细节以后可以展开讲讲。
其他基于 Cloudflare Workers 的方案和 Fruition 类似,区别只在于 Worker 中代码实现思路的不同。Cloudflare 作为良心企业,免费版 Worker 每天有 100k 请求的额度,对于绝大部分的基于 Notion 的个人网站来说是完全足够的。即使真的超过了额度,多加 $5 就可以多获得 100 倍的可用请求量,不可谓不划算。
缺点在于网上比较流行的几种 Worker 实现对 SEO 的支持都不算友好,也没有直接支持评论等功能,需要做比较多的二次开发才能满足较为复杂的需求。同时近年来 Cloudflare 的国际 CDN 在国内的访问速度越来越慢,有的地区甚至还会间歇性地无法访问,因此国内用户的使用体验可能会不太好。
既然是折腾和前端相关的东西,怎么能少了 Vercel 呢?比较著名的 Vercel 实现为 ijjk/notion-blog 项目。如果你熟悉 Vercel ,那基础配置比 Cloudflare Workers 方案要简单得多,只要找到 NOTION_TOKEN
和 BLOG_INDEX_ID
两个值(可以参考文档)就可以一键启动,然后再把实例绑定到期望的域名即可。
其实现机制和上文的 Cloudflare 方案差异较大,本质上是一个以 Notion 为数据库(直接访问 Notion 的内部 API )的基于 Next.js 的动态博客系统,这也是为什么该项目会要求相关 Notion 页面具备一个类似于其他博客系统的 front matter 配置即 table 用于记录元数据的原因。
虽然部署方式更简单了,但如果想做调整那就要对原项目进行修改。所以整体的自定义复杂度其实还是挺高的,更适合对前端项目有一定积累的用户使用。另外 Vercel 在国内的访问速度没比 Cloudflare 好多少,所以对于国内用户来说同样也可能会有体验问题。
如果手上已经有了一台 VPS 之类的机器,那我们还可以选择通过反向代理 Notion 的方式来复用已有机器自助建站。
以 Nginx 为例,我们首先要保证 Nginx 已经启用了 ngx_http_sub_module
模块,这个模块不一定是默认开启的,有可能会需要手动编译。该模块的主要作用为按配置修改代理后的响应内容。这一点至关重要,不然我们无法解决 Notion 原始响应中各类固定域名和响应字段,进而也就无法完成反向代理。
下面给出仅考虑可正常加载页面的最简单情况下 Nginx location 的配置,并对重点指令进行解释,自定义域名使用 example.foo
指代:
|
|
这类自定义反向代理方案的好处在于能复用已用机器资源,同时如果机器的网络比较优秀,还可以加速对 Notion 的访问,解决了上面几种方案在国内的尴尬使用体验。缺点是过于依赖 Notion 的前后端设计,Notion 如果做了大改动,那实现方式就需要重新探索。其实 Cloudflare Workers 方案也有这个问题,不过作为活跃的开源项目,Fruition 等的社区支持还是比较给力的。
笔记工具远没有持续输出重要。对于上述几个方案的选择,我的建议是没特殊需要就使用 Cloudflare Workers 实现,舍得花钱、想省事就选 SaaS 方案,愿意折腾、乐于折腾再考虑 Vercel 或 Nginx 方案。
2022-08-10 01:36:15
16 年的时候,博客使用的虚拟主机需要做迁移,当时所使用的 Typecho 是一个依赖于数据库的 PHP 博客系统,数据导出过程很艰辛。彼时 Gihub Pages 正大火,我也就跟风转投了静态博客系统 Hexo 。七年过去了,博客还在,但折腾 Hexo 的人是越来越少了。如今我也要和 Hexo 说声再见,拥抱 Hugo 的怀抱了。
在静态博客的同步和备份方案一文中,我分享了基于 Github 和 iCloud 的同步备份方案,期望在保证数据安全的同时,写作环境可以在我的两台电脑上无缝切换。
然而实际上,由于 Hexo 依赖于 Node.js ,庞大的 node_modules 并不能直接同步而是需要分别安装和更新,如果忘了运行 npm install -S
,那报错和渲染异常就是家常便饭的事。而 node-sass 这样的库还对 node 版本做了显式要求,导致如果哪台设备改了 nvm 中 node 的版本就会报错。但偏偏又有大量的主题和插件都依赖于 node-sass 。
而 Hugo 是基于 Golang 的二进制程序,安装和升级都很简单。由于内置功能足够多,插件(模块)不再是必需的了,如果有需要,其也都是通过 go mod 管理,轻量而简洁。虽然大部分主题仍然依赖于 Node.js ,但那只是创建和修改主题时的事情,不会影响到写作流程。
诚然,这并不能算作 Hexo 本身的问题,但由于底层的技术选型,导致 Hexo 必然和各类主题及插件的耦合较为严重。在三方组件实现和依赖复杂的情况下,整体的复杂度也就必然会成倍地上涨。
Hexo 裸安装后的网页生成速度并不算不可接受,和 Hugo 比起来也就几秒到十几秒的差异,没有网上传得那么夸张。但多加了几个像 hexo-all-minifier 这样生命周期靠后的插件后,生成速度确实会肉眼可见地下降。而 Hugo 的网页生成速度则非常稳定,总是保持在秒级别甚至毫秒级别,因此也可以真正意义上地实现本地实时预览。
Hugo 对 org-mode 、pandoc 等提供了原生支持,轻度使用体验也不错(深度使用也会遇到坑)。虽然 Hexo 等也可以通过安装插件和转换器等方式来实现,但这又会回到上面的依赖复杂的问题之中。此外,Hugo 的 shortcode 功能也非常强大,如果不考虑 md 文件的通用性,那结合 shortcodes 可以轻松实现很多本需要依赖于插件(模块)才能做到的功能。
首先安装 Hugo 并创建站点,以 macOS 系统为例:
|
|
这里需要注意的是,如果此前系统中已经安装过旧版本的 Go ,那有可能需要升级后才能使用 homebrew 完成安装。随后选一个喜欢的主题拉取到 /themes
目录,以 even 主题为例:
|
|
主题通常会带有示例配置文件 config.toml
,将其复制到站点的根目录下覆盖默认配置文件,并完成相应配置后,运行 hugo new post/test.md
新建文章,随后运行 hugo server -D
即可查看站点。对于存量的文章,需要将其复制到主题 /content/
目录下,其中文章类的需要按主题的设计来放置于具体目录,如 even 主题使用 post 目录,则需要将文章复制到 /content/posts
目录下,重新执行上面的命令就能在站点里看到文章了。
如果运行命令时报错,则可能是存量文章的 front matter 格式有不符合 Hugo 要求的情况,此时需要按官方文档进行修改适配。
整体写作习惯其实和 Hexo 的体验差别不大。不过 Hugo 提供了比 Hexo 更丰富的 front matter 默认配置,同时还支持 org-mode 等玩法,所以写作方式上的可玩性会更高些。
与 Hexo 主题的完全前端实现不同,Hugo 的主题使用了 Go 的模板语言,有点类似于 PHP 和 JSP ,并向主题暴露了一系列的全局变量和函数,所以其实主题和 Hugo 或 Golang 还是有一定的耦合的。
不过这也使得我们可以通过自定义模板覆盖主题默认模板的方式,来既实现自己的需求,又能最低限度地避免修改主题源代码导致的升级困难。但很多主题没有提供关键位置的钩子模板(也可以说是接口),导致我们经常需要拷贝一部分主题的源代码到自定义模板中,这又对主题的升级造成了一定的影响,可以说是有得必有失了。
迁移工作的一个核心要求就是尽量避免引入 breaking change 。首先要保证存量页面的链接不发生变化,以避免出现 404 的情况。其次要尽量对此前在 Hexo 中使用的各项功能进行支持。
在 Hexo 中,通常有以下三种 URL 永久链接路径格式:
/2021/07/06/a-better-hexo-theme-even/
/posts/slidev-tutorial/
/posts/8ccq01298/
而 Hugo 默认的永久链接格式为 /{{ 文章目录 }}/{{ 文章文件名 }}
,和上面第二种比较相似但又有所不同。那么我们该如何实现兼容呢?
首先我们要了解 Hugo 可以在根目录的 config.toml
中对永久链接进行自定义配置,例如:
|
|
因此我们只需要针对不同情况,对该配置进行自定义即可。
/:year/:month/:day/:title/
。/posts/:title
即可。 Hugo front matter 中的 slug
变量表示自定义别名,所以如果此前在 Hexo 使用了自定义的变量,只要仿照此前的配置将 title 改为 slug 即可,例如 /posts/:title
。archetypes/default.md
,再将其中的 slug 配置为一段具备哈希或 CRC 功能的表达式即可。不过存量文章可能需要通过 front-matter 中的 url
变量进行完整路径的显式声明,不然如果表达式的处理结果和 Hexo 中的不同,那链接可就变了。上面说明了 permalinks
的值,那 key 该如何配置呢?与 Hexo 不同,Hugo 中永久链接的固定前缀(对应上文的情况 2 和情况 3)是根据目录位置生成的,该位置的选择又与主题有关。有的主题使用的是 /content/post/
目录,有的主题使用的又是 /content/posts
目录,同时这个路径在很多主题的实现中是写死的。因此如果此前你在 Hexo 中所使用的固定前缀和所选 Hugo 主题的不同(如 /articles/
),那就会造成链接发生变化的问题。
所以我们需要在 permalinks
配置的 key 上做些文章,把主题所用的路径做一层指定映射,保证最终的路径以我们期望的前缀输出。以主题使用 /content/post/
作为内容目录、原 Hexo 文章的永久链接格式为 /posts/:slug
为例,对 permalinks
进行以下配置即可:
|
|
另外,对于此前在 Hexo 中配置了 html 后缀等情况,可以开启 Hugo 的 Ugly URLs 来实现兼容,细节可以参考官方文档。
前一节提到了主题对内容目录路径的选择可能是不同的,而这也会影响到归档页面的路径。在 Hugo 的大部分主题中,如果主题使用 /content/post/
作为内容目录,那归档页面路径则默认为 /post/
且不支持配置。而我们在 Hexo 中通常会使用 /archives/
作为归档页面的路径,如何才能保持不变呢?
虽然绝大部分主题(也可能是所有)都没有此项配置,但我们可以通过自定义一套模板和页面的方式来绕过主题的限制。以 even 主题的模板和 CSS 样式为例,在 /layouts/_default/
目录下新建 archives.html
模板,随后填充以下内容,用于按年分组遍历所有文章,并在原主题的框架下输出文章标题列表:
|
|
随后在 /content/
目录下新建 archives.md
页面,将 type
指定为刚刚定义的 archives
:
|
|
这时我们就已经可以通过访问 /archives/
路径来进入到归档页面了,接下来只要在 config.toml
中再将导航栏中的对应按钮指定为预期链接即可。
|
|
上文这种实现的效果和很多主题的归档页面相比,主要区别在于单页面内罗列了所有文章,即缺少分页。由于大部分主题的分页逻辑和其内部的其他模板耦合较为严重,同时 Hugo 的分页相关变量被限制不能用于自定义模板之中,所以如果希望自定义的归档页能支持分类,则可能需要对 Hugo 的原生逻辑进行包装即额外实现一套分页能力才行。这里不做展开讲述。
和 Hexo 一样,Hugo 也没有直接支持友情链接和自我介绍这类常用页面。在实现上我们要么在 /content/
目录下自定义页面也就是在页面内维护内容,要么如归档页面一般,通过自定义模板的方式来加载 config.toml
中的配置。两种实现都比较简单,我也更倾向于前者,毕竟这些是低频修改页面,是否可配置区别都不大。
在 Hexo 中,我们通常会在 _config.yml
中配置标签和分类的中英文映射,这样我们在 front matter 中可以使用任意语言标识标签和分类,但生成后两者的 URI 都是英文。然而在 Hugo 中却没有这类简易设置,也许我们可以通过修改主题和永久链接的方式来间接支持,但估计成本较高。所以如果对 URI 有强迫症的读者,还是建议把存量文章的标签和分类改为英文。而如果对此没有特殊需求,那使用中文也可。除了 URL 的分享可读性可能较差外,在 2022 年的今天其实已经不会影响搜索引擎的 SEO 效果了。
不知为何 Hugo 官方没有直接支持使用 Git 搭配 Git Hooks 部署站点,对于我这种把博客部署在 VPS 的用户给出的建议方案是 rsync 。其实 rsync 方案是完全可行且成本不高的,不过本着尽量兼容的原则我还是决定在部署时执行以下 shell 脚本来通过 Git 推送生成的 /public/
目录至 VPS ,而 VPS 上的 Git 库和 Git Hooks 配置则无需改动:
|
|
使用 Hexo 时博客的 RSS 是全文输出,而换到 Hugo 后 RSS 却变为了输出摘要。作为一个重度 RSS 用户,我自然是深知拉取到的文章还要二次跳转到浏览器才能看原文的体验有多差,所以还是要让 RSS 的表现和此前一致才行。
Hugo 的 RSS 是基于默认 RSS 模板生成的,所以我们只要重新定义一个模板并改为全文输出即可。Hugo 的默认实现中,决定输出内容的是如下这行代码:
|
|
我们只需要在 /layouts/
目录新建 index.rss.xml
覆盖默认模版并将原实现拷贝至其中,接着把代码中的 {{ .Summary | html }}
替换为代表全文内容的表达式 {{ .Content | html }}
即可:
|
|
由于此前一直在使用修改过的 Hexo even 主题,为保证前端效果不变,所以主题方面也采用了 Hugo 下的 even 主题,因此会有很多主题层面的额外适配工作。
此前使用 Hexo 下 even 主题时自定义了一个用于引导用户的导航栏,那么如何在 Hugo 的 even 主题中实现兼容呢?
首先我们在 /layouts/partials/header/
下新建 top-nav.html
模板,按需填充内容,如增加 Newsletter 、Telegram Channel 等引导:
|
|
随后我们需要找个位置引入该模板。受 even 主题实现的限制,我们需要将该模板放置于 header 块之后才能最低成本地保留原布局。因此我们只有一个选择,那就是将 baseof.html
这个基础模板进行覆盖。拷贝原模板内容至 /layouts/_default/baseof.html
中,并在 header
块之后、main
块之前引入此前定义的 top-nav.html
:
|
|
最后在 config.toml
中完成相关参数配置即可:
|
|
博客之前一直按「使用Nginx将请求转发至Google Analytics实现后端统计」一文的方式来实现请求统计。但这个方式的问题在于,由于不要求加载 JS ,很多非真实流量(主要为 RSS 阅读器的抓取)也会被统计进来。后来看到「搭建 umami 收集个人网站统计数据」这篇文章,便也用 umami 搭建了一个轻量的统计能力。
even 主题自然没有对 umami 进行原生支持,我们需要做的是先找到一个包含 head 的模版并在 <head/>
标签中添加以下内容:
|
|
然后在配置中完成定义即可:
|
|
由于 even 主题没有提供可以直接拓展 <head/>
标签的模板,我的选择是将代码加到此前不得不重写的 baseof.html
中。不得不说,这个实现很丑陋,但成本确实也是最低的。
此外,为了避免本地启动时 umami 将本地请求也进行了统计并将 Referrer 识别为 localhost ,上文的实现中对环境做了判断,即正式生成站点时才会引入 JS 依赖来上报 umami ,本地运行则不引入。
此前在 Hexo 的 even 下我也对文章末尾进行了自定义。对于 Hugo 的 even 主题,改造成本最低的方式为重写 /layouts/partials/post/copyright.html
模板。
首先要和此前展现形式对齐的是「原文链接」。even 主题本身只支持将 Markdown 原文件地址作为文章链接,所以我们需要在该模板中仿照 lionToMarkDown
部分添加以下内容:
|
|
因为暂时没有国际化需要所以文案是固定的中文,如果想更灵活些也可以仿照原实现中的 Markdown link 来做 i18n 。
随后只要在 copyright.html
的最后引入我们自定义的文末模板即可:
|
|
even 主题本身是支持 utterances 的,但用于生成 issue 的唯一标识参数被主题写死为了 issue-term="pathname"
即根据 URI 路径生成,并没有暴露配置。而我在使用 Hexo 时该参数的值是 issueTerm="title"
即根据文章标题生成,不进行适配的话会丢失存量评论。
所以我们需要在 /layouts/partials/
目录下新建 comments.html
覆盖主题原实现。顺便地,我们可以把另一个参数 label 也改为可配置的,这样一来,生成的 Github issues 便可以自动加上 utterances 标签方便分类:
|
|
随后我们便可以在 config.toml
中对 utterances 按需进行配置:
|
|
主题的社交图标使用的是托管于 iconfont 的私有实现所以直接拓展未支持的新图标较为困难。我在记hexo-theme-even主题优化一文中提到了相同的问题,文中最终选择了使用 Font Awesome 来解决,对于 Hugo 的 even 主题我们也如法炮制进行处理。
首先,在 Font Awesome 官网下载依赖并放置于 /static
目录下。例如我使用的是引入所有图标 JS 的方式,则最终路径为 /static/js/fontawesome.all.min.js
。然后在 config.toml
配置中引入该 JS 文件:
|
|
接着,我们在 /layouts/partials/
目录下新建 footer.html
覆盖主题原实现并保留原实现的其他代码,只对 social-links
部分进行如下修改:
|
|
最后在 config.toml
中添加需要的图标配置即可。icon
即图标的完整 class
属性,path
即需要跳转的链接地址。需要注意的是,主题的原逻辑为了实现多语言,将 RSS 图标的逻辑隔离在了通用逻辑之外。这里也保留了原实现,即 RSS 图标是默认出现且不可去除的。如果不需要 RSS 则可以对上面的代码再进行修改,以删除独立的 RSS 逻辑。
|
|
除了 Font Awesome ,最近我还看到了tabler ICONS这个库,直接支持 SVG 同时还是 MIT 协议的开源项目,也值得一试。
此外,由于我们已经覆盖了 footer 模板,那我们也可以对其他内容也进行自定义,比如将友情链接放置于 footer 等,下文的总字数统计也同样均基于自定义的 footer.html
进行处理。
even 主题自带每篇文章的字数和预计阅读时间统计,但却没有之前我借助 hexo-wordcount 所实现的全站文章字数统计。检索网络后找到了这么一篇文章 Hugo 总文章数和总字数 ,照猫画虎在 footer.html
中添加以下内容:
|
|
随后在 config.toml
中对相关参数进行配置即可:
|
|
除了以上逻辑,还可以通过改变 range
的查询范围来按需限定需要进行总字数统计的页面集合。另外配置中的固定文案比较生硬,可以考虑加入 i18n 相关实现来满足多语言切换的需要。
天下武功,唯快不破,Hugo 的速度确实让我印象深刻。但对于从 Hexo 迁移而来,同时还对 Hexo 有很多自定义配置的用户来说,迁移过程中的兼容和适配的成本其实是不低的,实际上目前的迁移仍未实现「基于 LeanCloud 的阅读计数」和「推荐阅读」两项功能的兼容。此外,无论是 Hexo 还是 Hugo ,其主题的深度自定义修改都比较麻烦,以后还是要考虑自己实现一套主题(明年一定)。
2022-08-02 12:18:28
最早听到旁路由这个词是在 2020 年折腾 N1 的时候,这台单网口的小盒子只能用网上所说的旁路由方案接入局域网来实现期望的功能。现在回想起来,旁路由这个词有可能就是在那个发烧友大量折腾斐讯 N1/P1/T1 的时期被发明出来的。你没办法在发烧友圈子外的互联网及各种学术材料中找到对旁路由的描述和定义,当然也找不到合适的英文翻译(导致这篇文章的 slug 定义困难);从拓扑上看,旁路由更像是杂糅了二级路由和透明网关的概念,除了实体确实多接了根网线放在主路由旁边,其本身并没有真正地开启一条旁路,做的事情也基本可以和网关的定义对齐。
不过,由于这个说法主要集中于网友的交流讨论之中,而且几年来在有相关需求的广大用户中被广为接受,所以只要这个词不变为一个学术概念,那我倒也不觉得有什么不妥。下文也仍然会用「旁路由」一词来指代在此类拓扑结构中担任代理网关角色的路由器。
此外,本文对于原理的解释偏多且为新手向,对于已经熟知相关概念的读者则可以将本文作为 cheat sheet 食用。
有人认为旁路由的加入(手动指定方式)不会在其出现问题时影响整个网络的可用性,所以应该把非路由功能都交给旁路由来实现。但实际上如果仅仅是为了达成这个目标,那在主路由上直接分流会是个更好的方案,因为这样不仅会大量减少疑难杂症的出现,而且还可以通过设置 fallback 的方式进一步提升网络的可用性。
所以我认为旁路由实际上只适用于一个场景,那就是出于某种考虑,主路由不能被替换或被大量修改,而主路由的固件又不能满足功能诉求,这时候旁路由便是一个可选的解决方案。
网上关于旁路由的配置教程多如牛毛,其中大部分是基于 F 大的 N1 OpenWrt 固件使用教程来写的,也有很多是结合了自己的踩坑经验的细化版本。由于版本太多、完整的说明太少,而且大部分没有讲清楚教程的环境上下文和原理,导致按照这些教程来配置的用户往往不得不一遍遍地折腾重试,甚至会遇到逐步配置最终却断网、访问不了部分网站等令人头疼的问题。
授之以鱼不如授之以渔,为了能彻底讲清楚旁路由该如何配置,我们暂且不谈具体步骤,而是先搞明白旁路由的运作原理。
由于计算机网络的术语在不同时期、不同环境下,对于细节的含义其实有比较大的差异,故首先我们先定义好下文中将使用到的各类专有名词的含义,以免出现信息不对称的情况。同时为了方便理解,我们也尽量和 OpenWrt 的名词对齐,并尝试与现实生活场景进行类比。
可以看到,无论如何配置,我们都需要保证数据按图中的拓扑进行流转,才能实现我们所希望的只在旁路由增加功能而不修改主路由的目的。由于流量(至少上行流量)总会流经旁路由,所以旁路由实质上就是一层透明代理。
那么我们该怎么实现这样的网络拓扑呢?让我们先来看下数据在网络的更底层是如何流转的。
从图中可以看到,当我们从手机等终端设备发出一个数据包时,数据包总是由我们的终端设备经由网关路由至目的地址,目的地址返回数据时也是相同的路径。这是因为终端设备本身通常是不具备路由功能的,单单一个路由表终端设备就搞不定。
既然数据必然经过网关,那么我们只要强制把旁路由作为终端设备对外数据交互的第一层网关即可。至此旁路由的工作原理其实就已经解释清楚了,即在另一台路由器上实现的基于网关的透明代理。而网上各式各样的教程其实都是在教我们解决如何配置网关的问题。
在这一章节还需要说明的是为什么各个教程都要求我们把旁路由的 IP 配置在和主路由相同的 IP 网段。所谓的 IP 网段实际上就是子网,同一子网下的主机(设备)可以直接通信,跨子网则需要通过某种形式转换后才能通信,而这些转换虽然可行但比较复杂,在旁路由这个场景下显然是没有必要的。本着不改变原有网络拓扑的原则,旁路由自然也要配置在和主路由及其他设备相同的子网才行。
那么我们该如何配置网关以让数据按上文的工作原理进行流转呢?
首先我们先来解决旁路由的网关问题。在上文的拓扑图中我们可以看到,旁路由虽然挂着路由器的名字,但它本质上也是网络链路中的一个节点,因此它也需要请求上层网关才能完成数据流转。而主路由是这个网络拓扑的出口,所以旁路由的网关自然要配置为主路由的 IP 地址。这一项配置是必须且不会随终端网关配置方式的变化而改变的,无论如何指定网关请求旁路由,旁路由本身都要依赖此配置才能完成正常的流量转发。
此外,还有子网掩码需要进行配置。前面有提到,在同一子网内的主机之间才能直接通信,而 IP 和子网掩码相组合便能确定设备当前所在的子网。旁路由并不改变网络拓扑,所以需要和主路由在同一子网内。因此将旁路由的子网掩码配置设置为主路由的子网掩码即可。同理,下文的所有子网掩码配置也均需要与主路由的保持一致。
虽然配置了网关后数据流转图中的左半边已经成型,但如果不对旁路由的 DHCP 进行配置,实际上会导致各种各样的疑难杂症或直接无法联网。
原因在于 DHCP 使用了 UDP 协议,UDP 是没有连接的,如果主路由和旁路由同时开启 DHCP,则任意一个 DHCP 服务器都可能会应答终端的申请,进而导致 IP 下发和路由表的混乱造成各种无法连接的疑难杂症。当然,我们可以将两个 DHCP 的子网网段拆分开来解决共存问题,但这个行为在旁路由场景下并没有实际意义。
因此我们需要保证网络中只有一个设备承担 DHCP 功能,出于不改变原网络拓扑和避免无意义 NAT 的考虑,我们通常选择关闭旁路由的 DHCP 功能(对应到 OpenWrt 则选择「忽略此接口」)。
对于手机、电脑等终端,我们的目标是将其网关配置为旁路由的 IP 。实现方案很多,成本较低的主要为以下两种。
顾名思义,只需要在终端设备的网络设置中将网关手动配置为旁路由即可。以 iOS 系统为例:
手动填写一个网络上未被占用的 IP 地址,而子网掩码以主路由为准,网关则填写旁路由的 IP 地址。
手动指定的好处在于完全不影响原网络的使用,设备按需配置是否使用旁路由作为网关以实现特定功能。当旁路由故障时,未手动指定的设备仍能正常上网。
缺点在于操作烦琐。手机、电脑还好,但电视或根本没有屏幕的设备设置起来就会很麻烦。
DHCP 除了可以管理 IP 的分配,还会下发网关和 DNS 服务器信息,因此我们还可以借助 DHCP 的这一机制来为所有终端统一设置网关,而不再需要逐个手动修改。
前面提到,我们关闭了旁路由的 DHCP 功能,因此这个统一下发的工作就要交给主路由来完成。只需要在主路由的 DHCP 配置中将网关配置为旁路由的 IP 地址即可。
以 OpenWrt 为例,将主路由 DHCP 下发的网关配置为旁路由 IP 地址即可(3 表示网关,6 表示 DNS 服务器地址)。
不过有些路由器的默认固件没有开放该配置项,对于这些设备,除非可以 SSH 连接后手动改配置,不然无法使用此种指定方式。
这种方式的好处显而易见,一次配置全家受用;缺点在于当旁路由出现故障时,所有连接的设备都会无法上网。
细心的读者可能发现了上文只提到了网关的配置,但未提到很多教程中的 DNS 配置。实际上单单就旁路由本身来说,网关配置完成后整个网络拓扑就已经搭建完毕了。但对于一些特定诉求,比如依赖旁路由进行统一的 DNS 劫持(很多功能的底层都依赖于此),则需要将对应位置的 DNS 也配置为旁路由的 IP 以将域名解析工作也完全交由旁路由处理。
虽然配置步骤看上去很简单,但很多人在实际使用中都会遇到逐步配置却上不了网或网络慢的问题,这里挑几个典型案例来解析。
这可能是争议最大的一条,有人说这条规则加上后影响性能而且没意义,但也有很多人表示不配这条就是连不上网(大多为连接不上国内网络)。
这条规则的作用本质上是在旁路由上做 SNAT,只不过修改的地址不需要指定而是动态获取旁路由对应接口网卡的 IP 地址,在 OpenWrt 里被称为「IP 伪装」。
单从旁路由的网络拓扑来说,这条规则确实没意义,因为主路由作为对外出口必做 NAT,但旁路由本身就在局域网内且只是链路上的一环,没有必要再对内网 IP 进行耗费性能的 NAT 操作。
但不要忘了,理论和现实是两回事,物理网络拓扑中的不同设备、不同固件都有可能产生各种奇怪的兼容问题。我自己倒是没有遇到过该问题,但检索网友们的各种帖子,大概可以分为以下几种原因:
MASQUERADE 配置其实并没有定向地去解决上面这些具体问题,而是通过 NAT 来隐藏终端设备、只向主路由暴露旁路由 IP 的方式,一刀切地避免了上述原因导致的问题。但由于上下行流量都会经过旁路由,所有流量都会被二次 NAT 和二次转发,网络的吞吐会有不小的下降,直观感受就是下载速度变慢了。
所以比较理想的策略是,先不加 MASQUERADE 规则观察是否有问题(尤其是国内流量),如果确实有问题,在权衡可以接受性能的损失后再配上该规则。
具体操作是取消桥接,再设置 WAN 和 LAN 共用同一个网卡(如 eth0 )。这个操作其实和 MASQUERADE 规则的效果类似,因为绑定后经过 WAN 的流量必然会被 SNAT 。适用于确实遇到了疑难杂症且能接受性能损失场景下的备选方案。
在许多教程里,这个操作和添加 MASQUERADE 规则是配套的。但桥接与否实际上并不会影响整体的网络拓扑,这看上去又是一项没有意义的配置。我猜测可能是网上流传的添加 MASQUERADE 规则的方式是下面这条固定命令:
|
|
也就是要求 SNAT 时从 eth0 网卡动态获取 IP 。而在桥接模式下,MASQUERADE 时是需要从 br-lan (常见的桥接后的默认网卡名称,也可能是其他名称,要视实际情况而定)获取 IP 的,直接复制粘贴上面的命令会导致 IP 伪装失败。所以只要把 -o 参数的值改为 br-lan 即可:
|
|
但似乎确实有网友不取消桥接就无法联网,这种情况大概率是旁路由固件对桥接模式的处理有问题(多见于 ARM 架构的固件,这类固件通常要做很多的魔改适配),如果真的遇到这种情况的话则确实可以取消桥接尝试下,毕竟大多数情况下旁路由内部的桥接也没什么实际意义,去掉后由于少了流量判断流程可能还会有非常微小的性能提升。
至于 N1 这种自带无线功能但实际上没人用的设备,在关掉无线后,确实可以顺便取消掉没有意义的桥接。只是在 OpenWrt 取消桥接保存配置时,要确定选中了有线网卡对应的接口比如 LAN/eth0 ,不然如果后台的前端存在体验问题自动选择了 wlan ,那保存后路由器可就直接失联了。
如果我想通过 DHCP 下发网关但又不想改变主路由的原配置该怎么办呢?在 OpenWrt 的接口 DHCP 配置中有一个选项叫做「强制」,勾选后,此设备会忽略网络上已经存在的 DHCP 服务,强制启动本机的 DHCP 服务,所以似乎我们只需要在旁路由上配置此选项,并在旁路由 DHCP 中配置好网关,主路由不做任何变更,即可实现本段开头的诉求。
但上文提到同一子网中只能有一个用于分配指定网段的 DHCP 服务,因此旁路由强制开启 DHCP 后,还需要主路由具备主动判断网络情况停止提供 DHCP 服务的能力,这个流程才能真正运转起来。但并不是所有的路由器和固件都支持这个能力,目前来看 OpenWrt 作为主路由固件时可以正确检测并停用 DHCP ,其他固件则需要在使用时做下兼容性测试。从工程角度上讲,由于这样的操作过于依赖外部能力,属于和外部组件产生了强耦合,不利于未来维护,故不太推荐此种方案。
各种组件内部实现大不相同,如果某个组件的代码对网络结构做了强限定(如上文所说的校验 IP 和 MAC 的匹配关系),那旁路由的加入可能就会打破组件预期的网络结构导致其无法运行。这种情况在组件本身不做适配时基本无解,只能尝试下开启 MASQUERADE 等配置,看看多加一层 NAT 后的网络拓扑是否能符合组件要求,但代价同样是会牺牲性能。
SYN-flood 是一种常见的攻击方式,SYN 指 TCP 建连三次握手中的第一步报文,flood 指大量发起该步骤的报文。由于 TCP 的实现原理要求服务端接收到 SYN 报文后回复客户端 SYN+ACK 报文表明请求被接受,并在一段时间内等待客户端回复最终的 ACK 报文,那么大量的 SYN 报文就会导致服务端出现大量等待最终资源耗尽挂掉,而攻击者并不需要真的完成建连,只要持续发送 ACK 包即可。
那路由器的防火墙又是如何作防御的呢?以 OpenWrt 为例,虽然 OpenWrt 的防火墙配置已经迁移到了 fw3 ,但翻看代码历史我们就会看到当时 OpenWrt 直接基于 iptables 的早期实现:
|
|
即借助 iptables 的 SYN 限流能力进行防御,同时此配置位于 default 配置中,会在 NAT 等具体网络操作之前执行。
对应到主路由,wan 口接收到攻击流量后便会进行限流,攻击者无法直接向后攻击到内网主机,那么同样为内网主机的旁路由自然理论上也就不会被攻击到。
但对于旁路由来说,理论上网络中的所有上行流量都会通过它来转发,那当流量超过防火墙的限流阈值时便会触发拦截,进而在终端上表现为网络时断时续。所以在主路由已开启 SYN-flood 防御的情况下,旁路由关闭该配置可以避免出现可能的网络不稳定问题。
IPv6 在家用网络中通常默认是没有 NAT 转换流程的,同时其动态地址配置方案比 IPv4 要复杂得多,比如 SLAAC 和之前的 DHCP 可以说完全不是一套机制,而 DHCPv6 又分有状态和无状态两类。而前面提到,我们实现旁路由网络拓扑的过程,其实就是在指定一个具备透明代理功能的网关的过程,但 SLAAC/DHCPv6 都没有提供网关下发能力,终端设备总是会以其所交互的主机作为网关,同时大多也不支持直接修改网关。此外,运营商不支持 DHCPv6-PD 、IPv6 子网限定范围等情况,都使得旁路由支持 IPv6 非常困难,在不同场景、不同网络下要面临不同的配置,甚至无方案可配置。
网上比较流行的旁路由 IPv6 实现是个曲线救国的折中方案,即先开启主路由的内网的 IPv6 地址分配进而让旁路由获得内网 IPv6 地址,随后再通过在旁路由开启一个 DHCPv6-Client 的方式获取到公网的 IPv6 地址,这样便可以将主路由的 DHCPv6 下发的 DNSv6 配置为旁路由的 IPv6 地址。此时除了 DNSv6 的解析是在旁路由进行,其他流程仍按原链路直连。而在需要分流的场景中,OpenWrt 的相关组件可以选择在解析域名时放过不需要处理的 IPv6 流量让其正常解析出 AAAA 记录,而对域名名单中的流量强制解析为 A 记录以继续走 IPv4 协议,从而实现和此前的类似的旁路由功能。
当然,这种解析实际上依赖于组件的能力。如果组件并不支持,那通过各种方式强制定义 IPv6 的路由表保证相关 IPv6 流量必然经过旁路由也是一种解决方案。不过无论哪种实现,由于不借助网关配置,其实都已经和本文的旁路由不相关了。
此外,还有种方案是通过 radvd 等支持配置路由单播和优先级的工具,用更高的优先级来指定终端的 IPv6 路由(可以简单理解为 IPv4 的网关),这样就替代了 IPv4 下手动配置或 DHCP 下发网关对应的功能,完美满足本文所说的旁路由网络拓扑,同时对 IPv6 动态地址配置方案的要求很低,但要求终端设备支持路由优先级配置。
旁路由实际上是运行透明代理功能的网关,有人认为这个概念很民科,但我并不认同,毕竟它只是在通过已有的能力来解决特定场景的问题,和我们写代码、做产品没有本质区别,而「旁路由」这个名词也不过是个约定俗成的叫法而已,不应该被批判。
另一方面,由于旁路由在不同设备、不同网络环境有可能遇到很多奇怪问题,其实对于非专业用户来说付出的时间成本很有可能会远大于直接替换主路由的成本。但生命不息,折腾不止,如果是为了收获折腾的快乐、学习到新的知识,那又有何不可呢?
2022-02-02 00:55:45
这一年工作有了些许新变量,收入多了些,也有了更多的表达欲望和副业想法,唯一不变的大概就只有个人的后消费主义时期下的持续消费。
和往年不同的是,今年很少会看到感兴趣的东西就下单,更多的则是基于自身或合理或过度的需求调研后买入,所以买的玩具更少了,实用(大概)的东西更多了。我为今年的数码消费打上四星满意度和一星的省钱度。
推荐指数:★★★★★
这是我近几年买过的最满意的苹果设备,虽然是最丐的版本,但在轻编程、码字和上网等中度使用场景性能完全够用,续航、发热方面有无数测评,我只追加一句:他们说的都是真的。而且由于不再烫腿,我使用它在床上躺着看视频的时间甚至超过了我的 iPad Pro ,是「真」全能设备。
在刚购入的时候,如 Golang 、VS Code 等常用开发工具还没有推出支持 M1 的正式版本,而 Final Cut Pro 及 Logic Pro 上的很多插件即使借助 Rosetta 2 也无法正常使用,但到了 2021 年下半年这些问题都基本得到了解决,我想生态的快速适配也是苹果敢于在全部产品线推进 M1 系列芯片的原因之一。
至于缺点,我认为主要是产品定位和用户的期望不一致所导致的,如果你认为它性能强大足以替代 MBP ,那 8G 的内存在重度使用(如多开 JetBrains 全家桶、剪辑大型视频)时会经常遇到内存不足的问题,低素质的屏幕也会让你在视觉相关专业场景下显得捉襟见肘,所以购买前明确好它只是你能在床上、沙发上、咖啡厅里无压力携带把玩的生产力工具才能产生愉悦的使用体验。
推荐指数:★★★★☆
两年前年少无知的我听信网上 24 英寸左右的 4K 显示器才是最适合 MBP 的话买入了老年机型 P2415Q ,但这台显示器的固件过于古老,以至于想使用 HDMI 2.0 还要做一套仪式感十足的设置。另外 23.8 英寸的尺寸无论显示效果有多好,在看了一整天公司的 27 英寸 4K 显示器后很难不感叹家里这块屏幕实在是太小了。
在 2021 年优化(败家)预算到位之后,我做的第一项升级就是加装一台 27 英寸的 4K 显示器。由于这台显示器不用来打游戏也只接 Mac ,所以整体的要求如下:
其实如果不考虑淘宝的定制显示器,那单单高瓦数 Type-C 供电这一项要求在 5000 以下就只有 U2720 这一个选择了,巧合的是这款显示器也正好能满足其他三项要求,因此这也就是我的最终选择。
入手后发现本代 Dell 的固件已经好用多了,各项功能也和宣传无异,我认为是这个价位当前最值得购入的 4K 显示器。
那么为什么不是 5 星推荐呢,原因就在于 Dell 的祖传做工和品控问题,右下角边框缝隙能插卡也许是调侃,但我手上这台插张纸还是没问题的,另外戴尔的祖传漏光也得以延续,使用中我还发现将 MBP 以 Type-C 接入并休眠后显示器会被随机唤醒退出休眠,导致我不得不每次都要在不使用时手动关闭显示器。这些小问题对我来说都还算能接受,读者们则要好好考虑下了。
推荐指数:★★★★★
由于家用设备的用电环境差、民用机器和部件的稳定性一般的问题,我是坚定的 all-in-one 反对者,但此前我却一直将 Home lab 搭建在只有 4 核 2.0 GHz 的白群晖 DS920+ 上,性能羸弱的同时,想跑非 Docker 的服务就要承担影响系统稳定性的风险。思前想后还是决定将 Home lab 相关功能独立出来。
我首先尝试了把早年买来用来打游戏的台式 PC 装 Arch Linux 做工作站,既承担 Home lab 的功能,也作为居家工作时的主力机。但几个月后我就放弃了,一是由于屋内环境的限制台式机离床较近风扇声影响休息,几百瓦的 TDP 想 7*24 小时运行也很不环保(费钱),二是由于家中电子设备过剩,我使用台式机办公的时间少之又少,忙于工作也不想折腾 KDE 或 i3wm。重新审视后我总结出了对于我这样的非 WFH 人士所需要的 Home lab 设备标准:
这样的要求下,一票主要用途是 NAS 和软路由的一类准系统就被直接排除了,而如 Mac mini 等 ARM 架构的小机器也不合适,几经筛选后我将目光转向了 PC 届的「Mac mini」即英特尔 NUC。
玩机界的同学都知道 8 代 NUC 的口碑和可玩性最高,但目前 8 代由于炒作的原因有些溢价,另外电子产品买新不买旧,在没有黑苹果需求且手头不紧时我认为购买最新一代 NUC (当前为 11 代)才是最优解。而 NUC 这种小盒子机箱很难压住 i7 及以上的 CPU ,能标压稳定跑满 i5 就不错了,因此我最后选择了 NUC11PAHi5 这款大众型号。
京东用日常折扣价购入后配上两条三星 DDR4 3200 笔记本内存装上 Debian 跑起来,运行情况完美符合我上面提到的各个要求,而且发热比预想中好得多,至少中等负荷场景比我的 19 款 MBP 安静得多。总的来说推荐给追求稳定、懒得折腾且不打算 all-in-one 的同学买来作为 Home lab 。
推荐指数:★★★☆☆
不怕各位看官笑话,长这么大我还没在高刷新率显示器上玩过 PC 端的游戏,进而导致我的 CSGO 水平很菜(不是),在 PC 台式机从 Home lab 场景退役后,我决定购入一款 2K 显示器让它发挥余热来提升我的 FPS 游戏水平。
我的游戏显示器购买标准如下:
几经研究才发现,2021 这个数码中庸年果然名不虚传,此前被戏称为「大金刚」、「小金刚」的显示器大多换汤不换药没什么吸引人的更新。最后还是选择了看似性价比很高的微星 MAG274QRF-QD。
这台 165Hz 2K 高刷显示器使用了 FastIPS 面板,理论上最快可以达到 1ms 的响应速度,支持 G-SYNC COMPATIBLE,附带着也支持 HDR 和 Type-C 充电,可以说从参数上来看是很优秀的水桶机了。
然而实际使用下来除了微星的固件和 Gaming OSD 对显示器配置调整来说非常方便和造型很酷外,发现了很多「小遗憾」:
总的来说显示器仍然是个一分价钱一分货的领域,2000 多块自然也不能奢求这台纸面参数优秀的显示器用起来有多完美,对于能接受画面稍微偏红且只用 DP 连接的同学可以考虑购入。
推荐指数:★★★★☆
买它其实主要是因为屋里的灯不是智能家居,床上关灯玩电子设备太伤视力,睡前下床关灯又是懒人噩耗,而这款灯支持米家体系,可通过米家 APP 远程控制,进而也可以用 iOS 捷径功能将相应的操作转换为语音指令添加到 Siri 中。有了它之后我躺在床上对 HomePod 喊声「台灯关」就可以关灯入睡了。
台灯是国 AA 级的,显色指数:Ra≥90,照明效果确实很适合伏案读书写字,作为屏幕灯的伪平替也颇为合适,此外色温范围是 2700K-5700K ,亮度也支持无极手触调节,使用体验上是款对得起价格的「现代台灯」。
而不是五星推荐的原因则是如下两点:
推荐指数:★★★★☆
原计划 2021 年要做一档播客,结果又犯了「做事前先买装备」的毛病,播客节目暂时流产于和朋友的试录,入门装备倒是集齐了。
购入前做了很多调研,在认清自家室内电器杂音较大不适合使用电容麦克风后,就一步到位入手了舒尔的 SM58 动圈话筒。不同于电容麦的自带声卡,经典的动圈麦还需要支持卡农 XLR 接口的独立声卡或调音台,对于 SM58 来说外接的声卡还需要支持 48V 幻象供电,而这套装备的入门就体现在我只选择了 2 话放版本的三代 Focusrite 2i2 声卡,而不是几千块起步的高级调音台。但选择丐版声卡搭配高级动圈麦的后果就是实测中 2i2 根本推不动 SM58 ,收到的声音非常小,不得已又入了一款颜值超高的 sE DM1 动圈话筒放大器,才达到了预期的收音水平。而装备党本性的暴露则主要体现在我又直接购入了入门级的 AKG-240 监听耳机,耳机音质比较平,好在个人佩戴起来还比较舒适。
现在再看,我仍然建议有制作播客想法的朋友为核心主播购入一些入门级的专业设备来提升音质,毕竟播客的音质是决定节目受欢迎度上限的因素之一,只是选择的时候可以考虑一些更便宜、更好推的动圈话筒,这样也能省下放大器甚至声卡的钱。监听耳机的边际效益较低,在前期则不建议购买。
推荐指数:★★★☆☆
20 年追着斐讯高性价比的尾巴,我入手了加价后的 T1 和 N1 ,T1 做电视盒子,N1 用来做旁路由。但好景不长,固件使用体验欠佳的 T1 早早就被我换成了 NVIDIA Shield TV ,而 N1 也在我使用了半年后出现了大概率也是固件问题导致的断网问题需要断电重启才能解决。Shield TV 的良好体验和这些神器的固件堪忧的稳定性让我痛定思痛,决定在路由层面也使用可扩展性和可定制性更高的 x86 架构软路由。
不巧的是那时正是 21 年年初,如果想买 J4125 的软路由就要承受较高的溢价而且没货!多番比对后我偶然看到了一款溢价较小的主打办公影院的准系统——Beelink GK55。
作为当时最新的赛扬处理器,J4125 的性能对前几代实现了碾压,到手后装上 ESXi 6.7 ,新建 OpenWrt 的同时还能再虚拟化个 Windows Server 2019 供特殊场景使用,使用体验非常丝滑,上网冲浪的速度更快了!
功耗层面没有具体测量但根据电费来看感知不强,风扇的声音不贴近几乎听不到,如果一段时间后偶现风扇起飞的情况,那有可能是主动散热结构的风扇在这个小盒子里积灰严重,清灰即可。
这款准系统还在售,我却不太推荐大家购买了,原因如下:
推荐指数:★★★★★
我手上的 NS 是玩了两年的港版初代,此前已经出现了轻微的摇杆漂移问题,本着一样东西不买两次的原则,我没有选择更换 Joy Con 而是直接购入 Switch Pro 手柄。这只手柄没什么可挑剔的,个人感觉手感比我的一代 Xbox 精英手柄还要好一些,但价格却只有精英手柄的一半不到。另外终于能在主机游戏设备上吃到国行红利了,价格优惠+保修很香。
如果要说缺点,那我觉得一代 Xbox 精英手柄的电池设计仍是我最喜欢的,只要电池管够,续航就不再焦虑。
软件 | 推荐指数 | 总结 |
---|---|---|
Chevereto V3 | ★★★★★ | 基于 PHP 的经典图床程序,价格合适且为买断制,功能很完备 |
uPic | ★★★★★ | 又一款图床客户端,比 PicGo 的 UE 更加完整且支持 iOS 端 |
iA Writer | ★★★☆☆ | 目前的主力码字工具,但深度使用后有很多交互层面的不适应,总体而言还是 WYSIWYG 类编辑器更适合大众 |
DAMA | ★★★★★ | 八爷出品的良心买断制软件,和熊猫吃短信一样在注重用户数据安全的同时为图片打码提供了超便捷的实现 |
ServerCat | ★★★★★ | 八爷出品的良心买断制软件+1,轻度使用管理多台服务器简直不要太方便,UI 和 UE 设计加分 |
服务 | 推荐指数 | 总结 |
---|---|---|
秘塔写作猫 | ★★★☆☆ | 在线文字纠正工具,对中文的支持非常完整,产品很好用但定价有些高,同时仅有在线版本无法对公司的敏感文字内容进行修正,新的一年希望能找到平替 |
Bear Pro | ★★★★☆ | 目前用来替代原生 Notes 体验不错,缺点在于虽然支持了 iCloud 同步,但没有目录管理能力,只适合轻度记录无法满足稍复杂的场景 |
flomo PRO | ★★★☆☆ | 很好用的轻量笔记工具,但当前的 PRO 订阅无法为把 flomo 当成私密微博、随手记的轻度用户创造更多价值和便捷,只推荐 flomo 的超级重度用户购买 |
DigitalOcean Spaces | ★★★★★ | 兼容 S3 的对象存储,物美价廉,不过部分 CDN 域名国内不可用,需要加一层反向代理 |
腾讯云香港轻量 VPS | ★★★★★ | 良心云诚不我欺! |
搬瓦工 SoftBank VPS | ★★★☆☆ | 性价比很低且仅适用于我这种联通用户 |
服务 | 推荐指数 | 总结 |
---|---|---|
Apple Music 美区 | ★★★★☆ | 曲库依然齐全,语言转换依然混乱,推荐依然鸡肋 |
Netflix | ★★★★☆ | 烂片烂剧越来越多,纠正了我集中注意力刷剧的毛病,再者就是价格是越来越高了 |
Pocket Casts Plus | ★★★☆☆ | 目前用来听播客的主力 APP ,Plus 订阅除了可以跨端同步进度,其他功能存在感很低 |
iCloud 200GB | ★★★★★ | 苹果设备越来越多后才能更加体会到 iCloud 的重要性 |
Setapp | ★★☆☆☆ | 曾经很实用的软件订阅集合,然而现在除了 Paste 和 Bartender ,其他软件大多用起来味同嚼蜡。推荐在第三方购买折扣码,除了便宜还比官方渠道的购买支持更多设备 |
愈发感觉这几年可能是个可大可小的历史转折期,在这样的时期应该做的不是消费,而是「少花钱,多看书」。
2021-09-06 00:55:20
没想到 2021 年还有很多人在争论是否该使用关系型数据库的外键,这种外键我们更习惯称其为物理外键,与之相对的是由业务逻辑控制的逻辑外键,实际上当今稍稍复杂些的业务都在使用外键,只是使用的是逻辑外键而非物理外键。
物理外键是我们学习数据库原理和设计时都会遇到的章节,它的主要优势是可以通过数据库实现强制的 Referential Integrity ,即引用完整性。但这样的完整性使用逻辑外键也完全能实现,有人认为逻辑外键由于完全依赖业务代码所以无法真正保证完整性,但这其实是个伪命题,因为物理外键也是由「人」来设置的,你只能确定已经设置过的物理外键能保证引用完整性,至于那些没考虑到的、设计错误的数据关联关系仍然是物理外键无法解决的,在这一点上物理外键和逻辑外键是没有实质区别的。而实际上当今的云原生架构在数据层面追求的是分布式和最终一致性,单个 DB 存储所有数据的时代早已过去,数据在服务间流转已经是常态,此外国内场景下很多数据也不被允许直接物理删除,物理外键的作用在现代架构下变得微乎其微。物理外键不是银弹,它甚至都没有成为银弹的实力。
而说到劣势,物理外键在现代后端架构中的缺点已经越发明显。分场景分析如下:
可见物理外键在数据模型迭代频繁以及大流量场景下具有非常明显的劣势。
其次是职责问题,复杂的物理外键维护需要 DBA 的参与,但在人员职责上,DBA 与业务强耦合本身就是不合理的,这和为什么要做前后端分离是一个道理,这也是为什么当今很多互联网公司会选择一名 DBA 对接一个后端大组甚至事业部的原因,DBA 的职责已经下沉到更核心的数据库稳定性和性能提升上。而在架构中的分层职责上,在持久层耦合业务逻辑是非常不明智的,因为这意味着你的架构会严重依赖某个数据库选型甚至某个特定版本数据库的功能,领域模型与数据模型的耦合也会产生很多人噩梦中的一个 Service 层走天下的情况,业务逻辑很难做进一步的抽象和拆分,至于读写模型分离、CQRS 也就是更不可能的事情了。
综上,使用物理外键能带来收益非常有限,但隐性成本(只要业务还在发展,那未来早晚会变为显性成本)却非常高,其本身又可以被逻辑外键所替代,那除了个人或团队喜好,我实在找不到继续使用物理外键的理由。