跳到正文

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、成功率均待测。

理解机制,讲清取舍,用复盘检验掌握。