NovaBot
GitHub

附录 A 实测数据与原理

正文里那些「实测下来」的结论,数字、条件与出处都收在这本附录里。 数字不进正文是为了不把新手吓跑,但它们不是拍脑袋拍的:每个都标了怎么测的, 愿意较真的可以照着复现。

匿名模式怎么开(配置键)

第 4 章说的匿名模式,就是设置页里的「匿名模式」一项;直接改配置文件 application.yml 的话,是这一段:

novabot:
  bilibili:
    account:
      anonymous: true

改成 true 重启后生效。开着的期间程序完全不使用凭据:不读已保存的凭据、 不弹二维码、不做登录态复检与续期;设置引导的「登录直播平台」一步自动算过。 换回登录模式:改回 false、重启、扫码。

程序启动日志和首页健康自检的「哔哩哔哩登录」一项里会提示同一句话,与下面两节的实测是同一份结论:

匿名模式:个人主播的直播间实测只能拿到约一成弹幕(七格实测 8.8%~12.5%),
拿得到的弹幕里发送者 uid 会被抹成 0、昵称只留首字(形如 b\*\*\*);
动态推送与自动关注不可用。需要完整数据请配置登录

不登录会少多少数据

2026-08-07 的对照实验:同一个房间、同一时段、两条连接,登录那条对独立基准的 到达率 100%,未登录那条只有 4.3%——29.3 分钟里只收到 6 条弹幕。

被削的不只是弹幕:同一次实验里进房、排行、点赞这些环境消息也只有 5.4% (133 / 2479),与弹幕削得一样多;2026-08-10 的成对复测同样如此(逐类 10~13%)。 也就是说未登录时整条数据流按比例变薄,而不是某一类消息单独受影响。

削减的形状是「有数据但少得多」,不是「报错」:程序照常运行、日志干净、 下播报告照出,只是数字系统性偏低,不去比对就发现不了。

发送者是谁拿不到,但抹法是挑着抹的:未登录时弹幕里 uid 一律为 0、昵称只留 首字(形如 b***);但头像和粉丝勋章是真的,点赞消息也仍带完整的 uid 与昵称。 所以「数据排行榜」这类按人统计的功能会全部失效。

削减程度还与房间有关:同批实验里另一个房间的未登录连接到达率有 99.7%。 这意味着不能拿「我这里看着正常」当作依据。

房间性质决定削减幅度

起作用的是房间性质,不是分区:

房间性质匿名到达率
个人实况房(虚拟、娱乐、网游的个人流,七个房间,样本 60~1201 条/格)约一成(8.8% ~ 12.5%)
官方赛事转播房(两个房间)约 99%

同为网游区,官方赛事转播间能拿 99%,个人实况间只有 10.9%,和虚拟区、娱乐区的 个人房完全一样。要监听的几乎一定是个人主播,所以按一成来预期。赛事转播间 为什么不削,没有证据,不做猜测。

内存要备多少:实测数字

第 2 章「备到 1 GB 以上」的依据在这里。两组实测,条件都写明:

空载基线(macOS / JDK 17.0.20 / 默认启动参数 / 未配置主播、未登录, 启动静置约 40 秒后每 4 秒采样一次):

指标数值
稳态常驻内存105 – 110 MB
启动瞬时峰值150 MB 左右(类加载期,随后回落)
堆实际使用约 29 MB
空闲 CPU低于 1%

带负载(RHEL 9.8 / x86_64 / 4 核,2 位主播、功能全开、已登录,运行 1 小时 41 分后 连续采样 5 次):

指标数值
稳态常驻内存约 476 MB
堆实际使用144 MB
1 小时 41 分累计 CPU 时间45 秒(约 0.7%)

另有一次连续运行 63 小时的稳态峰值 896 MB(同条件:2 位主播、功能全开)。 它是那个场景下的峰值,不是上界——主播更多、瞬时高峰更猛时还会往上走, 那种场景没有测过。

由此推的容量结论:

机器内存结论
512 MB不够。绘制报告图要同时持有若干张解码后的位图,必然内存不足
1 GB能跑,但装不下默认那组上限,要按公式一起调低(见下)
2 GB 及以上宽裕,默认参数即可

1 GB 机器调低时不能只压一处:两条上限(systemd 的 MemoryHigh / MemoryMax) 都必须高于「堆上限 + 元空间上限 + 约 150M」。默认值是 MemoryHigh=1.2G / MemoryMax=1.5G、启动脚本 -Xmx512m;按 384m 堆 + 128m 元空间算,一组参考值是 MemoryHigh=700M、MemoryMax=850M(按公式算的,未在 1 GB 机器上实测,改完自己验)。 配错了不用自己算:启动自检会读机器的实际限制,装不下时在日志里明说差多少、往哪改。 这两个值别直接改单元文件——每次升级都会被模板重写,要用覆盖设置放(见下一节的放法)。

影响占用主要是主播数(每位一条直播间长连接及收包缓冲)和是否启用 Redis。 量级随条件变化明显,照抄任何一个数字去规划容量都不可靠,上线后自己测一次才算数。

内存偏高时怎么量、怎么调

先确认测量方式。强制 GC 后读到的常驻内存会偏高(Full GC 会触碰所有页), 不能当稳态值。正确做法是让程序空跑一段时间后直接读常驻内存。

内存偏高时可用环境变量覆盖堆上限,不必改文件(容器里用 -e JAVA_OPTS=...):

JAVA_OPTS="-Xmx256m" ./start.sh

./start.sh 是脚本所在目录那份:手动安装在产物目录里,一键安装的机器是 /opt/starbot/releases/<版本>/start.sh(工作目录脚本自己会落回安装目录)。 命令行上这样带的 JAVA_OPTS 只管手动运行;systemd 起的实例不吃命令行环境变量, 要照下文把它放进覆盖设置。

注意 -Xms 会被提前提交,调大反而抬高常驻内存。 若同时用 systemd 部署,调低 -Xmx 后记得一并调低 MemoryHigh / MemoryMax (算法见上一节)——反过来,只压 cgroup 上限而不动 -Xmx,会让进程在堆涨起来时被内核直接杀掉。 这两个值不要直接改 /etc/systemd/system/novabot@.service:每次安装(升级)都会用 模板重写它,手改的值会悄悄丢。用覆盖设置放在模板单元上——落在 /etc/systemd/system/novabot@.service.d/ 里,安装脚本不碰这个目录, 所有版本的实例都吃:

sudo systemctl edit novabot@.service

在编辑器里写(数值用你按上一节公式算出来的,下面接着那组 1 GB 参考值写)。 两条 Memory 上限要和同一组的堆、元空间一起用:启动脚本默认 -Xmx512m、 -XX:MaxMetaspaceSize=192m,两项加起来比这组上限还高,只抄两条 Memory 行等于 配错。Environment= 传进去的 JAVA_OPTS 排在启动脚本的默认参数后面,同类参数 后出现的生效,正好盖掉默认值:

[Service]
Environment="JAVA_OPTS=-Xmx384m -XX:MaxMetaspaceSize=128m"
MemoryHigh=700M
MemoryMax=850M

容器里写死的监听地址

第 3 章说过:容器里的监听地址固定为所有网卡,设置页改了也不起作用。机制是: 第一次保存设置时,程序会往卷里的配置文件写 address: 0.0.0.0。这份配置文件 如果要搬到容器外用,先把这一行改掉或删掉,否则在外面会监听所有网卡。