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

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

转载于:https://www.cnblogs.com/jweiswu/p/zooland.html

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

  1. ASP.NET3.5 企业级项目开发 -- 第二章(续) 数据访问层(DAL)的开发解决方案提出...

    ASP.NET3.5 企业级项目开发 -- 第二章(续) 数据访问层(DAL)的开发解决方案提出 前言:首先给大家说声"对不起",因为自从打算写这系列的文章以来,得到大家很多的支持 ...

  2. blog微服务架构代码_DDD+微服务大型案例:Uber如何从复杂的RPC微服务转向面向业务领域的微服务架构DOMA? -优步工程博客...

    最近,围绕面向服务的体系结构,尤其是微服务体系结构的弊端进行了大量讨论.仅仅几年前,由于许多人宣传微服务架构的好处,例如独立部署形式的灵活性,明确的所有权,系统稳定性的改进以及更好的关注点分离,很多人 ...

  3. 视频教程-项目实战视频课程:美团小程序(Node.js+Express+支付)-微信开发

    项目实战视频课程:美团小程序(Node.js+Express+支付) 东北大学计算机专业硕士研究生,欧瑞科技创始人&CEO,曾任国内著名软件公司项目经理,畅销书作者,企业IT内训讲师,CSDN ...

  4. 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第二章:Android App 开发基础

    第 2 章 Android App开发基础 本章介绍基于Android系统的App开发常识,包括以下几个方面:App开发与其他软件开发有什么不一 样,App工程是怎样的组织结构又是怎样配置的,App开 ...

  5. 【OF框架】使用OF.WinService项目,添加定时服务,进行创建启动停止删除服务操作...

    准备 使用框架搭建完成项目,包含OF.WinService项目. 了解Window Service 和定时服务相关知识. 一.添加一个定时服务 第一步:了解项目结构 第二步:创建一个新的Job 第三步 ...

  6. 微服务项目部署服务器,第3章 3.2 部署服务器 - 编排多个微服务

    开发部署流程 开发部署流程.png 规划磁盘使用 在服务器上运行的Docker容器可以分为两类, 一类是业务型,主要是业务相关的接口服务,该类型容器采用了之前设计的代码镜像分离的原则,代码存储在Git ...

  7. 十次方项目开发系列【10】:接口加密Eureka微服务和网关服务开发

    学习目标 了解接口加密业务需求 掌握常用加密算法和密钥格式 实现十次方的接口加密微服务 文章目录 一 业务场景介绍 二 加密方式 2.1 摘要算法 2.2 对称加密 2.3 非对称加密 2.4 数字签 ...

  8. 如何评价亚马逊AI新开源自动机器学习项目AutoGluon?

    链接:https://www.zhihu.com/question/360250836 编辑:深度学习与计算机视觉 声明:仅做学术分享,侵删 作者:李沐 https://www.zhihu.com/q ...

  9. vue项目职责_进大厂兼职的机会来了!腾讯微校项目招人了!

    在经历了双十二等各种剁手 准备冬至.圣诞节的各种礼物之后 你是否也零钱"归零",余额"无余" 许多同学会选择做兼职 这样既能利用空余时间挣一些零花钱 还能积累一 ...

最新文章

  1. mysql直连1.执行语句_MySQL随笔01_一条SQL语句是如何执行的
  2. ZCMU 1048: 子串
  3. Silverlight 2.5D RPG游戏技巧与特效处理:(七)动画特写
  4. 机器学习——支持向量机SVM实例(兵王问题,SVM求解步骤以及思路,不求解不编程)
  5. IAR切BANK--命令连接器文件xcl格式说明
  6. webpack--插件配置:处理HTML中的图片(七)
  7. 讲讲金融业务(一)--自助结算终端POS
  8. pdg快速转换pdf源码_在手机上快速免费把图片转换成PDF文件
  9. php 7.4 Array and string offset access syntax with curly braces is deprecated
  10. Smart View 11.1.2.5配置共享连接
  11. 应用程序窗口小部件App Widgets
  12. 于的繁体字有几种写法_于的繁体字是什么(行书怎么写)
  13. 【最小开发板】Attiny85开发与实践
  14. 特殊字符是哪些字符python_python特殊字符
  15. 简单人物画像_超级简单人物素描画图片精选
  16. python绘制小提琴图_Python:matplotlib 和 Seaborn 之热图、小提琴图和箱线图 (三十四)...
  17. 用AR.js做图片追踪的webAR Demo
  18. 逻辑回归损失函数推导及其模型的推导
  19. uboot环境下mmc操作_uboot mmc命令详解
  20. 万字长文,为你送上全网最全Flutter学习资料!

热门文章

  1. scala hashmap_如何在Scala中将Hashmap转换为Map?
  2. ipad无法充电怎么办_IPAD充电线破损无法保修,资深“果粉”吐槽:店大欺客!...
  3. uva 701——The Archeologists\' Dilemma
  4. 【计算机网络】数据链路相关技术
  5. LeetCode【11--盛水最多的容器】LeetCode【12 -- 整数转罗马数字】
  6. 二叉树题目---3 另一个树的子树 AND 二叉树最大深度
  7. 设计模式----2(简单工厂模式的概念,简单工厂模式的实现,简单工厂模式的优缺点)
  8. linux编程手册读书笔记第一章(20140329)
  9. SQL Server【四】
  10. 【Linux网络编程学习】I/O多路复用——epoll