SteeltoeOSS / Steeltoe

.NET Components for Externalized Configuration, Database Connectors, Service Discovery, Logging and Distributed Tracing, Application Management, Security, and more.
https://steeltoe.io
Apache License 2.0
1.01k stars 163 forks source link

Does steeltoe support grpc? #433

Open iseejustdoit opened 4 years ago

iseejustdoit commented 4 years ago

I want to register .net core grpc to spring cloud eureka and gateway,and then use gateway calls between microservices. Does steeltoe support to do it?

TimHess commented 4 years ago

Not directly, not officially.. but since there's an integration with HttpClientFactory for Grpc I've heard that it works - we had a conversation on Slack about this a couple weeks ago https://steeltoeteam.slack.com/archives/C0ENXS0M8/p1598621292006000

Hawxy commented 4 years ago

Per the slack link above I tested this a few weeks ago. The current integration works great with grpc as far as I can tell.

With the client factory, all of the same Steeltoe HttpClientFactory extensions can be used:



services.AddGrpcClient<Greeter.GreeterClient>(o =>
{
    o.Address = new Uri("https://serviceName");
}).AddServiceDiscovery();
iseejustdoit commented 4 years ago

Not directly, not officially.. but since there's an integration with HttpClientFactory for Grpc I've heard that it works - we had a conversation on Slack about this a couple weeks ago https://steeltoeteam.slack.com/archives/C0ENXS0M8/p1598621292006000

I can't access this link.

I registed two services to spring cloud eureka: 1.net core OrderApi,port is 5001,registed service name is OrderService 2.net core ProductApi,port is 5002,registed service name is ProductService

In OrderApi, i can access ProductApi by registed service name without ProductApi ip+port like: http://productservice/productapi/product/get.

But I want to access ProductApi by grpc with registed service name like: var channel = GrpcChannel.ForAddress("**_http://productservice_**"); var client = new Greeter.GreeterClient(channel);

so,i have some questions: 1.Can grpc register to Spring cloud eureka? 2.Can the ProductApi be accessed by the registered service name

Hawxy commented 4 years ago

2.Can the ProductApi be accessed by the registered service name

Yes, either globally through the ClientFactory as described above (recommended), or standalone by passing in the DiscoveryHttpClientHandler manually as you would with the HttpClient:


var handler = new DiscoveryHttpClientHandler(/**/);
var channel = GrpcChannel.ForAddress("https://serviceName", new GrpcChannelOptions() { HttpHandler = handler } );
iseejustdoit commented 4 years ago

2.Can the ProductApi be accessed by the registered service name

Yes, either globally through the ClientFactory as described above (recommended), or standalone by passing in the DiscoveryHttpClientHandler manually as you would with the HttpClient:

var handler = new DiscoveryHttpClientHandler(/**/);
var channel = GrpcChannel.ForAddress("https://serviceName", new GrpcChannelOptions() { HttpHandler = handler } );

I created a separate grpc service, it really works!

But i have another question. Can web api register multiple ports to spring cloud eureka at once?

Here is my appsettings configration:

{
  "spring": {
    "application": {
      "name": "ProductService"
    }
  },
  "eureka": {
    "client": {
      "serviceUrl": "http://localhost:8761/eureka/",
      "shouldFetchRegistry": "false",
      "shouldRegisterWithEureka": true,
      "validateCertificates": false
    },
    "instance": {           
      "port": "5002",
      "ipAddress": "localhost",
      "preferIpAddress": true      
    }
  }
}

WebApi Port 5002,Grpc Server Port 5009:

 webBuilder.ConfigureKestrel(options =>
                    {
                        options.Listen(IPAddress.Any, 5002, listenOptions =>
                        {
                            listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
                        });
                        options.Listen(IPAddress.Any, 5009, listenOptions =>
                        {
                            listenOptions.Protocols = HttpProtocols.Http2;
                        });
                    }).UseStartup<Startup>();

Is it possible to register two ports at the same time?

TimHess commented 4 years ago

Is it possible to register two ports at the same time?

I don't think there's a reasonable way to do this directly with Steeltoe right now... Thinking about it, how would you expect it to work?

I'm thinking you'd almost want completely separate service entries in Eureka, otherwise you'd have to do something weird to map which port to use in which context. There is already support for mapping HTTP and HTTPS ports, and it's possible to specify metadata when registering a service, so there might be room to build out some customization on top of the IDiscoveryClient rather than the existing HttpClient-based classes we recommend using today

TimHess commented 4 years ago

Registering multiple ports probably requires registering as multiple services... this should be considered along with #479

TimHess commented 8 months ago

Restating our current understanding of this issue:

Consuming services: There should currently be no issues with the client side of this story if you are able to register two different service names (eg: myservice-http and myservice-grpc) and use the appropriate service name for the protocol to be used.

Registering services: Is it possible to have a discovery client manage more than one instance? We have doubts about this due to complexities around managing the metadata for this instance, and there does not appear to be any matching functionality in Spring today.