Ubuntu 22.04 安装 Centrifugo 指南
在 Ubuntu 22.04 服务器安装 Centrifugo v6.10.1:packagecloud 在线源、deb 离线包、tar.gz 二进制三种方案实测与 systemd 托管,含生成 JWT、连接订阅、HTTP API 发布、消息送达全链路验证。
Ubuntu 22.04 安装 Centrifugo 指南
目标:在 Ubuntu 22.04 服务器上从零安装 Centrifugo v6.10.1 实时消息服务器,覆盖在线仓库、deb 离线包、tar.gz 二进制三种安装方案与 systemd 托管,并完成「生成 JWT → 建立连接 → 订阅频道 → HTTP API 发布 → 消息送达」全链路验证。已在 Ubuntu 22.04.5 LTS(x86_64)服务器实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64),systemd 运行中
- Centrifugo 版本:v6.10.1(Go version: go1.27.3)
- 服务器主机名:centrifugo-server
- 服务监听:0.0.0.0:8130(默认端口 8000,本机 8000 已被其他服务占用,本文统一调整为 8130,调整方法见 4.5 节)
- 配置文件:/etc/centrifugo/config.json(JSON 格式,v6 起为嵌套结构)
- systemd 服务:centrifugo.service(随 deb/rpm 包提供)
- 运行用户:centrifugo(系统用户,uid 999,shell 为 /bin/false,家目录 /var/lib/centrifugo)
- 数据/日志目录:/var/lib/centrifugo、/var/log/centrifugo
- 软件包来源:packagecloud.io/FZambia/centrifugo(官方 apt/yum 仓库)与 GitHub Releases(离线包)
二、前置条件
- 一台 64 位 Linux 服务器(amd64 / arm64 / armv6 均有官方构建),本文以 Ubuntu 22.04 amd64 为准。Centrifugo 是 Go 语言编译的单二进制程序,无任何外部运行时依赖(不需要 JDK、Python、Node 等),空载常驻内存约 30 MB,1 核 1 GB 的云主机即可稳定跑通本文全部内容。
- 具备 sudo/root 权限。
- 安装基础下载工具(在线方案需要):
sudo apt-get update && sudo apt-get install -y curl wget
- 服务器需可访问外网(在线方案 A);断网服务器走方案 B/C,仅需能从内网跳板机传入安装包。
- 如服务器启用了防火墙(ufw),放行 Centrifugo 对外端口(本文为 8130):
sudo ufw allow 8130/tcp
三、版本选型说明
3.1 版本现状
截至 2026-10-21 查询 GitHub centrifugal/centrifugo 仓库 Releases:最新稳定版为 v6.10.1(v6.10.0 的补丁版),同日可见的版本序列为 v6.10.1 → v6.10.0 → v6.10.0-rc.1(预发布)→ v6.9.7 …,v6 系列处于活跃维护期,补丁版本迭代密集。本文选择 v6.10.1。
从 v6.10.0 起,官方对发布产物启用了 Sigstore 无密钥签名(keyless signing),并随版本提供 SBOM(软件物料清单)与 SHA-256 校验文件,离线场景可以逐项验证安装包完整性(见 5.2 节)。
3.2 官方包支持的发行版
官方 deb/rpm 包支持(摘自 centrifugal.dev 安装文档,查询日期 2026-10-21):64 位 Debian 10/11/12、Ubuntu 20.04/22.04/24.04、CentOS 7。32 位架构二进制可用但不再提供打包。Ubuntu 22.04 正好在官方支持列表内。
3.3 v6.10.1 Release 资产清单(GitHub Releases)
| 资产名 | 说明 |
|---|---|
| centrifugo_6.10.1-0_amd64.deb | Debian/Ubuntu 离线 deb 包(注意版本号带 -0 后缀) |
| centrifugo-6.10.1-0.x86_64.rpm | RHEL/CentOS 离线 rpm 包 |
| centrifugo_6.10.1_linux_amd64.tar.gz | Linux amd64 二进制压缩包(方案 C) |
| centrifugo_6.10.1_linux_arm64.tar.gz | Linux arm64 二进制压缩包 |
| centrifugo_6.10.1_checksums.txt | 全部产物的 SHA-256 校验值 |
| centrifugo_6.10.1_checksums.txt.sigstore.json | Sigstore 签名文件 |
| *.sbom.json | 各产物对应的 SBOM |
关键差异:deb/rpm 包自带 systemd 单元、logrotate 配置、专用系统用户并自动生成含随机密钥的初始配置,适合直接上服务器;tar.gz 只有一个裸二进制,适合无包管理器的环境与多版本并存管理。三种方案完整对比见第七章。
四、在线安装方案(A:官方 packagecloud apt 源,推荐)
4.1 方案说明
官方将 deb/rpm 包发布在 packagecloud.io 托管的软件仓库,仓库路径为 FZambia/centrifugo(FZambia 是 Centrifugo 作者 German Sokolov 的账号名,官方安装文档指向该仓库)。添加源后 apt install 一步完成安装,后续 apt upgrade 可随系统升级,这是有外网服务器的首选方案。
4.2 添加软件源
一条管道命令完成仓库注册与 GPG 密钥导入:
curl -fsSL "https://packagecloud.io/install/repositories/FZambia/centrifugo/script.deb.sh" | sudo bash
实测回显(末尾节选):
Installing /etc/apt/sources.list.d/FZambia_centrifugo.list...done.
Importing packagecloud gpg key... Packagecloud gpg key imported to /etc/apt/keyrings/FZambia_centrifugo-archive-keyring.gpg
done.
Running apt-get update... done.
The repository is setup! You can now install packages.
⚠️ 排障实录:网络上大量旧教程把仓库路径写成
centrifugo/centrifugo,执行脚本会直接报curl: (22) The requested URL returned error: 404。官方文档(centrifugal.dev/docs/getting-started/installation)明确的仓库路径是FZambia/centrifugo,请以官方文档为准。
4.3 安装
sudo apt-get install -y centrifugo
实测回显(节选):
Fetched 42.3 MB in 12s (3391 kB/s)
Selecting previously unselected package centrifugo.
(Reading database ... 7333 files and directories currently installed.)
Preparing to unpack .../centrifugo_6.10.1-0_amd64.deb ...
Unpacking centrifugo (6.10.1-0) ...
Setting up centrifugo (6.10.1-0) ...
验证版本:
centrifugo version
实测回显:
Centrifugo v6.10.1 (Go version: go1.27.3)
4.4 了解包安装布局
dpkg -L centrifugo
实测回显:
/.
/etc
/etc/logrotate.d
/etc/logrotate.d/centrifugo
/etc/centrifugo
/usr
/usr/share
/usr/share/doc
/usr/share/doc/centrifugo
/usr/share/doc/centrifugo/changelog.gz
/usr/lib
/usr/lib/centrifugo
/usr/lib/centrifugo/scripts
/usr/lib/centrifugo/scripts/centrifugo.service
/usr/lib/centrifugo/scripts/initd.sh
/usr/lib/centrifugo/scripts/centrifugo.upstart
/usr/lib/centrifugo/scripts/initd.el6.sh
/usr/bin
/usr/bin/centrifugo
要点:二进制在 /usr/bin/centrifugo;systemd 单元模板在 /usr/lib/centrifugo/scripts/,安装脚本会将其部署为 /lib/systemd/system/centrifugo.service(Ubuntu 22.04 上 /lib 是 /usr/lib 的符号链接);logrotate 轮转配置在 /etc/logrotate.d/centrifugo(daily、保留 7 份、copytruncate、压缩)。
安装脚本同时完成三件事:创建系统用户 centrifugo(uid 999)、创建空的 /etc/default/centrifugo 环境变量文件、首次安装时自动生成含随机密钥的初始配置 /etc/centrifugo/config.json。
查看服务单元内容(后续排障会用到):
cat /lib/systemd/system/centrifugo.service
实测回显:
[Unit]
Description=Centrifugo real-time messaging server
Documentation=https://github.com/centrifugal/centrifugo
# start once the network and logging subsystems available
After=network.target
[Service]
User=centrifugo
Group=centrifugo
LimitNOFILE=65536
Environment="CONFIG=/etc/centrifugo/config.json"
EnvironmentFile=/etc/default/centrifugo
ExecStartPre=/usr/bin/centrifugo checkconfig -c $CONFIG
ExecStart=/usr/bin/centrifugo -c $CONFIG $CENTRIFUGO_OPTS
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -SIGTERM $MAINPID
TimeoutStopSec=10
KillMode=control-group
RestartSec=1
Restart=on-failure
[Install]
WantedBy=multi-user.target
Alias=centrifugo.service
三个值得记住的设计:ExecStartPre 先跑 centrifugo checkconfig 做配置预检,配置非法时服务不会带病启动;ExecReload 发送 SIGHUP 让服务热重载配置(无需重启进程);Restart=on-failure 异常退出自动拉起。
4.5 修复配置文件权限(v6.10.1-0 包必踩的坑)
直接启动服务会失败:
sudo systemctl start centrifugo
实测回显:
Job for centrifugo.service failed because the control process exited with error code.
See "systemctl status centrifugo.service" and "journalctl -xeu centrifugo.service" for details.
定位根因:
journalctl -u centrifugo --no-pager | tail -5
实测回显:
Oct 21 14:55:06 centrifugo-server centrifugo[3517]: config file not found
Oct 21 14:55:06 centrifugo-server systemd[1]: centrifugo.service: Control process exited, code=exited, status=1/FAILURE
Oct 21 14:55:06 centrifugo-server systemd[1]: centrifugo.service: Failed with result 'exit-code'.
Oct 21 14:55:06 centrifugo-server systemd[1]: Failed to start Centrifugo real-time messaging server.
Oct 21 14:55:07 centrifugo-server systemd[1]: centrifugo.service: Start request repeated too quickly.
报错文案是 config file not found,但文件明明存在——查看权限即水落石出:
ls -la /etc/centrifugo/config.json
实测回显:
-rw------- 1 root root 490 Oct 21 14:54 /etc/centrifugo/config.json
根因:安装脚本以 root 身份调用 centrifugo genconfig 生成初始配置,而 Centrifugo 出于安全考虑以 0600 权限写配置文件(配置里含 HMAC 密钥等敏感信息,程序显式指定权限,与 umask 无关)。但服务单元以 User=centrifugo 普通用户运行,读不到这个 root 私有文件,于是抛出误导性的 config file not found。修复方式是把配置属组交给 centrifugo 并放开组读:
sudo chown root:centrifugo /etc/centrifugo/config.json
sudo chmod 640 /etc/centrifugo/config.json
ls -la /etc/centrifugo/config.json
实测回显:
-rw-r----- 1 root centrifugo 490 Oct 21 15:04 /etc/centrifugo/config.json
4.6 调整监听端口(8000 → 8130)
Centrifugo 默认监听 8000 端口。本机 8000 已被其他服务占用,因此本文将监听端口调整为 8130,后续所有命令与验证均基于 8130(如果你的 8000 空闲,可以保留默认值,把下述配置中的 8130 换回 8000 即可)。
编辑 /etc/centrifugo/config.json,加入 http_server 段(v6 起配置为嵌套 JSON,完整参数解析见《Centrifugo 6.10 配置参数详解》):
sudo python3 - <<'PYEOF'
import json
cfg = json.load(open("/etc/centrifugo/config.json"))
cfg["http_server"] = {"address": "0.0.0.0", "port": 8130}
json.dump(cfg, open("/etc/centrifugo/config.json", "w"), indent=2)
PYEOF
改后先跑一次配置预检再启动(与服务单元的 ExecStartPre 行为一致):
sudo centrifugo checkconfig -c /etc/centrifugo/config.json && echo CONFIG_OK
实测回显:
CONFIG_OK
💡 说明:
checkconfig对合法配置静默通过(退出码 0,无输出)。它还有-s/--strict严格模式,会拒绝配置文件里的未知字段,适合版本升级时兜底校验,用法详见《Centrifugo 6.10 常用 CLI 命令详解》。
4.7 systemd 托管与开机自启
sudo systemctl enable centrifugo
sudo systemctl restart centrifugo
验证运行状态:
systemctl is-active centrifugo
systemctl status centrifugo --no-pager
实测回显(节选,省略 CGroup 详情行):
active
● centrifugo.service - Centrifugo real-time messaging server
Loaded: loaded (/lib/systemd/system/centrifugo.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2026-10-21 15:04:39 UTC; 2s ago
Docs: https://github.com/centrifugal/centrifugo
Process: 3832 ExecStartPre=/usr/bin/centrifugo checkconfig -c $CONFIG (code=exited, status=0/SUCCESS)
Main PID: 3842 (centrifugo)
Tasks: 12 (limit: 94371)
Memory: 26.9M
启动日志确认所有端点已挂载:
journalctl -u centrifugo --no-pager -n 5
实测回显(末行节选):
Oct 21 15:04:39 centrifugo-server centrifugo[3842]: {"level":"info","version":"6.10.1","runtime":"go1.27.3","pid":3842,"gomaxprocs":12,"engine":"memory","time":"2026-10-21T15:04:39Z","message":"starting Centrifugo"}
Oct 21 15:04:39 centrifugo-server centrifugo[3842]: {"level":"info","algorithms":"HS256, HS384, HS512","time":"2026-10-21T15:04:39Z","message":"enabled JWT verifiers"}
Oct 21 15:04:39 centrifugo-server centrifugo[3842]: {"level":"info","time":"2026-10-21T15:04:39Z","message":"serving websocket, api endpoints on :8000"}
💡 说明:日志为 JSON 行格式(level/version/pid/message 等字段),
engine":"memory"表示当前使用内置内存引擎(单机模式);配置了 Redis 引擎后此处会变为 redis。日志级别的调整方法见配置详解篇。
4.8 HTTP 端点验证
默认配置下服务只开了 websocket 连接端点与 HTTP API。为便于运维验证,本文在 /etc/centrifugo/config.json 中补充开启健康检查、Prometheus 指标与 Swagger 文档三个端点(追加三个顶层段即可,改完 systemctl restart centrifugo):
"health": { "enabled": true },
"prometheus": { "enabled": true },
"swagger": { "enabled": true }
逐个验证(注意本文端口为 8130):
curl -s -o /dev/null -w "health: %{http_code}\n" http://127.0.0.1:8130/health
curl -s -o /dev/null -w "metrics: %{http_code}\n" http://127.0.0.1:8130/metrics
curl -s -o /dev/null -w "swagger: %{http_code}\n" http://127.0.0.1:8130/swagger/
实测回显:
health: 200
metrics: 200
swagger: 200
重启后再看日志,挂载端点清单已经变化(对照 4.7 节只有 websocket、api):
Oct 21 15:09:26 centrifugo-server centrifugo[4035]: {"level":"info","time":"2026-10-21T15:09:26Z","message":"serving websocket, http_stream, sse, emulation, api, admin, prometheus, health, swagger endpoints on 0.0.0.0:8130"}
(该行来自本文实验环境,额外开启了 sse/http_stream/admin 端点,读者未开启这些端点时清单会短一些。)
4.9 端到端消息链路验证(token → 连接 → 订阅 → 发布 → 送达)
这是安装成功的最终判据:走通「生成连接 JWT → WebSocket 连接并订阅 → 服务端 HTTP API 发布消息 → 客户端收到推送」完整链路。
第一步,签发一个用户 ID 为 42、有效期 1 小时的连接 JWT:
centrifugo gentoken -c /etc/centrifugo/config.json -u 42 -t 3600 -q
实测回显:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MiIsImV4cCI6MTc5MjU5OTEyOCwiaWF0IjoxNzkyNTk1NTI4fQ.2RmvtVqaHZE2FmHOVBIzgickqp2mqH9_EQCSZsmuISs
第二步,为了让客户端能自主订阅频道,在配置中声明一个 chat 频道命名空间并放开客户端订阅权限(allow_subscribe_for_client 默认为 false,这是 v6 的安全默认值),追加 channel 段后重启服务:
"channel": {
"namespaces": [
{
"name": "chat",
"allow_subscribe_for_client": true
}
]
}
第三步,安装 Python WebSocket 客户端库(服务器本机自测用):
sudo apt-get install -y python3-websocket
第四步,将下面脚本保存为 chain_test.py(订阅的频道名必须带命名空间前缀,写作 chat:main,直接写 chat 会落到无命名空间默认策略而被拒):
import websocket, json, threading, time, sys, urllib.request
TOKEN = sys.argv[1] # 第一步生成的连接 JWT
APIKEY = "你的 http_api.key,见 /etc/centrifugo/config.json"
ws = websocket.create_connection("ws://127.0.0.1:8130/connection/websocket", timeout=10)
ws.send(json.dumps({"id": 1, "connect": {"token": TOKEN, "name": "pyclient"}}))
print("<<", ws.recv()) # 连接回执
ws.send(json.dumps({"id": 2, "subscribe": {"channel": "chat:main"}}))
print("<<", ws.recv()) # 订阅回执
def publish():
time.sleep(1)
req = urllib.request.Request("http://127.0.0.1:8130/api",
data=json.dumps({"method": "publish", "params": {"channel": "chat:main", "data": {"text": "hello from api"}}}).encode(),
headers={"X-API-Key": APIKEY, "Content-Type": "application/json"})
print("API publish resp:", urllib.request.urlopen(req).read().decode())
threading.Thread(target=publish).start()
print("<<", ws.recv()) # 收到推送
ws.close()
⚠️ 两个高频坑都写进了脚本:其一,v6 客户端协议的每条命令必须携带自增
id字段,漏掉会收到 3501bad request断连(服务端源码对id == 0的命令直接拒绝);其二,浏览器型客户端必须被client.allowed_origins放行,Python websocket-client 默认携带 Origin 头,若配置保持默认空数组,握手阶段就会收到403 Forbidden,本文示例配置需将其设为"allowed_origins": ["*"](生产环境建议收敛为精确域名列表)。
第五步,运行脚本(TOKEN 与 APIKEY 换成你自己的实际值):
python3 chain_test.py "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MiIsImV4cCI6MTc5MjU5OTEyOCwiaWF0IjoxNzkyNTk1NTI4fQ.2RmvtVqaHZE2FmHOVBIzgickqp2mqH9_EQCSZsmuISs"
实测回显(密钥值各环境不同,结构一致):
<< {"id":1,"connect":{"client":"a86c3f2a-0894-4449-bb78-d900e5207b15","version":"6.10.1 OSS","expires":true,"ttl":3600,"ping":25,"pong":true}}
<< {"id":2,"subscribe":{}}
<< {"push":{"channel":"chat:main","pub":{"data":{"text": "hello from api"}}}}
API publish resp: {"result":{}}
四行输出对应四个里程碑:connect 回执(含服务端版本、连接过期时间与心跳参数 ping=25s)→ subscribe 空对象表示订阅成功 → push.pub.data 收到 API 发布的原始消息 → HTTP API 返回 {"result":{}}。看到第三行 push 即全链路打通。
五、deb 离线包安装方案(B:断网服务器)
5.1 方案说明
内网隔离服务器无法访问 packagecloud,可直接使用 GitHub Releases 提供的 deb 包。该包与仓库源的包完全同源(同一 CI 产物),区别只是分发渠道。需要在一台能上网的机器上下载并校验,再传入内网。
5.2 下载与 SHA-256 校验
在有外网的机器上下载 deb 包与官方校验文件:
wget https://github.com/centrifugal/centrifugo/releases/download/v6.10.1/centrifugo_6.10.1-0_amd64.deb
wget https://github.com/centrifugal/centrifugo/releases/download/v6.10.1/centrifugo_6.10.1_checksums.txt
⚠️ 排障实录:资产名必须带
-0。按直觉拼出的centrifugo_6.10.1_linux_amd64.deb会得到ERROR 404: Not Found,正确名称是centrifugo_6.10.1-0_amd64.deb(tar.gz 反而不带-0)。
用官方校验文件核对 SHA-256(--ignore-missing 表示只校验本地已下载的文件):
sha256sum -c --ignore-missing centrifugo_6.10.1_checksums.txt
实测回显:
centrifugo_6.10.1-0_amd64.deb: OK
5.3 安装
把 deb 包传入内网服务器(scp/介质均可)后安装。推荐用 apt install 携带本地路径,能自动处理依赖关系:
sudo apt install ./centrifugo_6.10.1-0_amd64.deb
实测回显(在已装同版本的服务器上重装演示,首次安装输出结构一致):
Selecting previously unselected package centrifugo.
(Reading database ... 7344 files and directories currently installed.)
Preparing to unpack .../centrifugo_6.10.1-0_amd64.deb ...
Unpacking centrifugo (6.10.1-0) over (6.10.1-0) ...
Setting up centrifugo (6.10.1-0) ...
也可以用 sudo dpkg -i centrifugo_6.10.1-0_amd64.deb,输出相同;若依赖报错,补一句 sudo apt-get -f install 即可。
5.4 配置与 systemd 托管
与方案 A 完全一致:安装脚本同样生成配置、创建用户、部署单元。按 4.5 节修复配置权限、按 4.6 节调整端口后,执行:
sudo systemctl enable centrifugo
sudo systemctl start centrifugo
systemctl is-active centrifugo
实测回显:
active
5.5 验证
centrifugo version
curl -s -o /dev/null -w "health: %{http_code}\n" http://127.0.0.1:8130/health
实测回显:
Centrifugo v6.10.1 (Go version: go1.27.3)
health: 200
六、tar.gz 二进制安装方案(C:任意 Linux + 多版本管理)
6.1 方案说明
官方 tar.gz 只含一个静态编译的 centrifugo 二进制与文档文件,适合三类场景:无法使用 deb/rpm 的发行版、需要多版本并存随时回滚、以及希望把二进制放进自建目录规范管理。代价是 systemd 单元、系统用户、logrotate 都要自己搭。本方案给出生产可用的完整手工托管流程。
6.2 下载、校验与解压
wget https://github.com/centrifugal/centrifugo/releases/download/v6.10.1/centrifugo_6.10.1_linux_amd64.tar.gz
wget https://github.com/centrifugal/centrifugo/releases/download/v6.10.1/centrifugo_6.10.1_checksums.txt
sha256sum -c --ignore-missing centrifugo_6.10.1_checksums.txt
实测回显:
centrifugo_6.10.1_linux_amd64.tar.gz: OK
按版本号解压到独立目录(这个目录结构就是多版本管理的载体):
sudo mkdir -p /opt/centrifugo-6.10.1
sudo tar -xzf centrifugo_6.10.1_linux_amd64.tar.gz -C /opt/centrifugo-6.10.1
ls -la /opt/centrifugo-6.10.1
实测回显:
total 64520
drwxr-xr-x 2 root root 4096 Oct 21 15:28 .
drwxr-xr-x 1 root root 4096 Oct 21 15:28 ..
-rw-r--r-- 1 1001 1001 100884 Oct 20 17:13 CHANGELOG.md
-rw-r--r-- 1 1001 1001 11351 Oct 20 17:13 LICENSE
-rw-r--r-- 1 1001 1001 7838 Oct 20 17:13 README.md
-rwxr-xr-x 1 1001 1001 65652736 Oct 20 17:13 centrifugo
验证二进制可独立运行:
/opt/centrifugo-6.10.1/centrifugo version
实测回显:
Centrifugo v6.10.1 (Go version: go1.27.3)
6.3 创建专用用户、目录与软链
sudo useradd --system -U -M centrifugo -s /bin/false -d /var/lib/centrifugo
sudo mkdir -p /var/lib/centrifugo /var/log/centrifugo /etc/centrifugo
sudo chown -R centrifugo:centrifugo /var/lib/centrifugo /var/log/centrifugo
sudo ln -sfn /opt/centrifugo-6.10.1/centrifugo /usr/local/bin/centrifugo
验证软链生效:
centrifugo version
实测回显:
Centrifugo v6.10.1 (Go version: go1.27.3)
6.4 生成配置文件
用 genconfig 子命令生成含随机密钥的最小配置(生成的密钥每次运行都不同):
sudo centrifugo genconfig -c /etc/centrifugo/config.json
sudo centrifugo checkconfig -c /etc/centrifugo/config.json && echo CONFIG_OK
实测回显:
CONFIG_OK
按 4.5/4.6 节同样处理:把端口改为 8130、按需开启 health 端点、并修正权限(tar.gz 方案没有安装脚本代劳,权限步骤同样不能省):
sudo chown root:centrifugo /etc/centrifugo/config.json
sudo chmod 640 /etc/centrifugo/config.json
6.5 手工编写 systemd 单元
写入 /etc/systemd/system/centrifugo.service(字段含义与官方包一致,路径改为本方案的实际路径):
[Unit]
Description=Centrifugo real-time messaging server
Documentation=https://github.com/centrifugal/centrifugo
After=network.target
[Service]
User=centrifugo
Group=centrifugo
LimitNOFILE=65536
Environment="CONFIG=/etc/centrifugo/config.json"
ExecStartPre=/usr/local/bin/centrifugo checkconfig -c $CONFIG
ExecStart=/usr/local/bin/centrifugo -c $CONFIG
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -SIGTERM $MAINPID
TimeoutStopSec=10
KillMode=control-group
RestartSec=1
Restart=on-failure
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable centrifugo
sudo systemctl start centrifugo
systemctl is-active centrifugo
实测回显:
active
6.6 验证
curl -s -o /dev/null -w "health: %{http_code}\n" http://127.0.0.1:8130/health
journalctl -u centrifugo --no-pager -n 3
实测回显(health 行 + 日志末行):
health: 200
Oct 21 15:30:10 centrifugo-server centrifugo[5312]: {"level":"info","time":"2026-10-21T15:30:10Z","message":"serving websocket, api endpoints on 0.0.0.0:8130"}
之后按 4.9 节做端到端链路验证即可,两种安装方式的服务行为完全一致。
6.7 多版本并存与升级回滚
tar.gz 方案天然支持多版本并存:新版本解压到新目录、切换软链、重启服务,即可完成升级;回滚只需把软链切回旧目录:
sudo ln -sfn /opt/centrifugo-6.10.1/centrifugo /usr/local/bin/centrifugo
sudo systemctl restart centrifugo
💡 说明:软链切换前的
/usr/local/bin/centrifugo指向目标保持不变即可实现"指回旧版本即回滚"。升级前建议用新版本二进制跑一次checkconfig -s(严格模式,拒绝未知配置字段),确认配置与新版本兼容——Centrifugo 大版本升级时常有配置项改名或移除。
七、方案对比与选择建议
| 维度 | A:packagecloud 在线源 | B:deb 离线包 | C:tar.gz 二进制 |
|---|---|---|---|
| 是否需联网 | 安装时需要 | 仅下载机需要 | 仅下载机需要 |
| 安装方式 | apt install 一步到位 | apt install ./xxx.deb 或 dpkg -i | 手工解压+建用户+写单元 |
| systemd 单元 | 自动部署 | 自动部署 | 手工编写 |
| 专用系统用户 | 自动创建 | 自动创建 | 手工创建 |
| logrotate | 自动配置 | 自动配置 | 手工配置 |
| 配置初始生成 | 自动(含随机密钥) | 自动(含随机密钥) | genconfig 生成 |
| 版本管理 | apt upgrade / 指定版本 | 换包重装 | 多目录+软链,最灵活 |
| 适用场景 | 可联网的生产服务器 | 内网隔离的 Debian/Ubuntu | 特殊发行版/多版本测试 |
选择建议:能联网直接选 A,一条 curl 管道换来长期 apt 升级能力;内网服务器选 B,包内容与 A 完全同源且同样自动配好 systemd;需要多版本并存、灰度升级或在非 Debian 系发行版上运行,选 C。
八、配置说明(三种方案共用)
8.1 配置文件与初始密钥
配置文件统一在 /etc/centrifugo/config.json(方案 C 为自定义路径)。v6 的配置是嵌套 JSON,deb/rpm 安装时由 genconfig 自动生成的初始结构如下(密钥为安装时随机生成的示例值,读者环境的值不同):
{
"client": {
"token": {
"hmac_secret_key": "rrhvFSIZo7M1Sd32xolB0rr5bvK4OPGRoNW5D2whDdD_eYk8XYU1E1ODUJ-W4d8WGjA3dU-28-_d2cgEiu8Rtg"
},
"allowed_origins": []
},
"admin": {
"enabled": false,
"password": "isao90S5n3kxQ7q381WBiQ",
"secret": "7OiEJ6VWrZwE5-n8bTZZONDyKYPqkVpgzS18EMsIqFzGGkwltGzQysSXe0CrqUNn0h26L6YTnFYsB2RhetRPNA"
},
"http_api": {
"key": "--WZmsF-2PDKd3GpbPDRAKqvHTQwI9xdspqkMEGUB3VAhKWZnn2SfBaebicBt7SxFTgosFWa7N3_J9GbUYI9xQ"
}
}
三个密钥的分工:client.token.hmac_secret_key 用于签发/校验连接 JWT(HS256 系列算法);http_api.key 是服务端调用 HTTP API 的凭据(请求头 X-API-Key);admin.password/secret 用于内置管理界面登录。本文实验环境将 admin.password 修改为 q1w2e3r4 并开启管理端点用于验证("admin": {"enabled": true, "external": true}),登录测试账号即 admin 角色口令 q1w2e3r4。管理界面无需单独端口,开启后直接访问服务根路径 http://127.0.0.1:8130/(页面标题为 Centrifugo admin web UI),认证接口实测为表单方式:
curl -s -X POST -d "password=q1w2e3r4" http://127.0.0.1:8130/admin/auth -w " http:%{http_code}"
实测回显:
{"token":"MTc5MjU5NjE2M3xEUXdBQ21GMWRHaHZjbWw2WldRPXwM9uF9x5Qow2Zc18L9ltHegUzAwwjgmi5MYbyjdk9flg=="} http:200
8.2 本文实验环境的完整配置
综合前面所有调整(端口 8130、放开 Origin、开启辅助端点、chat 命名空间),本文最终使用的完整配置如下,可直接作为最小可用模板:
{
"http_server": {
"address": "0.0.0.0",
"port": 8130
},
"log": {
"level": "info"
},
"client": {
"token": {
"hmac_secret_key": "rrhvFSIZo7M1Sd32xolB0rr5bvK4OPGRoNW5D2whDdD_eYk8XYU1E1ODUJ-W4d8WGjA3dU-28-_d2cgEiu8Rtg"
},
"allowed_origins": ["*"]
},
"admin": {
"enabled": true,
"external": true,
"password": "q1w2e3r4",
"secret": "7OiEJ6VWrZwE5-n8bTZZONDyKYPqkVpgzS18EMsIqFzGGkwltGzQysSXe0CrqUNn0h26L6YTnFYsB2RhetRPNA"
},
"http_api": {
"key": "--WZmsF-2PDKd3GpbPDRAKqvHTQwI9xdspqkMEGUB3VAhKWZnn2SfBaebicBt7SxFTgosFWa7N3_J9GbUYI9xQ"
},
"health": {
"enabled": true
},
"prometheus": {
"enabled": true
},
"swagger": {
"enabled": true
},
"sse": {
"enabled": true
},
"http_stream": {
"enabled": true
},
"channel": {
"namespaces": [
{
"name": "chat",
"allow_subscribe_for_client": true,
"history_size": 10,
"history_ttl": "1h"
}
]
}
}
逐项说明:http_server 绑定全部网卡并把端口改为 8130(默认 8000 被占用时的调整点);client.allowed_origins 放开浏览器来源校验(["*"] 仅供联调,生产应写精确域名,服务端也会对 * 打出 discourage 警告日志);admin 开启管理界面并暴露在外部端口;health/prometheus/swagger 三个运维端点(/health、/metrics、/swagger/);sse/http_stream 开启 WebSocket 之外的两个双向传输端点;channel.namespaces 声明 chat 命名空间允许客户端订阅并保留最近 10 条、1 小时内的历史消息。所有参数的完整语义、默认值与环境变量覆盖方式见《Centrifugo 6.10 配置参数详解》。
8.3 日常运维命令
sudo systemctl restart centrifugo # 重启(加载所有配置变更)
sudo systemctl reload centrifugo # 热重载配置(SIGHUP,不中断现有连接)
systemctl is-active centrifugo # 运行状态
journalctl -u centrifugo -f # 跟踪日志
热重载实测:修改配置后执行 systemctl reload centrifugo,日志出现确认行:
Oct 21 15:25:52 centrifugo-server centrifugo[4746]: {"level":"info","time":"2026-10-21T15:25:52Z","message":"configuration successfully reloaded"}
8.4 升级、降级与多版本管理(apt 体系)
查看仓库里可用的全部版本:
apt-cache policy centrifugo
实测回显:
centrifugo:
Installed: 6.10.1-0
Candidate: 6.10.1-0
Version table:
*** 6.10.1-0 500
500 https://packagecloud.io/FZambia/centrifugo/ubuntu jammy/main amd64 Packages
100 /var/lib/dpkg/status
6.10.0-0 500
升级与降级都走同一条指定版本安装命令:
sudo apt-get install -y centrifugo=6.10.1-0 # 升级/保持
sudo apt-get install -y centrifugo=6.10.0-0 # 降级到上一版
降级前请先停止服务并用新版本语义校验过的配置做好备份;配置项在跨版本时可能增删,建议每次变更版本后执行 centrifugo checkconfig -s -c /etc/centrifugo/config.json 做严格校验。锁版本防误升:
sudo apt-mark hold centrifugo
tar.gz 方案的多版本管理见 6.7 节。
九、常见问题(FAQ)
Q1:执行 packagecloud 安装脚本报 curl: (22) The requested URL returned error: 404?
仓库路径写错了。正确的是 https://packagecloud.io/install/repositories/FZambia/centrifugo/script.deb.sh,把 FZambia 写成 centrifugo 就会 404。官方文档安装指引见参考链接。
Q2:服务起不来,journalctl 显示 config file not found,但文件明明存在?
配置文件权限问题(详见 4.5 节实测):genconfig 以 0600 权限写配置,服务以 centrifugo 用户运行读不到。执行 sudo chown root:centrifugo /etc/centrifugo/config.json && sudo chmod 640 /etc/centrifugo/config.json 后重启即可。这个错误文案有误导性,本质是「无权限读」而非「文件不存在」。
Q3:客户端 WebSocket 握手收到 403 Forbidden?
服务端按 client.allowed_origins 校验请求的 Origin 头,默认空数组拒绝所有浏览器来源。联调期可临时设 ["*"],生产环境写精确域名列表(如 ["https://app.example.com"])。服务端对 * 会输出警告日志 usage of allowed_origins * is discouraged for security reasons, consider setting exact list of origins。
Q4:WebSocket 连上后立刻被断开,服务端日志显示 bad request(关闭码 3501)?
v6 客户端协议要求每条命令携带自增整数 id 字段(如 {"id":1,"connect":{...}}),缺失 id 的命令被服务端直接拒绝并断连。服务端 debug 日志中对应的判定是 cmd.Id == 0 分支。给每条命令补上 id 即可。
Q5:订阅频道返回 {"error":{"code":103,"message":"permission denied"}}?
两种原因:其一,v6 默认禁止客户端主动订阅任何频道,需要频道所属命名空间配置 allow_subscribe_for_client: true(或改用服务端订阅/订阅令牌);其二,频道名没带命名空间前缀——命名空间 chat 下的频道必须写作 chat:main,写裸的 chat 会落入无命名空间的默认策略(全部拒绝)。
Q6:HTTP API 调用返回 401?
请求头缺少 X-API-Key 或值与配置 http_api.key 不符。注意 API 请求体是 {"method":"publish","params":{...}} 的方法包裹结构,方法名拼错时返回的是 400 Bad Request 纯文本而非 JSON 错误体。
Q7:curl /health 返回 404?
健康检查端点默认关闭,配置 "health": {"enabled": true} 并重启后即可访问(4.8 节实测)。同类的 /metrics、/swagger/ 分别需要 prometheus.enabled、swagger.enabled。
Q8:管理界面(admin UI)访问 /ui/ 返回 404?
v6 的管理界面不再挂在 /ui/ 路径,而是服务根路径 /,且需要 "admin": {"enabled": true, "external": true}(external 控制是否暴露在外部端口)。登录用 POST 表单提交 password 字段到 /admin/auth(JSON Content-Type 会得到 400,8.1 节有实测)。
十、卸载与清理
10.1 apt/deb 安装的卸载
sudo apt-get purge -y centrifugo
实测回显(节选):
After this operation, 92.3 MB disk space will be freed.
(Reading database ... 7344 files and directories currently installed.)
Removing centrifugo (6.10.1-0) ...
(Reading database ... 7335 files and directories currently installed.)
Purging configuration files for centrifugo (6.10.1-0) ...
dpkg: warning: while removing centrifugo, directory '/etc/centrifugo' not empty so not removed
purge 会移除二进制与 systemd 单元,但有两类残留需要手工确认清理(都是安装/运行期生成的非包属主文件):
sudo rm -f /etc/centrifugo/config.json && sudo rmdir /etc/centrifugo # 生成的配置与目录
sudo rm -rf /var/lib/centrifugo /var/log/centrifugo # 数据与日志目录
💡 说明:
/var/lib/centrifugo(运行数据)与/var/log/centrifugo(日志)在卸载后仍保留,重装前清理即可;若计划重装,保留它们也无妨。
10.2 tar.gz 安装的卸载
sudo systemctl stop centrifugo
sudo systemctl disable centrifugo
sudo rm -f /etc/systemd/system/centrifugo.service && sudo systemctl daemon-reload
sudo rm -f /usr/local/bin/centrifugo
sudo rm -rf /opt/centrifugo-6.10.1 /etc/centrifugo /var/lib/centrifugo /var/log/centrifugo
sudo userdel centrifugo
十一、参考链接
- 官方文档安装页:https://centrifugal.dev/docs/getting-started/installation
- 官方快速开始:https://centrifugal.dev/docs/getting-started/quickstart
- GitHub 仓库与 Releases:https://github.com/centrifugal/centrifugo
- 官方软件仓库(packagecloud):https://packagecloud.io/FZambia/centrifugo
- 站内进阶阅读:《Centrifugo 6.10 介绍与选型指南》、《Centrifugo 6.10 配置参数详解》、《Centrifugo 6.10 常用 CLI 命令详解》