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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/390003.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

187. 重复的DNA序列

187. 重复的DNA序列 所有 DNA 都由一系列缩写为 ‘A’&#xff0c;‘C’&#xff0c;‘G’ 和 ‘T’ 的核苷酸组成&#xff0c;例如&#xff1a;“ACGAATTCCG”。在研究 DNA 时&#xff0c;识别 DNA 中的重复序列有时会对研究非常有帮助。 编写一个函数来找出所有目标子串&am…

牛客网_Go语言相关练习_选择题(2)

注&#xff1a;题目来源均出自牛客网。 一、选择题 Map&#xff08;集合&#xff09;属于Go的内置类型&#xff0c;不需要引入其它库即可使用。 Go-Map_菜鸟教程 在函数声明中&#xff0c;返回的参数要么都有变量名&#xff0c;要么都没有。 C选项函数声明语法有错误&#xff0…

机器学习模型部署_9月版部署机器学习模型

机器学习模型部署每月版 (MONTHLY EDITION) Often, the last step of a Data Science task is deployment. Let’s say you’re working at a big corporation. You’re building a project for a customer of the corporation and you’ve created a model that performs well…

352. 将数据流变为多个不相交区间

352. 将数据流变为多个不相交区间 给你一个由非负整数 a1, a2, …, an 组成的数据流输入&#xff0c;请你将到目前为止看到的数字总结为不相交的区间列表。 实现 SummaryRanges 类&#xff1a; SummaryRanges() 使用一个空数据流初始化对象。void addNum(int val) 向数据流中…

Java常用的八种排序算法与代码实现

排序问题一直是程序员工作与面试的重点&#xff0c;今天特意整理研究下与大家共勉&#xff01;这里列出8种常见的经典排序&#xff0c;基本涵盖了所有的排序算法。 1.直接插入排序 我们经常会到这样一类排序问题&#xff1a;把新的数据插入到已经排好的数据列中。将第一个数和第…

熊猫ai智能机器人量化_机器学习中的熊猫是什么

熊猫ai智能机器人量化Machine learning is a complex discipline. The implementation of machine learning models is now far much easier than it used to be, this is as a result of Machine learning frameworks such as pandas. Wait!! isnt panda an animal? As I rec…

441. 排列硬币

441. 排列硬币 你总共有 n 枚硬币&#xff0c;并计划将它们按阶梯状排列。对于一个由 k 行组成的阶梯&#xff0c;其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的。 给你一个数字 n &#xff0c;计算并返回可形成 完整阶梯行 的总行数。 示例 1&#xff1a;…

调用百度 Echarts 显示重庆市地图

因为 Echarts 官方不再提供地图数据的下载&#xff0c;在这里保存一份&#xff0c;供日后使用&#xff0c;重庆地图数据的 JSON 文件在 CSDN 上下载。 <!DOCTYPE html> <html style"height: 100%"><head><meta charset"utf-8"><…

JEESZ-SSO解决方案

2019独角兽企业重金招聘Python工程师标准>>> 第一节&#xff1a;单点登录简介 第一步&#xff1a;了解单点登录 SSO主要特点是: SSO应用之间使用Web协议(如HTTPS)&#xff0c;并且只有一个登录入口. SSO的体系中有下面三种角色: 1) User(多个) 2) Web应用(多个) 3) …

女朋友天天气我怎么办_关于我的天气很奇怪

女朋友天天气我怎么办带有扭曲的天气应用 (A Weather App with a Twist) Is My Weather Weird?™ is a weather app with a twist — it offers a simple answer to a common question we’ve all asked. To do this we look at how often weather like today’s used to happ…

Java中length,length(),size()的区别

&#xff08;一&#xff09;区别&#xff1a; ①length&#xff1a;用于算出数组的长度。 ②length&#xff08;&#xff09;&#xff1a;用于找出字符串的长度。 ③size&#xff08;&#xff09;&#xff1a;用于找出泛型集合的元素个数。转载于:https://www.cnblogs.com/not-…

5895. 获取单值网格的最小操作数

5895. 获取单值网格的最小操作数 给你一支股票价格的数据流。数据流中每一条记录包含一个 时间戳 和该时间点股票对应的 价格 。 不巧的是&#xff0c;由于股票市场内在的波动性&#xff0c;股票价格记录可能不是按时间顺序到来的。某些情况下&#xff0c;有的记录可能是错的…

为什么要用Redis

最近阅读了《Redis开发与运维》&#xff0c;非常不错。这里对书中的知识整理一下&#xff0c;方便自己回顾一下Redis的整个体系&#xff0c;来对相关知识点查漏补缺。我按照五点把书中的内容进行一下整理&#xff1a;为什么要选择Redis&#xff1a;介绍Redis的使用场景与使用Re…

第一次马拉松_成为数据科学家是一场马拉松而不是短跑

第一次马拉松Since Data Science became the “Sexiest Job of the 21st Century” the interest in the field has grown tremendously. With it so have the courses available to gain the necessary knowledge. As great as this is, the downside is a field marketed as …

273. 整数转换英文表示

273. 整数转换英文表示 将非负整数 num 转换为其对应的英文表示。 示例 1&#xff1a;输入&#xff1a;num 123 输出&#xff1a;"One Hundred Twenty Three" 示例 2&#xff1a;输入&#xff1a;num 12345 输出&#xff1a;"Twelve Thousand Three Hundred…

Java-运算符

算术运算符 加法 相加运算符两侧的值- 减法 左操作数减去右操作数* 乘法 相乘操作符两侧的值/ 除法 左操作数除以右操作数&#xff08;int类型的数相除时&#xff0c;会得到int类型的值&#xff0c;如果结果有小数&#xff0c;则小数部分会被舍弃&#xff09;% 模余运算&…

区块链开发公司谈区块链在商业上的应用

对于近期正受科技界和资本市场关注的区块链行业&#xff0c;一句话概括说如果互联网技术解决的是通讯问题的话&#xff0c;区块链技术解决的是信任问题&#xff0c;其在商业领域应用如何呢&#xff1f;我们来从两个方面去进行剖析。 第一方面&#xff0c;区块链技术可以解决基础…

ORACLE1.21 PLSQL 01

-- 有了SQL 为什么还需要PL/SQL -- SQL功能很强大&#xff0c;但如果是单1sql语句&#xff0c;没有流程控制 -- PL/SQL 是什么&#xff1f; --不仅仅实现流程控制&#xff0c;同时保留SQL本身所有的功能 --还提供变量、常量等支持 --提供更多数据类型的支持 --第一&#xff0c;…

云原生数据库_数据标签竞赛云原生地理空间冲刺

云原生数据库STAC specification is getting closer to the ver 1.0 milestone, and as such the first virtual Cloud Native Geospatial Sprint is being organized next week. An outreach day is planned on Sep 8th with a series of talks and tutorials for everyone. R…

Linux 下的 hosts文件

2019独角兽企业重金招聘Python工程师标准>>> hosts 文件 目录在 /etc/hosts netstat -ntlp //linux 下查看端口 转载于:https://my.oschina.net/u/2494575/blog/1923074