mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-04-16 21:33:40 +00:00
feat: 修改目前实现类使用统一重试降级逻辑;
This commit is contained in:
@@ -14,6 +14,8 @@ import org.springframework.stereotype.Component;
|
|||||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import org.ruoyi.chat.support.RetryNotifier;
|
||||||
|
import org.ruoyi.chat.util.SSEUtil;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@@ -21,12 +23,18 @@ import java.util.Objects;
|
|||||||
public class FastGPTSSEEventSourceListener extends EventSourceListener {
|
public class FastGPTSSEEventSourceListener extends EventSourceListener {
|
||||||
|
|
||||||
private SseEmitter emitter;
|
private SseEmitter emitter;
|
||||||
|
private Long sessionId;
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
public FastGPTSSEEventSourceListener(SseEmitter emitter) {
|
public FastGPTSSEEventSourceListener(SseEmitter emitter) {
|
||||||
this.emitter = emitter;
|
this.emitter = emitter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FastGPTSSEEventSourceListener(SseEmitter emitter, Long sessionId) {
|
||||||
|
this.emitter = emitter;
|
||||||
|
this.sessionId = sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOpen(EventSource eventSource, Response response) {
|
public void onOpen(EventSource eventSource, Response response) {
|
||||||
log.info("FastGPT sse连接成功");
|
log.info("FastGPT sse连接成功");
|
||||||
@@ -40,6 +48,9 @@ public class FastGPTSSEEventSourceListener extends EventSourceListener {
|
|||||||
if ("flowResponses".equals(type)){
|
if ("flowResponses".equals(type)){
|
||||||
emitter.send(data);
|
emitter.send(data);
|
||||||
emitter.complete();
|
emitter.complete();
|
||||||
|
if (sessionId != null) {
|
||||||
|
RetryNotifier.clear(sessionId);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
emitter.send(data);
|
emitter.send(data);
|
||||||
}
|
}
|
||||||
@@ -57,13 +68,26 @@ public class FastGPTSSEEventSourceListener extends EventSourceListener {
|
|||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void onFailure(EventSource eventSource, Throwable t, Response response) {
|
public void onFailure(EventSource eventSource, Throwable t, Response response) {
|
||||||
if (Objects.isNull(response)) {
|
if (Objects.isNull(response)) {
|
||||||
|
if (sessionId != null) {
|
||||||
|
SSEUtil.sendErrorEvent(emitter, t != null ? t.getMessage() : "SSE连接失败");
|
||||||
|
RetryNotifier.notifyFailure(sessionId);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ResponseBody body = response.body();
|
ResponseBody body = response.body();
|
||||||
if (Objects.nonNull(body)) {
|
if (Objects.nonNull(body)) {
|
||||||
log.error("FastGPT sse连接异常data:{},异常:{}", body.string(), t);
|
String msg = body.string();
|
||||||
|
log.error("FastGPT sse连接异常data:{},异常:{}", msg, t);
|
||||||
|
if (sessionId != null) {
|
||||||
|
SSEUtil.sendErrorEvent(emitter, msg);
|
||||||
|
RetryNotifier.notifyFailure(sessionId);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.error("FastGPT sse连接异常data:{},异常:{}", response, t);
|
log.error("FastGPT sse连接异常data:{},异常:{}", response, t);
|
||||||
|
if (sessionId != null) {
|
||||||
|
SSEUtil.sendErrorEvent(emitter, String.valueOf(response));
|
||||||
|
RetryNotifier.notifyFailure(sessionId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
eventSource.cancel();
|
eventSource.cancel();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
import org.ruoyi.chat.support.RetryNotifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扣子聊天管理
|
* 扣子聊天管理
|
||||||
@@ -53,6 +54,7 @@ public class CozeServiceImpl implements IChatService {
|
|||||||
Flowable<ChatEvent> resp = coze.chat().stream(req);
|
Flowable<ChatEvent> resp = coze.chat().stream(req);
|
||||||
ExecutorService executor = Executors.newFixedThreadPool(10);
|
ExecutorService executor = Executors.newFixedThreadPool(10);
|
||||||
executor.submit(() -> {
|
executor.submit(() -> {
|
||||||
|
try {
|
||||||
resp.blockingForEach(
|
resp.blockingForEach(
|
||||||
event -> {
|
event -> {
|
||||||
if (ChatEventType.CONVERSATION_MESSAGE_DELTA.equals(event.getEvent())) {
|
if (ChatEventType.CONVERSATION_MESSAGE_DELTA.equals(event.getEvent())) {
|
||||||
@@ -62,10 +64,15 @@ public class CozeServiceImpl implements IChatService {
|
|||||||
if (ChatEventType.CONVERSATION_CHAT_COMPLETED.equals(event.getEvent())) {
|
if (ChatEventType.CONVERSATION_CHAT_COMPLETED.equals(event.getEvent())) {
|
||||||
emitter.complete();
|
emitter.complete();
|
||||||
log.info("Token usage: {}", event.getChat().getUsage().getTokenCount());
|
log.info("Token usage: {}", event.getChat().getUsage().getTokenCount());
|
||||||
|
RetryNotifier.clear(chatRequest.getSessionId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
RetryNotifier.notifyFailure(chatRequest.getSessionId());
|
||||||
|
} finally {
|
||||||
coze.shutdownExecutor();
|
coze.shutdownExecutor();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import org.ruoyi.chat.support.RetryNotifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dify 聊天管理
|
* dify 聊天管理
|
||||||
@@ -112,20 +113,24 @@ public class DifyServiceImpl implements IChatService {
|
|||||||
chatRequestResponse.setSessionId(chatRequest.getSessionId());
|
chatRequestResponse.setSessionId(chatRequest.getSessionId());
|
||||||
chatRequestResponse.setPrompt(respMessage.toString());
|
chatRequestResponse.setPrompt(respMessage.toString());
|
||||||
chatCostService.deductToken(chatRequestResponse);
|
chatCostService.deductToken(chatRequestResponse);
|
||||||
|
RetryNotifier.clear(chatRequest.getSessionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(ErrorEvent event) {
|
public void onError(ErrorEvent event) {
|
||||||
System.err.println("错误: " + event.getMessage());
|
System.err.println("错误: " + event.getMessage());
|
||||||
|
RetryNotifier.notifyFailure(chatRequest.getSessionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onException(Throwable throwable) {
|
public void onException(Throwable throwable) {
|
||||||
System.err.println("异常: " + throwable.getMessage());
|
System.err.println("异常: " + throwable.getMessage());
|
||||||
|
RetryNotifier.notifyFailure(chatRequest.getSessionId());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("dify请求失败:{}", e.getMessage());
|
log.error("dify请求失败:{}", e.getMessage());
|
||||||
|
RetryNotifier.notifyFailure(chatRequest.getSessionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return emitter;
|
return emitter;
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class FastGPTServiceImpl implements IChatService {
|
|||||||
ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
|
ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
|
||||||
OpenAiStreamClient openAiStreamClient = ChatConfig.createOpenAiStreamClient(chatModelVo.getApiHost(), chatModelVo.getApiKey());
|
OpenAiStreamClient openAiStreamClient = ChatConfig.createOpenAiStreamClient(chatModelVo.getApiHost(), chatModelVo.getApiKey());
|
||||||
List<Message> messages = chatRequest.getMessages();
|
List<Message> messages = chatRequest.getMessages();
|
||||||
FastGPTSSEEventSourceListener listener = new FastGPTSSEEventSourceListener(emitter);
|
FastGPTSSEEventSourceListener listener = new FastGPTSSEEventSourceListener(emitter, chatRequest.getSessionId());
|
||||||
FastGPTChatCompletion completion = FastGPTChatCompletion
|
FastGPTChatCompletion completion = FastGPTChatCompletion
|
||||||
.builder()
|
.builder()
|
||||||
.messages(messages)
|
.messages(messages)
|
||||||
@@ -41,7 +41,12 @@ public class FastGPTServiceImpl implements IChatService {
|
|||||||
.detail(true)
|
.detail(true)
|
||||||
.stream(true)
|
.stream(true)
|
||||||
.build();
|
.build();
|
||||||
|
try {
|
||||||
openAiStreamClient.streamChatCompletion(completion, listener);
|
openAiStreamClient.streamChatCompletion(completion, listener);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
org.ruoyi.chat.support.RetryNotifier.notifyFailure(chatRequest.getSessionId());
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
return emitter;
|
return emitter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import org.ruoyi.chat.support.RetryNotifier;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,12 +67,15 @@ public class OllamaServiceImpl implements IChatService {
|
|||||||
emitter.send(substr);
|
emitter.send(substr);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
SSEUtil.sendErrorEvent(emitter, e.getMessage());
|
SSEUtil.sendErrorEvent(emitter, e.getMessage());
|
||||||
|
RetryNotifier.notifyFailure(chatRequest.getSessionId());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
api.chat(requestModel, streamHandler);
|
api.chat(requestModel, streamHandler);
|
||||||
emitter.complete();
|
emitter.complete();
|
||||||
|
RetryNotifier.clear(chatRequest.getSessionId());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
SSEUtil.sendErrorEvent(emitter, e.getMessage());
|
SSEUtil.sendErrorEvent(emitter, e.getMessage());
|
||||||
|
RetryNotifier.notifyFailure(chatRequest.getSessionId());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -51,15 +51,18 @@ public class QianWenAiChatServiceImpl implements IChatService {
|
|||||||
public void onCompleteResponse(ChatResponse completeResponse) {
|
public void onCompleteResponse(ChatResponse completeResponse) {
|
||||||
emitter.complete();
|
emitter.complete();
|
||||||
log.info("消息结束,完整消息ID: {}", completeResponse);
|
log.info("消息结束,完整消息ID: {}", completeResponse);
|
||||||
|
org.ruoyi.chat.support.RetryNotifier.clear(chatRequest.getSessionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(Throwable error) {
|
public void onError(Throwable error) {
|
||||||
error.printStackTrace();
|
error.printStackTrace();
|
||||||
|
org.ruoyi.chat.support.RetryNotifier.notifyFailure(chatRequest.getSessionId());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("千问请求失败:{}", e.getMessage());
|
log.error("千问请求失败:{}", e.getMessage());
|
||||||
|
org.ruoyi.chat.support.RetryNotifier.notifyFailure(chatRequest.getSessionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return emitter;
|
return emitter;
|
||||||
|
|||||||
@@ -51,14 +51,16 @@ public class ZhipuAiChatServiceImpl implements IChatService {
|
|||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@Override
|
@Override
|
||||||
public void onError(Throwable error) {
|
public void onError(Throwable error) {
|
||||||
// System.out.println(error.getMessage());
|
// 透传错误并触发重试
|
||||||
emitter.send(error.getMessage());
|
emitter.send(error.getMessage());
|
||||||
|
org.ruoyi.chat.support.RetryNotifier.notifyFailure(chatRequest.getSessionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCompleteResponse(ChatResponse response) {
|
public void onCompleteResponse(ChatResponse response) {
|
||||||
emitter.complete();
|
emitter.complete();
|
||||||
log.info("消息结束,完整消息ID: {}", response.aiMessage());
|
log.info("消息结束,完整消息ID: {}", response.aiMessage());
|
||||||
|
org.ruoyi.chat.support.RetryNotifier.clear(chatRequest.getSessionId());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,6 +73,7 @@ public class ZhipuAiChatServiceImpl implements IChatService {
|
|||||||
model.chat(chatRequest.getPrompt(), handler);
|
model.chat(chatRequest.getPrompt(), handler);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("智谱清言请求失败:{}", e.getMessage());
|
log.error("智谱清言请求失败:{}", e.getMessage());
|
||||||
|
org.ruoyi.chat.support.RetryNotifier.notifyFailure(chatRequest.getSessionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return emitter;
|
return emitter;
|
||||||
|
|||||||
Reference in New Issue
Block a user