Tinode 0.25.3 配置参数详解
Tinode 0.25.3 服务端配置文件 tinode.conf 全参数详解:26 个顶层分区逐项说明(入口与传输、密钥与安全、数据库适配器、账号策略、凭据验证、推送通知、可观测),关键参数均带修改-验证闭环实测(端口切换、uid_key 非法值、数据库字段名错误、最短用户名 422、验证码调试回执、stdout 推送启停),并汇总排障实录。全部命令与回显来自真实服务器实测。
Tinode 0.25.3 配置参数详解
目标:把 Tinode v0.25.3 唯一的配置文件 tinode.conf 讲透——先给出 26 个顶层分区的全景地图,再按「入口与传输、安全与密钥、数据库、账号策略、凭据验证、消息策略、推送、可观测」逐项解释含义与默认值,关键参数附上「修改 → 重启 → 验证」的实测闭环与踩坑实录。本文所有命令与回显均来自真实服务器实测(Ubuntu 22.04 + MySQL 8)。
一、环境信息
本文的配置实验在以下环境完成(与安装篇同一台服务器,版本自证取自服务启动日志):
| 项目 | 实测值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS |
| 服务端 | Tinode v0.25.3(启动日志 Server v0.25:/opt/tinode-app/tinode:v0.25.3) |
| 配置文件 | /opt/tinode-app/tinode.conf(705 行,JSON 带注释) |
| 数据库 | MySQL 8.0.46(适配器 schema 版本 116) |
| 服务托管 | systemd(单元 tinode.service) |
配置文件全文行数实测:
wc -l /opt/tinode-app/tinode.conf
705 /opt/tinode-app/tinode.conf
二、配置文件总览
2.1 文件位置与加载方式
Tinode 的全部配置集中在一个 JSON 文件中,由启动参数 -config 指定(systemd 单元中的 ExecStart=/opt/tinode-app/tinode -config /opt/tinode-app/tinode.conf)。格式是「带 // 注释的 JSON」——官方在文件首行就提醒注释语法较为脆弱(// The JSON comments are somewhat brittle. Don't try anything too fancy.),手工编辑时不要添加尾注释或调整引号风格。
所有配置项均在启动时读取,修改后必须重启服务才生效。这是本文每个修改-验证闭环的固定动作:systemctl restart tinode 后用 systemctl is-active tinode(预期 active)与 journalctl -u tinode 确认。
2.2 顶层分区全景
用 grep 列出全部顶层键(实测回显):
grep -nP '^\t"[a-z_]+"' /opt/tinode-app/tinode.conf
9: "listen": ":6060",
13: "api_path": "/",
16: "cache_control": 39600,
20: "ws_compression_disabled": false,
23: "static_mount": "/",
28: "grpc_listen": ":16060",
32: "grpc_keepalive_enabled": true,
36: "api_key_salt": "T713/rYYgW7g4m3vG6zGRh7+FM1t0T8j13koXScOAj4=",
43: "max_message_size": 131072,
50: "max_subscriber_count": 128,
53: "max_tag_count": 16,
56: "permanent_accounts": false,
60: "expvar": "/debug/vars",
70: "use_x_forwarded_for": true,
74: "x_frame_options": "SAMEORIGIN",
79: "default_country_code": "",
92: "msg_delete_age": 600,
96: "alias_tag": "alias",
99: "media": {
155: "tls": {
188: "auth_config": {
245: "store_config": {
387: "acc_validation": {
506: "acc_gc_config": {
517: "push": [
618: "webrtc": {
650: "cluster_config": {
678: "plugins": [
26 个顶层键按职能分为四类:
| 分区 | 键 | 职能 |
|---|---|---|
| 入口与传输 | listen、api_path、cache_control、ws_compression_disabled、static_mount、grpc_listen、grpc_keepalive_enabled | 三种通道的监听与 Web 静态托管 |
| 全局策略 | max_message_size、max_subscriber_count、max_tag_count、permanent_accounts、msg_delete_age、alias_tag、default_country_code | 消息与主题的硬限制 |
| 安全 | api_key_salt、tls、use_x_forwarded_for、x_frame_options | API key 签名、TLS、反代头 |
| 子配置块 | media、auth_config、store_config、acc_validation、acc_gc_config、push、webrtc、cluster_config、plugins、expvar | 各子系统独立配置 |
其中 expvar(第 60 行)虽是标量键,本质是可观测开关:运行时统计暴露在 /debug/vars 路径,留空或设为 - 即关闭。本章第三至十节按上述顺序展开,每个关键参数给出「含义、默认值、修改-验证实测」。
三、服务入口与传输参数
3.1 listen:客户端入口端口(修改-验证实测)
listen(第 9 行,默认 :6060)是 HTTP/WebSocket/长轮询三通道共用的监听地址,Web 控制台静态托管也走这里。支持 host:port、:port、:https 服务名或 unix:/path/to/socket.sock 套接字形式;留空时无 TLS 默认 :80,有 TLS 默认 :443。命令行 --listen 可覆盖。
修改-验证实测:把端口从 6060 改为 6160,重启后验证新端口、随后改回:
sed -i 's/"listen": ":6060"/"listen": ":6160"/' /opt/tinode-app/tinode.conf
systemctl restart tinode
systemctl is-active tinode
curl -sI http://localhost:6160/ | head -1
active
HTTP/1.1 200 OK
改回 6060 并重启后 curl -sI http://localhost:6060/ | head -1 再次回显 HTTP/1.1 200 OK。这演示了配置修改的通用闭环:改文件 → restart → is-active + curl 验证。
3.2 其余传输参数逐项
| 键(行号) | 默认值 | 含义与要点 |
|---|---|---|
| api_path(13) | / | 流式通道与大文件 API 的 URL 前缀;命令行 --api_path 可覆盖 |
| cache_control(16) | 39600 | 静态资源 Cache-Control 秒数(39600 = 11 小时;安装篇 Web 验证回显中的 max-age=39600 即来源于此) |
| ws_compression_disabled(20) | false | 是否禁用 WebSocket 逐消息压缩(RFC 7692.4);官方注释:反向代理为 MSFT IIS 时应设 true |
| static_mount(23) | / | 静态文件挂载路径,默认用服务端直接托管 Web 控制台 |
| grpc_listen(28) | :16060 | gRPC 通道监听;留空则禁用 gRPC |
| grpc_keepalive_enabled(32) | true | gRPC keepalive,把 KEEPALIVE_TIME 从默认 2 小时缩到 60 秒 |
验证 gRPC 入口的方法是看启动日志(实测回显,来自 journalctl -u tinode):
Oct 26 12:23:26 tinode-sys tinode[5744]: I2026/10/26 12:23:26 gRPC/1.82.0 server is registered at [:16060]
Oct 26 12:23:26 tinode-sys tinode[5744]: I2026/10/26 12:23:26 Listening for client HTTP connections on [:6060]
static_mount 生效的证据是启动行 Serving static content from '/opt/tinode-app/static' at '/'。
四、安全与密钥参数
4.1 api_key_salt 与 keygen 配对(第 36 行)
api_key_salt 是 API key 的签名盐(32 字节 base64),与发行包内 keygen 工具生成的 key 成对使用。keygen 实测输出:
cd /opt/tinode-app && ./keygen
API key v1 seq1 [ordinary]: AQAAAAABAABb1lv6-dWoYXC4M6VO5gY9
HMAC salt: XxCVzrVjlX84Urtke1MuW+6DzuqchOYPkYlUgJAz+m8=
验证方法:salt 与 key 不配对时,所有客户端请求会被拒。本环境 salt/key 配对时 LP 会话创建正常返回(实测回显):
curl -s -X POST "http://localhost:6060/v0/channels/lp?apikey=AQAAAAABAAAoeOI7tA3HsYvdzDhYhZJy"
{"ctrl":{"params":{"sid":"aX06iiNwxZs"},"code":201,"text":"created","ts":"2026-10-26T13:04:32.448Z"}}
要点:每次 keygen 输出全新一对;替换 salt 后必须重启,且客户端侧的 key 要同步换成同一对,否则 201 变 403。
4.2 uid_key:UID 生成密钥(排障实录实测)
uid_key 位于 store_config 内(第 249 行,本环境值 6cTXIXgdxO8qxObF30+1hg==),是用户 UID 加密生成器(snowflake + XTEA)的 16 字节 base64 密钥。它的正确性在启动时强校验——改成非法 base64(33 个字符)实测:服务直接启动失败,journald 回显:
E2026/10/26 12:53:19 Failed to connect to DB: store: failed to parse config: illegal base64 data at input byte 32({
错误信息在 illegal base64 data at input byte 32( 之后原样回显了整段 store_config JSON(含 mysql/postgres/rethinkdb/mongodb 各段,多行输出),systemd 层面表现为 Main process exited, code=exited, status=1/FAILURE。修复:恢复 16 字节 base64 值后 systemctl restart tinode,is-active 回显 active。
⚠️ uid_key 的运维纪律:它决定 UID 的编解码。一旦库里有用户数据,此值绝不可再改——换了 key,既有 UID 全部无法解析。全新部署可在首次 init-db 前自定义。
4.3 tls / use_x_forwarded_for / x_frame_options
- tls(第 155 行):内嵌 TLS 配置块,配置证书后 listen 可直接服务 HTTPS;不配则前面挂 Nginx/Caddy 反代。
- use_x_forwarded_for(第 70 行,默认 true):从 X-Forwarded-For 头取客户端真实 IP。注意安全语义:直连暴露时应确认不会被伪造头污染。
- x_frame_options(第 74 行,默认 SAMEORIGIN):Web 控制台的防点击劫持响应头。
五、数据库参数(store_config,第 245 行起)
5.1 use_adapter 与适配器段
store_config.use_adapter(第 256 行)从 alldbs 发行包内置的四个适配器中选一个(本文 mysql)。每个适配器在 store_config.adapters 下有独立配置段。store_config.max_results 限制单次查询返回上限;uid_key 见 4.2 节。
5.2 mysql 连接参数(排障实录实测)
本环境 mysql 段仅显式配置了两项(实测回显):
sed -n '/"mysql": {/,/}/p' /opt/tinode-app/tinode.conf | grep -E 'User|Passwd'
"User": "tinode",
"Passwd": "q1w2e3r4",
其余连接参数(本机实例、库名 tinode)沿用适配器默认值。字段名必须逐字符正确——把 Passwd 误写成 Password 的实测后果:JSON 解析对未知字段不报错、静默忽略,等效于空密码连接,服务反复重启失败:
Oct 26 12:52:25 tinode-sys tinode[5975]: E2026/10/26 12:52:25 Failed to connect to DB: Error 1045 (28000): Access denied for user 'tinode'@'localhost' (using password: NO)
Oct 26 12:52:25 tinode-sys systemd[1]: tinode.service: Main process exited, code=exited, status=1/FAILURE
using password: NO 是空密码特征,遇到它优先怀疑字段名拼错而非密码本身。改正字段名重启后 is-active 回显 active 恢复。
六、账号与鉴权策略(auth_config,第 188 行起)
6.1 basic 段:最短用户名/密码(422 边界实测)
发行包默认的 basic 鉴权配置实测原文(第 196-206 行):
// Basic (login + password) authentication.
"basic": {
// Add 'auth-name:username' to tags making user discoverable by username.
"add_to_tags": true,
// The minimum length of a login in unicode runes, i.e. "登录" is length 2, not 6.
// The maximum length is 32 and it cannot be changed.
"min_login_length": 4,
// The minimum length of a password in unicode runes, "пароль" is length 6, not 12.
// There is no limit on maximum length, but MySQL & PgSQL adapters have a limit of 32 bytes.
"min_password_length": 6
},
逐项说明:add_to_tags: true 把 basic:用户名 加入用户可搜索标签(按用户名搜索用户的前提);min_login_length: 4(按 Unicode 字符计,最大 32 固定不可改);min_password_length: 6(无上限,但 MySQL/PgSQL 适配器单字段限 32 字节)。
修改-验证实测:在 min_login_length: 4 生效的服务器上注册 3 字符用户名 bob(实测回显):
{"ctrl":{"id":"2","params":{"what":"auth"},"code":422,"text":"policy violation","ts":"2026-10-26T12:37:30.071Z"}}
422 policy violation 且 params.what:"auth" 指向鉴权策略不满足。同节实测的姊妹边界:注册时完全不提供 email 凭据,同样 422 但参数指向凭据(params.creds:["email"]),对应 7.1 节的注册策略:
{"ctrl":{"id":"3","params":{"creds":["email"]},"code":422,"text":"policy violation","ts":"2026-10-26T12:37:30.08Z"}}
6.2 token 段
token 鉴权器(第 209 行起)控制登录令牌:expire_in: 1209600(2 周有效期)、serial_num: 1(序列号,整体 +1 可一次性作废全部已发令牌)、以及令牌签名用的 HMAC 盐(官方注释要求自生成并保密)。实测佐证:登录成功响应中 expires 恰为 2 周后(2026-10-26T12:18:29 登录,expires 2026-11-09T12:18:29)。
七、注册凭据验证(acc_validation,第 387 行起)
7.1 email 验证器与 debug_response
acc_validation 定义注册时要求的凭据与验证方式。发行包默认启用了调试回执(实测位置与原文):
grep -n -B2 'debug_response' /opt/tinode-app/tinode.conf | head -6
456- // REMOVE IN PRODUCTION!!! Otherwise anyone will be able to register
457- // with fake emails.
458: "debug_response": "123456"
含义:未配置真实 SMTP 出口时,邮箱验证码固定为 123456(第 498 行为手机号验证的同类默认值)。官方注释明确生产必须删除。修改-验证闭环:注册 tina 时先收到 300 validate credentials(响应含临时 token 与 cred:["email"]),再用验证码 123456 登录成功(实测回显):
{"ctrl":{"id":"2","params":{"authlvl":"auth","cred":["email"],"desc":{"created":"2026-10-26T12:18:29.413Z","updated":"2026-10-26T12:18:29.413Z","defacs":{"auth":"JRWPASD","anon":"N"}},"expires":"2026-11-09T12:18:29.466Z","token":"8Y/EkEKfpugVuvFqFAABAAAAQvhB+rA5MyV/S4WOCW7LA6p1I96hHx0jQAzuu/ZYDt0=","user":"usr8Y_EkEKfpug"},"code":300,"text":"validate credentials","ts":"2026-10-26T12:18:29.41Z"}}
{"ctrl":{"id":"3","params":{"authlvl":"auth","expires":"2026-11-09T12:18:29.531Z","token":"8Y/EkEKfpugVuvFqFAABAAEAnYMLpmuWIaVG4LSgn77ADpt2BgKOpQ2GZXKGV4X7n+k=","user":"usr8Y_EkEKfpug"},"code":200,"text":"ok","ts":"2026-10-26T12:18:29.481Z"}}
生产化路径:在对应验证器配置中填入真实发信参数(SMTP 令牌等)并删除 debug_response,验证码改为真实下发后凭 resp 完成登录。
八、消息与主题策略
| 键(行号) | 默认值 | 含义与验证方式 |
|---|---|---|
| max_message_size(43) | 131072 | 单条消息最大字节数(128KB);超限大文件走 out-of-band 上传(maxFileUploadSize 上限 8388608 = 8MB)。验证:hi 握手响应 params.maxMessageSize:131072 |
| max_subscriber_count(50) | 128 | 群组话题可配置专属权限的订阅者上限(频道读者不受限)。验证:hi 响应 maxSubscriberCount:128 |
| max_tag_count(53) | 16 | 每话题/用户可索引标签数上限。验证:hi 响应 maxTagCount:16 |
| permanent_accounts(56) | false | 为 true 时普通用户不可注销账号 |
| msg_delete_age(92) | 600 | 已删除消息的硬删除延迟(分钟);验证:hi 响应 msgDelAge:600 |
| alias_tag(96) | "alias" | 别名标签命名空间;验证:启动日志 Alias tag: alias |
| default_country_code(79) | "" | 手机号注册缺省国家码 |
这些上限值都会随 hi 握手一次性下发(实测回显节选):
"params":{"build":"mysql:v0.25.3","maxFileUploadSize":8388608,"maxMessageSize":131072,"maxSubscriberCount":128,"maxTagCount":16,"maxTagLength":96,"minTagLength":2,"msgDelAge":600,...}
修改任一项后重启,再发一次 hi 即可看到新值,这是最省事的「改配置-看生效」验证通道。
九、推送通知参数(push,第 517 行起)
9.1 stdout 推送启停(修改-验证实测)
push 是数组配置,每个元素是一个通知器。发行包默认仅含 stdout 通知器且关闭(第 518-525 行实测原文):
{
// Notificator which writes to STDOUT. Useful for debugging.
"name":"stdout",
"config": {
// Disabled.
"enabled": false
}
},
把 enabled 改为 true 并重启后,启动日志从 Push handlers configured: [](关闭态实测)变为:
Oct 26 12:23:26 tinode-sys tinode[5744]: I2026/10/26 12:23:26 Push handlers configured: [stdout]
推送效果实测:注册 derek 并向 tina 发消息后,journald 中出现 stdout 通知器的 Receipt 结构体输出(两条:sub 订阅通知与 msg 消息通知,map 内是各接收者与未读计数):
&{map[1iHXaDZ-kxI:{0 [] 0 false}] {sub false usrJ83MPZorA1g 2026-10-26 12:53:24.209 +0000 UTC usrJ83MPZorA1g 0 <nil> false JRWPAD JRWPAD}}
&{map[1iHXaDZ-kxI:{0 [] 1 true} J83MPZorA1g:{1 [] 0 false}] {msg false p2p1iHXaDZ-kxInzcw9misDWA 2026-10-26 12:53:24.216 +0000 UTC usrJ83MPZorA1g 1 text/plain stdout push test false N N}}
msg 通知中可见接收方(未读 +1)、在线发送者自身({1 [] 0 false},在线则静默)、P2P 话题名 p2p1iHXaDZ-kxInzcw9misDWA 与消息内容 stdout push test。stdout 通知器官方定位就是调试用;生产环境在此数组中加入 fcm(Google 推送)或 tnpg 等元素并配置对应凭据。
十、运行时可观测(expvar)
expvar(第 60 行,默认 /debug/vars)暴露运行时统计。实测:
curl -s http://localhost:6060/debug/vars | head -c 300
输出为 JSON 计数器集合,其中 CtrlCodesTotal2xx 等键累计了各协议状态码计数(实测值 140 起,随请求增长)。不需要时把该键置为空串或 - 即关闭暴露,重新启动后 /debug/vars 不再可访问。
十一、修改配置的通用方法与排障实录汇总
11.1 通用方法
每个配置项的验证都遵循同一闭环,实测步骤模板:
vi /opt/tinode-app/tinode.conf
systemctl restart tinode
systemctl is-active tinode
journalctl -u tinode --no-pager -n 20
三条验证判据:is-active 回显 active;journald 出现完整启动行序列(Listening for client HTTP connections on [:6060] 等);对应功能的业务验证通过(如端口改动后 curl 新端口 200、推送改动后出现 Receipt 行)。建议每次改前备份(cp tinode.conf tinode.conf.bak),本文三处故障实测均以备份一键恢复。
11.2 排障实录汇总
本文实测复现的三类配置错误及其指纹:
| 故障 | 实测指纹(journald 关键行) | 根因 | 解决 |
|---|---|---|---|
| mysql 密码字段名写成 Password | Failed to connect to DB: Error 1045 (28000): Access denied ... (using password: NO) | JSON 未知字段静默忽略,等效空密码 | 字段名改回 Passwd |
| uid_key 非法 base64 | Failed to connect to DB: store: failed to parse config: illegal base64 data at input byte 32({...整段 store_config 回显 | 密钥格式强校验失败 | 恢复 16 字节 base64 |
| 注册用户名过短 | 接口返回 {"code":422,"text":"policy violation","params":{"what":"auth"}} | min_login_length=4 策略 | 用户名加长或调小该值(下限受 32 上限约束) |
共同规律:配置错误一律表现为启动失败(journald 里的 E 级错误行)或接口 4xx,绝不会静默半生效;定位入口就是 journalctl -u tinode 的错误行原文。
十二、参考链接
- 本系列选型篇:《Tinode 0.25.3 介绍与选型指南》
- 本系列安装篇:《Ubuntu 22.04 安装 Tinode 0.25.3 指南》
- 官方仓库(含 tinode.conf 全量注释):https://github.com/tinode/chat
- 官方服务端配置 FAQ:https://github.com/tinode/chat/blob/master/INSTALL.md
- 官网与在线演示:https://tinode.co