sofastack/sofa-jraft

gRPC 场景下如何处理服务端的异常消息

googlefan opened this issue · 3 comments

Your question

@fengjiachun 大佬 问个问题:

Describe your question clearly
我在 使用gRPC impl 作为raft rpc 的实现,在定义 请求-返回 映射map时,我有个疑问, 如果一个请求 有不同的返回消息实体,怎么办?
或者如果一个请求,当服务端发生了业务异常,想 将业务异常 消息抛给 客户端,怎么办?
在 构造MarshallerHelper 这个对象时,由于它是Map 类型的数据结构,key - value 是多对一的, 而不是一对多的,那么一个request 就只有一个固定的response 了:
`
public static void initGRpc() {
if ("com.alipay.sofa.jraft.rpc.impl.GrpcRaftRpcFactory".equals(RpcFactoryHelper.rpcFactory().getClass()
.getName())) {
RpcFactoryHelper.rpcFactory().registerProtobufSerializer(CounterOutter.GetValueRequest.class.getName(),
CounterOutter.GetValueRequest.getDefaultInstance());
RpcFactoryHelper.rpcFactory().registerProtobufSerializer(
CounterOutter.IncrementAndGetRequest.class.getName(),
CounterOutter.IncrementAndGetRequest.getDefaultInstance());
RpcFactoryHelper.rpcFactory().registerProtobufSerializer(CounterOutter.ValueResponse.class.getName(),
CounterOutter.ValueResponse.getDefaultInstance());

        try {
            Class<?> clazz = Class.forName("com.alipay.sofa.jraft.rpc.impl.MarshallerHelper");
            Method registerRespInstance = clazz.getMethod("registerRespInstance", String.class, Message.class);
            registerRespInstance.invoke(null, CounterOutter.GetValueRequest.class.getName(),
                CounterOutter.ValueResponse.getDefaultInstance());
            registerRespInstance.invoke(null, CounterOutter.IncrementAndGetRequest.class.getName(),
                CounterOutter.ValueResponse.getDefaultInstance());
        } catch (Exception e) {
            LOG.error("Failed to init grpc server", e);
        }
    }
}

`
如上代码,假如 CounterOutter.IncrementAndGetRequest 这个请求在 服务端throw 了 bunisessException, 此时 由于已经定义了
CounterOutter.ValueResponse.getDefaultInstance() 消息 实例, bunisessException 消息就无法返回给客户端了吧

Your scenes

我想将异常抛给客户端(gRPC)
Describe your use scenes (why need this feature)

Your advice

Describe the advice or solution you'd like

Environment

  • SOFAJRaft version: 1.3.13
  • JVM version (e.g. java -version): 1.8
  • OS version (e.g. uname -a): centos
  • Maven version: 3.6

你好,别喊大佬啊我不是...
对于你的问题,业务异常信息放到 ValueResponse 的 errorMsg 不行吗?

你好,别喊大佬啊我不是... 对于你的问题,业务异常信息放到 ValueResponse 的 errorMsg 不行吗?

哈哈,不要谦虚. 你说的方案操作是 可行的,但是很不方便, 像 bolt rpc 是可以基于返回的消息 做instanceof 类型判断 的,
而 grpc 就定死了 了一个请求一个返回. 我在接口设计时, 想做一些动态的消息返回 也没法做.
而且 请求的返回 消息全部包含 异常的消息, 从设计上就没隔离开,很不优雅

嗯,我没有其他办法,这个问题与 jraft 关系不大,这里就不深入讨论了 ,暂时先关闭这个 issue 了