8 changed files with 159 additions and 13 deletions
@ -0,0 +1,53 @@ |
|||||
|
package com.project.interaction.utils; |
||||
|
|
||||
|
import com.github.tingyugetc520.ali.dingtalk.api.DtService; |
||||
|
import com.github.tingyugetc520.ali.dingtalk.bean.message.DtCorpConversationMessage; |
||||
|
import com.github.tingyugetc520.ali.dingtalk.bean.message.DtCorpConversationMsgSendResult; |
||||
|
import com.github.tingyugetc520.ali.dingtalk.bean.message.DtMessage; |
||||
|
import com.google.common.collect.Lists; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
|
||||
|
@Slf4j |
||||
|
@Component |
||||
|
public class NotifyUtil { |
||||
|
|
||||
|
@Autowired |
||||
|
private DtService dtService; |
||||
|
|
||||
|
public void notify(Long taskId,Long clusterId) { |
||||
|
// "283712335120874575", "01231011386731976125",
|
||||
|
ArrayList<String> userIDList = Lists.newArrayList( "283712335120874575", "01231011386731976125","590204300932000212"); |
||||
|
|
||||
|
try { |
||||
|
String markdown = String.format("### 【告警】算法生题API调用失败通知 \n\n") + |
||||
|
String.format("## 核心信息\n") + |
||||
|
String.format("- 考试任务ID:%d\n", taskId) + |
||||
|
String.format("- 知识点簇ID:%d\n\n", clusterId) + |
||||
|
String.format("## 异常说明\n") + |
||||
|
String.format("算法服务生成题目时调用失败,可能导致考试题目不完整或无法正常作答,请尽快排查以下问题:\n") + |
||||
|
String.format("- 算法服务是否正常运行\n"); |
||||
|
DtCorpConversationMessage corpConversationMessage = DtCorpConversationMessage.builder() |
||||
|
.agentId(dtService.getDtConfigStorage().getAgentId()) |
||||
|
.userIds(Lists.newArrayList(userIDList)) |
||||
|
.msg(DtMessage.MARKDOWN() |
||||
|
.content("算法生题API调用失败通知") |
||||
|
.text(markdown) |
||||
|
.build()) |
||||
|
.build(); |
||||
|
DtCorpConversationMsgSendResult result = dtService.getCorpConversationMsgService().send(corpConversationMessage); |
||||
|
if (result.getErrCode() == 0) { |
||||
|
log.info(">>> [算法生题API调用失败通知] 成功发送通知 ,考试任务ID:{} ,知识点簇ID:{}", taskId, clusterId); |
||||
|
} else { |
||||
|
log.error(">>> [算法生题API调用失败通知] 发送失败.考试任务ID:{} ,知识点簇ID:{}, 错误码: {}, 错误信息: {}", taskId, clusterId, |
||||
|
result.getErrCode(), result.getErrMsg()); |
||||
|
} |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
log.error(">>> [算法生题API调用失败通知] 钉钉接口调用异常, 考试任务ID:{} ,知识点簇ID:{}, 原因: {}",taskId, clusterId, e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
package com.project.question.config; |
||||
|
|
||||
|
import com.project.question.domain.service.impl.QuestionGenerationRateLimiter; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
|
||||
|
/** |
||||
|
* 题目生成相关配置 |
||||
|
*/ |
||||
|
@Configuration |
||||
|
public class QuestionGenerationConfig { |
||||
|
|
||||
|
@Value("${question.generation.rate-limit:5}") |
||||
|
private double rateLimit; |
||||
|
|
||||
|
/** |
||||
|
* 创建题目生成限流器 |
||||
|
*/ |
||||
|
@Bean |
||||
|
@ConditionalOnMissingBean(QuestionGenerationRateLimiter.class) |
||||
|
public QuestionGenerationRateLimiter questionGenerationRateLimiter() { |
||||
|
return new QuestionGenerationRateLimiter(this.rateLimit); |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,36 @@ |
|||||
|
package com.project.question.domain.service.impl; |
||||
|
|
||||
|
import com.google.common.util.concurrent.RateLimiter; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 题目生成API限流器 |
||||
|
* 用于控制调用算法服务的请求速率,防止一大批请求同时涌入导致服务压力过大 |
||||
|
*/ |
||||
|
@Component |
||||
|
@Slf4j |
||||
|
public class QuestionGenerationRateLimiter { |
||||
|
|
||||
|
/** |
||||
|
* RateLimiter 使用令牌桶算法 |
||||
|
* 每秒允许固定数量的请求通过 |
||||
|
*/ |
||||
|
private final RateLimiter rateLimiter; |
||||
|
|
||||
|
public QuestionGenerationRateLimiter(@Value("${question.generation.rate-limit:5}") double permitsPerSecond) { |
||||
|
this.rateLimiter = RateLimiter.create(permitsPerSecond); |
||||
|
log.info(">>> [限流器初始化] 题目生成限流速率设置为: {}/秒", permitsPerSecond); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取令牌,如果令牌不足则阻塞等待 |
||||
|
* 调用此方法的线程会被阻塞,直到获取到令牌为止 |
||||
|
*/ |
||||
|
public void acquire() { |
||||
|
rateLimiter.acquire(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
Loading…
Reference in new issue