Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mychalvlcek/a9aabb9bfc76a48749dd673e3b280dd4 to your computer and use it in GitHub Desktop.
Save mychalvlcek/a9aabb9bfc76a48749dd673e3b280dd4 to your computer and use it in GitHub Desktop.
Multi tenant circuit breaker with resilience4j & spring

updated usage of @CircuitBreaker annotation

- @CircuitBreaker(name = "backend", fallbackMethod = "exampleFallbackMethod")
+ @CircuitBreaker(name = "@tenantCircuitBreakerResolver.resolveName('backend')", fallbackMethod = "exampleFallbackMethod")

whats happening in background:

  • CB configuration is duplicated during spring context startup
  • for each registered CB in CBregistry configuration is extracted and copypasted for all supported tenants
  • only possible drawback: multitenant setup/configuration is created for all registered CBs (even for those without multitenant resolving
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class CircuitBreakerAutoConfiguration implements ApplicationListener<ApplicationReadyEvent> {
private final CircuitBreakerRegistry circuitBreakerRegistry;
private final MultiTenantConfiguration multiTenantConfiguration;
private final TenantCircuitBreakerResolver multiTenantCircuitBreakerResolver;
@Override
public void onApplicationEvent(final ApplicationReadyEvent event) {
for (var cb : circuitBreakerRegistry.getAllCircuitBreakers()) {
for (var tenant : multiTenantConfiguration.getSupportedTenants()) {
TenantContext.setTenantId(tenant);
var cbTenantName = multiTenantCircuitBreakerResolver.resolveName(cb.getName());
var config = cb.getCircuitBreakerConfig();
circuitBreakerRegistry.circuitBreaker(cbTenantName, config);
log.debug("Configuring new Circuit breaker: {}", cbTenantName);
TenantContext.clear();
}
}
}
}
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component("tenantCircuitBreakerResolver")
public class TenantCircuitBreakerResolver {
public String resolveName(final String circuitBreakerName) {
if (TenantContext.getTenantId() != null) {
return circuitBreakerName + "__" + TenantContext.getTenantId();
}
return circuitBreakerName;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment