유량제어 오류 메시지 개선 -> API 호출 한도 초과 [테스트 그룹1: 10req/MIN]
This commit is contained in:
@@ -8,7 +8,8 @@ public interface Bucket {
|
|||||||
public InflowTargetVO getInflowThreashold(String inter);
|
public InflowTargetVO getInflowThreashold(String inter);
|
||||||
|
|
||||||
// 그룹 관련 메서드
|
// 그룹 관련 메서드
|
||||||
public boolean isGroupPass(String groupId);
|
/** @return null이면 통과, "PER_SECOND" 또는 "THRESHOLD"면 해당 버킷에서 차단 */
|
||||||
|
public String isGroupPass(String groupId);
|
||||||
public InflowGroupVO getGroupInflowThreshold(String groupId);
|
public InflowGroupVO getGroupInflowThreshold(String groupId);
|
||||||
public String getGroupIdByInterface(String interfaceId);
|
public String getGroupIdByInterface(String interfaceId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,24 +17,31 @@ public class CustomGroupBucket {
|
|||||||
this.groupVo = groupVo;
|
this.groupVo = groupVo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 소비 결과: 성공 */
|
||||||
|
public static final String RESULT_PASS = null;
|
||||||
|
/** 소비 결과: 초당 임계치 초과 */
|
||||||
|
public static final String RESULT_BLOCKED_PER_SECOND = "PER_SECOND";
|
||||||
|
/** 소비 결과: 추가 임계치 초과 */
|
||||||
|
public static final String RESULT_BLOCKED_THRESHOLD = "THRESHOLD";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 두 버킷 모두에서 토큰 소비 시도
|
* 두 버킷 모두에서 토큰 소비 시도
|
||||||
* @return 모든 버킷에서 소비 성공 시 true
|
* @return null이면 성공, "PER_SECOND" 또는 "THRESHOLD"면 해당 버킷에서 차단
|
||||||
*/
|
*/
|
||||||
public boolean tryConsume() {
|
public String tryConsume() {
|
||||||
boolean perSecondPass = (perSecondBucket == null) || perSecondBucket.tryConsume(1);
|
boolean perSecondPass = (perSecondBucket == null) || perSecondBucket.tryConsume(1);
|
||||||
if (!perSecondPass) {
|
if (!perSecondPass) {
|
||||||
return false;
|
return RESULT_BLOCKED_PER_SECOND;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean thresholdPass = (thresholdBucket == null) || thresholdBucket.tryConsume(1);
|
boolean thresholdPass = (thresholdBucket == null) || thresholdBucket.tryConsume(1);
|
||||||
if (!thresholdPass) {
|
if (!thresholdPass) {
|
||||||
// 초당 버킷에서 이미 소비했으므로 롤백은 불가 (Token Bucket 특성상)
|
// 초당 버킷에서 이미 소비했으므로 롤백은 불가 (Token Bucket 특성상)
|
||||||
// 하지만 초당 버킷은 빠르게 리필되므로 실질적 영향 미미
|
// 하지만 초당 버킷은 빠르게 리필되므로 실질적 영향 미미
|
||||||
return false;
|
return RESULT_BLOCKED_THRESHOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return RESULT_PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -470,11 +470,11 @@ public class InflowControlManager implements Lifecycle, Bucket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGroupPass(String groupId) {
|
public String isGroupPass(String groupId) {
|
||||||
CustomGroupBucket b = groupBucketList.get(groupId);
|
CustomGroupBucket b = groupBucketList.get(groupId);
|
||||||
|
|
||||||
if (b == null)
|
if (b == null)
|
||||||
return true;
|
return null;
|
||||||
|
|
||||||
return b.tryConsume();
|
return b.tryConsume();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ public class SessionManagerForEhcache extends SessionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
System.setProperty("net.sf.ehcache.skipUpdateCheck", "true");
|
System.setProperty("net.sf.ehcache.skipUpdateCheck", "true");
|
||||||
String bootstrapAsynchronously = "false";
|
String bootstrapAsynchronously = "true";
|
||||||
|
|
||||||
Configuration cf = new Configuration();
|
Configuration cf = new Configuration();
|
||||||
FactoryConfiguration ppFactory = new FactoryConfiguration();
|
FactoryConfiguration ppFactory = new FactoryConfiguration();
|
||||||
|
|||||||
@@ -1022,9 +1022,11 @@ public class RequestProcessor extends RequestProcessorSupport {
|
|||||||
}
|
}
|
||||||
// 그룹 우선, 없으면 인터페이스 유량제어 체크
|
// 그룹 우선, 없으면 인터페이스 유량제어 체크
|
||||||
String groupId = bucket.getGroupIdByInterface(vo.getEaiSvcCd());
|
String groupId = bucket.getGroupIdByInterface(vo.getEaiSvcCd());
|
||||||
|
String groupBlockedType = null;
|
||||||
if (groupId != null) {
|
if (groupId != null) {
|
||||||
// 그룹에 속한 인터페이스 → 그룹 유량제어 체크
|
// 그룹에 속한 인터페이스 → 그룹 유량제어 체크
|
||||||
if (!bucket.isGroupPass(groupId)) {
|
groupBlockedType = bucket.isGroupPass(groupId);
|
||||||
|
if (groupBlockedType != null) {
|
||||||
blockedType += "G";
|
blockedType += "G";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1044,11 +1046,26 @@ public class RequestProcessor extends RequestProcessorSupport {
|
|||||||
} else {
|
} else {
|
||||||
inflowTargetVO = bucket.getInterfaceInflowThreashold(vo.getEaiSvcCd());
|
inflowTargetVO = bucket.getInterfaceInflowThreashold(vo.getEaiSvcCd());
|
||||||
}
|
}
|
||||||
|
String inflowErrorMsg;
|
||||||
// 에러처리
|
// 에러처리
|
||||||
vo.setRspErrorCode(EAIMessageKeys.EAI_INFLOW_BLOCKED_CODE);
|
vo.setRspErrorCode(EAIMessageKeys.EAI_INFLOW_BLOCKED_CODE);
|
||||||
String inflowInfo = (inflowGroupVO != null) ? inflowGroupVO.toString() :
|
if (inflowGroupVO != null) {
|
||||||
(inflowTargetVO != null ? inflowTargetVO.toString() : "N/A");
|
if ("PER_SECOND".equals(groupBlockedType)) {
|
||||||
vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), vo.getEaiSvcCd() ) + ", " + inflowInfo);
|
inflowErrorMsg = String.format("API 호출 한도 초과 [%s: %dreq/sec]",
|
||||||
|
inflowGroupVO.getGroupName(),
|
||||||
|
inflowGroupVO.getThresholdPerSecond());
|
||||||
|
} else {
|
||||||
|
inflowErrorMsg = String.format("API 호출 한도 초과 [%s: %dreq/%s]",
|
||||||
|
inflowGroupVO.getGroupName(),
|
||||||
|
inflowGroupVO.getThreshold(),
|
||||||
|
inflowGroupVO.getThresholdTimeUnit());
|
||||||
|
}
|
||||||
|
} else if (inflowTargetVO != null) {
|
||||||
|
inflowErrorMsg = String.format("API 호출 한도 초과 [%s]", inflowTargetVO.getName());
|
||||||
|
} else {
|
||||||
|
inflowErrorMsg = "API 호출 한도 초과";
|
||||||
|
}
|
||||||
|
vo.setRspErrorMsg(inflowErrorMsg);
|
||||||
|
|
||||||
// eaiMsg.setRspErrCd(vo.getRspErrorCode());
|
// eaiMsg.setRspErrCd(vo.getRspErrorCode());
|
||||||
// eaiMsg.setRspErrMsg(vo.getRspErrorMsg());
|
// eaiMsg.setRspErrMsg(vo.getRspErrorMsg());
|
||||||
@@ -1082,7 +1099,7 @@ public class RequestProcessor extends RequestProcessorSupport {
|
|||||||
sb.append("EAISevrInstncName [" + eaiServerManager.getLocalServerName() + "]\n");
|
sb.append("EAISevrInstncName [" + eaiServerManager.getLocalServerName() + "]\n");
|
||||||
sb.append("EAISvcName [" + eaiMsg.getEAISvcCd() + "]\n");
|
sb.append("EAISvcName [" + eaiMsg.getEAISvcCd() + "]\n");
|
||||||
sb.append("ADPTRBZWKGROUPNAME[" + vo.getAdapterGroupName() + "]\n");
|
sb.append("ADPTRBZWKGROUPNAME[" + vo.getAdapterGroupName() + "]\n");
|
||||||
sb.append("InflowInfo [" + inflowInfo + "]\n");
|
sb.append("InflowInfo [" + inflowErrorMsg + "]\n");
|
||||||
if (groupId != null) {
|
if (groupId != null) {
|
||||||
sb.append("InflowGroupId [" + groupId + "]\n");
|
sb.append("InflowGroupId [" + groupId + "]\n");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user