Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RpcContext.getServiceContext().getLocalAddressString() return zero port on consumer side ! #13305

Closed
2 tasks done
chchpanda opened this issue Nov 3, 2023 · 19 comments · Fixed by #13751
Closed
2 tasks done
Labels
help wanted Everything needs help from contributors type/proposal Everything you want Dubbo have
Milestone

Comments

@chchpanda
Copy link

chchpanda commented Nov 3, 2023

  • I have searched the issues of this repository and believe that this is not a duplicate.
  • I have searched the release notes of this repository and believe that this is not a duplicate.

Describe the feature

I'm doing some logging thing by using Filter, and I use RpcContext.getServiceContext().getLocalAddressString() to get the local address, both on the provider and consumer side. It goes very well on provider side. However, unexpected things happens when it’s running on consumer side.

The code is something like follows (here I've kept only the necessary parts for simplicity):

@Activate(order = 50, group = {"consumer"})
public class MyLogFilter implements Filter {
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        return invoker.invoke(invocation).whenCompleteWithContext(
            (r, t) -> {
                String localAddress = RpcContext.getServiceContext().getLocalAddressString();
                // record log ...
            }
        );
    }
}

When I'm trying to get local address through RpcContext.getServiceContext().getLocalAddressString(), I expect it will return something like "1.2.3.4:56789", in which "1.2.3.4" is the IP address and "56789" is the port. But what I have got is "1.2.3.4:0". I get a zero port here, which clearly is not the truth! That makes me confused. I wonder how can I get the real port value, and I think it should be contained in the return of RpcContext.getServiceContext().getLocalAddressString() method, just like when it's called on provider side.

@chchpanda chchpanda changed the title RpcContext.getServiceContext().getRemoteAddressString() return zero port on consumer side ! RpcContext.getServiceContext().getLocalAddressString() return zero port on consumer side ! Nov 3, 2023
@AlbumenJ AlbumenJ added help wanted Everything needs help from contributors good first issue labels Nov 4, 2023
@AlbumenJ
Copy link
Member

AlbumenJ commented Nov 4, 2023

@namelessssssssssss PTAL

@aofall
Copy link
Contributor

aofall commented Nov 6, 2023

caused by org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter#invoke declare the port is 0

I try to fixed it but found another bug, if there are multiple network interface and using dubbo.protocol.host specify one of the IP in application.yml, the host is incorrect also.

image

image

Should we add more parameter to the org.apache.dubbo.common.URL when registering the consumer? Then we can get the get the correct parameters and get expected results in RpcContext.getServiceContext().getLocalAddressString().

@AlbumenJ
Copy link
Member

AlbumenJ commented Nov 7, 2023

caused by org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter#invoke declare the port is 0

I try to fixed it but found another bug, if there are multiple network interface and using dubbo.protocol.host specify one of the IP in application.yml, the host is incorrect also.

image

image

Should we add more parameter to the org.apache.dubbo.common.URL when registering the consumer? Then we can get the get the correct parameters and get expected results in RpcContext.getServiceContext().getLocalAddressString().

The best way to get real consumer address is from tcp connection.

@KitwahSin
Copy link
Contributor

@aofall are you solving this issue?

@aofall
Copy link
Contributor

aofall commented Nov 10, 2023

@aofall are you solving this issue?

yes

@CrazyHZM
Copy link
Member

@aofall
Is there any progress?

@CrazyHZM CrazyHZM added this to the 3.2.11 milestone Dec 25, 2023
@aofall
Copy link
Contributor

aofall commented Dec 26, 2023

@aofall Is there any progress?

The URL for consumer is different to provider, the consumer only requests and does not need to constantly listen on a port, so it is normal not to get a port. And since the int type cannot be null, getting 0 is expected behavior. If we need to get the port set in the protocol, we need to add more parameters to the URL. I think we need a more appropriate way to handle this to avoid getting a "0" value.

eg.

consumer://192.168.190.137/demo.dubbo.api.DemoService?application=DemoConsumerApplication&background=false&category=providers,configurators,routers&dubbo=2.0.2&executor-management-mode=isolation&file-cache=true&interface=demo.dubbo.api.DemoService&logger=slf4j&methods=sayHello&pid=21820&qos.enable=false&reference.filter=appended&release=3.2.11-SNAPSHOT&side=consumer&sticky=false&timeout=500000&unloadClusterRelated=false

provider://192.168.190.137:50051/demo.dubbo.api.DemoService?anyhost=false&application=DemoProviderApplication&background=false&bind.ip=192.168.190.137&bind.port=50051&category=configurators&check=false&deprecated=false&dubbo=2.0.2&dynamic=true&executor-management-mode=isolation&file-cache=true&generic=false&interface=demo.dubbo.api.DemoService&logger=slf4j&methods=sayHello&pid=25180&prefer.serialization=fastjson2,hessian2&qos.enable=false&release=3.2.11-SNAPSHOT&service-name-mapping=true&service.filter=appended&side=provider&timeout=500000

@AlbumenJ
Copy link
Member

@aofall Is there any progress?

The URL for consumer is different to provider, the consumer only requests and does not need to constantly listen on a port, so it is normal not to get a port. And since the int type cannot be null, getting 0 is expected behavior. If we need to get the port set in the protocol, we need to add more parameters to the URL. I think we need a more appropriate way to handle this to avoid getting a "0" value.

eg.

consumer://192.168.190.137/demo.dubbo.api.DemoService?application=DemoConsumerApplication&background=false&category=providers,configurators,routers&dubbo=2.0.2&executor-management-mode=isolation&file-cache=true&interface=demo.dubbo.api.DemoService&logger=slf4j&methods=sayHello&pid=21820&qos.enable=false&reference.filter=appended&release=3.2.11-SNAPSHOT&side=consumer&sticky=false&timeout=500000&unloadClusterRelated=false

provider://192.168.190.137:50051/demo.dubbo.api.DemoService?anyhost=false&application=DemoProviderApplication&background=false&bind.ip=192.168.190.137&bind.port=50051&category=configurators&check=false&deprecated=false&dubbo=2.0.2&dynamic=true&executor-management-mode=isolation&file-cache=true&generic=false&interface=demo.dubbo.api.DemoService&logger=slf4j&methods=sayHello&pid=25180&prefer.serialization=fastjson2,hessian2&qos.enable=false&release=3.2.11-SNAPSHOT&service-name-mapping=true&service.filter=appended&side=provider&timeout=500000

We can set the local port from netty tcp connection

@aofall
Copy link
Contributor

aofall commented Jan 2, 2024

We can set the local port from netty tcp connection

@AlbumenJ How to get the local port from netty tcp connection, the filter chain is effort before the invoker innvocation. Although the Netty connections established at the application start and it can be reused during the invocation, but the connections can also be set. If the protocol is injvm, can we also get the result from Netty?

@AlbumenJ
Copy link
Member

AlbumenJ commented Jan 4, 2024

  1. For Dubbo protocol, you can read the local tcp connection when creating invocations
  2. For injvm protocol, 0 is acceptable

@laywin
Copy link
Contributor

laywin commented Jan 26, 2024

please assign to me, ths!

@aofall
Copy link
Contributor

aofall commented Jan 26, 2024

please assign to me, ths!

@AlbumenJ assign it to him, I'm sorry i am too busy recently

@aofall
Copy link
Contributor

aofall commented Jan 26, 2024

please assign to me, ths!

@laywin It may be find another way to reslove? (Or My analysis may also be wrong) . If just for the logs, it can use link tracing to solve the problem.

Netty invoke is in the dubbo-remoting module, and the filter chain of ConsumerContextFilter is build in the dubbo-cluster module, the filter is effort before the netty invoke.

@laywin
Copy link
Contributor

laywin commented Jan 26, 2024

please assign to me, ths!

@laywin It may be find another way to reslove? (Or My analysis may also be wrong) . If just for the logs, it can use link tracing to solve the problem.

Netty invoke is in the dubbo-remoting module, and the filter chain of ConsumerContextFilter is build in the dubbo-cluster module, the filter is effort before the netty invoke.

i think your analysis is no problem, but the point is get local address in whenCompleteWithContext instead of in filter directly, so only set the address before invoke happens and it can be get in whenCompleteWithContext.

@KitwahSin
Copy link
Contributor

please assign to me, ths!

@laywin It may be find another way to reslove? (Or My analysis may also be wrong) . If just for the logs, it can use link tracing to solve the problem.

Netty invoke is in the dubbo-remoting module, and the filter chain of ConsumerContextFilter is build in the dubbo-cluster module, the filter is effort before the netty invoke.

When you raise a connection to a server,you don't need to specific the local port and local address.We just need to specific the server address and server port,after the tcp connection is established. The socket object would contains four items - local address,local port,target address,target port. Before you return to filter,you set the local address and local port to the filter chain or other variables. so you can get it.

@laywin
Copy link
Contributor

laywin commented Jan 26, 2024

please assign to me, ths!

@laywin It may be find another way to reslove? (Or My analysis may also be wrong) . If just for the logs, it can use link tracing to solve the problem.
Netty invoke is in the dubbo-remoting module, and the filter chain of ConsumerContextFilter is build in the dubbo-cluster module, the filter is effort before the netty invoke.

When you raise a connection to a server,you don't need to specific the local port and local address.We just need to specific the server address and server port,after the tcp connection is established. The socket object would contains four items - local address,local port,target address,target port. Before you return to filter,you set the local address and local port to the filter chain or other variables. so you can get it.

we all agree that, the point of disagreement is whether to obtain the local address before or after the invoker invoke happens. I think the focus of this issue is to obtain the local address after that.

@CrazyHZM CrazyHZM modified the milestones: 3.2.11, 3.2.12 Jan 27, 2024
@KitwahSin
Copy link
Contributor

please assign to me, ths!

@laywin It may be find another way to reslove? (Or My analysis may also be wrong) . If just for the logs, it can use link tracing to solve the problem.
Netty invoke is in the dubbo-remoting module, and the filter chain of ConsumerContextFilter is build in the dubbo-cluster module, the filter is effort before the netty invoke.

When you raise a connection to a server,you don't need to specific the local port and local address.We just need to specific the server address and server port,after the tcp connection is established. The socket object would contains four items - local address,local port,target address,target port. Before you return to filter,you set the local address and local port to the filter chain or other variables. so you can get it.

we all agree that, the point of disagreement is whether to obtain the local address before or after the invoker invoke happens. I think the focus of this issue is to obtain the local address after that.

where is the invoker in ? Which module, I mean. When the connection established, you can get the local address and local port and set it into RpcContext. You can do this in the dubbo-rpc module.

@laywin
Copy link
Contributor

laywin commented Jan 30, 2024

please assign to me, ths!

@laywin It may be find another way to reslove? (Or My analysis may also be wrong) . If just for the logs, it can use link tracing to solve the problem.
Netty invoke is in the dubbo-remoting module, and the filter chain of ConsumerContextFilter is build in the dubbo-cluster module, the filter is effort before the netty invoke.

When you raise a connection to a server,you don't need to specific the local port and local address.We just need to specific the server address and server port,after the tcp connection is established. The socket object would contains four items - local address,local port,target address,target port. Before you return to filter,you set the local address and local port to the filter chain or other variables. so you can get it.

we all agree that, the point of disagreement is whether to obtain the local address before or after the invoker invoke happens. I think the focus of this issue is to obtain the local address after that.

where is the invoker in ? Which module, I mean. When the connection established, you can get the local address and local port and set it into RpcContext. You can do this in the dubbo-rpc module.

RpcContext is based on threadLocal. When establishing a connection, there may be multiple clients, which means there are multiple ports. How to set the address into the filter at this time? What I mean is that when DubboInvoker doInvoke, it will determine which client to use, so The port of the client can be determined and set into the RpcContext. When the request is completed, the filter callback will be entered to obtain the address information.

@KitwahSin
Copy link
Contributor

please assign to me, ths!

@laywin It may be find another way to reslove? (Or My analysis may also be wrong) . If just for the logs, it can use link tracing to solve the problem.
Netty invoke is in the dubbo-remoting module, and the filter chain of ConsumerContextFilter is build in the dubbo-cluster module, the filter is effort before the netty invoke.

When you raise a connection to a server,you don't need to specific the local port and local address.We just need to specific the server address and server port,after the tcp connection is established. The socket object would contains four items - local address,local port,target address,target port. Before you return to filter,you set the local address and local port to the filter chain or other variables. so you can get it.

we all agree that, the point of disagreement is whether to obtain the local address before or after the invoker invoke happens. I think the focus of this issue is to obtain the local address after that.

where is the invoker in ? Which module, I mean. When the connection established, you can get the local address and local port and set it into RpcContext. You can do this in the dubbo-rpc module.

RpcContext is based on threadLocal. When establishing a connection, there may be multiple clients, which means there are multiple ports. How to set the address into the filter at this time? What I mean is that when DubboInvoker doInvoke, it will determine which client to use, so The port of the client can be determined and set into the RpcContext. When the request is completed, the filter callback will be entered to obtain the address information.

aha, may be we have the same idea. What I want to do is that we can set local address in TripleInvoker#doInvke function. After the connectionClient.isConnected is called and it returns true, we can get local address, local port from connectClient and set it into RpcContext.

@AlbumenJ AlbumenJ added type/proposal Everything you want Dubbo have and removed type/feature labels Mar 8, 2024
AlbumenJ pushed a commit that referenced this issue Mar 11, 2024
…13751)

* fix(#13305): RpcContext local address info get null on custom filter

* fix ci build failed

* fix ci build failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Everything needs help from contributors type/proposal Everything you want Dubbo have
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

6 participants