zoukankan      html  css  js  c++  java
  • gRPC Client的负载均衡器

    一、gRPC是什么?

    gRPC是一个高性能、通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers)序列化协议开发,且支持众多开发语言。gRPC提供了一种简单的方法来精确地定义服务和为iOS、Android和后台支持服务自动生成 可靠性很强的客户端功能库。客户端充分利用高级流和链接功能,从而有助于节省带宽、降低的TCP链接次数、节省CPU使用、和电池寿命。

    二、为什么使用gRPC?

    有了 gRPC, 我们可以一次性的在一个 .proto 文件中定义服务并使用任何支持它的语言去实现客户端和服务器,反过来,它们可以在各种环境中,从Google的服务器到你自己的平板电脑- gRPC 帮你解决了不同语言间通信的复杂性以及环境的不同.使用 protocol buffers 还能获得其他好处,包括高效的序列号,简单的 IDL 以及容易进行接口更新。

    三、出现启动其中一个服务挂了、中间服务挂了、服务重新启动这三种情况,如何保证客户端的正常访问?

    1、haproxy

    缺点:每次连接都会创建一个channel,并发高的话资源消耗大,这样性能也会有问题

    2、客户端负载均衡器

    优点:单例,资源消耗小,性能比较好

    缺点:可能还存在点问题,代码有点乱

    3、zk、consul

    以后改进方案

    4、如果大家有更好的方案,欢迎大家拍砖,谢谢

    四、相关包的引用版本是多少?

    1、Grpc.Core.0.15.0

    2、Grpc.HealthCheck.0.15.0-beta

    3、Google.Protobuf.3.0.0-beta3

    五、核心代码如下:

    获取工作中的服务通道

    public static Channel GetWorkingChannel(string key)
        {
          Ensure.NotNullOrEmpty(key);
          CachedItem item = null;
          _cacheMap.TryGetValue(key, out item);
          Channel currentChosenChannel = null;
          if (_cacheMap.IsNotEmpty())
          {
            foreach (var channel in item.Channels.OrderBy(o => Guid.NewGuid()))
            {
              try
              {
                if (channel.State == ChannelState.Idle || channel.State == ChannelState.Ready)
                {
                  channel.ConnectAsync(DateTime.Now.AddMilliseconds(100)).Wait();
                  currentChosenChannel = channel;
                  break;
                }
              }
              catch
              {
                channel.ShutdownAsync().Wait();
              }
            };
          }
    
          if (currentChosenChannel == null) InitWorkingChannelsByKey(key);
          return currentChosenChannel;
        }
    

      

    进行健康检查

    private static bool CheckIfConnectionIsWorking(Channel serverChannel)
        {
          if (serverChannel != null)
          {
            try
            {
              var client = new Health.HealthClient(serverChannel);
              var response = client.Check(new HealthCheckRequest { Service = "HealthCheck" });
              return response.Status == HealthCheckResponse.Types.ServingStatus.Serving;
            }
            catch (Exception ex)
            {
              serverChannel.ShutdownAsync().Wait();
              return false;
            }
          }
          return false;
        }
    

      

    定时任务维护

     private static void ExecuteMaintenance(object state)
        {
          if (Interlocked.CompareExchange(ref _executing, 1, 0) != 0)
            return;
          try
          {
            if (_cacheMap.Count == 0)
            {
              StopMaintenance();
              if (_cacheMap.Count != 0)
                StartMaintenance();
            }
            else
            {
              DateTime oldThreshold = DateTime.UtcNow - _timeout;
              var expiredItems = _cacheMap.Where(i => i.Value.Updated < oldThreshold).Select(i => i.Key);
              for (int i = 0; i < expiredItems.Count(); i++)
              {
                var key = expiredItems.ElementAt(i);
                DisposeChannelsByKey(key);
                InitWorkingChannelsByKey(key);
              }
            }
          }
          finally
          {
            Interlocked.Exchange(ref _executing, 0);
          }
        }
    

      

    gRPC Client源代码已上传git,本人比较懒没有完整上传解决方案,该有的都有了。

  • 相关阅读:
    聊聊WS-Federation
    用双十一的故事串起碎片的网络协议(上)
    责任链模式的使用-Netty ChannelPipeline和Mina IoFilterChain分析
    最小化局部边际的合并聚类算法(中篇)
    最小化局部边际的合并聚类算法(上篇)
    UVaLive 7371 Triangle (水题,判矩形)
    UVaLive 7372 Excellence (水题,贪心)
    POJ 3312 Mahershalalhashbaz, Nebuchadnezzar, and Billy Bob Benjamin Go to the Regionals (水题,贪心)
    UVa 1252 Twenty Questions (状压DP+记忆化搜索)
    UVa 10817 Headmaster's Headache (状压DP+记忆化搜索)
  • 原文地址:https://www.cnblogs.com/hj4444/p/5793984.html
Copyright © 2011-2022 走看看