feat: 유량제어 그룹 버킷 분리 및 현황 화면 개선

- CustomGroupBucket 클래스 신규 생성: 초당/추가 임계치를 별도 LocalBucket으로 분리하여 개별 토큰 조회 가능
  - InflowControlManager 수정: groupBucketList 타입을 CustomGroupBucket으로 변경, makeGroupBucket() 메서드 추가
  - InflowGroupBucketService 단순화: 복잡한 리플렉션 로직 제거, CustomGroupBucket 직접 메서드 사용
  - 현황 탭에 전체 인스턴스 합산 요약 추가 (활성 인스턴스 수, 초당/추가 임계치 합산)
  - 추가 임계치 시간단위에서 '초(SEC)' 옵션 제거
  - 저장 완료 후 리스트 화면 이동 제거
This commit is contained in:
yunjy-hp
2025-12-11 11:04:11 +09:00
parent 39244dc0df
commit d326ffc373
2 changed files with 108 additions and 27 deletions
@@ -27,6 +27,7 @@ import com.ext.eai.common.stdmessage.STDMessageKeys;
import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket4j;
import io.github.bucket4j.local.LocalBucket;
import io.github.bucket4j.local.LocalBucketBuilder;
@Component
@@ -40,7 +41,7 @@ public class InflowControlManager implements Lifecycle, Bucket {
private Map<String, CustomBucket> adapterBucketList = new HashMap<>();
private Map<String, CustomBucket> interfaceBucketList = new HashMap<>();
private Map<String, CustomBucket> groupBucketList = new HashMap<>();
private Map<String, CustomGroupBucket> groupBucketList = new HashMap<>();
private Map<String, String> interfaceToGroupMap = new HashMap<>();
private Map<String, InflowGroupVO> groupVoMap = new HashMap<>();
private boolean started;
@@ -134,7 +135,7 @@ public class InflowControlManager implements Lifecycle, Bucket {
for (InflowGroupVO groupVo : inflowGroupVoList) {
if (isInflowGroupTarget(groupVo)) {
CustomBucket bucket = makeBucketUsingGroupVO(groupVo);
CustomGroupBucket bucket = makeGroupBucket(groupVo);
if (bucket != null) {
groupBucketList.put(groupVo.getGroupId(), bucket);
groupVoMap.put(groupVo.getGroupId(), groupVo);
@@ -262,7 +263,7 @@ public class InflowControlManager implements Lifecycle, Bucket {
InflowGroupVO groupVo = map.get(key);
if (isInflowGroupTarget(groupVo)) {
CustomBucket bucket = makeBucketUsingGroupVO(groupVo);
CustomGroupBucket bucket = makeGroupBucket(groupVo);
if (bucket != null) {
groupBucketList.put(groupVo.getGroupId(), bucket);
groupVoMap.put(groupVo.getGroupId(), groupVo);
@@ -390,30 +391,33 @@ public class InflowControlManager implements Lifecycle, Bucket {
return null;
}
private CustomBucket makeBucketUsingGroupVO(InflowGroupVO groupVo) {
if (isInflowGroupTarget(groupVo)) {
LocalBucketBuilder builder = Bucket4j.builder();
if (groupVo.getThresholdPerSecond() > 0) {
builder.addLimit(Bandwidth.simple(groupVo.getThresholdPerSecond(), Duration.ofSeconds(1)));
}
if (groupVo.getThreshold() > 0 && StringUtils.isNotBlank(groupVo.getThresholdTimeUnit())) {
builder.addLimit(Bandwidth.simple(groupVo.getThreshold(),
InflowControlManager.getPeriod(groupVo.getThresholdTimeUnit())));
}
// InflowTargetVO로 변환하여 CustomBucket 생성
InflowTargetVO targetVo = new InflowTargetVO();
targetVo.setName(groupVo.getGroupId());
targetVo.setThreshold(groupVo.getThreshold());
targetVo.setThresholdPerSecond(groupVo.getThresholdPerSecond());
targetVo.setThresholdTimeUnit(groupVo.getThresholdTimeUnit());
targetVo.setActivate(groupVo.isActivate());
return new CustomBucket(builder.build(), targetVo);
/**
* 그룹용 버킷 생성 - 초당/추가 임계치를 별도 버킷으로 분리
*/
private CustomGroupBucket makeGroupBucket(InflowGroupVO groupVo) {
if (!isInflowGroupTarget(groupVo)) {
return null;
}
return null;
LocalBucket perSecondBucket = null;
LocalBucket thresholdBucket = null;
// 초당 임계치 버킷 (별도)
if (groupVo.getThresholdPerSecond() > 0) {
perSecondBucket = Bucket4j.builder()
.addLimit(Bandwidth.simple(groupVo.getThresholdPerSecond(), Duration.ofSeconds(1)))
.build();
}
// 추가 임계치 버킷 (별도)
if (groupVo.getThreshold() > 0 && StringUtils.isNotBlank(groupVo.getThresholdTimeUnit())) {
thresholdBucket = Bucket4j.builder()
.addLimit(Bandwidth.simple(groupVo.getThreshold(),
InflowControlManager.getPeriod(groupVo.getThresholdTimeUnit())))
.build();
}
return new CustomGroupBucket(perSecondBucket, thresholdBucket, groupVo);
}
@Override
@@ -467,12 +471,12 @@ public class InflowControlManager implements Lifecycle, Bucket {
@Override
public boolean isGroupPass(String groupId) {
CustomBucket b = groupBucketList.get(groupId);
CustomGroupBucket b = groupBucketList.get(groupId);
if (b == null)
return true;
return b.getLocalBucket().tryConsume(1);
return b.tryConsume();
}
@Override