如何托管GRPC服务?

时间:2016-02-03 11:41:26

标签: c# grpc

我使用Link给出的示例在C#中创建了一个GRPC服务器。现在我想弄清楚我应该如何托管这个服务器,以便我实现以下目标:

  • 我应该将此服务器设置为控制台应用程序还是Windows服务。如果我把它变成一个Windows服务,那么更新服务将是麻烦的(这是一个很大的负面),如果我把它变成一个控制台应用程序,那么更新将只需要关闭exe。但这与错误关闭相同的价格有关。还有其他更好的办法吗?
  • 使用IIS,这个问题在那里赢了,因为我可以简单地从LB中删除该网站并停止网站执行更新,但由于GRPC不能成为IIS的一部分,我不知道是什么&# 39;这是让这种方式发挥作用的方式。

欢迎任何有关更好架构的参考资料。

4 个答案:

答案 0 :(得分:13)

我们可以使用Microsoft.Extensions.Hosting pacakge来托管.net核心控制台应用程序,方法是使用HostBuilder API开始构建gRPC主机并进行设置。

为了运行gRPC服务,我们首先需要在托管服务中启动/停止Grpc.Core.Server。托管服务基本上是主机本身启动时由主机运行的一段代码,而停止时则由托管服务运行。以下代码实现GrpcHostedService以覆盖IHostedService接口:

using System.Threading;
using System.Threading.Tasks;
using Grpc.Core;
using Microsoft.Extensions.Hosting;

namespace Grpc.Host
{
    public class GrpcHostedService: IHostedService
    {
        private Server _server;

        public GrpcHostedService(Server server)
        {
            _server = server;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _server.Start();
            return Task.CompletedTask;
        }

        public async Task StopAsync(CancellationToken cancellationToken) => await _server.ShutdownAsync();
    }
}

Program.cs中,使用HostBuilder API开始构建我们的grpc主机并进行设置:

public class Program
{
    public static async Task Main(string[] args)
    {
        var hostBuilder = new HostBuilder()
             // Add configuration, logging, ...
            .ConfigureServices((hostContext, services) =>
            {
                // Better to use Dependency Injection for GreeterImpl
                Server server = new Server
                {
                    Services = {Greeter.BindService(new GreeterImpl())},
                    Ports = {new ServerPort("localhost", 5000, ServerCredentials.Insecure)}
                };
                services.AddSingleton<Server>(server);
                services.AddSingleton<IHostedService, GrpcHostedService>();
            });

        await hostBuilder.RunConsoleAsync();
    }
}

通过这样做,通用主机将自动在我们的托管服务上运行StartAsync,而托管服务又会在Server实例上调用StartAsync,实质上是启动gRPC服务器。

当我们使用Control-C关闭主机时,通用主机将自动在我们的托管服务上调用StopAsync,这将再次调用Server实例上的StopAsync进行清理。

对于HostBuilder中的其他配置,您可以看到此blog

答案 1 :(得分:3)

目前gRPC不支持与ASP.Net/IIS集成。您需要在控制台或Windows服务中托管服务器。

您可能希望将其作为Windows服务,以便在重新启动或崩溃时更轻松地保持服务器正常运行。如果您想轻松将控制台应用程序转换为Windows服务,我建议您使用优秀的TopShelf Nuget。

可以像控制台应用一样更新服务。

  • 停止Windows服务。 net stop <service-name}>
  • 复制更新的程序集。
  • 启动Windows服务net start <service-name>

答案 2 :(得分:2)

我的公司(Shortbar)正在为gRPC上的一个名为HOLMS的酒店管理系统构建应用服务器。我们的设置如下:

  • HOLMS.Application是一个.NET类库(程序集),用于执行服务器的实际工作
  • HOLMS.Application.ConsoleRunner是一个托管HOLMS.Application的C#控制台应用程序。控制器运行器由(1)开发人员使用以方便(在问题中提到)以及(2)在Docker容器内运行的生产方案,其中容器运行时(例如Amazon ECS)实现作业控制/缩放。它遵循“12因素应用程序”指南,包括将自身作为单个,独立,无状态进程,快速启动/关闭和环境变量配置注入运行。系统记录到stdout,它被排出,但stdout在prod环境中耗尽(例如Sumo,logstash等)。这就是我们的SaaS多租户解决方案将投入生产的方式。
  • HOLMS.Application.ServiceRunner将HOLMS.Application打包到Windows服务中,用于更传统的内部部署情况,其中客户的IT组将自行运行服务。此程序包使用Windows注册表进行配置,并依赖Windows服务作业控制来启动/关闭/重新启动。它会记录到Windows事件日志。

ConsoleRunner和ServiceRunner每个只有大约200行代码;在大多数情况下,他们只需打包应用程序包,然后调用它。

希望这会有所帮助。

答案 3 :(得分:2)

我要再增加一个选项。

使用dot net core,您现在可以将其作为Linux守护程序运行。