Closed someview closed 1 year ago
I have traced the code,and find some graph in grpcChannel class:
#if NET5_0_OR_GREATER
private static readonly Uri HttpLoadBalancerTemporaryUri = new Uri("http://loadbalancer.temporary.invalid");
private static readonly Uri HttpsLoadBalancerTemporaryUri = new Uri("https://loadbalancer.temporary.invalid");
private static bool IsProxied(SocketsHttpHandler socketsHttpHandler, Uri address, bool isSecure)
{
// Check standard address directly.
// When load balancing the channel doesn't know the final addresses yet so use temporary address.
Uri resolvedAddress;
if (IsHttpOrHttpsAddress(address))
{
resolvedAddress = address;
}
else if (isSecure)
{
resolvedAddress = HttpsLoadBalancerTemporaryUri;
}
else
{
resolvedAddress = HttpLoadBalancerTemporaryUri;
}
var proxy = socketsHttpHandler.Proxy ?? HttpClient.DefaultProxy;
return proxy.GetProxy(resolvedAddress) != null;
}
#endif
when create grpcChannel like this:
channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions
{
HttpHandler = new SocketsHttpHandler
{
EnableMultipleHttp2Connections = true,
PooledConnectionIdleTimeout = TimeSpan.FromSeconds(60),
ConnectTimeout = TimeSpan.FromSeconds(5),
},
Credentials = credentials,
ServiceConfig = new ServiceConfig
{
LoadBalancingConfigs = {
new BalanceConfig(opt.BalancerName)
}
},
LoggerFactory = _loggerFactory,
ServiceProvider = services.BuildServiceProvider(),
});
var proxy = socketsHttpHandler.Proxy ?? HttpClient.DefaultProxy
the conditon may cause an unexpected result if HttpClient.DefaultProxy is not setted correctly.And this may casue the situition I have mentioned above:
the channel treat address like "grpc:///roomservice:5002" as proxy url
dbug: 2023-08-14 01:55:39Z Grpc.Net.Client.Internal.GrpcCall[1] Starting gRPC call. Method type: 'Unary', URI: 'http://loadbalancer.temporary.invalid/TL.Count.Contract.Cou │
│ dbug: 2023-08-14 01:55:39Z Grpc.Net.Client.Balancer.Internal.ConnectionManager[6] Successfully picked subchannel id '1' with address 100.105.97.197:5002.
there may exist a concurrent issue: when first client has no avaliable address, they may affect another.
I have discovered the truth。
private GrpcMethodInfo CreateMethodInfo(IMethod method)
{
var uri = new Uri(method.FullName, UriKind.Relative);
var scope = new GrpcCallScope(method.Type, uri);
var methodConfig = ResolveMethodConfig(method);
var uriBuilder = new UriBuilder(Address);
uriBuilder.Path = method.FullName;
// The Uri used to create HttpRequestMessage must have a http or https scheme.
uriBuilder.Scheme = IsSecure ? Uri.UriSchemeHttps : Uri.UriSchemeHttp;
// A Uri with a http or https scheme requires a host name.
// Triple slash URIs, e.g. dns:///custom-value, won't have a host and UriBuilder throws an error.
// Add a temp value as the host. The tempuri.org host may show up in some logging but it will
// get replaced in the final HTTP request address by the load balancer.
if (string.IsNullOrEmpty(uriBuilder.Host))
{
// .invalid is reserved for temporary host names.
// https://datatracker.ietf.org/doc/html/rfc2606#section-2
uriBuilder.Host = "loadbalancer.temporary.invalid";
}
return new GrpcMethodInfo(scope, uriBuilder.Uri, methodConfig);
}
The grpc call is ok, but the logger record is strange. http://loadbalancer.temporary.invalid/TL.Count.Contract.CountContract/getCounts
even there is a normal address.
version:
grpc-dotnet: 2.5.5
steps
desc
This occurs when a first service not exist