0

I'm connecting from NodeJS to the gRPC server which runs over IPv4. I create a gRPC client using address of format <FQDN>:<port> (not <ipv4address>:<port>). The communication between the server and the client is encrypted using SSL, so I cannot replace FQDN with ipv4address while creating a client. During resolving an end-point address I receive 4 addresses (since I have 2 network interfaces):

I0423 11:01:17.316000000 29056 pick_first.cc:265] Pick First 0000023C5D6DF8C0 received update with 4 addresses
I0423 11:01:17.317000000 29056 subchannel_list.h:370] [pick_first 0000023C5D6DF8C0] Creating subchannel list 0000023C5D371B90 for 4 subchannels
I0423 11:01:17.317000000 29056 client_channel.cc:831] chand=0000023C5D52B790: creating subchannel wrapper 0000023C5D545080 for subchannel 0000023C5D350890
I0423 11:01:17.317000000 29056 subchannel_list.h:420] [pick_first 0000023C5D6DF8C0] subchannel list 0000023C5D371B90 index 0: Created subchannel 0000023C5D545080 for address uri ipv6:[fe80::e8d0:a101:496f:2d8d%256]:8500
I0423 11:01:17.318000000 29056 client_channel.cc:831] chand=0000023C5D52B790: creating subchannel wrapper 0000023C5D5461B0 for subchannel 0000023C5D350A20
I0423 11:01:17.318000000 29056 subchannel_list.h:420] [pick_first 0000023C5D6DF8C0] subchannel list 0000023C5D371B90 index 1: Created subchannel 0000023C5D5461B0 for address uri ipv6:[fe80::bd41:4da9:9385:c8f8%2520]:8500
I0423 11:01:17.318000000 29056 client_channel.cc:831] chand=0000023C5D52B790: creating subchannel wrapper 0000023C5D545710 for subchannel 0000023C5D350BB0
I0423 11:01:17.319000000 29056 subchannel_list.h:420] [pick_first 0000023C5D6DF8C0] subchannel list 0000023C5D371B90 index 2: Created subchannel 0000023C5D545710 for address uri ipv4:172.26.1.57:8500
I0423 11:01:17.319000000 29056 client_channel.cc:831] chand=0000023C5D52B790: creating subchannel wrapper 0000023C5D545CB0 for subchannel 0000023C5D350D40
I0423 11:01:17.319000000 29056 subchannel_list.h:420] [pick_first 0000023C5D6DF8C0] subchannel list 0000023C5D371B90 index 3: Created subchannel 0000023C5D545CB0 for address uri ipv4:172.18.100.193:8500

Resolver tries to resolve the endpoint address preferring IPv6:

I0423 11:01:17.320000000 29056 tcp_client_custom.cc:151] CLIENT_CONNECT: 0000023C5D6EE820 ipv6:[fe80::e8d0:a101:496f:2d8d%256]:8500: asynchronously connecting
I0423 11:01:17.321000000 29056 client_channel.cc:1040] chand=0000023C5D52B790: processing connectivity change in combiner for subchannel wrapper 0000023C5D545080 subchannel 0000023C5D350890 (connected_subchannel=0000000000000000 state=CONNECTING): watcher=0000023C5D55F2E0
I0423 11:01:17.321000000 29056 subchannel_list.h:249] [pick_first 0000023C5D6DF8C0] subchannel list 0000023C5D371B90 index 0 of 4 (subchannel 0000023C5D545080): connectivity changed: state=CONNECTING, shutting_down=0, pending_watcher=0000023C5D55F2E0
I0423 11:01:17.322000000 29056 client_channel.cc:1273] chand=0000023C5D52B790: update: state=CONNECTING picker=0000023C5D55F860
I0423 11:01:17.322000000 29056 connectivity_state.cc:147] SET: 0000023C5D52B850 client_channel: CONNECTING --> CONNECTING [helper]
I0423 11:01:17.322000000 29056 client_channel.cc:3847] chand=0000023C5D52B790 calld=0000023C5D535330: LB pick returned QUEUE (subchannel=0000000000000000, error="No Error")
I0423 11:01:17.322000000 29056 completion_queue.cc:960] grpc_completion_queue_next(cq=0000023C5D333480, deadline=gpr_timespec { tv_sec: -9223372036854775808, tv_nsec: 0, clock_type: 0 }, reserved=0000000000000000)
I0423 11:01:17.323000000 29056 completion_queue.cc:1060] RETURN_EVENT[0000023C5D333480]: QUEUE_TIMEOUT
[SKIPPED]
I0423 11:01:17.360000000 29056 completion_queue.cc:960] grpc_completion_queue_next(cq=0000023C5D333480, deadline=gpr_timespec { tv_sec: -9223372036854775808, tv_nsec: 0, clock_type: 0 }, reserved=0000000000000000)
I0423 11:01:17.361000000 29056 completion_queue.cc:1060] RETURN_EVENT[0000023C5D333480]: QUEUE_TIMEOUT
I0423 11:01:18.320000000 29056 tcp_client_custom.cc:69] CLIENT_CONNECT: ipv6:[fe80::e8d0:a101:496f:2d8d%256]:8500: on_alarm: error="Cancelled"
I0423 11:01:18.321000000 29056 subchannel.cc:1034] Connect failed: {"created":"@1587628878.320000000","description":"Failed to connect to remote host","file":"t:\src\github\grpc-node\packages\grpc-native-core\deps\grpc\src\core\lib\iomgr\tcp_uv.cc","file_line":72,"grpc_status":14,"os_error":"connection refused"}
[SKIPPED]
I0423 11:01:18.324000000 29056 tcp_client_custom.cc:151] CLIENT_CONNECT: 0000023C5D6AC1D0 ipv6:[fe80::bd41:4da9:9385:c8f8%2520]:8500: asynchronously connecting
I0423 11:01:18.324000000 29056 client_channel.cc:1040] chand=0000023C5D52B790: processing connectivity change in combiner for subchannel wrapper 0000023C5D5461B0 subchannel 0000023C5D350A20 (connected_subchannel=0000000000000000 state=CONNECTING): watcher=0000023C5DAB9D10
I0423 11:01:18.325000000 29056 subchannel_list.h:249] [pick_first 0000023C5D6DF8C0] subchannel list 0000023C5D371B90 index 1 of 4 (subchannel 0000023C5D5461B0): connectivity changed: state=CONNECTING, shutting_down=0, pending_watcher=0000023C5DAB9D10
I0423 11:01:18.325000000 29056 client_channel.cc:1273] chand=0000023C5D52B790: update: state=CONNECTING picker=0000023C5DAB9F90
I0423 11:01:18.325000000 29056 connectivity_state.cc:147] SET: 0000023C5D52B850 client_channel: CONNECTING --> CONNECTING [helper]
I0423 11:01:18.325000000 29056 client_channel.cc:3847] chand=0000023C5D52B790 calld=0000023C5D535330: LB pick returned QUEUE (subchannel=0000000000000000, error="No Error")
I0423 11:01:18.326000000 29056 completion_queue.cc:960] grpc_completion_queue_next(cq=0000023C5D333480, deadline=gpr_timespec { tv_sec: -9223372036854775808, tv_nsec: 0, clock_type: 0 }, reserved=0000000000000000)
I0423 11:01:18.326000000 29056 completion_queue.cc:1060] RETURN_EVENT[0000023C5D333480]: QUEUE_TIMEOUT
I0423 11:01:19.325000000 29056 tcp_client_custom.cc:69] CLIENT_CONNECT: ipv6:[fe80::bd41:4da9:9385:c8f8%2520]:8500: on_alarm: error="Cancelled"
I0423 11:01:19.325000000 29056 subchannel.cc:1034] Connect failed: {"created":"@1587628879.325000000","description":"Failed to connect to remote host","file":"t:\src\github\grpc-node\packages\grpc-native-core\deps\grpc\src\core\lib\iomgr\tcp_uv.cc","file_line":72,"grpc_status":14,"os_error":"connection refused"}

As you see, each attempt to bind causes a 1 second delay, which in my environment results in 2 seconds delay before creating a client channel.

Is there a way to configure the resolver so that it prefers IPv4 addresses, or somehow reduce this timeout?

Pasick
  • 384
  • 2
  • 7

1 Answers1

0

A solution was suggested by Michael Lumish of gRPC team here:

One other option that works with either library is to use the round robin load balancing policy. That will start connecting to every backend address at once, and send requests to all of the ones it connects to, in a cycle. You can enable that by setting the "grpc.service_config" client construction argument. Its value is a stringified JSON representation of a service config object. It would look something like this:

const serviceConfig = {
    "loadBalancingConfig": [ { "round_robin": {} } ]
};
const options = {
    'grpc.service_config': JSON.stringify(serviceConfig),
    // plus any other options you are using
}
const client = new ClientClass(target, credentials, options);
Pasick
  • 384
  • 2
  • 7
  • I suggest also checking out the `@grpc/grpc-js` library, which is a close-to-faithful re-implementation of the `grpc` library. It uses a slightly different algorithm for connecting to backends that should decrease the delay mentioned in the question. – murgatroid99 Jan 07 '21 at 23:28