2个稳定版本
1.10.0 | 2021年5月4日 |
---|---|
1.8.0 | 2021年3月31日 |
#521 in HTTP服务器
465KB
13K SLoC
Mitsuba
Mitsuba是一个用Rust编写的轻量级4chan论坛存档程序。它持续监控一组4chan论坛,获取新帖子、缩略图,可选地获取完整图片,并通过图像板Web UI以及兼容4chan官方API的只读JSON API提供它们。
Mitsuba的主要目标是CPU和内存使用非常轻量级,Rust有助于实现这一目标。Mitsuba设计得易于部署,目前除了需要一个Postgresql数据库外,没有其他运行时依赖。
预期用途是在预算低的环境中自托管存档,然而基于Actix的Web UI和API性能相当出色,应该能够扩展到任何数量的读者,与使用其他语言的竞争框架相比,资源消耗更低,并且没有由垃圾回收引起的可能的延迟峰值。
Mitsuba不支持“幽灵发帖”,因为它不是一个图像板引擎。这可能在未来的工作中得到支持(主要是前端),但需要实际的管理工具和账户系统,这两者目前都不存在。Mitsuba有一些选项是通过CLI设置的。
如果您想在野外查看它,https://mitsuba.world/ 总是在运行最新的版本。那里的大多数论坛只有缩略图,但 /vip/
和几个其他论坛有存档的完整图片和文件。
功能
- 非常快速且易于设置
- 除了运行的Postgresql数据库外,没有运行时依赖。
- 单个静态可执行文件,所有资产和依赖项都内嵌。
- 极其轻量级,可以在预算VPS上运行。
- 完全集成:Mitsuba存档论坛、线程和图片,通过JSON API和Web UI提供。
- 通过几个CLI命令轻松管理
- 可配置的速率限制器
- 可选的按板下载完整图片设置
- Web UI有一个字段,允许您通过输入帖子的ID并选择论坛来跳转到任何帖子
- Sha256图像去重,不依赖于4chan的MD5哈希
- 支持S3兼容的图像存储后端
- 减少数据库写入:每篇帖子的哈希值保存在内存中,如果帖子没有改变,则不执行数据库操作
- 可以从原始4chan URL中找到图像。代码
https://i.4cdn.org/po/1546293948883.png
可以在mitsuba的/po/1546293948883.png
找到 - 可以配置为在多个不同权重的代理之间平衡对4chan的请求,以绕过速率限制
缺少一些重要功能
- 没有“幽灵帖子”或任何类型的帖子。仅读存档。
- 没有全文搜索,或任何搜索功能。只能通过ID获取帖子或线程。我们希望最终实现搜索。
- 没有管理UI,只有管理CLI(但您不需要更改的只有很少的事情)
- 没有删除单个帖子或图像的管理工具(但如有必要,您可以安全地从文件夹中删除图像文件,它将不会被再次下载)
- 完全没有账户系统(但这使其本质上很安全)
- 没有删除特定版块中所有帖子或图像的工具(这是一个计划中的功能,目前您可以针对每个版块运行一个实例)
依赖项
您需要有一个Postgresql实例可供Mitsuba访问,可以通过提供的DATABASE_URL环境变量访问。如果在启动时收到服务器不接受更多连接的错误,您可能需要增加数据库的max_connections
配置。
快速设置
export DATABASE_URL="postgres://user:[email protected]/mitsuba"
export RUST_LOG=mitsuba=info # Optional, to get feedback
mitsuba add po
mitsuba start
在存档了一些线程之后,您可以访问http://127.0.0.1:8080/po/1以查看/po版块的新的存档。
这将只获取帖子缩略图,但不会获取完整图像。
使用mitsuba add po --full-images=true
来更改这一点。
Mitsuba不会为以前存档的帖子获取完整图像,除非它必须再次访问该帖子。目前这意味着,如果您在一个只有缩略图的版块上启用了完整图像,Mitsuba不会在特定线程上的帖子中获取完整图像,直到该特定线程出现新帖子。
mitsuba add BOARD
和mitsuba remove BOARD
在Mitsuba运行时是安全的。但在此情况下,它们将不会生效,直到当前存档周期完成。
设置指南
Mitsuba设计得既简单又快速。下载适用于您系统的二进制构建,或克隆存储库并构建可执行文件。目前Mitsuba使用的所有静态文件都嵌入在可执行文件中。您应该只需在空文件夹中运行Mitsuba。
某些选项需要作为环境变量传递。Mitsuba使用dotenv
,这意味着您不需要自己设置环境变量,而是可以在名为.env
的文件中指定它们的值,该文件必须位于您运行mitsuba可执行文件的目录中。Mitsuba将读取此文件并应用指定的环境变量及其值。
您可以在本存储库中找到一个example.env
文件。复制它并将其重命名为.env
,然后根据需要编辑其配置。现在有几个设置需要您注意
-
数据库URL:在此处指定您的Postgresql实例的连接URI。示例文件中为
postgres://用户:密码@127.0.0.1/mitsuba
。请用正确的用户名、密码以及地址、端口和数据库名称替换。如果该用户已经是指定数据库(在此例中称为mitsuba
)的所有者,则无需创建;否则,您需要自行创建。 -
数据根:保存图片文件的目录。这是一个可选设置。如果您完全省略,Mitsuba将在当前工作目录中创建一个“data”文件夹,并使用它。
-
RUST_LOG:推荐的设置是“mitsuba=info”。这控制了mitsuba的日志输出。目前mitsuba使用
env_logger
,它只将日志信息打印到标准输出(控制台)。如果没有设置,您将只能看到错误和警告,而没有其他反馈。
唯一必需的设置是DATABASE_URL,但RUST_LOG="info"也是推荐的。只需使用example.env
文件内容,并更改数据库URI。
在本指南中,我们将从现在起将可执行文件称为mitsuba
,但在Windows®上,它当然称为mitsuba.exe
。
运行mitsuba help
以获取快速使用指南和可能的命令列表
$ mitsuba help
mitsuba 1.0
High performance board archiver software. Add boards with `add`, then start with `start` command.
See `help add` and `help start`
USAGE:
mitsuba.exe <SUBCOMMAND>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
SUBCOMMANDS:
add Add a board to the archiver, or replace its settings.
help Prints this message or the help of the given subcommand(s)
list List all boards in the database and their current settings. Includes
disabled ('removed') boards
remove Stop and disable archiver for a particular board. Does not delete any
data. Archiver will only stop after completing the current cycle.
start Start the archiver, API, and webserver
start-read-only Start in read only mode. Archivers will not run, only API and webserver
您可以使用mitsuba help COMMAND
来获取每个命令和可能的选项的更详细信息
$ mitsuba help add
Add a board to the archiver, or replace its settings.
USAGE:
mitsuba.exe add [OPTIONS] <name>
ARGS:
<name> Board name (eg. 'po')
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
--full-images <full-images> (Optional) If false, will only download thumbnails for this
board. If true, thumbnails and full images. Default is false.
此命令将为指定的板及其设置添加数据库条目。下次运行Mitsuba时,将为该板以及您使用add
添加的任何其他板启动存档器。
如您所见,板特定设置只有一个选项。
full-images=true
将使存档器下载该板的完整图片(和文件)。默认值是false
,意味着只下载缩略图。
请注意,每次您在之前已添加的板上使用add
时,如果该板已被remove
禁用,则启用该板,并用您指定的值或默认值替换该板的配置,或之前的设置将被忽略。所以,如果您之前在/po/上启用了完整图像下载,等待时间为100,然后执行mitsuba add po
,设置将重置为默认的无完整图像下载,等待时间为10。
因此,让我们添加我们的第一个板,/po/是一个很好的例子,因为它通常是4chan上最慢的板
mitsuba add po --full-images=true
Added /po/ Enabled: true, Full Images: true
If mitsuba is running, you need to restart it to apply these changes.
我们将获取所有图片,我们将在前一个更新完成后10分钟后寻找新的线程更新。让我们使用list
命令确认我们的更改,该命令列出添加到mitsuba的所有板。
$ mitsuba list
/po/ Enabled: true, Full Images: true
1 boards found in database
Enabled
表示该板目前正在积极存档。
最后,我们来看看start
命令
$ mitsuba help start
Start the archiver, API, and webserver
USAGE:
mitsuba.exe start [OPTIONS]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
--archiver-only <archiver-only> (Optional) If true, will only run the archiver and
not the web ui or the web API. If false, run
everything. Default is false.
--burst <burst> (Optional) Max burst of requests started at once.
Default is 10.
--jitter-min <jitter-min> (Optional) Minimum amount of jitter to add to rate-
limiting to ensure requests don't start at the same
time, in milliseconds. Default is 200ms
--jitter-variance <jitter-variance> (Optional) Variance for jitter, in milliseconds.
Default is 800ms. Jitter will be a random value
between min and min+variance.
--max-time <max-time> (Optional) Maximum amount of time to spend retrying a
failed image download, in seconds. Default is 600s
(10m).
--rpm <rpm> (Optional) Max requests per minute. Default is 60.
此命令启动我们添加的板的存档器和用于浏览存档以及JSON API的Web UI。有各种选项,所有这些都与存档器的速率限制相关,除了一个:archiver-only
。
--archiver-only=true
将启动 mitsuba 仅作为归档器。将获取帖子,下载图片,但没有 Web UI 或 API 来查看归档内容。此选项不太有用,但将使用 大量 更少的 RAM,降至 ~9-17MB。您可以单独运行 Web UI 和 API,使用 mitsuba start-read-only
。如果您想的话,甚至可以同时运行多个 Web UI 实例,因为它像名字暗示的那样是只读的。
--rpm
是主要的速率限制选项。它决定了 mitsuba 对 4chan API 和图片服务器的请求频率,全局范围内。所有速率限制设置都是全局的,适用于所有版块和图片,但请注意,图片和 API 调用(用于获取线程)在速率限制中是 单独 计数的。
这意味着如果您将 RPM 设置为 60,mitsuba 将每分钟执行 60 次请求(最多,平均将少得多,这取决于有多少线程被更新)以获取 4chan API 上的新线程,并且 它将每分钟执行 60 次请求以获取图片,全局总请求量为每分钟最多 120 次。这种分离确保即使有大量的图片要下载,mitsuba 也可以同时继续获取新帖子,而不会相互干扰。
现在我们可以使用 mitsuba start
启动我们的归档器。它将开始归档板 /po/ 的工作。过了一会儿,您可以通过访问 http://127.0.0.1:8080/po/1 浏览您的归档。
您可以使用 mitsuba start-read-only
启动 mitsuba 的只读实例,它将仅提供 Web UI 和 API,但不进行任何归档。
您可以通过单独运行归档器使用 mitsuba start --archiver-only=true
,然后单独启动 mitsuba start-read-only
。这意味着您可以停止或重启归档器,添加新的要归档的板,而不会对正在浏览归档的用户造成任何明显的干扰。您也可以根据需要运行多个 mitsuba start-read-only
实例,或者使用 mitsuba start
运行完整的归档器和 Web UI,并附带额外的只读实例。
Web UI
Web UI 目前设计得看起来和功能都与 4chan 的 Yotsuba Blue 主题完全相同,只是在每个版块上都是如此(即使是非安全版块)。我们还包含了 4chan 的官方默认“内联扩展”,包括所有功能和选项(内联扩展许可为 MIT)。
JS 代码经过反复试验和错误修改以与 Mitsuba 正确工作。如果您发现问题,请提交错误报告。
在其他方面,Mitsuba 的 UI 看起来和功能(几乎)与 4chan 的 UI 完全相同,因为它们确实是相同的。这只是一个简单易行的短期解决方案,并允许我们利用我们的 API 与 4chan 的 API 相同的事实,从而使内联扩展工作。将来,我们希望使用不同的颜色自定义主题至少,以区分它,并添加适合归档的功能。
Web UI 也支持禁用 JavaScript,就像 4chan 的 UI 一样。
4chan的大多数功能在Web UI中都能正确显示。一个限制是,目前仅支持真实国家的国旗,而“捣蛋国旗”(例如“无政府资本主义”国旗)在UI中根本不显示。然而,这些功能只在其中一个论坛(/pol/)上启用。
此外,所有大写代码帖子(例如Mod、Admin、Manager等)都将与“版主”一样显示,没有角色之间的区别。这些帖子非常罕见(除了正确显示的“版主”),我认为目前没有这样的帖子,而且这种区别似乎并不重要。也许最终会修复。
Flash论坛也有一些我们没有实现的功能,但Flash已经死了。
注意
目前,Web UI在处理URL方面非常不灵活。例如,对于一条线程,你必须访问/[board]/thread/[id]
,例如/po/thread/570368/welcome-to-po
会因为尾部的welcome-to-po
而返回404。
索引页面需要在URL中明确包含索引号,例如/po/1
可以工作,但仅/po/
本身会返回404。这是WIP。此外,没有任何主页/
。
API
Mitsuba提供了一个只读的JSON API,该API旨在与4chan的官方API兼容。因此,我们在这里不会完全记录它,因为这将是多余的。你可以阅读他们的文档,因为URI和数据返回大多是相同的。以下有一些(非破坏性)差异,将在下面进行解释(当然,除了这个API不是从4chan的域名提供,而是从你的服务器提供之外)。
首先,目前,只有Threads和Indexes端点已经实现。除此之外,我们还添加了一个端点来提供单个帖子。
- 线程:
/[board]/thread/[op ID].json
提供完整的4chan线程,格式与官方API使用相同。 - 索引:
/[board]/[1...].json
服务器为板索引页的内容。这是您访问板时看到的默认页面,例如 https://boards.4channel.org/po/ 。在4chan上,通常只有15个索引页,例如从/po/1.json
到/po/15.json
。在Mitsuba上,由于旧帖子永远不会被删除,所以需要多少页面来列出当前存档中的所有帖子就有多少页面。一旦没有更多帖子,较高的索引号将返回404状态码。这意味着您可以轻松地刮取Mitsuba存档,并逐步增加索引直到404。然而请注意,顺序与4chan相同,因此不一定保持一致。顺序是基于哪个帖子最近有新的帖子,而不是帖子最初存档的时间。此外,页面不包含完整的帖子,而只包含OP和几条帖子。
除了这些端点之外,我们还实现了一个仅针对Mitsuba的端点:/[board]/post/[ID].json
,该端点仅提供单个帖子。使用此端点,即使只知道其ID而不知道OP的ID,也可以获取帖子。
还有一个额外的端点完全是针对Mitsuba的:/boards-status.json
,它返回与CLI的list
命令相同的数据,但格式为JSON。
与4chan API的差异
与4chan API的主要区别是,每个帖子都包含一个board
字段,其中包含其所在的板名称。
除此之外,在4chan API不会返回字段的所有情况下,我们返回该字段并使用默认值。
4chan API中仅有的类型是整数和字符串,因此对于整数,其值是0
,对于字符串则是一个空字符串。这意味着我们的API返回的所有JSON帖子都保证包含帖子可能包含的所有37个字段,无论板或帖子类型如何。例如,在4chan的一侧,sticky
字段仅在OP帖子中设置,如果设置了,其值为1
。在我们的端点,如果4chan没有设置它,则它将存在但设置为0
。
实际上,只要您检查每个字段的真值而不是其存在性,这应该不会与针对4chan API的现有代码造成任何问题。从某种程度上说,这在大多数语言中应该更容易处理,因为所有字段总是保证存在。
图片
除了API兼容性之外,我们还支持从4chan使用的相同路径获取图片。
例如,如果4chan上的图片从https://i.4cdn.org/po/1546293948883.png提供,Mitsuba将在/po/1546293948883.png
下提供它,其相应的缩略图将是/po/1546293948883s.jpg
,就像在原始网站上一样。
这允许您从存档中获取图片,即使您只有原始链接(现在可能已经失效)并且不知道帖子或线程ID。
请注意,这旨在帮助您找到丢失的图片,但这不是向许多用户提供服务的方式。每次访问这些链接都会涉及数据库查找,因为我们存储图片的方式与4chan不同。
您可以在Web UI上看到使用的静态图片的正确链接。URL基于4chan提供的图片MD5哈希,但以Base32进行编码。
例如,对于上一张图片,完整图片的链接将是 /img/full/XG/XGKR4ZPAOXQFKUPYY43ETQPPKQ.png
,缩略图位于 /img/thumb/XG/XGKR4ZPAOXQFKUPYY43ETQPPKQ.jpg
。
/img/
路径直接从磁盘提供所有图片。Mitsuba会查找您的 DATA_ROOT
文件夹,默认为 data
,并从该路径(/img/
)提供其中的 images
文件夹。因此,您可以在这里找到所有图片。
代理
Mitsuba可以被配置为使用一个或多个代理来请求4chan的API以及图片获取。负载均衡系统在这些代理之间分配请求,允许您绕过4chan的速率限制。这主要是在绝对必要时使用,例如,当4chan遭受DDoS攻击,导致Cloudflare对客户端进行速率限制,这对存档器造成问题时。不应使用此功能来滥用4chan的API。
为了添加代理,您需要设置环境变量 PROXY_URL_{N}
为您打算使用的代理的URL,其中N是一个从0开始的数字,代表第一个代理,然后是第二个,等等。例如
PROXY_URL_0=socks5://user:[email protected]:1337
PROXY_URL_1=socks5://user:[email protected]:1337
您必须从0开始,不要跳过任何数字,否则一些或所有代理将无法检测到。您可以给每个代理设置一个权重,这是一个整数,决定了它相对于其他代理的使用频率。
PROXY_WEIGHT_0=3
PROXY_WEIGHT_1=1
默认情况下,即使您已经设置了代理,Mitsuba 也将同时使用您的机器的常规IP地址(绕过任何代理)以及您配置的代理,将其视为权重为1的代理。这意味着,如果您设置了两个代理,Mitsuba将在代理0、代理1和不使用任何代理之间根据分配的权重交替进行请求。这可以通过 PROXY_ONLY
进行配置。如果设置为true,所有请求将通过代理路由。可以将您的IP地址作为“代理”在负载均衡中的权重设置为 PROXY_WEIGHT_SELF
PROXY_ONLY=false
PROXY_WEIGHT_SELF=2
请注意,我们使用的底层HTTP库采用连接池。这意味着可以多次重用相同的服务器连接。每次重用连接时,代理将与之前使用相同连接的请求相同。因此,代理的使用是在创建新连接时决定的,而不是在每次请求时决定。这意味着权重不决定代理的使用频率,而是决定打开新连接的频率。由于可以重用任意次数的连接,因此不能保证使用所有配置的代理。
命令
使用 mitsuba help
获取命令列表及其描述,使用 mitsuba help COMMAND
查看每个命令的特定选项。
列表
mitsuba list
返回存档器目前所知的所有板的信息。包括“已移除”的板,这些板不会被存档,它们的“启用”设置为False。
添加
mitsuba addBOARD [选项]
如果数据库中没有该板,将其添加到数据库并设置为启用。下次启动存档器时,它也会存档这个板。如果板在运行此命令时不存在或已禁用,并且Mitsuba的存档器正在运行,您需要重新启动它,才能使该板开始存档。
可以为板设置一些选项,这些选项存储在数据库中。《code>help add 获取有关选项的更多信息。如果您未指定选项,则将其设置为默认值。即使板已在数据库中,并且设置不同,如果您使用 add
,设置也会重置为默认值,除非您指定了不同的值。
删除
mitsuba removeBOARD
它 不会 从数据库中删除板,也不会删除任何数据、帖子或图片。
它 会 停止存档板。这意味着它将停止存档。如果该板正在执行循环中的某个部分,存档器将完成当前循环,然后关闭。其他板不会受到影响。
这也不会影响Web UI或API。已经存档的数据将像正常一样提供服务,只是不会更新。
您可以使用 add
再次启用板,但是这不会立即生效,直到您重新启动mitsuba。
启动
mitsuba start
启动存档器、Web UI和Web API服务器。您可以使用 help start
查看各种设置,其中大多数是速率限制器的设置。
选项 --archiver-only=true
将仅启动存档器,而不启动API或Web UI。如果您想使用 start-read-only
分别启动Web UI/API,这很有用,这种设置允许您在不影响公共网站的情况下重新启动或停止存档器。
只读启动
mitsuba start-read-only
启动Web UI和API,但不启动存档器。您可以在只读模式下运行任意数量的Mitsuba实例。
管理
Mitsuba除了上述CLI命令外,没有其他管理UI。
没有命令可以清除数据库中的板或删除其图片。
图片存储在所有板的相同文件夹中,因此您不能轻松删除特定板的全部图片,而且一些图片可能已发布在多个板上。
缩略图和完整图片 确实 存储在不同的文件夹中(full
和 thumb
),因此如果您想删除所有完整图片(针对所有板),只需删除整个文件夹即可。
但是,如果您确实需要删除特定图片,只需删除文件即可。磁盘上的图片永远不会被读取,图片是否已下载由数据库跟踪。因此,Mitsuba不知道图片已被从磁盘删除,并且永远不会再次下载它,因为它会被标记为已存在。
删除磁盘上的任何图片都是安全的,但当然,如果有人尝试访问它们,它们将返回404错误。
我们希望最终有一些方便的CLI工具用于管理。也许将来会有一个Web UI,但这是一项更大的任务。
未来
可能会添加一些功能
- 搜索:这是迄今为止最大的缺失功能。我本来想在1.0版本中加入这个功能,但时间不允许。理想情况下,我们应该有全文搜索功能,用于帖子内容、标题、名称等,以及所有foolfuuka拥有的高级搜索选项。有几种方法可以实现这一目标,目前我正在考虑两种。第一种方案是使用Postgresql全文搜索。这有限制,但实际上它确实具备我们使用场景中实际需要的所有功能,并且不会添加任何外部依赖。这将确保搜索始终可用。第二种方案是使用
meilisearch
,这是一个轻量级且易于设置的rust全文搜索引擎,它可以直接使用。这将给我们带来更多的能力,它非常灵活。但它是外部依赖,用户需要单独下载和运行,就像Postgresql本身一样。因此,我对此有些犹豫,并且它将是可选的,使搜索不总是可用。另一方面,使用像elasticsearch这样的东西将是一个巨大的依赖,我不愿意承担,并且需要更多的配置。此外,它在Web服务器中是最不轻量级的。 purge BOARD
命令,用于删除特定论坛的所有存档数据。这将删除所有帖子以及仅在该论坛上发布的所有图片,同时保留在其他论坛上也存在的图片。将提供选项,仅删除完整图片并保留缩略图和帖子数据。hide ID
命令,用于隐藏特定帖子不通过API提供服务,或者如果ID是线程OP的ID,则隐藏整个线程。这将在数据库中将帖子标记为“隐藏”,而不删除它,但它将不再公开可见。主要用于某人被doxx并要求删除信息的情况。这还将提供一个选项,删除与帖子或线程关联的图片,这些图片在其他帖子中不存在,同时仍然将它们标记为已下载,这样它们就不会再次被下载。check
命令,用于检查图像存储是否存在损坏或缺失的图像。这首先会扫描数据库以查看所有标记为已下载的图像,然后确保它们存在于磁盘上,并计算文件的哈希值以比较MD5,以确保它们未损坏。如果图像缺失或损坏,它将修正数据库,并将其标记为缺失。还可能会删除磁盘上的图像,但这些图像在数据库中未跟踪。- 对象存储(S3兼容)选项用于存储图像。本身并不难实现,但需要处理更多错误情况,例如在将图像上传到对象存储提供商失败时重试。目前如果图像无法保存到磁盘,它将立即被丢弃,不会进行重试。但与远程存储提供商相比,更多事情可能失败,并且它们可能只是暂时失败。
目前一个完整的图像论坛引擎,包括发布和管理,被认为超出了范围,但是如果你对此感兴趣,你应该创建一个问题进行讨论。
依赖项
~41–57MB
~1M SLoC