115 lines
4.7 KiB
Java
115 lines
4.7 KiB
Java
package com.eactive.eai.custom.inflow;
|
|
|
|
import java.util.Collections;
|
|
import java.util.Map;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
import com.eactive.eai.common.inflow.Bucket;
|
|
import com.eactive.eai.common.inflow.InflowTargetVO;
|
|
import com.eactive.eai.common.inflow.InflowType;
|
|
import com.eactive.eai.common.inflow.dual.DualCustomBucket;
|
|
import com.eactive.eai.common.inflow.dual.DualInflowControlManager;
|
|
import com.eactive.eai.common.lifecycle.LifecycleException;
|
|
import com.eactive.eai.common.util.ApplicationContextProvider;
|
|
import com.eactive.eai.common.util.Logger;
|
|
|
|
/**
|
|
* 어댑터/인터페이스 이중 버킷(DualInflowControlManager)에 클라이언트 유량제어를 추가한 관리자.
|
|
*
|
|
* <p>적용 방법: INFLOW.properties에 아래 한 줄 추가.
|
|
* <pre>inflow.control.bucket.className=com.eactive.eai.common.inflow.dual.ClientDualInflowControlManager</pre>
|
|
*/
|
|
@Component
|
|
public class ClientDualInflowControlManager extends DualInflowControlManager implements ClientDualBucket {
|
|
|
|
private static final Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
|
|
|
|
public static synchronized Bucket getBucket() {
|
|
return ApplicationContextProvider.getContext().getBean(ClientDualInflowControlManager.class);
|
|
}
|
|
|
|
private volatile Map<String, DualCustomBucket> clientBucketMap = new ConcurrentHashMap<>();
|
|
private final ConcurrentHashMap<String, TargetMetrics> clientMetricsMap = new ConcurrentHashMap<>();
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Lifecycle
|
|
// -------------------------------------------------------------------------
|
|
|
|
@Override
|
|
public void start() throws LifecycleException {
|
|
super.start();
|
|
try {
|
|
initClients();
|
|
} catch (Exception e) {
|
|
throw new LifecycleException("ClientDualInflowControlManager init failed: " + e.getMessage());
|
|
}
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// 초기화 / 리로드
|
|
// -------------------------------------------------------------------------
|
|
|
|
private void initClients() throws Exception {
|
|
this.clientBucketMap = loadBucketMap(InflowType.CLIENT);
|
|
if (logger.isInfo()) logger.info("ClientDualInflowControlManager] initClients: " + clientBucketMap.size() + " buckets");
|
|
}
|
|
|
|
public synchronized void reloadClient() throws Exception {
|
|
initClients();
|
|
clientMetricsMap.clear();
|
|
}
|
|
|
|
public synchronized void reloadClient(String clientId) throws Exception {
|
|
reloadBucketMap(clientBucketMap, InflowType.CLIENT, clientId);
|
|
TargetMetrics m = clientMetricsMap.get(clientId);
|
|
if (m != null) m.reset();
|
|
}
|
|
|
|
public synchronized void removeClient(String clientId) {
|
|
clientBucketMap.remove(clientId);
|
|
clientMetricsMap.remove(clientId);
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// 클라이언트 메트릭 접근자
|
|
// -------------------------------------------------------------------------
|
|
|
|
public TargetMetrics getClientMetrics(String clientId) { return clientMetricsMap.get(clientId); }
|
|
public Map<String, TargetMetrics> getAllClientMetrics() { return Collections.unmodifiableMap(clientMetricsMap); }
|
|
public void resetClientMetrics(String clientId) { TargetMetrics m = clientMetricsMap.get(clientId); if (m != null) m.reset(); }
|
|
public void resetAllClientMetrics() { clientMetricsMap.values().forEach(TargetMetrics::reset); }
|
|
|
|
// -------------------------------------------------------------------------
|
|
// ClientDualBucket — 클라이언트 유량제어
|
|
// -------------------------------------------------------------------------
|
|
|
|
@Override
|
|
public String isClientPassDetail(String clientId) {
|
|
DualCustomBucket b = clientBucketMap.get(clientId);
|
|
if (b == null) return DualCustomBucket.RESULT_PASS;
|
|
String result = b.tryConsume();
|
|
recordMetrics(clientMetricsMap, clientId, result);
|
|
return result;
|
|
}
|
|
|
|
@Override
|
|
public InflowTargetVO getClientInflowThreshold(String clientId) {
|
|
DualCustomBucket b = clientBucketMap.get(clientId);
|
|
return (b == null) ? null : b.getInflowTargetVo();
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// 모니터링용 접근자
|
|
// -------------------------------------------------------------------------
|
|
|
|
public DualCustomBucket getClientBucket(String clientId) {
|
|
return clientBucketMap.get(clientId);
|
|
}
|
|
|
|
public Map<String, DualCustomBucket> getClientBucketMap() {
|
|
return clientBucketMap;
|
|
}
|
|
}
|