简介:这是一份面向企业级应用场景的运营级在线客服系统源码包,适合需要搭建稳定在线客服渠道的开发者、运维人员及技术管理者。系统基于 Nginx + PHP7.3 + MySQL5.6 环境设计,覆盖实时聊天、消息推送、客服分配、客户信息管理等核心功能,功能全面且扩展性强。资源压缩包约65.96MB,共包含2010个文件,以JavaScript、HTML、CSS等前端资源为主,结合PHP后端逻辑。其中JavaScript文件用于实现交互逻辑,HTML/CSS构建页面框架与样式,PHP脚本处理业务请求,SQL脚本完成数据表与初始数据的创建,Shell脚本则简化服务启动流程。另配有安装配置文档与授权协议,便于快速部署或按业务二次开发。尤其适合没有技术背景的企业用户,依靠附带教程完成上线。目前已有59人学习下载,是一套可直接用于生产环境参考的完整客服系统解决方案。
1. 运营级在线客服系统源码:别再为每个坐席按月付费,这套部署方案能让你自主可控
凌晨两点,访客在咨询页发了一条紧急售后消息,客服没在线,系统也不做离线留言,这条线索就这么丢了。这是很多团队从“网页版聊天插件”升级到“运营级在线客服系统”时最常见的痛点。所谓运营级,不是界面好看,而是会话、坐席、权限、消息可靠性、数据报表这些环节都能支撑真实业务运转——而这正是开源和商业 SaaS 之间最明显的分水岭。这套带教程的运营级在线客服系统源码,适合有技术团队的公司做私有化部署,也适合外包团队拿来做二次开发交付。它解决的核心问题有三个:数据不出自己服务器、坐席权限按需分配、会话记录可回溯可统计。接下来按我实际部署这套系统的顺序,把技术选型、安装步骤、参数调优和踩过的坑一次说清。
2. 把“运营级”三个字拆开:客服系统不只是聊天窗口
在线客服系统从功能上可以分为三个层次:最简单的只能做“网页弹出聊天框 + 转人工”;中等层次加了会话分配、坐席管理、常用语、离线留言;而运营级至少要具备完整的状态机、可审计的消息存储、灵活的权限角色、多维度的统计报表。标题里的“源码”和“教程”指向的正是这第三类系统,它自带部署文档和二次开发接口,但前提是你得先搞清楚每一块模块为什么这么设计。
2.1 会话全生命周期管理:从访客进线到工单归档的状态机
运营级客服系统与普通聊天插件最大的区别,是它把“一段对话”当成一个有状态的对象来管理。访客打开聊天窗口、发起第一条消息时,会话进入“pending”状态;被自动分配或手动接入后变成“active”;客服主动关闭或超时未回复时进入“waiting”;最终归档到“closed”。这四条状态转换不是拍脑袋定的,它直接影响后面所有业务逻辑:未读计数、消息路由、工单生成、满意度评价,全部依赖当前会话状态。
我部署这套源码时,会先在数据库里查看会话表的 state 字段索引是否完善,因为运营后台的“会话列表筛选”和“历史记录查询”都压在这个字段上。如果源码里没做索引,访问量一上来就会慢,这是第一个要动手补的地方。
2.2 坐席与权限体系:运营级和多用户版的分水岭
一个能用于生产环境的客服系统,坐席角色至少要分成三类:管理员、客服组长、普通客服。管理员能看到全队会话记录和统计报表,组长能分配会话和查看组内数据,普通客服只能处理分配给自己或自己接入的会话。这套源码默认带了 RBAC 权限模型,但每个角色的菜单权限和操作权限需要你按业务调整。
这里有个容易被忽略的细节:客服之间的“转接”权限。如果普通客服可以把会话转给任意坐席,权限边界就形同虚设。合规做法是只允许转给同组坐席,跨组转接必须经过组长。我在部署时会在角色配置里把转接目标范围改成“仅本组”,这比事后审计会话操作日志省心得多。
2.3 消息可靠性:为什么聊天记录不能只存 Redis
很多轻量级客服系统喜欢把消息先写 Redis 再用定时任务刷到 MySQL,省事,但运营级系统不能这么干。Redis 是缓存,不是持久化存储,宕机丢消息这种事在客服场景里属于事故。生产级做法是:消息实时写入 MySQL(InnoDB 事务),Redis 只做未读计数和在线状态缓存,WebSocket 推送失败的消息走本地队列重试。
这套源码采用的是双写策略,消息先落库、再推送给在线坐席。我在部署时还会额外开启 MySQL 的 binlog,这样即使误删数据,也能用 binlog 做时间点恢复。聊天记录是客服系统的核心资产,这个钱不能省。
3. 在 Linux 服务器上跑通最小可用系统:从环境准备到手动部署
拿到源码压缩包后,第一件事不是解压运行,而是确认服务器环境。运营级客服系统一般由三个部分组成:Web 服务(PHP 或 Java)、实时推送服务(WebSocket)、数据库层(MySQL + Redis)。不同源码的技术栈不一样,常见的 PHP 版本用 Workerman 做 WebSocket,Java 版本用 Netty 或 Spring Boot + STOMP。这套源码的教程里写了推荐环境,我的建议是先用最小配置跑通,再考虑横向扩展。
3.1 环境规划:PHP、MySQL、Redis 的版本选型
先看服务器配置。我一般建议最低 2 核 4G 内存,操作系统用 Ubuntu 20.04 或 CentOS 7.9,数据库用 MySQL 5.7 或 8.0,Redis 用 5.x 以上。PHP 版本要特别注意,很多旧源码在 PHP 7.4 上正常、到 PHP 8.1 就报错,因为后者对隐式类型转换更严格。
# Ubuntu 20.04 环境准备示例 sudo apt update sudo apt install -y nginx mysql-server redis-server php7.4-fpm php7.4-mysql php7.4-redis php7.4-mbstring php7.4-curl php7.4-zip # 检查服务状态 systemctl status mysql systemctl status redis-server参数说明:php7.4-redis 是 PHP 访问 Redis 的扩展,php7.4-mbstring 处理 UTF-8 中文消息时必需,缺少它会出现在线聊天内容乱码。如果你拿到的是 Java 版源码,就把 PHP 换成 JDK 11 和 Maven,但 MySQL 和 Redis 的选型逻辑不变。
3.2 源码包结构解读与初始化数据库
解压源码后先看目录结构,不要急着配环境。运营级客服系统的源码一般分成 web 前台(访客聊天窗)、admin 后台(坐席工作台)、server 端(推送与接口服务)。三个部分可能在一个工程里,也可能拆成两个或三个目录,教程里通常会给目录对比图。
# 解压并查看目录结构 unzip kefu-source.zip -d /var/www/kefu cd /var/www/kefu ls -la # 常见目录:web/ admin/ server/ sql/ doc/找到 sql 文件夹下的初始化脚本,在 MySQL 里创建数据库并导入。初始化脚本名字一般是 init.sql 或 kefu.sql,里面包含建表语句和默认管理员账号。
mysql -uroot -p CREATE DATABASE kefu DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE kefu; SOURCE /var/www/kefu/sql/init.sql;导完数据后修改配置文件,把数据库连接、Redis 地址、WebSocket 端口改成你的实际环境。配置文件一般叫 .env、config.php 或 application.yml,里面会有类似 DB_HOST、DB_PASSWORD、REDIS_HOST 的键。
# config.php 修改示例(PHP 版) 'db' => [ 'host' => '127.0.0.1', 'port' => 3306, 'name' => 'kefu', 'user' => 'kefu_user', 'pass' => '你的密码', ], 'redis' => [ 'host' => '127.0.0.1', 'port' => 6379, 'auth' => '', ], 'websocket' => [ 'port' => 8280, ],执行完这三步,Web 站点其实已经能访问了,但推送服务还没起来,访客发消息会一直转圈。别急着点“开始体验”,先把 WebSocket 服务启动流程走完。
# 启动 WebSocket 推送服务(PHP 版基于 Workerman) cd /var/www/kefu/server php start.php start -d最后的 -d 参数表示 daemonize,让服务在后台常驻。启动后检查端口是否监听:
netstat -lntp | grep 8280这一步没问题的话,最小可用系统就算跑通了。访问你的服务器 IP,打开访客聊天页,模拟发一条消息,再到坐席后台看是否能收到推送。
4. 把系统调成“运营级”:连接池、消息推送与工单路由的必调参数
跑通是一回事,支撑真实流量是另一回事。我在部署这套客服系统时,发现不少团队卡在同一个误区:系统能跑就以为可以上线,结果运营两周后频繁出现消息延迟和数据库连接数打满。运营级和 demo 级的差距,全在参数调优上。
4.1 WebSocket 推送参数与连接数上限
在线客服系统的实时性全靠 WebSocket 长连接撑着。每个在线访客和每个在线坐席都保持一条长连接,所以连接数峰值 = 同时在线访客数 + 在线坐席数。PHP 版基于 Workerman 时,默认连接数上限受文件描述符限制,需要单独调。
# 调整系统文件描述符上限 vim /etc/security/limits.conf # 文件末尾追加 * soft nofile 65535 * hard nofile 65535 # 并调整 Workerman 服务的配置 vim /var/www/kefu/server/start.php // 设置进程数,按 CPU 核数调整,一般设 4 $worker->count = 4;连接数上来后,另一个瓶颈是 Nginx 反向代理的超时设置。如果你用 Nginx 代理 WebSocket,默认 60 秒无数据就会断开连接,这对客服系统是致命的。要在 Nginx 站点配置里加上长连接支持。
location /ws { proxy_pass http://127.0.0.1:8280; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 3600s; proxy_send_timeout 3600s; }proxy_read_timeout 设成 3600 秒是最低要求。否则客服挂机超过一分钟,连接被 Nginx 掐断,消息就推不过去了。这个坑我踩过不止一次,每次排查都是从客户端看到“连接已断开”的报错。
4.2 MySQL 连接池与慢查询设置
客服系统的消息写入是典型的高频小事务操作,每个访客消息都是一条 insert,坐席回复也是一条 insert。并发高了以后,数据库连接数容易吃满,系统会报“Too many connections”。常见做法是把 max_connections 调大,但更合理的做法是同时调大连接池并优化写入路径。
这套源码如果支持连接池参数,在配置里会看到 pool_size 或 max_connections 的选项。MySQL 侧也要给足连接配额:
# my.cnf 针对客服场景的调整 max_connections = 500 innodb_buffer_pool_size = 1G slow_query_log = ON long_query_time = 2参数说明:innodb_buffer_pool_size 设为物理内存的 50% 左右比较稳妥,2G 内存的服务器就设 1G。慢查询日志打开是排查消息延迟的利器,后面第 5 章会用到。
4.3 自动分配规则与离线留言的边界条件
自动分配是运营级系统的核心功能之一——访客发消息后,系统要按规则把会话推给合适的坐席。常见的分配策略有轮询、按当前会话数最少分配、按技能组分配。这套源码默认用的是“空闲坐席优先”,但如果你所有坐席都显示忙碌,会话会停在 pending 状态,访客侧没有任何提示。
我一般会在运营后台把“无坐席可用时的提示语”和“离线留言开关”配合着配置。如果业务上要求必须即时响应,就把队列等待上限设成 30 秒,超时自动转离线留言。这样既不让访客干等,也不至于漏掉线索。
5. 上线前必看:五个让客服系统翻车的常见问题与排查思路
任何客服系统上线前几周都是问题高发期。以下是这几次部署中反复出现的故障模式,按“现象→原因→解决”整理。每一条我都亲手排查过,照着顺序做能少走半天弯路。
5.1 现象:访客消息能发出去,坐席工作台却收不到
前端显示发送成功,后台不弹窗,这是推送链路问题。原因是 WebSocket 服务没有启动或已经崩溃,访客消息入库成功但推送环节失败。排查第一步看推送进程是否存活:
ps aux | grep start.php netstat -lntp | grep 8280如果进程没了,看日志 server/log 下的 workerman.log,常见的报错是端口被占用或内存不足。解决方法是重启服务并确认配置的端口没有和别的服务冲突。
5.2 现象:系统越用越慢,MySQL 报“Too many connections”
连接数打满通常是两种原因:连接池配置太小,或代码里每次请求都新建连接而没释放。可以先临时调大连接数救急,更重要的是从慢查询日志里找出占用连接的元凶:
mysql -uroot -p SHOW PROCESSLIST;观察有没有大量 State 为 Sleeping 的连接,如果有,说明连接没有复用,属于代码层面的连接泄漏。常见解法是把数据库操作改成统一的单例模式,或者在框架层面启用长连接。在快速修复时,把 wait_timeout 调短让空闲连接尽快释放也能缓解:
SET GLOBAL wait_timeout = 60;5.3 现象:重启服务后聊天记录里的中文变成乱码
这属于典型的基础设施坑。原因是数据库连接字符集和表字符集不一致,源码的建表语句用的是 utf8mb4,但 PHP 连接 MySQL 时默认用的可能还是 utf8。
解决方式是同时处理两个位置:源码的数据库配置文件里把 charset 改成 utf8mb4,并确认表结构本身是 utf8mb4。
ALTER TABLE kefu_message CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ALTER TABLE kefu_session CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;改完重启服务,新写入的消息就不会乱码,但历史乱码数据需要单独修复。
5.4 现象:WebSocket 每隔一段时间就自动断开,坐席在线状态闪烁
在线状态不稳定,最常见原因是 Nginx 的 proxy_read_timeout 没设置(前面已经提过),其次是服务器防火墙或负载均衡器对长连接做了空闲超时。如果部署在内网,还要确认交换机或云厂商的 LB 是否开启 TCP 空闲超时。解决方法是把超时参数统一调到 3600 秒以上,并开启 WebSocket 的心跳机制,服务端每 30 秒 ping 一次,客户端响应 pong,这样链路一直有数据在走,就不容易触发超时。
5.5 现象:坐席工作台加载慢,消息记录要转好几秒才出来
打开历史会话慢,通常是数据库查询没走索引。会话表和消息表的数据量增长后,如果只靠主键查询而不给 session_id 和 create_time 加复合索引,翻页查询会全表扫描。
在 MySQL 里补齐常用查询条件的索引:
ALTER TABLE kefu_message ADD INDEX idx_session_time (session_id, create_time); ALTER TABLE kefu_session ADD INDEX idx_state_updated (state, updated_at);加完索引后测试同样的查询,通常能从秒级降到毫秒级。这里必须注意:索引不是越多越好,上述两个索引覆盖了消息查询和会话列表两条高频路径,够用即可。
6. 从“能用”到“好用”的进阶验证:压测、备份与多商户改造技巧
最后一章不写总结,写三个我每次交付前都要做的动作,它们决定了这套系统在真实运营中能走多远。
6.1 用压测验证推送瓶颈在哪里
上线前至少做一次压测,但不要一上来就压两千并发。我习惯先压 50 并发,观察消息推送延迟;再逐步升到 200、500,同时盯三个指标:WebSocket 连接成功率、消息端到端延迟、MySQL 慢查询数量。
压测工具用现成的即可,比如用脚本模拟 200 个 WebSocket 客户端同时连接、发消息。压测时如果发现 CPU 没满但消息延迟变大,瓶颈在 MySQL;如果 MySQL 响应正常但推送延迟高,瓶颈在 WebSocket 服务的进程数配置。这两种情况的调法不同,前者加数据库索引或提升硬件配置,后者加 worker 进程数。
6.2 每日凌晨全量备份,外加 binlog 增量备份
客服系统的聊天记录不可再生,定时备份是底线。我的习惯是每天凌晨 3 点做一次全量备份,保留最近 7 天,同时开启 MySQL binlog 做增量。全量备份用 mysqldump,增量备份靠 mysqlbinlog 定期拉取。
# 每日全量备份脚本示例(crontab 每天执行) mysqldump -ukefu_user -p密码 kefu --single-transaction --quick | gzip > /backup/kefu_$(date +\%Y\%m\%d).sql.gz find /backup -name "*.sql.gz" -mtime +7 -delete注意 --single-transaction 参数,它保证备份时不会锁表,客服系统在线期间执行备份不影响业务。恢复演练建议每季度做一次,不要等真出事才发现备份文件是坏的。
6.3 多商户改造的最小改动点:租户字段与数据隔离
如果你打算拿这套源码做 SaaS 交付,会遇到一个绕不开的话题——多商户。每个企业客户都要自己的坐席、会话和数据,但共用一套部署。常见做法是在核心表里加 tenant_id 字段,所有查询强制带上这个条件。
先加字段,再改查询逻辑,最后改写入逻辑。注意不止是会话表和消息表,坐席表、工单表、配置表全部要加。改造时最容易漏的是 WebSocket 推送服务里的过滤条件——坐席登录时把 tenant_id 传入连接鉴权,推送消息时按 tenant_id 过滤接收方,否则就会发生“A 企业的客服收到 B 企业消息”的事故。
最后的习惯是,我每次部署完都会故意错误登录几次、手动断开几次 WebSocket、删一条生产数据再恢复,确保这套系统在故障面前有后悔药可吃。这套源码加教程的真正价值不在开箱即用,而在你能顺着文档把每个模块看懂、改掉、压过、备份好。希望这些部署和排障经历能帮到你。
本文还有配套的精品资源,点击获取