Martian-cloud 4.0,跟注册中心拜拜了,基于传染机制的分布式组件诞生

2020-11-10 19:18:15 +08:00
 Joker123456789

基于传染机制的分布式组件

项目简介

Martian-cloud 是 Martian 的官方分布式组件,基于传染机制,不再需要注册中心

  1. 完全丢弃了注册中心,且不依赖任何注册中心,采用传染机制实现服务的发现与治理
  2. 服务间通话采用 rest 风格
  3. 对 Martian 的侵入非常小

什么是传染机制

比如我们现在有三个服务

http://mars-framework.com/img/ws-blank.png
这些服务之间是相互独立的,他们无法发现对方,所以我们需要做一些事

可以将他们连接起来

比如像这个样子 [图 1 ]

http://mars-framework.com/img/ws-one.png

也可以是这样子 [图 2 ]

http://mars-framework.com/img/ws-two.png
连接方式随意,只要别让任何服务落单即可

当这些服务连接后,会发生什么

我们用图 1 来举例

  1. 当 A 启动时,此时只有一台服务,所以相安无事,完全独立
  2. 当 B 启动时,由于 A 连接的是 B,所以 A,B 之间产生了关系,他们的接口会互相传染,此时 A 中有 B 的接口,B 中有 A 的接口
  3. 当 C 启动时,由于 B 连接的是 C,所以 B,C 之间产生了关系,而 B 和 A 又存在关系,所以三台服务器都产生了关系,他们的接口再一次相互传染了,此时 A,B,C 都有对方的完整接口列表
  4. 如果三台服务中任意一个宕机了,也没关系,因为他们的接口已经传染开了,所有服务都产生了联系,可以跳过一开始的传染途径,直接进行感染
  5. 宕机的这个服务的接口会从其他的服务上自动消失

使用起来也很简单

一、 仅需一个依赖

<dependency>
    <groupId>com.github.yuyenews</groupId>
    <artifactId>mars-cloud-starter</artifactId>
    <version>最新版,具体看《组件介绍》</version>
</dependency>

二、 支持 Feign 调用

/* 
这个注解的 serverName 跟你要调用的那个服务的 name 一致(配置类里 cloud 配置的 name ) 
beanName 不写的话,默认为类名首字母小写
*/
@MarsFeign(serverName="mars-demo",beanName="demoFeign")
public interface DemoFeign {
    /* 
        这里面的所有方法,跟你要调用的那个 API 中的方法名一致
    */
    返回类型 insert(DemoEntity entity);

    /*
        可以用 @MarsContentType 注解 来指定本次请求的 ContentType
    */
    @MarsContentType(ContentType = ContentType.JSON)
    返回类型 selectList(DemoEntity entity);
}

三、 也支持 RestTemplate

返回类型 result = MarsRestTemplate.request(服务 name,MarsApi 接口的方法名,new Object[]{参数对象 1,参数对象 2},返回类型.class, ContentType.FORM);

官方网站

http://mars-framework.com/

3571 次点击
所在节点    Java
53 条回复
myCupOfTea
2020-11-11 08:58:20 +08:00
每个服务都多了事,问题太多了吧
myCupOfTea
2020-11-11 08:58:41 +08:00
服务的下线上线,负载均衡,熔断啥的
Joker123456789
2020-11-11 09:57:10 +08:00
@myCupOfTea 其实你楼上说的 比较符合我的想法。

先来说说 有注册中心的时候:

1. 启动时会从注册中心获取一套接口,缓存在本地。
2. 定时给注册中心发送心跳告诉他 自己还活着。
3. 注册中心会给其他服务发送通知,告诉他们那些服务已经下线了,然后收到通知的服务会从本地删除相应的接口。

而我现在这套思路:

1. 上面第一条 依然保留,只不过他不是从 zk,nacos 获取一套接口,而是从配置文件中配置的的那个服务上获取
2. 上面第二点依然保留,只不过他不是心跳给 zk,nacos,而是心跳给其他服务。
3. 如果自己挂了,他是无法通知别人的,但是每个微服务本地的缓存 都有失效时间的,只要没按时收到心跳就会删除本地缓存

所以整个考虑下来,其实并没有多做什么事。

至于负载均衡,熔断啥的,本身也跟注册中心没啥关系吧, 负载均衡目前我是提供了的, 熔断 还在开发中。
Joker123456789
2020-11-11 10:23:57 +08:00
@Kirsk

可能是我理解的不够透彻吧, 我先说下我的理解,欢迎指正:

1. 注册中心主要做这三件事: 储存接口,服务上线通知, 服务下线通知。

2. 微服务在启动时会从注册中心获取一次接口,然后缓存在本地, 本地缓存的接口在收到 服务上下线通知后会更新。

3. 调用时,都是从本地缓存获取对应的接口,然后按照负载均衡的方式筛选 调用。 所以即使注册中心挂了,也不影响正在运行的微服务。

上面三个点整理出几个关键词:获取接口,本地缓存,上下线通知。 这几个关键词,目前我都是满足的。

其他跟注册中心无关的东西,比如负载均衡,熔断等,都不受影响

-----------------------------------------------------------------------------

不过肯定还有很多我没想到的细节,欢迎指正与指教
Sunmxt
2020-11-11 10:54:25 +08:00
其实就是 gossip 吧?感觉很多问题想得有点粗糙了。就拿楼主提到的心跳机制来说,这个就决定了这个系统没法 scale up 。一个节点要给所有节点定时发心跳,节点数量为 n,网络中一段时间内的消息数量是 O(n^2)的,规模一大网络压力就上来了,很可怕。其他的,诸如一致性问题就不说了。
ppyzzz
2020-11-11 11:14:21 +08:00
少量服务实例可以用,多实例的话还是不行.轮询都会占不少的 CPU 资源,而且这个单服务 down 了以后时延性以及后面的处理也得考究
Joker123456789
2020-11-11 11:47:55 +08:00
@Sunmxt 是的,所以还有很长的路要走,我需要再好好考虑下细节,不断优化才行。
Kirsk
2020-11-11 13:18:13 +08:00
@Joker123456789 你只是做了一部分 服务发现 打个比方 通过你的做法 能提高稳定性么 什么场景下注册失败率高 传染机制可行
myCupOfTea
2020-11-11 13:45:12 +08:00
@Joker123456789 Sunmxt 说的没错,本来 1: n,编程了 n:n.想想感觉会不太好维护的
不过东西都是慢慢试出来的
tikazyq
2020-11-11 13:57:32 +08:00
楼主之前一直在推他开发了近 2 年却只有 200 多 star 的 Java 框架,扬言似乎要取代 SpringBoot,结果被 v2 众佬围观。

这一次又是准备革命分布式计算么?(doge)

https://v2ex.com/t/695080
https://v2ex.com/t/695080
tikazyq
2020-11-11 14:00:29 +08:00
看到这里,忍不住贴一个百度百科地址,祝楼主好运 https://baike.baidu.com/item/%E5%94%90%C2%B7%E5%90%89%E8%AF%83%E5%BE%B7/59900
palmers
2020-11-11 14:00:34 +08:00
我理解 这样仅仅是为了去掉了注册中心 但是 似乎没有一个成熟的追踪路径 这样一旦出现问题 排查起来就非常的麻烦 而且 不维护注册中心 而出现问题的维护成本和维护注册中心带来的成本 我更倾向于维护注册中心 因为维护注册中心更有确定性
mritd
2020-11-11 14:06:30 +08:00
是个狠人
wysnylc
2020-11-11 14:14:04 +08:00
传播模式不可靠,而且无法校验"我"是否连上了整个服务而不是连上一个小的闭环
Joker123456789
2020-11-11 14:15:00 +08:00
@tikazyq 有屁可以直接放,2 年只有 200 多个有什么问题吗? 你别忘了,我做的这个领域可不是蓝海,而是被 spring 统治的红海。

你认知中的那些 随便发发文章就上千 star 的项目

1. 要么是 XX 管理系统,帮人偷懒用的
2. 要么只是依附于 spring 的小工具
3. 要么是某科技巨头发布的
4. 要么是蓝海的东西

请问有可比性吗?

最后,我还是那句话,有屁可以直接放,不用拐弯抹角,给我分享个百科是想干嘛?劝我放弃吗?

我还想说你病的不轻呢,你不感兴趣就滚出去,在这大放厥词干嘛? 你要真有脑子,就学学你口中的众佬,说说你的看法。
Joker123456789
2020-11-11 14:18:39 +08:00
@tikazyq 你这种人就是 闲着蛋疼, 看到别人做东西,就过来疯狂嘲笑,我建议你去看看精神科,我认真的建议你。
UmiKz
2020-11-11 14:38:13 +08:00
楼主的另辟蹊径,让我看到了无数大牛都没想总结的某些技术使用的套路本质,感谢~~~
woshiaha
2020-11-11 14:42:40 +08:00
拜占庭问题了解一下 这种群体互相检测心跳的方式可能会导致一个服务的状态在 A 的状态是宕机 但是在 B 的状态是存活 没做负载均衡的时候可能问题不大 但是要实现负载均衡的时候就有影响了
Joker123456789
2020-11-11 14:50:00 +08:00
@woshiaha 对,但这个是延迟到问题, 在 B 的状态 很快就会变成宕机的,只要 N 毫秒内没收到心跳,立刻会被判定为宕机。 不过这个延迟是无法避免的,即使是 zk 通知 也是有延迟的。

而且我的 心跳机制并不是群体互相检测的哦,而是有我告诉大家我还活着,并不是你帮我告诉大家我还活着。

这位大佬 [Sunmxt ] ,对我的意思理解的比较透彻,因为提出的问题比较犀利,也是我一直在想办法解决的问题
tikazyq
2020-11-11 16:22:24 +08:00
古人云:“不因言废人,不因人废言”

因为楼主恼羞成怒,我有些担心自己的言辞有偏见,就专门看了一下这个项目的代码。

不得不佩服,楼主的代码整体非常整洁,代码结构也很合理,在合适的位置配有注释,这个值得表扬,这个项目适合让新人提升阅读理解开源项目的能力。

但缺点也很明显:
1. 喜欢重复造轮子,例如 HTTP 的 Utility 部分竟然有单独重写 URL 参数的方法,这违背了 DRY 原则(重复造轮子的必要性能否解释下?)
2. 框架似乎是用 REST 来做的远程通信,这要求显式配置需要传播的节点 IP 地址和端口,不管是从安全还是效率上都让人堪忧
3. 层层嵌套的方法太多,这种组织方式显得很冗余,大大降低代码可读性,也有降低灵活性易用性的问题
4. 楼主没有写一些基本的部署教程或步骤,只有通过阅读源码来猜测框架是如何启动的,我甚至有些怀疑楼主是否能用这个框架跑通一个 demo,是否在实际分布式环境中做了测试,实际的效率、易用性、扩展性如何

暂时就这些反馈。

总之,除了这些缺点以外,真正让人持怀疑态度的是楼主没有给出令人信服的测试结果,推销你的框架好,总之要给点证据吧,这些都没有在楼主的描述中体现出来。因此,楼主项目不受人待见,是自然而然的事情,真的没必要大动肝火。建议多学习一下其他的框架,而不是搞这些看上去高大上的框架,酒香不怕巷子深,你这个东西好用,自然有人用,你这个东西不好用,你把它吹上天也没人鸟你。所以,楼主加油

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/723703

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX