fix(service): 优化向量搜索超时与中断处理
新增 ListenableFuture 超时保护(10s),捕获中断与超时异常并恢复中断状态,提升高并发鲁棒性。
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package com.yolo.keyborad.service.impl;
|
||||
|
||||
import com.google.common.primitives.Floats;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.yolo.keyborad.common.ErrorCode;
|
||||
import com.yolo.keyborad.exception.BusinessException;
|
||||
import com.yolo.keyborad.model.vo.QdrantSearchItem;
|
||||
@@ -88,19 +89,32 @@ public class QdrantVectorService {
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 搜索向量(高并发优化版本,避免阻塞线程池)
|
||||
*
|
||||
* @param userVector 用户输入的向量
|
||||
* @param limit 返回结果数量限制
|
||||
* @return 搜索结果列表
|
||||
*/
|
||||
public List<QdrantSearchItem> searchPoint(float[] userVector, int limit) {
|
||||
try {
|
||||
Points.QueryPoints query = Points.QueryPoints.newBuilder()
|
||||
.setCollectionName(COLLECTION_NAME) // ★ 必须
|
||||
.setQuery(nearest(userVector)) // ★ 语义向量
|
||||
.setLimit(limit) // 限制返回数量
|
||||
.setWithPayload(enable(true)) // ★ 带上 payload
|
||||
.setWithPayload(enable(true)) // ★ 带上 payload
|
||||
.build();
|
||||
|
||||
List<Points.BatchResult> batchResults = qdrantClient.queryBatchAsync(
|
||||
// 使用 ListenableFuture,添加超时保护
|
||||
ListenableFuture<List<Points.BatchResult>> future = qdrantClient.queryBatchAsync(
|
||||
COLLECTION_NAME,
|
||||
List.of(query)
|
||||
).get();
|
||||
);
|
||||
|
||||
// 设置超时时间(10秒),避免无限等待
|
||||
List<Points.BatchResult> batchResults = future.get(
|
||||
10, java.util.concurrent.TimeUnit.SECONDS
|
||||
);
|
||||
Points.BatchResult batchResult = batchResults.get(0);
|
||||
|
||||
// 3. 把 Protobuf 的 ScoredPoint 转成你的 DTO
|
||||
@@ -129,10 +143,17 @@ public class QdrantVectorService {
|
||||
})
|
||||
.toList();
|
||||
|
||||
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
log.error("search point 失败", e);
|
||||
throw new BusinessException(ErrorCode.OPERATION_ERROR);
|
||||
} catch (InterruptedException e) {
|
||||
// 恢复中断状态,避免吞掉中断信号
|
||||
Thread.currentThread().interrupt();
|
||||
log.error("search point 被中断", e);
|
||||
throw new BusinessException(ErrorCode.OPERATION_ERROR, "向量搜索被中断");
|
||||
} catch (java.util.concurrent.TimeoutException e) {
|
||||
log.error("search point 超时", e);
|
||||
throw new BusinessException(ErrorCode.OPERATION_ERROR, "向量搜索超时,请稍后重试");
|
||||
} catch (ExecutionException e) {
|
||||
log.error("search point 执行失败", e);
|
||||
throw new BusinessException(ErrorCode.OPERATION_ERROR, "向量搜索执行失败");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user