Pre-check

  • [x] I am sure that all the content I provide is in English.

Search before asking

  • [x] I had searched in the issues and found no similar issues.

Apache Dubbo Component

Java SDK (apache/dubbo)

Dubbo Version

3.2 +

Steps to reproduce this issue

ConfigurableApplicationContext context = SpringApplication.run(ConsumerApplication.class, args); ConsumerApplication application = context.getBean(ConsumerApplication.class); String result = application.doSayHello("world"); System.out.println("result: " + result); InetSocketAddress rpcContext = RpcContext.getServiceContext() .getRemoteAddress(); // its null String providerIp = rpcContext.getAddress().getHostAddress();// npe System.out.println("provider ip: " + providerIp);

What you expected to happen

RpcContext.getServiceContext().getRemoteAddress() should not be null。

Anything else

RpcContext.RestoreServiceContext originServiceContext = RpcContext.storeServiceContext();

    try {
        URL url = invoker.getUrl();
        String serviceKey = url.getServiceKey();
        rpcInvocation.setTargetServiceUniqueName(serviceKey);

        // invoker.getUrl() returns consumer url.
        RpcServiceContext.getServiceContext().setConsumerUrl(url);

        if (ProfilerSwitch.isEnableSimpleProfiler()) {
            ProfilerEntry parentProfiler = Profiler.getBizProfiler();
            ProfilerEntry bizProfiler;
            if (parentProfiler != null) {
                bizProfiler = Profiler.enter(
                        parentProfiler,
                        "Receive request. Client invoke begin. ServiceKey: " + serviceKey + " MethodName:"
                                + rpcInvocation.getMethodName());
            } else {
                bizProfiler = Profiler.start("Receive request. Client invoke begin. ServiceKey: " + serviceKey + " "
                        + "MethodName:" + rpcInvocation.getMethodName());
            }
            rpcInvocation.put(Profiler.PROFILER_KEY, bizProfiler);
            try {
                return invoker.invoke(rpcInvocation).recreate();
            } finally {
                Profiler.release(bizProfiler);
                Long timeout =
                        RpcUtils.convertToNumber(rpcInvocation.getObjectAttachmentWithoutConvert(TIMEOUT_KEY));

                if (timeout == null) {
                    timeout = (long) url.getMethodPositiveParameter(
                            rpcInvocation.getMethodName(), TIMEOUT_KEY, DEFAULT_TIMEOUT);
                }
                long usage = bizProfiler.getEndTime() - bizProfiler.getStartTime();
                if ((usage / (1000_000L * ProfilerSwitch.getWarnPercent())) > timeout) {
                    StringBuilder attachment = new StringBuilder();
                    rpcInvocation.foreachAttachment((entry) -> {
                        attachment
                                .append(entry.getKey())
                                .append("=")
                                .append(entry.getValue())
                                .append(";\n");
                    });

                    logger.warn(
                            PROXY_TIMEOUT_REQUEST,
                            "",
                            "",
                            String.format(
                                    "[Dubbo-Consumer] execute service %s#%s cost %d.%06d ms, this invocation almost (maybe already) timeout. Timeout: %dms\n"
                                            + "invocation context:\n%s" + "thread info: \n%s",
                                    rpcInvocation.getProtocolServiceKey(),
                                    rpcInvocation.getMethodName(),
                                    usage / 1000_000,
                                    usage % 1000_000,
                                    timeout,
                                    attachment,
                                    Profiler.buildDetail(bizProfiler)));
                }
            }
        }
        return invoker.invoke(rpcInvocation).recreate();
    } finally {
        **_RpcContext.restoreServiceContext(originServiceContext);_**
    }
}

}

Here is overwrite the rpccontent

Are you willing to submit a pull request to fix on your own?

  • [ ] Yes I am willing to submit a pull request on my own!

Code of Conduct

Comment From: zrlw

RpcContext is divided into four major modules (ServerContext, ClientAttachment, ServerAttachment, and ServiceContext).

Each module has different responsibilities:

  • ServiceContext: Used internally in Dubbo to pass parameter information along the call chain, such as the invoker object, etc.
  • ClientAttachment: Used on the client side, parameters written to ClientAttachment will be passed to the server.
  • ServerAttachment: Used on the server side; parameters read from ServerAttachment are passed from the client.
  • ServerContext: Used on both the client and server sides to pass data back from the server to the client; parameters written to ServerContext on the server can be retrieved on the client side after the call ends.

Comment From: wcy666103

https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/tasks/framework/attachment/

Comment From: LeoDominicXu

Thank you — I just want to obtain the provider’s IP after invoking a Dubbo interface,as in the example。

After reading the source code, I found that in the InvocationUtil class, the ServiceContext of RpcContext is initialized first. During the try block everything works fine, but after the finally block executes, the ServiceContext is gone (reset back to its initial state). I figured this might just be a characteristic of Dubbo’s context behavior. Thanks!