Skip to content

brpc exception, serviceInterface must not be set repeatedly, please use another RpcClient #37

Open

Description

@liuzihua699

问题描述:遇到了和 #23 描述的情况,当客户端发起顺序/并发写请求时报错
问题复现:

启动3节点raft-server:
1. git clone https://github.com/wenweihu86/raft-java
2. cd raft-java/raft-java-example && sh deploy.sh

使用如下代码测试写功能会报错:

String ipPorts = "list://127.0.0.1:8051,127.0.0.1:8052,127.0.0.1:8053";
RpcClient rpcClient = new RpcClient(ipPorts);
ExampleService exampleService = BrpcProxy.getProxy(rpcClient, ExampleService.class);

for (int i = 0; i < 10; i++) {
    String key = UUID.randomUUID().toString();
    String value = UUID.randomUUID().toString();

    ExampleProto.SetRequest setRequest = ExampleProto.SetRequest.newBuilder().setKey(key).setValue(value).build();
    ExampleProto.SetResponse setResponse = exampleService.set(setRequest);
    System.out.print(setResponse);
}
rpcClient.stop();

异常如下:

Caused by: com.baidu.brpc.exceptions.RpcException: serviceInterface must not be set repeatedly, please use another RpcClient
	at com.baidu.brpc.protocol.standard.BaiduRpcProtocol.decodeResponse(BaiduRpcProtocol.java:162)
	at com.baidu.brpc.protocol.standard.BaiduRpcProtocol.decodeResponse(BaiduRpcProtocol.java:70)
	at com.baidu.brpc.client.handler.ClientWorkTask.run(ClientWorkTask.java:65)
	at com.baidu.brpc.utils.ThreadPool.consume(ThreadPool.java:131)
	at com.baidu.brpc.utils.ThreadPool.access$000(ThreadPool.java:37)
	at com.baidu.brpc.utils.ThreadPool$1.run(ThreadPool.java:79)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.lang.Thread.run(Thread.java:748)

Activity

  1. xiaoquanju commented on Apr 27, 2021

    @xiaoquanju

    我也遇到了

  2. xiaoquanju commented on Apr 27, 2021

    @xiaoquanju

    想用到产品里 遇到这个问题 有点不敢用了

  3. day210 commented on Nov 24, 2021

    @day210

    +1,有进展了吗,单条写没问题,一次多条就报错了,具体能多少也不固定,有时候能一次写10条,有时候4个就开始报这个错了。 现在一次一条太连续也不行了,得隔十几秒。

  4. day210 commented on Nov 27, 2021

    @day210
  5. fwhdzh commented on Jun 20, 2024

    @fwhdzh

    我发现楼主和其他人已经提了对这个问题的PR #38 #24 ,但是作者并没有进一步合并。

    这个问题的关键在于ExampleServiceImpl.java的这里

    else if (raftNode.getLeaderId() != raftNode.getLocalServer().getServerId()) {
                onLeaderChangeEvent();
                ExampleService exampleService = BrpcProxy.getProxy(leaderRpcClient, ExampleService.class);
                ExampleProto.SetResponse responseFromLeader = exampleService.set(request);
                responseBuilder.mergeFrom(responseFromLeader);
            }
    

    这里会在每一次有用户set请求时,使用leaderRpcClient生成一个新的ExampleService实例。但是对于同一个RpcClient对象来说,多次使用BrpcProxy.getProxy生成新的Service实例是不被brpc-java允许的。
    因此这里应该重写下代码,不在leaderRpcClient没有被赋值为新对象的情况下重新生成ExampleService实例。具体可以参考楼主和其他人的PR。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions