diff --git a/core-impl/client/src/main/java/com/alipay/sofa/rpc/client/FailoverCluster.java b/core-impl/client/src/main/java/com/alipay/sofa/rpc/client/FailoverCluster.java index ec2d5dd95..d82b04616 100644 --- a/core-impl/client/src/main/java/com/alipay/sofa/rpc/client/FailoverCluster.java +++ b/core-impl/client/src/main/java/com/alipay/sofa/rpc/client/FailoverCluster.java @@ -67,6 +67,15 @@ public SofaResponse doInvoke(SofaRequest request) throws SofaRpcException { providerInfo = select(request, invokedProviderInfos); SofaResponse response = filterChain(providerInfo, request); if (response != null) { + // 检查是否是用户自定义的可重试异常 + Object appResponse = response.getAppResponse(); + if (appResponse instanceof SofaRpcException) { + if (((SofaRpcException) appResponse).getErrorType() == RpcErrorType.CUSTOMER_RETRY_ERROR) { + time++; + throwable = (SofaRpcException) appResponse; + continue; + } + } if (throwable != null) { if (LOGGER.isWarnEnabled(consumerConfig.getAppName())) { LOGGER.warnWithApp(consumerConfig.getAppName(), diff --git a/core/api/src/main/java/com/alipay/sofa/rpc/filter/ProviderInvoker.java b/core/api/src/main/java/com/alipay/sofa/rpc/filter/ProviderInvoker.java index 9cf35d3f6..07fa0848b 100644 --- a/core/api/src/main/java/com/alipay/sofa/rpc/filter/ProviderInvoker.java +++ b/core/api/src/main/java/com/alipay/sofa/rpc/filter/ProviderInvoker.java @@ -17,6 +17,7 @@ package com.alipay.sofa.rpc.filter; import com.alipay.sofa.rpc.common.RpcConstants; +import com.alipay.sofa.rpc.common.annotation.RetryableException; import com.alipay.sofa.rpc.config.ProviderConfig; import com.alipay.sofa.rpc.context.RpcInternalContext; import com.alipay.sofa.rpc.context.RpcInvokeContext; @@ -113,7 +114,12 @@ public SofaResponse invoke(SofaRequest request) throws SofaRpcException { // sofaResponse.setErrorMsg(e.getMessage()); } catch (InvocationTargetException e) { // 业务代码抛出异常 cutCause(e.getCause()); - sofaResponse.setAppResponse(e.getCause()); + // 查看该异常是否被用户声明为可重试异常 + if (e.getCause().getClass().isAnnotationPresent(RetryableException.class)) { + sofaResponse.setAppResponse(new SofaRpcException(RpcErrorType.CUSTOMER_RETRY_ERROR, e.getCause())); + } else { + sofaResponse.setAppResponse(e.getCause()); + } } finally { // R8: Record business processing execution time if (RpcInternalContext.isAttachmentEnable()) { diff --git a/core/common/src/main/java/com/alipay/sofa/rpc/common/annotation/RetryableException.java b/core/common/src/main/java/com/alipay/sofa/rpc/common/annotation/RetryableException.java new file mode 100644 index 000000000..4840c03a3 --- /dev/null +++ b/core/common/src/main/java/com/alipay/sofa/rpc/common/annotation/RetryableException.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.rpc.common.annotation; + +import java.lang.annotation.*; + +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface RetryableException { +} \ No newline at end of file diff --git a/core/exception/src/main/java/com/alipay/sofa/rpc/core/exception/RpcErrorType.java b/core/exception/src/main/java/com/alipay/sofa/rpc/core/exception/RpcErrorType.java index 937165e29..6080258f8 100644 --- a/core/exception/src/main/java/com/alipay/sofa/rpc/core/exception/RpcErrorType.java +++ b/core/exception/src/main/java/com/alipay/sofa/rpc/core/exception/RpcErrorType.java @@ -107,4 +107,9 @@ public class RpcErrorType { * 客户端未定义异常 */ public static final int CLIENT_UNDECLARED_ERROR = 299; + + /** + * 用户自定义可重试异常 + */ + public static final int CUSTOMER_RETRY_ERROR = 300; }