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

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

posted @ 2018-07-31 21:44 小小明 阅读(545) 评论(2) 推荐(1) 编辑
摘要: DBLayer,我最近开源的数据库轻量级orm框架,目前支持sqlserver、mysql、oracle, 特别做了分页的封装。 这个框架从七八年前开始逐渐升级而来,也经历了不少项目,希望可以将大家从sql字符串中解放出来。 开源地址 https://github.com/wutao0315/DBL 阅读全文
posted @ 2017-06-15 10:20 小小明 阅读(5883) 评论(20) 推荐(4) 编辑
摘要: Docker 是一个开源的轻量级容器项目,用于让你的应用在它上面打包、集装和运行。Docker 运行的环境既包含未知硬件也包含未知操作系统。这句话的意思是它可以运行在任何地方,小到你的笔记本大到一个大型的云计算实体,除此之外也不需要你掌握或用到任何特定的开发语言、框架或者打包系统。这使得他们能够在不 阅读全文
posted @ 2017-03-13 20:15 小小明 阅读(334) 评论(0) 推荐(0) 编辑
摘要: 近段时间在看SOA,在国外网站有很多资料可以查看,本来在中文网站中找到一片关于这两个框架的对比介绍的可惜笔者没有认真翻译,只有花点时间自己翻译了一个版本,希望对技术界的朋友有所帮助。我正纠结于NServiceBus和MassTransit的选择上的利弊。现在我已经知道一些思路,但是这些并不能真正回答... 阅读全文
posted @ 2015-12-16 15:21 小小明 阅读(2439) 评论(0) 推荐(5) 编辑
摘要: 做了7年的开发了,时间越久越是发现自己需要一个像标题写的那样的一个架构做为整个平台的支撑。 我的技术种类又是.net开发,总觉得.net技术人才容易出现瓶颈;其实这种瓶颈更像是这种环境造成的。简单快捷的开发本来就是.net所追求的,而这种追求导致整个语言平台在技术上都喜欢用最直接简单的方法解决... 阅读全文
posted @ 2015-05-28 21:42 小小明 阅读(3799) 评论(11) 推荐(2) 编辑
摘要: 最近一直在看关于thrift的相关文章,涉及到的内容的基本都是表层的。一旦具体要用到实际的项目中的时候就会遇到各种问题了!比如说:thrift 的服务器端载体的选择、中间代码的生成options(async asyncctp wcf 等等)、实现服务器端和客户端的基础框架的选择、和承载各层之间的... 阅读全文
posted @ 2014-12-21 16:58 小小明 阅读(968) 评论(3) 推荐(1) 编辑
摘要: 这周的工作终于告一段落,费神的一周啊。在历史功能上开发新功能,历史代码还有bug。开发过程中心情相当的纠结。还好,最后还是把它拿下了,逻辑还算清晰,但是就是代码太多了,这个提醒我们,在编码规则中必须加一条,一个方法的代码不能超过多少行代码,每行代码不能超过多少字,每个类不能超过多少个方法。 其... 阅读全文
posted @ 2014-10-24 15:58 小小明 阅读(701) 评论(0) 推荐(0) 编辑
摘要: hadoop java 开源项目。 它的设计让我如此喜欢。分布式文件存储系统,mapreduce算法。作为一个.net 的开发工程师。从众多的java开源项目中让我学到了不少好东西。从我正式投身工作以来,我无时无刻不在寻找。 他的分布式文件系统,用多系统备份和多文件块的方式,既可以保证文件的安全,同时利用带宽和负载均衡的方式,有限利用集群带宽提高整个系统的负载能力。 他的分布式算法,mapreduce 和自身的分布式文件存储系统一起协作,及有效利用每台服务器的文件块,带宽,同时把大文件分发给不同的服务器,同时运算,利用集群的算法提高大文件的搜索速度。得到的结果也是相当的理想。比起那些花了... 阅读全文
posted @ 2012-08-10 15:35 小小明 阅读(360) 评论(0) 推荐(0) 编辑
摘要: 做了三年多的程序了,一起出来的朋友们还从事这一行的却所剩无几。之所以我们这个it市场人才需求量这么大,其实需要的不是大量青年加入,而是要能坚持有恒心的人努力的坚持下来。 我一直有从从事这个行业开始,就已经想好。就是我以前听过的一个谚语,关于画画卖画的故事-具体的内容已经模糊了,反正大概就是一天做十幅画不如十天做一幅画。其实在我看来,做软件这个行业也是一样的。尤其是我们现在接触到的b/s结构。也许我们开发只需要3个月,可是真的三个月完了这幅画就完成吗,其实不然。我花了三年多的时间一直在不断的更新升级,优化,开发新功能等等的工作。与其说我们的开发期是花了3个月,还不如说这三个月我们只是把花的... 阅读全文
posted @ 2012-08-09 18:06 小小明 阅读(886) 评论(1) 推荐(1) 编辑
摘要: SEO工具包2010-03-03 15:36过去几个星期里,我一直在询问开发人员,看有多少人在使用新的搜索引擎优化(SEO)工具包来增加他们网站的流量。让我吃惊的是,有很多人要么从来没有听说过这个工具,要么还没有机会针对自己网站运行该工具。本博客将就为什么任何做web开发的人都应该看一下这个工具提供一个简单的摘要。为什么要使用一个免费的SEO工具包?简而言之,这个免费的SEO工具包分析器(SEO ... 阅读全文
posted @ 2010-03-03 16:38 小小明 阅读(917) 评论(2) 推荐(1) 编辑
点击右上角即可分享
微信分享提示