外观
Go 后端实现与难点
状态:未准备(核心候选素材,需确认本人贡献)
实现概览
源码根目录:EinoTalk。Go / Gin 提供业务接口,JWT 限制访问,GORM / MySQL 保存实体,Redis 缓存业务数据;聊天服务支持 channel / Kafka 两种入口,Eino 负责 AI 助手编排。
难点与取舍
1. 双消息入口复用公共分发
- 具体问题与背景:channel 与 Kafka 若各写业务逻辑,容易在群发、回显、缓存和 Agent 触发上出现差异。
- 我的实现(候选,待确认):抽取公共 dispatcher,复用消息构造、落库尝试、推送、缓存和 Agent 触发流程。
- 备选方案:两套独立逻辑;所有场景都强制 Kafka。
- 选择理由与限制:单机启动成本低,也能使用队列模式;当前落库失败只记录日志,不能宣称推送与落库原子一致。
- 结果与验证方式:同一组私聊、群聊、回显用例分别验证两种模式,检查结果与失败分支。
- 代码路径 / 证据:
internal/service/chat/dispatch.go、dispatch_test.go、server.go、kafka_server.go。
2. 多实例在线路由与旧连接清理
- 具体问题与背景:消息消费实例可能没有收件人连接,用户重连时旧实例也可能延迟清理路由。
- 我的实现(候选,待确认):Redis 保存在线位置,节点总线转发到目标实例;通过 Lua 比较所有权后再清理路由,避免旧连接删除新映射。
- 备选方案:所有实例广播;统一连接网关;持久化节点队列。
- 选择理由与限制:当前结构便于扩展节点;Pub/Sub 无持久化,节点失联时不保证实时投递,仍需核对历史拉取与丢失处理。
- 结果与验证方式:双实例交叉连接,模拟重连和旧实例延迟下线,核对新路由与实际收包。
- 代码路径 / 证据:
internal/service/chat/cluster_bridge.go、internal/service/cluster/registry.go、internal/service/cluster/bus.go及集成测试。
3. Eino 流式 Agent 与权限范围
- 具体问题与背景:模型生成耗时,逐 token 推送会增加事件频率;工具查询还需要限制业务数据范围。
- 我的实现(候选,待确认):异步触发 Agent,合并流式片段;通过后端注入的身份 / 会话范围执行工具,设置超时与失败提示。
- 备选方案:同步等待完整回复;直接将查询范围交给模型;不使用工具只拼历史文本。
- 选择理由与限制:兼顾渐进反馈和业务授权;上游群成员权限也要独立校验,不能只依靠提示词。Mock 初始化回退不能替代真实调用验证。
- 结果与验证方式:固定问题集,测试首个增量、工具越权、模型超时;聚合阈值是配置参数,不是实测延迟。
- 代码路径 / 证据:
internal/agent/service.go、internal/agent/tools.go、internal/agent/client.go。
4. HTTP 鉴权与前端闭环
- 具体问题与背景:登录用户和管理员可操作的数据、接口不同。
- 我的实现(候选,待确认):服务端 JWT 与管理员中间件限制访问,前端统一附加 token 并处理未认证 / 无权限。
- 备选方案:只在前端隐藏菜单,无法提供服务端授权保证。
- 选择理由与限制:身份校验和具体资源授权是两层要求,不能把有 JWT 等同于全部业务无越权。
- 结果与验证方式:普通用户访问管理员接口、伪造发送者、访问非所属会话等负向用例待运行。
- 代码路径 / 证据:
internal/middleware/auth.go、frontend/src/api/axios.ts。
待完善项
- 简历四条建议:业务与鉴权闭环 → 公共消息分发 → 多实例路由 → AI 助手。以本人贡献为准删减。
- Redis List 追加存在 Pipeline 非事务边界,不写“整个缓存更新原子执行”。
- 会话分区键不等同于端到端严格保序;容量、P95、成功率均待测。