我尝试像这样处理rpc异常
try {
rpcService.invokeRemoteMethod(foo)
} catch (Exception e) {
logger.error("invokeRemoteMethod failed, foo = {} ", foo);
throw CustomException(e);
}
当rpcService不可用时,例如超时,这段代码会将大量的堆栈跟踪日志写入文件,这可能会消耗大量的杯子和内存。所以我猜我是否可以设置一些阈值,比如当同样的异常诅咒每分钟一次时,我打印整个异常堆栈,每分钟10次,我只是打印异常消息,100次以上,我没有记录任何内容。
答案 0 :(得分:1)
在我看来,断路器是控制日志记录的合适模式(如果延迟很高,也可以防止DOS服务)。如果更多说5个例外(可以是每个服务的配置),电路可以打开,这样如果远程服务关闭,应用程序就不会调用并记录错误。
根据您的项目,您可以使用开源断路器,也可以使用AOP编写简单的断路器或使用断路器包装RPC类。
理解的最小例子是
public abstract class CircuitBreaker
{
private Circuit circuit;
public CircuitBreaker(){
circuit = new Circuit();
}
public void execute()
{
if(circuit.isOpen()) {
throw CircuitOpenException();
}
invokeService();
}
protected void recordFailure(){
circuit.recordFailure();
}
protected abstract <T extends Object> T invokeService();
}
public class RPCServiceExecutor extends CircuitBreaker
{
protected Result invokeService() {
try {
Result result = rpcService.invokeRemoteMethod(foo);
return new Result();
} catch (Exception e) {
this.recordFailure();
logger.error("invokeRemoteMethod failed, foo = {} ", foo);
throw CustomException(e);
}
}
}
当电路打开时,不要记录异常,当电路关闭时总是记录异常。
有关详细信息和示例,请参阅
https://martinfowler.com/bliki/CircuitBreaker.html
https://spring.io/guides/gs/circuit-breaker/
希望这有帮助。如果您需要更详细的实例,请告诉我。