关闭

Grpc的一个简单的负载均衡类库

3322人阅读 评论(0) 收藏 举报
分类:

首先先列下Grpc的教程,然后目前Grpc的C#的版本为1.0 prev版,反正就是还有坑的阶段,实际会出内存错误导致程序崩溃(内存错误你懂得,unsafe代码异常捕获都没用),这里就当是尝鲜版试验使用了下,然后就简单的写了个类,具体代码如下

GrpcChannelTargetsSection,用来配置服务器地址的类

    public class GrpcChannelTargetsSection : ConfigurationSection
    {
        public static GrpcChannelTargetsSection Current
        {
            get { return (GrpcChannelTargetsSection)ConfigurationManager.GetSection("grpcChannelTargets"); }
        }
        /// <summary>
        /// 连接超时时间(单位毫秒)
        /// </summary>
        [ConfigurationProperty("connectTimeout", DefaultValue = 500)]
        public int ConnectTimeout
        {
            get { return Convert.ToInt32(this["connectTimeout"]); }
            set { this["connectTimeout"] = value; }
        }

        [ConfigurationProperty("", IsDefaultCollection = true)]
        public KeyValueConfigurationCollection Targets
        {
            get
            {
                return (KeyValueConfigurationCollection)base[""];
            }
        }
        readonly IDictionary<string, IEnumerable<string>> _dic = new Dictionary<string, IEnumerable<string>>();
        protected override void PostDeserialize()
        {
            if (this.Targets == null || this.Targets.Count == 0)
            {
                throw new ArgumentException("No target can be found!");
            }
            foreach (var key in this.Targets.AllKeys)
            {
                var target = this.Targets[key].Value.Split(',').Where(str => !string.IsNullOrWhiteSpace(str));
                if (!target.Any())
                {
                    throw new ArgumentException("Argument error,the target of " + key + " is empty");
                }
                this._dic.Add(key, target);
            }
            base.PostDeserialize();
        }
        public IEnumerable<string> GetTarget(string key)
        {
            if (this._dic.ContainsKey(key))
            {
                return this._dic[key];
            }
            return null;
        }
    }
ChannelHelper,根据配置获取可用Channel的赋值类
    using global::Grpc.Core;
    public class ChannelHelper
    {
        public static Channel GetFirstChannel(ChannelCredentials credentials = null, IEnumerable<ChannelOption> options = null)
        {
            return GetChannel(GrpcChannelTargetsSection.Current.Targets.AllKeys[0], credentials, options);
        }
        /// <summary>
        /// 获取Grpc Channel
        /// </summary>
        /// <param name="key">配置中的Key值</param>
        /// <param name="credentials"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public static Channel GetChannel(string key, ChannelCredentials credentials = null, IEnumerable<ChannelOption> options = null)
        {
            var targets = GrpcChannelTargetsSection.Current.GetTarget(key);
            if (targets == null)
            {
                throw new KeyNotFoundException("Can not find target with key '" + key + "'");
            }
            Channel channel = null;
            if (credentials == null)
            {
                credentials = ChannelCredentials.Insecure;
            }
            foreach (var target in targets.OrderBy(x => Guid.NewGuid()))
            {
                try
                {
                    channel = new Channel(target, credentials, options);
                    channel.ConnectAsync(DateTime.UtcNow.AddMilliseconds(GrpcChannelTargetsSection.Current.ConnectTimeout)).Wait();
                    if (channel.State != ChannelState.Shutdown
                        && channel.State != ChannelState.TransientFailure)
                    {
                        break;
                    }
                }
                catch (Exception ex)
                {
                    //如果不关闭,貌似虽然超时跳出了,但Connect还会一直进行连接尝试
                    //因为能在控制台输出界面能一直看到连接错误信息
                    if (channel != null)
                    {
                        var tmpChannel = channel;
                        Task.Factory.StartNew((c) =>
                        {
                            var tmp = c as Channel;
                            if (tmp != null)
                            {//虽然关闭的方法名写的是Async,但实际还要等待N秒
                                tmp.ShutdownAsync().Wait();
                            }
                        }, tmpChannel);
                        channel = null;
                    }
                }
            }
            return channel;
        }
    }
实际使用时需在config中增加如下配置

1、在configSections中增加下级配置,注意后面的type需改成实际项目的命名空间

<section name="grpcChannelTargets" type="Demo.Grpc.GrpcChannelTargetsSection, Demo" />

2、增加configSections同级配置

  <grpcChannelTargets connectTimeout="1000"><!--connectTimeout 为连接超时设置,单位为毫秒,用于判断获取到的服务地址是否可用-->
    <!--每个add对应一项Grpc服务器,若该项服务配置了多台服务器,那么value部分通过,分隔,程序会随机抽取一项返回-->
    <add key="GrpcServer_1" value="192.168.5.113:90,192.168.5.114:90" />
    <add key="GrpcServer_2" value="192.168.5.113:92" />
    <add key="GrpcServer_3" value="192.168.5.113:94,192.168.5.114:94,192.168.5.115:94" />
  </grpcChannelTargets>
使用代码如下
var channle = ChannelHelper.GetFirstChannel();//取配置的第一项服务
channle = ChannelHelper.GetChannel("GrpcServer_1");//按配置的Key获取对应的服务

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Grpc的一个简单的负载均衡类库

首先先列下Grpc的教程,然后目前Grpc的C#的版本为1.0 prev版,反正就是还有坑的阶段,实际会出内存错误导致程序崩溃(内存错误你懂得,unsafe代码异常捕获都没用),这里就当是尝鲜版试验使...
  • starfd
  • starfd
  • 2016-08-01 10:27
  • 3322

grpc(1):Centos 安装java的grpc服务,使用haproxy进行负载均衡,nginx不支持

1,关于grpcGRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go...
  • freewebsys
  • freewebsys
  • 2017-02-28 10:31
  • 3444

gRPC服务发现&负载均衡

https://segmentfault.com/a/1190000008672912 构建高可用、高性能的通信服务,通常采用服务注册与发现、负载均衡和容错处理等机制实现。根据负载均...
  • leonpengweicn
  • leonpengweicn
  • 2017-05-26 18:05
  • 1727

利用nginx和docker实现一个简单负载均衡

测试步骤:1.在服务器中搭建一个nginx服务器并启动 2.在docker中从源中拉一下nginx的官方镜像,留以docker容器运行//下载过程可能会有点慢,不如吃点零食 docker pull ...
  • li_haijiang
  • li_haijiang
  • 2017-07-01 09:59
  • 243

利用nginx和docker实现一个简单负载均衡

测试步骤: 1.在服务器中搭建一个nginx服务器并启动 2.在docker中从源中拉一下nginx的官方镜像,留以docker容器运行 //下载过程可能会有点慢,不如吃点零食 docker pu...
  • qq_36663951
  • qq_36663951
  • 2017-12-13 09:27
  • 30

网络负载均衡(NLB)的一个例子

  • 2013-06-04 13:55
  • 244KB
  • 下载

FreeBSD下用nginx配置简单web负载均衡

  • 2012-03-05 16:03
  • 48KB
  • 下载

F5网络负载均衡配置手册及简单的参数说明

  • 2017-11-08 13:36
  • 1.50MB
  • 下载

A10负载均衡SLB简单配置

  • 2015-05-07 12:26
  • 1.75MB
  • 下载

nginx+tomcat负载均衡简单配置

  • 2012-02-24 17:11
  • 544KB
  • 下载
    个人资料
    • 访问:370912次
    • 积分:3941
    • 等级:
    • 排名:第9251名
    • 原创:73篇
    • 转载:4篇
    • 译文:0篇
    • 评论:125条
    文章分类
    最新评论