1. 为什么我决定自己部署一个RSSHub
信息获取这件事,这几年变得越来越割裂。我每天要看的几个独立博客、两个视频频道的更新、一个技术论坛的精华帖、还有几个垂直站点的专栏文章,分散在五六个不同的入口里。平台算法推什么我就看什么,久而久之,真正想追的内容反而被淹没在信息流里。RSS这个老东西重新回到我的视野,不是怀旧,是刚需——它把"我想看什么"的决定权还给了我。
RSSHub这个开源项目解决的核心问题很直接:很多网站本身不提供RSS订阅源,它通过一套路由规则把网页内容转换成标准的RSS输出。你可以把它理解成一个"万能翻译器",把没有订阅功能的站点翻译成任何RSS阅读器都能识别的格式。官方提供了公共实例,但公共实例的稳定性、访问速度和路由覆盖范围都有不确定性,尤其是某些小众路由经常因为请求量过大而失效。自己部署一份,等于拥有了一个专属的内容转换服务,路由想加就加,频率自己控制,数据不经过第三方。
这篇内容适合两类人看:一类是有基本动手能力、想摆脱算法推荐、重建个人信息流的内容消费者;另一类是想了解Serverless部署实践、拿一个真实项目练手的开发者。不需要你有服务器运维经验,也不需要懂复杂的网络配置,跟着步骤走,半小时内能跑起来。我会把每个关键决策背后的原因讲清楚,也会把踩过的坑提前标出来,让你少走弯路。
2. 部署方案选型:为什么是Vercel而不是别的
2.1 自建RSSHub的几种常见路径对比
在动手之前,我先把可选方案捋了一遍。自建RSSHub大致有三条路:买一台云服务器长期跑、用容器平台托管、或者用Serverless函数平台部署。这三种方式我都在不同项目里试过,各自的脾气差别很大。
云服务器是最传统的方式,一台最低配的实例就能跑,Docker一条命令拉起容器,控制权完全在自己手里。但问题在于成本和维护——即使是最便宜的配置,一年下来也是一笔固定支出,而且系统更新、证书续期、进程守护这些杂事都得自己盯着。对于只是想要一个RSS转换服务的人来说,这些运维负担明显过重。
容器托管平台省去了系统层面的维护,但免费额度通常很有限,而且冷启动问题比较明显。我试过某个容器平台,免费实例在闲置一段时间后会被回收,下次请求要等十几秒才能唤醒,阅读器拉取订阅源时经常超时。
Serverless函数平台是我最终选定的方向。它的计费模型是按请求和计算时长算的,RSSHub这种"请求进来、转换、返回"的轻量服务正好契合——没有常驻进程的浪费,闲时零成本。Vercel在这个品类里对个人开发者最友好:免费额度足够个人使用,部署流程和代码托管平台深度集成,推送代码即自动构建发布,还自带域名和证书。
2.2 Vercel免费额度的真实边界
很多人担心免费额度不够用,我实测下来可以给个参考。Vercel免费计划每月提供一定量的函数调用次数和计算时长,对于个人订阅场景——假设你订阅了五十个源,阅读器每小时刷新一次——每月的请求量大概在几万次量级,完全在免费额度之内。真正需要注意的是单次函数执行时长限制和带宽,前者影响复杂路由的抓取,后者影响你返回内容的体积。
提示:RSSHub的部分路由需要抓取多个页面再聚合,执行时间会偏长。如果你的订阅源里有这类重路由,建议在阅读器端把刷新间隔调大一些,避免频繁触发超时。
还有一个容易被忽略的点:Vercel的函数运行在特定区域,抓取目标站点时的网络路径会影响成功率。这个没法完全控制,但可以通过合理设置路由参数来缓解,后面实操部分会讲。
2.3 方案选型的核心逻辑
我把选型逻辑总结成一句话:用最小的运维成本换取可控的内容转换能力。云服务器给你完全控制权但附带运维负担,容器平台折中但免费额度紧张,Serverless平台在"个人轻量使用"这个场景下性价比最高。Vercel不是唯一选择,但它的部署体验和免费策略对新手最友好,出问题的排查路径也最清晰——构建日志、函数日志、请求日志都在一个面板里,不用东拼西凑。
3. 动手前的准备工作
3.1 账号与代码托管
你需要准备两样东西:一个代码托管平台的账号(用来存放RSSHub的代码副本),一个Vercel账号。Vercel支持直接用代码托管账号登录,登录后会自动关联你的仓库列表,省去手动配置的麻烦。
代码这边,最省事的做法是先把RSSHub的官方仓库完整复制一份到你自己的账号下。注意是复制而不是直接关联官方仓库——你需要一个自己能推送改动的副本,后续加自定义路由、改配置都在这份副本上操作。复制完成后,建议先看一眼仓库根目录的结构,重点认识几个文件:package.json(依赖和脚本定义)、vercel.json(部署配置)、lib/目录(核心逻辑)、lib/routes/目录(路由规则存放处)。这几个是你后面会反复打交道的地方。
3.2 本地环境的最低要求
虽然Vercel负责构建和运行,但本地最好还是能跑起来做验证,否则每次改动都要推上去等构建,效率太低。本地需要的是Node.js运行环境和一个包管理器。Node版本建议用当前主流的LTS版本,太老的版本可能在依赖安装阶段就报错。
装好之后,在项目根目录执行依赖安装,然后跑本地开发命令。RSSHub的本地开发模式会启动一个本地服务,你可以用浏览器直接访问路由路径看输出。这一步的意义在于:先在本地确认路由能正常工作,再推送到Vercel,把问题隔离在本地,避免在部署环节反复试错。
注意:本地跑通不代表线上一定跑通。线上环境的网络出口、函数执行限制都和本地不同,本地验证通过只是第一道关。
3.3 需要提前想清楚的两个配置项
部署前有两个配置项值得先想清楚,它们直接影响服务的行为。
第一个是访问路径前缀。RSSHub默认的路由路径是根路径下的固定格式,如果你希望所有订阅源都挂在一个统一前缀下(方便记忆和管理),可以在配置里指定。这个前缀一旦定下来,后续所有订阅地址都要带上它,中途改的话阅读器里的订阅全部要重新添加,所以最好一开始就定好。
第二个是缓存策略。RSSHub内置了缓存机制,同一个路由在缓存有效期内的重复请求会直接返回缓存结果,减少对目标站点的压力。缓存时间设太短,目标站点容易限流;设太长,内容更新不及时。个人使用场景下,我倾向于把缓存时间设得适中偏长,配合阅读器端的刷新间隔,整体体验比较平衡。
4. 核心部署流程拆解
4.1 从代码副本到Vercel项目的完整链路
部署的完整链路是这样的:你的代码副本推送到托管平台,Vercel监听到仓库变动后拉取代码、安装依赖、执行构建、发布函数。整个过程是自动的,你只需要完成一次初始关联。
在Vercel的控制台里新建项目,选择导入你复制的那份仓库。导入后Vercel会自动识别项目类型并给出构建配置建议。这里有个关键点:RSSHub的构建产物和运行方式需要特定的配置,仓库里自带的部署配置文件就是干这个的,正常情况下不需要你手动改。但你要确认构建命令和输出目录被正确识别,如果面板里显示的是空白或者明显不对的路径,需要手动指定。
环境变量这一步容易被跳过。RSSHub有一些可选的环境变量用来调整行为,比如前面提到的路径前缀、缓存时间、请求超时等。这些不是必填项,但建议至少把路径前缀和缓存时间配上,避免用默认值跑一段时间后再回头改。环境变量的添加在项目设置里完成,添加后需要重新部署才生效。
4.2 构建阶段的常见卡点
第一次部署最容易卡在构建阶段。我遇到过的情况有这么几种:
依赖安装超时。RSSHub的依赖树比较大,构建时安装依赖的时间偏长,如果网络状况不好可能触发超时。这种情况重试一次通常能过,如果反复失败,可以检查仓库里是否有锁文件(锁定依赖版本的那个文件),有锁文件的情况下安装会更快更稳定。
Node版本不匹配。某些依赖对Node版本有要求,版本太低会在安装或构建时报错。解决办法是在项目设置里指定Node版本,或者在仓库里加一个版本声明文件,让构建环境用你指定的版本。
构建内存不足。这个在免费计划里偶有发生,表现为构建过程被中断、日志里出现内存相关的错误。RSSHub的完整构建确实吃内存,如果反复遇到,可以考虑精简不需要的路由模块——把用不到的路由目录排除掉,能显著降低构建负担。这也是自己部署的一个隐藏好处:你只为用得上的功能付出构建成本。
4.3 部署成功后的验证方法
构建完成不等于服务可用,必须做实际验证。验证分三步走:
第一步,访问根路径看服务是否响应。部署成功后会分配一个默认域名,直接在浏览器里打开,应该能看到RSSHub的欢迎页面或者路由说明页。如果打不开或者报错,先看函数日志,日志里会写明失败原因。
第二步,挑一个简单的路由做实际请求。选一个你确定目标站点可访问、路由规则简单的源,把完整路径拼在域名后面访问。正常情况应该返回一段结构化的订阅内容。如果返回错误,对照日志里的状态码判断:是目标站点拒绝、是路由参数不对、还是函数执行超时。
第三步,把订阅地址导入阅读器,观察一到两次刷新周期。这一步验证的是端到端的可用性——阅读器能不能正常解析、内容能不能持续更新、有没有偶发的超时。我建议至少观察一天,因为有些问题只在特定时段或特定请求频率下才暴露。
4.4 自定义域名的取舍
Vercel分配的默认域名可以直接用,但如果你打算长期使用,绑一个自己的域名体验更好。原因有两个:默认域名比较长,每次手动拼订阅地址很麻烦;默认域名在某些阅读器里可能被识别为不常见的来源,虽然不影响功能,但看着别扭。
绑定自定义域名的流程在项目设置里完成,添加域名后按提示配置解析记录。Vercel会自动签发证书,不需要你手动处理。这里唯一需要注意的是解析生效时间,配置完成后可能要等一段时间才能全局生效,别急着反复改配置。
提示:如果你没有自己的域名,用默认域名完全够用。域名只是锦上添花,不影响核心功能,不必为了部署这个服务专门去买一个。
5. 路由管理与内容源配置实战
5.1 理解路由规则的组织方式
RSSHub的路由规则按目标站点分目录组织,每个目录下是该站点各个栏目的转换逻辑。你要订阅某个站点的内容,本质上就是找到对应的路由路径,把参数填对。路由路径的格式通常是"站点标识/栏目标识/参数"这样的层级结构。
找路由最直接的方式是查官方文档的路由列表,里面按站点分类列出了所有支持的路由和参数说明。我的习惯是先在文档里搜目标站点的名字,找到对应路由后,把参数含义看清楚再拼地址。有些路由的参数是可选的,不填会用默认值;有些是必填的,漏了会直接报错。
5.2 添加自定义路由的思路
官方路由覆盖不到你想要的站点时,就得自己写。这件事听起来吓人,实际拆开看并不复杂。一个路由本质上就是一段抓取网页、提取内容、组装成标准格式的代码。RSSHub提供了封装好的工具函数,处理请求、解析页面、生成输出这些重复劳动都有现成的轮子。
写自定义路由的步骤大致是:先在路由目录下建一个文件,定义路径和参数;然后用工具函数发起请求拿到页面内容;接着从页面里定位到你需要的元素,提取标题、链接、时间、正文摘要;最后按规定的结构返回。难点不在代码本身,在于定位页面元素——目标站点的页面结构可能经常变,你的提取逻辑要写得足够健壮,不能依赖过于脆弱的层级选择。
我个人的经验是,写自定义路由前先用浏览器的开发者工具把目标页面的结构摸清楚,确认你要的数据在哪个位置、有没有稳定的标识可以用作选择依据。如果页面是动态渲染的(内容由脚本加载),直接抓静态页面拿不到数据,这种情况要么找页面背后的数据接口,要么放弃这个源——不是所有站点都适合做RSS转换,学会取舍很重要。
5.3 订阅源的组织与阅读器搭配
部署好服务、配好路由之后,最后一环是阅读器。RSS阅读器的选择很多,核心功能都差不多:添加订阅地址、定时拉取、分类管理、标记已读。我选阅读器的标准是支持OPML导入导出和能自定义刷新间隔,前者方便迁移,后者方便控制请求频率。
订阅源的组织我建议按"信息密度"分类,而不是按站点类型。高密度源(更新频繁、单篇信息量大)单独一组,低密度源(偶尔更新)放另一组,这样每天打开阅读器时,先扫高密度组,有时间再看低密度组,避免被低价值内容占据注意力。这个分类习惯比工具本身更重要,工具只是载体。
注意:订阅源不是越多越好。我一开始贪多,加了上百个源,结果每天未读数爆炸,反而产生了新的信息焦虑。后来砍到二十个左右,每个都是真正会看的,阅读体验才回到正轨。RSS解决的是"信息茧房",但订阅列表本身也可能变成另一种茧房,定期清理很有必要。
6. 常见问题排查与避坑实录
6.1 部署与运行阶段的典型故障
下面这张表是我在实际操作中整理出来的高频问题,按现象、原因、处理方式三列对照,遇到问题时可以直接查。
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 构建失败,日志显示依赖安装错误 | 网络波动或依赖版本冲突 | 重试构建;检查锁文件是否完整;必要时指定Node版本 |
| 部署成功但访问根路径报错 | 函数入口配置不对或环境变量缺失 | 检查部署配置文件的入口设置;核对环境变量是否添加并重新部署 |
| 某个路由请求超时 | 目标站点响应慢或路由抓取逻辑重 | 增大该路由的缓存时间;降低阅读器刷新频率;检查目标站点是否可正常访问 |
| 返回内容为空或格式异常 | 目标页面结构变化导致提取失败 | 对照页面实际结构调整路由逻辑;确认目标站点没有改版 |
| 间歇性请求失败 | 函数冷启动或网络出口波动 | 属正常现象,阅读器端重试通常能恢复;频繁出现则考虑调整刷新策略 |
6.2 几个容易踩的坑
坑一:把公共实例的地址直接换成自己的域名,路径没改全。公共实例和自建实例的路由路径格式可能因为前缀配置不同而有差异,迁移订阅时要把每个地址的前缀部分核对一遍,不能只替换域名部分。我一开始图省事批量替换,结果一半的源失效,排查了半天才发现是前缀问题。
坑二:忽略目标站点的访问频率限制。自建服务不代表可以无限请求。有些站点对高频访问有明确的限制策略,请求过密会被临时拒绝。解决办法是给这类源单独设置更长的缓存时间,或者在阅读器端把刷新间隔调大。尊重目标站点的规则,服务才能长期稳定。
坑三:环境变量改了没重新部署。环境变量的修改不会自动应用到已部署的实例,必须触发一次重新部署才生效。这个细节很容易忘,改完配置发现行为没变,先想想是不是漏了重新部署这一步。
坑四:自定义路由写得太"脆"。依赖页面深层级结构的选择器,页面稍微调整就失效。写路由时尽量用稳定的标识(比如固定的类名、数据属性)作为定位依据,提取逻辑加一些容错处理,页面结构小改时不至于整个路由崩掉。
6.3 长期维护的几点心得
服务跑起来只是开始,长期可用需要一点维护习惯。我的做法是:定期检查订阅源的健康状况,阅读器里连续几天没有更新的源,手动访问一下订阅地址确认是否还正常;关注部署平台的构建通知,构建失败会发提醒,及时处理避免服务中断;自定义路由做好注释,过几个月回头看自己写的代码,没有注释基本等于重写。
还有一点值得说:不要把所有源都压在一个实例上。如果你的订阅量比较大,可以考虑部署两个实例做分流,一个跑高频源,一个跑低频源,互不影响。Vercel的免费额度对单个实例是够的,但分散部署能让故障影响面更小,排查问题也更清晰。
7. 关于信息获取方式的一点个人体会
这套东西跑了大半年,最大的变化不是"看到了更多内容",而是"看内容的心态变了"。以前刷推荐流,是被动接收,看完就忘;现在打开阅读器,是主动挑选,每一条都是自己选的,读的时候更专注,也更容易形成自己的判断。RSSHub在这个过程里扮演的角色很朴素——它只是把散落的内容重新聚拢,把选择权交回来。
技术上,Vercel加RSSHub这个组合的性价比确实高,免费额度覆盖个人使用绰绰有余,部署流程也足够简单。但我想提醒的是,工具搭好之后,真正决定体验的是你的订阅列表和阅读习惯。源选得精、分类分得清、定期做减法,这三件事比任何技术配置都重要。我见过不少人花大力气部署服务,结果订阅列表里塞满了营销号和标题党,那和刷推荐流没有本质区别。
最后分享一个我一直在用的小技巧:给每个订阅源在阅读器里加一个备注,写清楚"为什么订阅它"和"多久看一次合适"。过一段时间回看这些备注,哪些源值得留、哪些该删,一目了然。这个习惯帮我砍掉了将近一半的冗余订阅,信息流清爽了很多。