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

  1. static void Main(string[] args)
  2. {
  3. var context = ContextRegistry.GetContext();
  4. var helloServiceThrift = context.GetObject<RpcContractThrift.IHelloService>();
  5. var helloServiceGrpc = context.GetObject<RpcContractGrpc.IHelloService>();
  6. var helloServiceWcf = context.GetObject<RpcContractWcf.IHelloService>();
  7. var helloServiceHttp = context.GetObject<RpcContractHttp.IHelloService>();
  8. var helloServiceAkka = context.GetObject<RpcContractAkka.IHelloService>();
  9. var helloServiceRemoting = context.GetObject<RpcContractRemoting.IHelloService>();
  10. while (true)
  11. {
  12. Console.WriteLine("请选择:wcf | grpc | thrift | http | akka | remoting");
  13. var mode = Console.ReadLine().ToLower();
  14. switch (mode)
  15. {
  16. case "wcf":
  17. CallWhile((helloword) => { WcfHello(helloServiceWcf, helloword); });
  18. break;
  19. case "grpc":
  20. CallWhile((helloword) => { GrpcHello(helloServiceGrpc, helloword); });
  21. break;
  22. case "thrift":
  23. CallWhile((helloword) => { ThriftHello(helloServiceThrift, helloword); });
  24. break;
  25. case "http":
  26. CallWhile((helloword) => { HttpHello(helloServiceHttp, helloword); });
  27. break;
  28. case "akka":
  29. CallWhile((helloword) => { AkkaHello(helloServiceAkka, helloword); });
  30. break;
  31. case "remoting":
  32. CallWhile((helloword) => { RemotingHello(helloServiceRemoting, helloword); });
  33. break;
  34. case "all":
  35. for (int i = ; i < ; i++)
  36. {
  37. Task.Run(() =>
  38. {
  39. try
  40. {
  41. WcfHello(helloServiceWcf);
  42. }
  43. catch (Exception ex)
  44. {
  45. throw ex;
  46. }
  47. });
  48. Task.Run(() =>
  49. {
  50. try
  51. {
  52. GrpcHello(helloServiceGrpc);
  53. }
  54. catch (Exception ex)
  55. {
  56. throw ex;
  57. }
  58.  
  59. });
  60. Task.Run(() =>
  61. {
  62. try
  63. {
  64. ThriftHello(helloServiceThrift);
  65. }
  66. catch (Exception ex)
  67. {
  68. throw ex;
  69. }
  70.  
  71. });
  72. Task.Run(() =>
  73. {
  74. try
  75. {
  76. HttpHello(helloServiceHttp);
  77. }
  78. catch (Exception ex)
  79. {
  80.  
  81. throw ex;
  82. }
  83.  
  84. });
  85. Task.Run(() =>
  86. {
  87.  
  88. try
  89. {
  90. AkkaHello(helloServiceAkka);
  91. }
  92. catch (Exception ex)
  93. {
  94.  
  95. throw ex;
  96. }
  97. });
  98. }
  99. break;
  100. }
  101.  
  102. if (mode == "end")
  103. {
  104. break;
  105. }
  106. }
  107.  
  108. }
  109. private static void ThriftHello(RpcContractThrift.IHelloService helloServiceThrift, string helloword = "world")
  110. {
  111. var callNameVoid = helloServiceThrift.CallNameVoid();
  112. Console.WriteLine(callNameVoid);
  113. helloServiceThrift.CallName(helloword);
  114. Console.WriteLine("CallName called");
  115. helloServiceThrift.CallVoid();
  116. Console.WriteLine("CallVoid called");
  117. var hello = helloServiceThrift.Hello(helloword);
  118. Console.WriteLine(hello);
  119. var helloResult = helloServiceThrift.SayHello(helloword + "perfect world");
  120. Console.WriteLine($"{helloResult.Name},{helloResult.Gender},{helloResult.Head}");
  121. helloResult.Name = helloword + "show perfect world";
  122. var showResult = helloServiceThrift.ShowHello(helloResult);
  123. Console.WriteLine(showResult);
  124. }
  125. private static void GrpcHello(RpcContractGrpc.IHelloService helloServiceGrpc, string helloword = "world")
  126. {
  127. var callNameVoid = helloServiceGrpc.CallNameVoid(new RpcContractGrpc.Void());
  128. Console.WriteLine(callNameVoid);
  129. helloServiceGrpc.CallName(new RpcContractGrpc.NameResult { Name = helloword });
  130. Console.WriteLine("CallName called");
  131. helloServiceGrpc.CallVoid(new RpcContractGrpc.Void());
  132. Console.WriteLine("CallVoid called");
  133. var hello = helloServiceGrpc.Hello(new RpcContractGrpc.NameResult { Name = helloword });
  134. Console.WriteLine(hello.Name);
  135. var helloResult = helloServiceGrpc.SayHello(new RpcContractGrpc.NameResult { Name = $"{helloword} perfect world" });
  136. Console.WriteLine($"{helloResult.Name},{helloResult.Gender},{helloResult.Head}");
  137. helloResult.Name = helloword + "show perfect world";
  138. var showResult = helloServiceGrpc.ShowHello(helloResult);
  139. Console.WriteLine(showResult.Name);
  140. }
  141. private static void WcfHello(RpcContractWcf.IHelloService helloServiceWcf, string helloword = "world")
  142. {
  143. var callNameVoid = helloServiceWcf.CallNameVoid();
  144. Console.WriteLine(callNameVoid);
  145. helloServiceWcf.CallName(helloword);
  146. Console.WriteLine("CallName called");
  147. helloServiceWcf.CallVoid();
  148. Console.WriteLine("CallVoid called");
  149. var helloWcf = helloServiceWcf.Hello(helloword);
  150. Console.WriteLine(helloWcf);
  151. var helloResultWcf = helloServiceWcf.SayHello($"{helloword} perfect world");
  152. Console.WriteLine($"{helloResultWcf.Name},{helloResultWcf.Gender},{helloResultWcf.Head}");
  153. helloResultWcf.Name = helloword + "show perfect world";
  154. var showResultWcf = helloServiceWcf.ShowHello(helloResultWcf);
  155. Console.WriteLine(showResultWcf);
  156. }
  157. private static void HttpHello(RpcContractHttp.IHelloService helloServiceHttp, string helloword = "world")
  158. {
  159. var callNameVoid = helloServiceHttp.CallNameVoid();
  160. Console.WriteLine(callNameVoid);
  161. helloServiceHttp.CallName(helloword);
  162. Console.WriteLine("CallName called");
  163. helloServiceHttp.CallVoid();
  164. Console.WriteLine("CallVoid called");
  165. var helloWcf = helloServiceHttp.Hello(helloword);
  166. Console.WriteLine(helloWcf);
  167. var helloResultWcf = helloServiceHttp.SayHello($"{helloword} perfect world");
  168. Console.WriteLine($"{helloResultWcf.Name},{helloResultWcf.Gender},{helloResultWcf.Head}");
  169. helloResultWcf.Name = helloword + "show perfect world";
  170. var showResultWcf = helloServiceHttp.ShowHello(helloResultWcf);
  171. Console.WriteLine(showResultWcf);
  172. }
  173. private static void AkkaHello(RpcContractAkka.IHelloService akkaServiceHttp,string helloword = "world")
  174. {
  175. var callNameVoid = akkaServiceHttp.CallNameVoid();
  176. Console.WriteLine(callNameVoid);
  177. akkaServiceHttp.CallName(new RpcContractAkka.NameResult { Name = helloword });
  178. Console.WriteLine("CallName called");
  179. akkaServiceHttp.CallVoid();
  180. Console.WriteLine("CallVoid called");
  181. var hello = akkaServiceHttp.Hello(new RpcContractAkka.NameResult { Name = helloword });
  182. Console.WriteLine(hello.Name);
  183. var helloResult = akkaServiceHttp.SayHello(new RpcContractAkka.NameResult { Name = $"{helloword} perfect world" });
  184. Console.WriteLine($"{helloResult.Name},{helloResult.Gender},{helloResult.Head}");
  185. helloResult.Name = helloword + "show perfect world";
  186. var showResultWcf = akkaServiceHttp.ShowHello(helloResult);
  187. Console.WriteLine(showResultWcf.Name);
  188.  
  189. }
  190. private static void RemotingHello(RpcContractRemoting.IHelloService remotingServiceHttp, string helloword = "world")
  191. {
  192. var callNameVoid = remotingServiceHttp.CallNameVoid();
  193. Console.WriteLine(callNameVoid);
  194. remotingServiceHttp.CallName(helloword);
  195. Console.WriteLine("CallName called");
  196. remotingServiceHttp.CallVoid();
  197. Console.WriteLine("CallVoid called");
  198. var hello = remotingServiceHttp.Hello(helloword);
  199. Console.WriteLine(hello);
  200. var helloResult = remotingServiceHttp.SayHello($"{helloword} perfect world");
  201. Console.WriteLine($"{helloResult.Name},{helloResult.Gender},{helloResult.Head}");
  202. helloResult.Name = helloword + "show perfect world";
  203. var showResult = remotingServiceHttp.ShowHello(helloResult);
  204. Console.WriteLine(showResult);
  205.  
  206. }
  207.  
  208. private static void CallWhile(Action<string> map)
  209. {
  210. var helloword = "world";
  211. while (true)
  212. {
  213. try
  214. {
  215. map(helloword);
  216. var mode = Console.ReadLine().ToLower();
  217. helloword = mode;
  218. if (helloword == "end")
  219. {
  220. break;
  221. }
  222. }
  223. catch (Exception ex)
  224. {
  225. Console.WriteLine(ex.StackTrace);
  226. }
  227. }
  228. }
  229. }

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

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

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

奉上项目开源地址:

https://github.com/wutao0315/zooland

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

联系作者

mail:wutao0315@qq.com

qq:1164636434

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

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

  1. Thrift 个人实战--RPC服务的发布订阅实现(基于Zookeeper服务)

    前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ...

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

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

  3. 通过游戏学python 3.6 第一季 第九章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账号--锁定次数--菜单功能'menufile

      通过游戏学python 3.6 第一季 第九章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁 ...

  4. 通过游戏学python 3.6 第一季 第八章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账号--锁定次数

    通过游戏学python 3.6 第一季 第八章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账 ...

  5. .NET Core/.NET5/.NET6 开源项目汇总6:框架与架构设计(DDD、云原生/微服务/容器/DevOps/CICD等)项目

    系列目录     [已更新最新开发文章,点击查看详细] 开源项目是众多组织与个人分享的组件或项目,作者付出的心血我们是无法体会的,所以首先大家要心存感激.尊重.请严格遵守每个项目的开源协议后再使用.尊 ...

  6. JAVAEE——BOS物流项目07:WebService入门、apache CXF入门、基于CXF发布CRM服务

    1 学习计划 1.WebService入门 n 什么是WebService n 调用网络上的WebService服务 n SOAP和WSDL概念 n 基于JDK1.7发布一个简单的WebService ...

  7. Captcha服务(后续2)— 改造Captcha服务之Asp.Net Core项目中如何集成TypeScript

    环境准备 .Net Core 版本:下载安装.Net Core SDK,安装完成之后查看sdk版本 ,查看命令dotnet --version,我的版本是2.2.101 IDE: Visual Stu ...

  8. 002-Spring4 快速入门-项目搭建、基于注解的开发bean,Bean创建和装配、基于注解的开发bean,Bean初始化销毁、Bean装配,注解、Bean依赖注入

    一.项目搭建 1.项目创建 eclipse→project explorer→new→Project→Maven Project 默认配置即可创建项目 2.spring配置 <dependenc ...

  9. 「微前端实践」使用Vue+qiankun微前端方案重构老项目的本地验证

    10月份换了新的工作,参与完一个月的需求迭代后,接到了项目重构的任务.简单来说,需要在短时间内提出方案设想,同时进行本地验证,最终需要拿出一套技术替换方案来.于是,埋头苦干了一个月,总算干了点成绩出来 ...

随机推荐

  1. mysql index hint 在index不存在时的处理

    关于index_hint 在mysql查询语句中可以通过指定index_hint来告诉优化器如何使用索引,详细可以参考这里 index_hint: USE {INDEX|KEY} [FOR {JOIN ...

  2. Redis集群迁移

    1:开发中断程序,登录各个主节点查看key信息 INFO # Keyspace db0:keys,expires,avg_ttl # Keyspace db0:keys,expires,avg_ttl ...

  3. linux信息收集篇之sosreport

    sosreport是一个类型于supportconfig 的工具,sosreport是python编写的一个工具,适用于centos(和redhat一样,包名为sos).ubuntu(其下包名为sos ...

  4. Content-Length和body_bytes_sent

    [map@cq01-map-lbsop-hbase conf]$ curl 'http://10.46.43.14:8100/50x.html' -v* About to connect() to 1 ...

  5. Nginx 配置支持 WebSocket

    找到nginx的配置文件:nginx.conf,增加以下三行配置. 示例: server { listen 80; server_name www.test.com; location / { pro ...

  6. MySQL基础之 标准模式通配符

    MySQL标准魔兽通配符 作用:在搜索数据库中的数据时,SQL通配符可以替代一个或多个字符 注意:标准模式SQL通配符必须与LIKE运算符一起使用 1.%  通配符 作用:匹配一个或多个字符. 找出以 ...

  7. 阿里八八Alpha阶段Scrum(4/12)

    今日进度 叶文滔: 整合了一下已完成的界面设计,修复了一些BUG. 问题困难:制作多级悬浮按钮阻碍重重,首先是刚更新不久的Andriod Studio 3.0向前兼容性差,一些语句规则的修改无所适从, ...

  8. Alpha冲刺报告(5/12)(麻瓜制造者)

    今日已完成 明日计划 部分api示意图 燃尽图 scrum会议照片 今日已完成 邓弘立: 完成部分首页逻辑功能 符天愉: 写代码写着写着想起来昨天的登录接口有个非常zz的逻辑错误,今天修改完后应该没有 ...

  9. Git提交分支

    Git提交分支操作 1.git add 命令告诉 Git 开始对这些文件进行跟踪 git add . 2.然后提交 git commit -m'这是注释信息' 3.git pull命令用于从另一个存储 ...

  10. 【Android自动化】编写一个log模块,输出至控制台,供程序运行查看

    # -*- coding:utf-8 -*- import logging def get_log(name): log = logging.getLogger(name) log.setLevel( ...