
先从一个我经手的选型场景说起。当时一家制造业公司找我做内部通讯工具升级车间、办公室加起来两百多人每天在微信群里传图纸、排班表、质量报告结果最常见的问题就是文件过期、记录被清理、新员工进来啥历史都看不到更麻烦的是产品图纸全在公网服务器上过了一遍。折腾了几套方案后我把目光放在私有化部署的局域网即时通讯工具上最终接触了 BeeWorks。这篇文章就是我对 BeeWorks 从调研、部署到上线维护的完整复盘包括资源估算、安装步骤、上线后真实踩过的坑以及把 IM 扩成企业内部通讯底座的一些思路适合正在做 IM 选型的 IT 负责人也适合只有一两台服务器、却想彻底摆脱公网依赖的中小团队。1. 为什么要把即时通讯做进局域网1.1 私有化部署解决的不只是“数据安全”很多团队一上来就盯着加密、审计这些词实际上私有化部署最先解决的是“数据的物理位置”。用 BeeWorks 这类局域网 IM所有消息记录、图片、文件、音视频都落在你自己的服务器或者 NAS 上客户端跟服务器之间走的是内网交换机或无线 AP不经过任何第三方服务器。这意味着哪怕办公室外网断掉只要局域网还在工作沟通照常进行。我在生产环境里还发现一个容易被忽略的好处网速可控。公有云 IM 的消息收发受上行带宽影响Wi-Fi 信号不好时发个大文件经常失败。而内网部署走的是千兆局域网文件传输瓶颈主要在磁盘速度体验会明显好一个档次。1.2 你的团队现在需要局域网 IM 吗用下面几个问题自测如果命中两个以上就说明该认真考虑私有化部署公司有自建机房或常开机的服务器希望核心沟通数据留在内网业务涉及研发代码、设计源文件、客户合同等敏感信息不适合经外部服务器中转工位、车间、库房存在固定内网环境员工多数时间坐在办公室需要完整的消息留痕账号、组织架构、权限都由企业自己管理公有云办公软件经常出现文件过期或群聊内容无法按部门隔离。当然BeeWorks 也不是万能的。如果你们的核心诉求是让客户、供应商也加入聊天或者需要跟微信生态直接互通那局域网私有化 IM 本身就不是为这种场景设计的需要额外做网关和服务号对接复杂度会明显上升。我更愿意把它定位成“企业内部的抖音”只给内部人用内容完全受控。1.3 一个成熟的私有化 IM 该具备哪些基本功单聊、群聊、文件传输这些只是最基础的功能。真正让 BeeWorks 从“玩具”变成“生产力工具”的是这几个能力组织架构同步按公司部门创建通讯录离职账号一键禁用消息记录持久化不是阅后即焚而是可检索、可导出、可审计权限分级普通员工只能看自己相关的群和文件管理员可以配置消息备份策略高并发下的长连接稳定性一两百人同时在线时不能出现大规模延迟或掉线多端支持Windows、macOS、Linux以及手机端在局域网内的访问。这些点决定了工具在真实办公场景里能不能站住脚而不是只在演示环境里跑得动。2. 部署前必须想清楚的架构和资源问题2.1 服务端组件拆解别再被“一体机”带偏BeeWorks 的部署形态通常是把所有业务组件打成容器镜像本地用 Docker 或 Podman 跑起来。它一般包含下面几块组件作用我的习惯部署方式消息核心服务处理单聊、群聊、在线状态、消息路由主服务器容器负责业务逻辑文件服务保存图片、附件、音视频同一宿主机数据目录独立挂载数据库用户、群关系、消息索引、审计日志MySQL 8.0生产环境建议主从缓存在线状态、未读计数、分布式锁Redis 6.2 以上做持久化管理后台组织架构、账号、策略配置Web 控制台通常和核心服务分开端口这里要提醒一句不要一开始就把服务端往 Kubernetes 上堆除非你真的有十几个节点。企业内网场景一台 4C8G 的服务器跑容器编排比裸机好维护得多也比 K8s 简单得多。所谓“一体化套路”在大多数局域网场景里其实是过度设计。2.2 服务器配置到底怎么算给你一个可以直接套的公式很多朋友问我两百人部署 BeeWorks 要买多大服务器我一般会给一个经验公式而不是直接甩一张配置表。内存方面物理内存 ≈ 最大在线用户数 × 4MB 到 5MB再加上系统本身和数据库缓存的余量。比如 200 人团队按所有员工都同时在线4MB × 200 0.8GB再算上 MySQL 的 InnoDB 缓冲池、Redis 缓存、文件服务的临时索引整机建议 8GB 起步。如果你们经常开大型直播会议内存需求还要再往上加。CPU 方面双核机器带五六十人没问题超过一百人建议直接上 4 核再往上重点其实在网络连接数而不是 CPU 主频。IM 的并发瓶颈通常在并发连接和数据库写入不在简单加减法。磁盘方面按消息量来估。我见过一个约 300 人的内部团队工作日平均每天产生 1.8 万条消息左右。假设每条消息落库约 1.2KB一天是 21.6MB一年大约 7.9GB算上索引膨胀数据库一年 15GB 左右比较常见。文件附件另算图片视频占用的空间往往比数据库大一个量级。所以我部署时给的默认推荐是系统盘 100GB 以上数据盘独立挂载容量至少 500GB。2.3 客户端怎么连服务器域名比 IP 好用得多局域网内最让人头疼的不是装服务而是客户端填服务器地址。我强烈建议你在内网 DNS 里配一条 A 记录比如im.internal.company.com指向服务器内网 IP而不是让每个员工去记192.168.1.88:8080这种地址。原因很简单以后服务迁移、端口调整、IP 变动客户端那边的地址都不用改。如果没有独立 DNS 服务也可以先用各终端 hosts 文件顶一阵子但那是应急方案不是长期方案。规模稍大一点还是要把内网 DNS 做起来。3. 在测试环境里把 BeeWorks 跑起来3.1 为什么我选择容器化部署而不是直接装 RPM我一开始也在物理机上直接跑过传统安装包后来切到 Docker是因为三个痛点一是依赖冲突太常见OpenSSL、icu、libevent 这些库版本不同装一次折腾半宿二是升级回滚难直接覆盖安装很容易留下残留配置三是离线环境部署不方便而容器可以提前在联网环境把镜像导出成 tar 包拿到内网再导入效率完全不同。所以下面的流程都基于 Docker Compose。如果你所在的网络完全离线记得提前下载 Docker 的离线安装包、Compose 插件以及 BeeWorks 镜像包。3.2 初始化系统环境我用的是 Ubuntu Server 22.04 LTS系统装好后先更新内核 IP 转发和内网 DNS。以下命令在测试阶段够用# 安装基础工具 sudo apt update sudo apt install -y curl wget vim net-tools # 安装 Docker离线环境请用内网软件源或 dpkg 方式安装 curl -fsSL https://get.docker.com | sudo sh # 安装 compose 插件 sudo apt install -y docker-compose-plugin然后建立部署目录sudo mkdir -p /opt/beeworks/{config,data/mysql,data/files,data/redis,backup}3.3 一份可参考的 docker-compose.yml下面是我部署时使用的 Compose 文件核心结构具体的镜像名和版本号请以你拿到的 BeeWorks 安装包为准。不要指望一份配置通用所有版本但框架基本是这样version: 3.8 services: beeworks-core: image: registry.internal/beeworks/core:3.2.0 container_name: beeworks-core restart: always ports: - 8080:8080 - 8081:8081 environment: DB_HOST: beeworks-mysql DB_USER: beeworks DB_PASSWORD: your_db_password REDIS_HOST: beeworks-redis FILE_STORE: /data/files volumes: - ./data/files:/data/files - ./config:/app/config depends_on: - beeworks-mysql - beeworks-redis beeworks-mysql: image: mysql:8.0 container_name: beeworks-mysql restart: always environment: MYSQL_ROOT_PASSWORD: your_root_password MYSQL_DATABASE: beeworks MYSQL_USER: beeworks MYSQL_PASSWORD: your_db_password volumes: - ./data/mysql:/var/lib/mysql command: --character-set-serverutf8mb4 --collation-serverutf8mb4_unicode_ci beeworks-redis: image: redis:6.2 container_name: beeworks-redis restart: always volumes: - ./data/redis:/data command: redis-server --appendonly yes注意几点MySQL 一定要开utf8mb4否则中文和 emoji 在历史记录里会出现乱码式问题Redis 开appendonly yes否则服务重启后在线状态和未读计数可能丢失。数据库密码不要用简单密码我见过太多部署最后栽在弱密码导致的异常审计记录上。3.4 初始化数据库与创建管理员镜像启动后进到容器里执行数据迁移和创建管理员cd /opt/beeworks docker compose up -d # 等待 MySQL 初始化完成 docker compose logs -f beeworks-mysql # 执行数据库迁移具体命令以安装包文档为准 docker compose exec beeworks-core /app/bin/manage.py migrate docker compose exec beeworks-core /app/bin/manage.py createsuperuser如果迁移提示连接不上数据库先检查depends_on和容器网络很多时候是 MySQL 还在初始化多等一下再执行。3.5 客户端接入与首次登录服务端起来后浏览器打开http://im.internal.company.com:8081进入管理后台创建部门和员工账号。客户端安装包可以从后台下载也可以用 U 盘分发到各工位。客户端登录时服务器地址填im.internal.company.com:8080协议用 HTTP如果走 HTTPS 需要提前在网关配好证书。首次登录成功后先测三件事单聊消息是否秒达、传一个 100MB 的文件、建一个全员大群看消息顺序。这三项过了基本可以交给业务团队测试。4. 上线后最容易踩的坑以及完整排查链路4.1 客户端一直提示“无法连接服务器”怎么办我曾经在一个客户现场遇到整整一个楼层连不上 BeeWorks研发的直觉是服务挂了但服务端日志明明正常。后来排查下去问题出在客户端的 hosts 文件里还是旧 IP服务器换了网卡地址后没有同步。这里把排查链路完整写出来你照着做能找到 90% 的问题第一步先确认网络层通不通。在出问题的电脑上执行ping im.internal.company.com不同说明 DNS 解析有问题检查内网 DNS 记录和 hosts 文件。第二步确认端口通不通telnet im.internal.company.com 8080如果通说明核心服务至少能建立 TCP 连接如果不通大概率是端口未映射、防火墙拦截或者 Docker 容器根本没起来。第三步看服务端容器状态cd /opt/beeworks docker compose ps docker compose logs -f --tail200 beeworks-core重点看日志里有没有数据库连接超时、Redis 超时、磁盘读写权限的报错。我踩过的坑里最快定位的一次就是因为文件存储目录权限不对服务一直处于半启动状态。第四步看防火墙。如果装了 ufw确认端口放行sudo ufw status sudo ufw allow 8080/tcp sudo ufw allow 8081/tcp企业级网络还有硬件防火墙需要让网络管理员放行对应端口和源 IP 段。这种情况最常见的特征是服务端本机能访问其他电脑都不行。4.2 大群消息在无线网络下延迟严重办公室 Wi-Fi 环境下大群消息经常出现“延迟几秒到几十秒”的情况。这不是 BeeWorks 本身的问题而是无线网络半双工和带宽争抢导致 TCP 重传率上升。排查时我在服务端用两个命令看当前连接和实时流量ss -s iftop -n -P如果看到某台客户端的 TCP 连接大量重传就要考虑是不是 AP 带机量过高。简单的解决办法是把办公网络按部门拆成多个 SSID或者限制每个 AP 的最大接入数在交换机上给 IM 服务的端口做优先级配置让消息流量不被视频下载挤占。另外一定要提醒员工不要用 Wi-Fi 省电模式很多手机锁屏后会把长连接杀掉导致消息要亮屏才推送。4.3 文件存储和数据库的无序增长部署完三个月最容易忽略的是磁盘。图片、视频、语音消息会在文件存储目录里越堆越多。我的处理方案是分两层第一层定时清理临时文件缓存。很多版本会在发送失败后留下临时文件这个目录长时间不清理会悄悄占空间。可以用一个简单的 cron 任务# 每天凌晨 3 点清理 7 天前的临时文件 0 3 * * * find /opt/beeworks/data/files/temp -type f -mtime 7 -delete第二层数据库消息归档。直接 delete 历史消息是大忌一旦误删找不回来。我会先用自带导出功能把历史消息导出成 JSON再归档到备份目录然后才清理过期消息。建议备份顺序是先备份 MySQL再导出消息文件最后清理。4.4 数据库连接数占满导致的“服务忽好忽坏”还有一个很隐蔽的坑MySQL 默认最大连接数是 151对数据库连接池配置不合理的 IM 服务来说客户端一批批量登录时连接数很容易打满。表现症状是前几分钟很正常一到上班高峰期就大量超时。排查时进入 MySQL 看当前连接数docker compose exec beeworks-mysql mysql -uroot -p -e show variables like max_connections; docker compose exec beeworks-mysql mysql -uroot -p -e show status like Threads_connected;如果 Threads_connected 长期接近 max_connections就要把最大连接数调大同时让核心服务的连接池复用现有连接而不是每个请求都新建连接。单机部署建议把 max_connections 调到 300 左右再配合 Redis 缓存降低数据库压力。5. 从“能聊”到“好用”变成企业的通讯底座5.1 生产环境的高可用和消息不丢如果 BeeWorks 承担的是日常生产沟通单机部署只能算是验证环境。我会在生产环境至少做三件事数据库做主从复制定时同步到备机文件存储目录挂到 RAID 磁盘或者定期同步到 NAS消息核心服务做双实例配合负载均衡做故障转移。消息可靠性这块注意看客户端发送状态是不是“已提交到服务器后再显示成功”。我们踩过教训有些客户端在弱网下盲目重试导致一条消息发了两遍接收方看到重复内容。后来发现关键在于服务端要落库成功后再返回 ACK客户端收到 ACK 才算发送完成。5.2 多楼宇、分支机构的局域网接入方式很多公司不止一个办公区两个楼宇距离几百米到几公里都有。最稳妥的方式不是把 BeeWorks 暴露到公网而是优先考虑内网打通同园区可以拉光缆跨楼宇可以租运营商专线让 BeeWorks 服务端放在总部分厂客户端通过内部路由访问同一条内网网段。如果距离远到必须跨公网我个人的建议是用带有加密功能的企业接入网关而不是简单地在路由器上做端口映射。端口映射不仅容易被扫描而且把消息服务直接暴露出去和私有化部署的初衷就是矛盾的。5.3 对接 LDAP、OA让通讯录和待办自动流转BeeWorks 真正发挥价值的地方是可以变成整个企业的通讯底座。最常见的是对接统一身份认证LDAP/AD员工入职自动开通账号离职自动禁用不再需要管理员手工维护一份通讯录。集成方向常见方式解决的核心问题统一身份认证LDAP / AD 同步账号生命周期自动化OA 待办Webhook 推送到 IM审批结果第一时间触达消息通知服务端 API业务系统告警发到对应群组文件归档文件服务目录挂载审计日志和附件集中管理这些集成做完后员工的工作流会慢慢沉淀在 IM 里而不是散落在各种外部工具中。5.4 团队规模翻倍后的扩容路径最后说说扩容。BeeWorks 初期可能是单机跑着等到三百人、五百人时我会按这样的优先顺序调整先分离数据库和文件存储到独立主机再给核心服务加一个实例做负载均衡最后把文件存储换成内网对象存储比如 MinIO。每一步都不需要停机因为容器化的好处就是可以先加实例再切换流量。我自己的习惯是在扩容前先做一轮消息量和并发压测用脚本模拟全员同时登录、同时群发看服务端的延迟曲线。只要延迟曲线在 100ms 以内就说明当前架构还有余量。如果超过 300ms优先检查数据库慢查询和网络带宽而不是急着堆硬件。说到底私有化部署这件事的价值不在于服务器有多新而在于数据主权和管理边界是否真的掌握在自己手里。BeeWorks 这类工具把部署门槛降了下来真正考验人的反而是运维习惯备份是否每天执行、磁盘告警是否接入、权限是否有人定期核对。希望上面这些经验能帮你把 IM 从“能用”推到“好用”。