- 应用骨架: Solon + MyBatis-Plus + PostgreSQL + Redis + Sa-Token - 核心链路: 回调网关 → 消息落库(幂等) → 分发队列(FOR UPDATE SKIP LOCKED) → worker消费/重试/死信 - 多租户隔离: 前缀法账号映射, 所有业务表带 tenant_id - 管理后台: FreeMarker 渲染, 租户/授权/队列/用量管理页面 - 历史消息补拉: 水位线驱动, getRoamMsg/getGroupMsg 增量拉取, 兜底回调丢失 - msg_key 统一算法(回调/补拉共享, 跨路径去重) Co-Authored-By: Claude <noreply@anthropic.com>
62 lines
2.5 KiB
Java
62 lines
2.5 KiB
Java
package com.imutil.mapper;
|
||
|
||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||
import com.imutil.entity.PullWatermark;
|
||
import org.apache.ibatis.annotations.Insert;
|
||
import org.apache.ibatis.annotations.Param;
|
||
import org.apache.ibatis.annotations.Select;
|
||
|
||
import java.time.OffsetDateTime;
|
||
import java.util.List;
|
||
|
||
/**
|
||
* 补拉水位线 Mapper
|
||
* <p>
|
||
* upsert 用 PG ON CONFLICT,selectNeedCheck 按 updated_at 升序取最久未补拉的会话,
|
||
* 配合补拉成功后推进 updated_at,实现会话轮询公平覆盖。
|
||
*
|
||
* @author imutil
|
||
*/
|
||
public interface PullWatermarkMapper extends BaseMapper<PullWatermark> {
|
||
|
||
/**
|
||
* 水位线 upsert(PG ON CONFLICT)
|
||
* <p>
|
||
* 回调落库 / 补拉推进时调用。last_seq、last_time 取 GREATEST 不回退(防乱序回调回退游标),
|
||
* updated_at 始终刷新为 now(驱动 selectNeedCheck 的轮询顺序)。
|
||
*
|
||
* @param tenantId 租户ID
|
||
* @param convId 会话ID
|
||
* @param convType 会话类型 1=C2C 2=GROUP
|
||
* @param lastSeq 最新消息 Seq
|
||
* @param lastTime 最新消息时间
|
||
* @param now 当前时间(updated_at)
|
||
* @return 影响行数(1=新增或更新)
|
||
*/
|
||
@Insert("INSERT INTO pull_watermark (tenant_id, conv_id, conv_type, last_seq, last_time, updated_at) " +
|
||
"VALUES (#{tenantId}, #{convId}, #{convType}, #{lastSeq}, #{lastTime}, #{now}) " +
|
||
"ON CONFLICT (tenant_id, conv_id) DO UPDATE SET " +
|
||
"last_seq = GREATEST(pull_watermark.last_seq, EXCLUDED.last_seq), " +
|
||
"last_time = GREATEST(pull_watermark.last_time, EXCLUDED.last_time), " +
|
||
"updated_at = EXCLUDED.updated_at")
|
||
int upsert(@Param("tenantId") String tenantId,
|
||
@Param("convId") String convId,
|
||
@Param("convType") int convType,
|
||
@Param("lastSeq") long lastSeq,
|
||
@Param("lastTime") OffsetDateTime lastTime,
|
||
@Param("now") OffsetDateTime now);
|
||
|
||
/**
|
||
* 取最久未补拉的 N 个会话(按 updated_at 升序)
|
||
* <p>
|
||
* 补拉任务每轮调用,updated_at 最老的优先;补拉后 updated_at 推进到 now,
|
||
* 该会话自然排到队尾,实现轮询式公平覆盖。
|
||
*
|
||
* @param limit 每轮会话数
|
||
* @return 待补拉会话列表
|
||
*/
|
||
@Select("SELECT tenant_id, conv_id, conv_type, last_seq, last_time, updated_at " +
|
||
"FROM pull_watermark ORDER BY updated_at ASC LIMIT #{limit}")
|
||
List<PullWatermark> selectNeedCheck(@Param("limit") int limit);
|
||
}
|