• zooland 新开源的RPC项目,希望大家在开发的微服务的时候多一种选择,让微服务开发简单,并且容易上手。


    zooland 我叫它动物园地,一个构思很长时间的一个项目。起初只是觉得各种通信框架都封装的很好了,但是就是差些兼容,防错,高可用。同时在使用上,不希望有多余的代码,像普通接口一样使用就可以了。

    基于这些想法,看了很多资料,有了很多启发;也开发出这样一个版本,而且也在实际项目中应用起来了,算是小有成就吧。但同时深知一个人的力量有限,希望得到整个社区帮助。帮助我完善它,让它成为.net 平台下一个不错的选择。

    首先,介绍一下这个项目。

    项目中没有实现自己的通信层代码,因为大厂为我们提供了 比如 thrift、grpc、HTTP、wcf、akka.net、netty.net 等等。

    其次既然我都支持了这么多种通信框架了,那么他们在同一个项目中进行混用也是可以的。比如你的.net 项目内使用wcf 或 netty通信,这个时候elk或者搜索引擎为你提供了thrift的接口,那么用这个框架会是不错的选择。

    项目中 主要的精力放在了LoadBalace、调用错误隔离、重试、缓存,多种形式的Cluster、以及如何以最简单的方式让队员通过直链的方式进行开发。

    服务注册和发现,现在还没有很好的实现想法,希望社区能帮忙,当然有接口性能监控的能手,和调用链或熟悉dapper的能加入我,那么我会更高兴。

    ioc上无赖选择了Spring.net,希望spring.net 早点出.net core版本的,这样我会很省心的去开发.net core 版的zooland;

    autofac 我正在尝试,希望能作为spring.net 的替代版本,可能是因为习惯了spring.net 感觉autofac我增加我的配置文档的数量,这是我不喜欢的

    ioc 我也不喜欢对框架内部侵入太多的,它会让我觉得我的架构很臃肿,让我觉得ioc 不过是虚拟工厂来生产真正的实例,而且还要让我到处引用虚拟工厂的类库,想想都觉得烦。

    计划还是有的:

    准备在框架层加入过滤器,这样CAS 做分布式事务的开源框架也能整合进来,缓存也能独立成一个Filter 的实现

    比较麻烦的是调用链,需要埋点,由于支持了多种通信框架,而基于dapper论文的追踪访问链条的方式,可能导致有些通信框架不支持,比较麻烦,一直在想,tcp/ip协议是不是也有想http一样的,可以在访问header里面添加调用链的内容。也希望社区有好的办法。当然能推动大厂们提供的通信框架的改进,那就更好了。

    有代码有真相,下面是用于调用的代码,对使用来说绝对easy

    static void Main(string[] args)
            {
                var context = ContextRegistry.GetContext();
                var helloServiceThrift = context.GetObject<RpcContractThrift.IHelloService>();
                var helloServiceGrpc = context.GetObject<RpcContractGrpc.IHelloService>();
                var helloServiceWcf = context.GetObject<RpcContractWcf.IHelloService>();
                var helloServiceHttp = context.GetObject<RpcContractHttp.IHelloService>();
                var helloServiceAkka = context.GetObject<RpcContractAkka.IHelloService>();
                var helloServiceRemoting = context.GetObject<RpcContractRemoting.IHelloService>();
                while (true)
                {
                    Console.WriteLine("请选择:wcf | grpc | thrift | http | akka | remoting");
                    var mode = Console.ReadLine().ToLower();
                    switch (mode)
                    {
                        case "wcf":
                            CallWhile((helloword) => { WcfHello(helloServiceWcf, helloword); });
                            break;
                        case "grpc":
                            CallWhile((helloword) => { GrpcHello(helloServiceGrpc, helloword); });
                            break;
                        case "thrift":
                            CallWhile((helloword) => { ThriftHello(helloServiceThrift, helloword); });
                            break;
                        case "http":
                            CallWhile((helloword) => { HttpHello(helloServiceHttp, helloword); });
                            break;
                        case "akka":
                            CallWhile((helloword) => { AkkaHello(helloServiceAkka, helloword); });
                            break;
                        case "remoting":
                            CallWhile((helloword) => { RemotingHello(helloServiceRemoting, helloword); });
                            break;
                        case "all":
                            for (int i = 0; i < 3; i++)
                            {
                                Task.Run(() =>
                                {
                                    try
                                    {
                                        WcfHello(helloServiceWcf);
                                    }
                                    catch (Exception ex)
                                    {
                                        throw ex;
                                    }
                                });
                                Task.Run(() =>
                                {
                                    try
                                    {
                                        GrpcHello(helloServiceGrpc);
                                    }
                                    catch (Exception ex)
                                    {
                                        throw ex;
                                    }
    
                                });
                                Task.Run(() =>
                                {
                                    try
                                    {
                                        ThriftHello(helloServiceThrift);
                                    }
                                    catch (Exception ex)
                                    {
                                        throw ex;
                                    }
    
                                });
                                Task.Run(() =>
                                {
                                    try
                                    {
                                        HttpHello(helloServiceHttp);
                                    }
                                    catch (Exception ex)
                                    {
    
                                        throw ex;
                                    }
    
                                });
                                Task.Run(() =>
                                {
    
                                    try
                                    {
                                        AkkaHello(helloServiceAkka);
                                    }
                                    catch (Exception ex)
                                    {
    
                                        throw ex;
                                    }
                                });
                            }
                            break;
                    }
    
                    if (mode == "end")
                    {
                        break;
                    }
                }
    
            }
            private static void ThriftHello(RpcContractThrift.IHelloService helloServiceThrift, string helloword = "world")
            {
                var callNameVoid = helloServiceThrift.CallNameVoid();
                Console.WriteLine(callNameVoid);
                helloServiceThrift.CallName(helloword);
                Console.WriteLine("CallName called");
                helloServiceThrift.CallVoid();
                Console.WriteLine("CallVoid called");
                var hello = helloServiceThrift.Hello(helloword);
                Console.WriteLine(hello);
                var helloResult = helloServiceThrift.SayHello(helloword + "perfect world");
                Console.WriteLine($"{helloResult.Name},{helloResult.Gender},{helloResult.Head}");
                helloResult.Name = helloword + "show perfect world";
                var showResult = helloServiceThrift.ShowHello(helloResult);
                Console.WriteLine(showResult);
            }
            private static void GrpcHello(RpcContractGrpc.IHelloService helloServiceGrpc, string helloword = "world")
            {
                var callNameVoid = helloServiceGrpc.CallNameVoid(new RpcContractGrpc.Void());
                Console.WriteLine(callNameVoid);
                helloServiceGrpc.CallName(new RpcContractGrpc.NameResult { Name = helloword });
                Console.WriteLine("CallName called");
                helloServiceGrpc.CallVoid(new RpcContractGrpc.Void());
                Console.WriteLine("CallVoid called");
                var hello = helloServiceGrpc.Hello(new RpcContractGrpc.NameResult { Name = helloword });
                Console.WriteLine(hello.Name);
                var helloResult = helloServiceGrpc.SayHello(new RpcContractGrpc.NameResult { Name = $"{helloword} perfect world" });
                Console.WriteLine($"{helloResult.Name},{helloResult.Gender},{helloResult.Head}");
                helloResult.Name = helloword + "show perfect world";
                var showResult = helloServiceGrpc.ShowHello(helloResult);
                Console.WriteLine(showResult.Name);
            }
            private static void WcfHello(RpcContractWcf.IHelloService helloServiceWcf, string helloword = "world")
            {
                var callNameVoid = helloServiceWcf.CallNameVoid();
                Console.WriteLine(callNameVoid);
                helloServiceWcf.CallName(helloword);
                Console.WriteLine("CallName called");
                helloServiceWcf.CallVoid();
                Console.WriteLine("CallVoid called");
                var helloWcf = helloServiceWcf.Hello(helloword);
                Console.WriteLine(helloWcf);
                var helloResultWcf = helloServiceWcf.SayHello($"{helloword} perfect world");
                Console.WriteLine($"{helloResultWcf.Name},{helloResultWcf.Gender},{helloResultWcf.Head}");
                helloResultWcf.Name = helloword + "show perfect world";
                var showResultWcf = helloServiceWcf.ShowHello(helloResultWcf);
                Console.WriteLine(showResultWcf);
            }
            private static void HttpHello(RpcContractHttp.IHelloService helloServiceHttp, string helloword = "world")
            {
                var callNameVoid = helloServiceHttp.CallNameVoid();
                Console.WriteLine(callNameVoid);
                helloServiceHttp.CallName(helloword);
                Console.WriteLine("CallName called");
                helloServiceHttp.CallVoid();
                Console.WriteLine("CallVoid called");
                var helloWcf = helloServiceHttp.Hello(helloword);
                Console.WriteLine(helloWcf);
                var helloResultWcf = helloServiceHttp.SayHello($"{helloword} perfect world");
                Console.WriteLine($"{helloResultWcf.Name},{helloResultWcf.Gender},{helloResultWcf.Head}");
                helloResultWcf.Name = helloword + "show perfect world";
                var showResultWcf = helloServiceHttp.ShowHello(helloResultWcf);
                Console.WriteLine(showResultWcf);
            }
            private static void AkkaHello(RpcContractAkka.IHelloService akkaServiceHttp,string helloword = "world")
            {
                var callNameVoid = akkaServiceHttp.CallNameVoid();
                Console.WriteLine(callNameVoid);
                akkaServiceHttp.CallName(new RpcContractAkka.NameResult { Name = helloword });
                Console.WriteLine("CallName called");
                akkaServiceHttp.CallVoid();
                Console.WriteLine("CallVoid called");
                var hello = akkaServiceHttp.Hello(new RpcContractAkka.NameResult { Name = helloword });
                Console.WriteLine(hello.Name);
                var helloResult = akkaServiceHttp.SayHello(new RpcContractAkka.NameResult { Name = $"{helloword} perfect world" });
                Console.WriteLine($"{helloResult.Name},{helloResult.Gender},{helloResult.Head}");
                helloResult.Name = helloword + "show perfect world";
                var showResultWcf = akkaServiceHttp.ShowHello(helloResult);
                Console.WriteLine(showResultWcf.Name);
                
            }
            private static void RemotingHello(RpcContractRemoting.IHelloService remotingServiceHttp, string helloword = "world")
            {
                var callNameVoid = remotingServiceHttp.CallNameVoid();
                Console.WriteLine(callNameVoid);
                remotingServiceHttp.CallName(helloword);
                Console.WriteLine("CallName called");
                remotingServiceHttp.CallVoid();
                Console.WriteLine("CallVoid called");
                var hello = remotingServiceHttp.Hello(helloword);
                Console.WriteLine(hello);
                var helloResult = remotingServiceHttp.SayHello($"{helloword} perfect world");
                Console.WriteLine($"{helloResult.Name},{helloResult.Gender},{helloResult.Head}");
                helloResult.Name = helloword + "show perfect world";
                var showResult = remotingServiceHttp.ShowHello(helloResult);
                Console.WriteLine(showResult);
    
            }
    
            private static void CallWhile(Action<string> map)
            {
                var helloword = "world";
                while (true)
                {
                    try
                    {
                        map(helloword);
                        var mode = Console.ReadLine().ToLower();
                        helloword = mode;
                        if (helloword == "end")
                        {
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.StackTrace);
                    }
                }
            }
        }

    目前只支持了spring.net ,有autofac的高手,欢迎加入

    希望为一部分使用.net framework 的WCF做通信层框架,转微服务架构,作为一个不错的并且平滑的升级选择。

    新技术不要怕不稳定,源码都有了,而且框架结构这么简单,大胆用,有问题了,可以联系技术支持啥。

    奉上项目开源地址:

    https://github.com/wutao0315/zooland

    现在还没有搞明白怎么编译好一个版本怎么弄到nuget上,而且版本管理经验也欠缺,也需要依赖社区了。

    联系作者

    mail:wutao0315@qq.com

    qq:1164636434

    想加入我的,邮件给我吧,欢迎每一个热爱编程的同学。

  • 相关阅读:
    ASP.NET Core 2.2 基础知识(二) 中间件
    ASP.NET Core 2.2 基础知识(一) 依赖注入
    初识.NET Core
    volatile 和 Interlocked
    线程池
    MySQL 将某个字段值的记录排在最后,其余记录单独排序
    MySQL 一张表中两个字段值互换
    (转) C#解惑:HashSet<T>类
    利用 ildasm 修改被编译后DLL文件
    shell 字符串判断
  • 原文地址:https://www.cnblogs.com/jweiswu/p/zooland.html
Copyright © 2020-2023  润新知