文档章节

曹大谈 dubbo mesh : 在 MOSN 中玩转 dubbo-go

dubbo-go开源社区
 dubbo-go开源社区
发布于 06/12 23:33
字数 2324
阅读 1.6W
收藏 12

行业解决方案、产品招募中!想赚钱就来传!>>>

service mesh 简介

service mesh 本身的理念并不复杂,就是将现代微服务应用的功能性与非功能性需求进行分离,并将非功能性需求下沉到应用的外部模块,从而使应用模块可以尽量聚焦于业务,不用关心诸如:服务发现、限流、熔断、tracing 这类非业务需求。下沉之后,相关的 service mesh 模块可以交由基础架构团队进行维护,使基础设施和业务能够完成解耦。

service mesh 设计一般划分为两个模块,控制面和数据面。可以通过下图来理解相应的职责:

对于应用来说,所有流量都会经过 service mesh 中的数据面进行转发。而能顺利转发的前提:数据面需要知道转发的目标地址,目标地址本身是由一些业务逻辑来决定的(例如服务发现),所以自然而然地,我们可以推断控制面需要负责管理数据面能正常运行所需要的一些配置:

  • 需要知道某次请求转发去哪里:服务发现配置
  • 外部流量进入需要判断是否已经达到服务流量上限:限流配置
  • 依赖服务返回错误时,需要能够执行相应的熔断逻辑:熔断配置

开源界目前比较有名的主要是 istio,envoy 和 linkerd 这几个项目,今天我们来介绍一下蚂蚁推出的 service mesh 数据面项目:MOSN。

MOSN 简介

MOSN 是蚂蚁金服出品的用 Go 语言实现的 service mesh 数据面,在蚂蚁内部已大规模落地,在开源过程中我们了解到外部用户有较多的 dubbo 用户,这些 dubbo 用户也希望能够享受 service mesh 社区的发展红利。同时可以针对自己公司的特殊业务场景,对 service mesh 的数据面进行一定的扩展。

谈到扩展,MOSN 使用 Go 编写的优势就体现出来了。相比 C++,Go 语言通过自带的内存分配器与 GC 实现了一定程度的内存安全,解放了程序员的心智。相比 C++ 编写的 envoy,无论是编程和问题定位都要轻松不少。

MOSN 同时提供了强大的 XProtocol 协议扩展框架,用户可以根据自己的需求编写自定义协议解析。如果你使用的是 SOFA/Dubbo/HTTP/HTTP2,那么 MOSN 已经为你准备好了现成的实现。开箱即用。

为了满足社区的需求,从今年 4 月开始,MOSN 社区与 dubbo-go 社区进行了深入的交流与合作。可能还有些同学对 dubbo-go 不太了解,简单介绍一下。

dubbo-go 简介

dubbo 是阿里巴巴出品一个非常优秀的 Java RPC 框架,相比其它框架,有较为全面的服务治理功能。

dubbo-go 是 dubbo 的 Go 语言版本,该项目已进入 apache 一年有余,开发社区很活跃,版本发布节奏较快。功能上也基本和 dubbo 的 Java 版都对齐了。

对于喜欢 dubbo 的 gopher 来说,dubbo-go 是个不错的选择。使用它来构建整个公司的服务框架,省时省心。

MOSN + dubbo-go 双剑合璧

service mesh 能够给微服务的整体架构带来很多好处,然而业界提供的全家桶方案不一定能很好地在企业内落地,有下面一些原因:

  • 要求数据面和控制面一起上线,早期 istio 因为设计问题,有众多模块。会大幅增加企业的运维负担。
  • 企业上 mesh 一定是渐进部署,不可能一次性让所有服务全部上。这样就会有在 mesh 中的应用和非 mesh 中的应用需要能够互通的需求。

蚂蚁的 service mesh 落地过程相对较为成功,值得参考。在内部落地时,首先只落地数据面,这样运维负担较轻,同时出问题时也容易排查。

但只落地数据面的话,有些控制面的功能我们就没有了,比如服务发现、路由配置订阅等等。因此在 MOSN 中,又额外对这些功能进行了支持(相当于目前的数据面单模块同时承载了数据面和控制面的部分功能)。当数据面稳定落地之后,再进行控制面的落地相对来说负担就小很多了。

上面的是蚂蚁内部的情况,在社区内,MOSN 借助 dubbo-go 的能力,已经实现了服务发现功能,用户应用启动、退出时需要和 MOSN 进行简单的交互,以完成服务的发布和订阅功能,下面是发布流程:

在应用启动时,访问本地的 MOSN http 接口,告知需要将本地的服务发布出去,MOSN 收到请求后对外发布 MOSN 的 ip 和端口到注册中心。这样监听本服务的 consumer 便可以从注册中心收到服务变更的通知,并将本实例加入到相应的 provider 列表。当应用退出时,需要主动进行 unpub。

这种情况下的改造成本:

  1. 对于业务方来说,只需要升级 sdk。
  2. 对于 sdk 维护方,在执行 sub/pub/unsub/unpub 时,需要增加一个开关判断,开关打开时,说明本实例已上 service mesh。请求相应的本地 MOSN 接口。
  3. 对于 mesh 提供方,只要做好配置和部署就可以了。

接入 MOSN 后,mesh 化和非 mesh 化的应用可以互通:

当然,开发过程也并不是一帆风顺的。在我们刚开始使用 dubbo-go 时,便遇到了 dubbo-go 的依赖与 MOSN 的依赖有冲突的问题:

Go 语言的 go mod 语义会“自作聪明”地认为 0.y.z 的外部依赖都是彼此兼容的,然而我们从 semver 规范可以学习到:

> Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable.

0.y.z 只是用来做初始的开发,本身 API 的变化就是很频繁的,依赖管理工具不应该自动去升级这些依赖。但是 Go 社区的人有不少人坚持 go mod 的行为正确,并且祭出 MVS 算法,表示碰到问题的只是不懂 Go 的哲学。

当前 Go 的依赖管理使得两个大项目发生依赖冲突时,比较难处理,我们只能根据实际情况去 go.mod 中去写一些 replace 逻辑,来锁定外部依赖库版本。

除了依赖问题以外,dubbo-go 最初的设计大量使用了 init 函数。init 函数用来实现一些初始化和依赖注入确实比较方便,但如果一个项目中的模块会被其它外部项目依赖时,init 则可能给我们造成麻烦,举个简单的例子:

package x
var GlobalMap = map[string]int{}

package a
func init() {
    x.GlobalMap["x"] = 1
}

package b
func init() {
    x.GlobalMap["x"] = 2
}

如果我们在某个包中同时依赖 a 和 b,那么下面的两种写法,得到的结果是不一样的:

package show
import (
    "a"
    "b"
    "x"
)

func main() {
    println(x.GlobalMap["x"])
}
package show
import (
    "b"
    "a"
    "x"
)
func main() {
    println(x.GlobalMap["x"])
}

为了避免这些隐式的 init 行为,我们实际上是 fork 了 dubbo-go 并进行了少量修改的。当然,改动并不多,未来如果 dubbo-go 有更好的模块化方法的话,我们也可以很轻松地迁移回直接依赖 dubbo-go。

在 MOSN 集成 dubbo-go 的过程中,dubbo-go 社区的老哥们给予了我们大量的支持,贤哥(https://github.com/zouyx)帮助我们在 dubbo-go 中实现了之前不支持的 unsub/unpub 功能,并帮助我们解决了很多技术方面的问题。dubbo-go 社区负责人于雨( https://github.com/alexstocks )也在开发过程中提供了大量的信息和技术支持。有这两位的支持,MOSN 和 dubbo 的集成才顺畅无比,否则的话要多走很多弯路。

其它选择

除了本文提到的 MOSN + dubbo-go 集成方式,多点的陈鹏同学为我们提供了另一种思路进行集成,本文就不展开了,感兴趣的同学可以参考文末的资料 [3]。

本文作者

曹春晖,开源 MOSN committer,@cch123,蚂蚁金服系统部技术专家,主攻 Service Mesh 方向。个人技术网站 xargin.com,和他人合著《Go语言高级编程》。

参考资料

[1]. https://jimmysong.io/blog/what-is-a-service-mesh/

[2]. https://mosn.io/zh/docs/concept/multi-protocol

[3]. https://mp.weixin.qq.com/s/mhHnH6ZDPPs6Gr0a20WGOw

欢迎加入 dubbo-go 社区

有任何 dubbo-go 相关的问题,可以加我们的钉钉群 23331795 询问探讨,我们一定第一时间给出反馈。

最新活动

Dubbo-go ASoC 相关题目 ,参加详情 请点击

dubbo-go开源社区
粉丝 11
博文 8
码字总数 17989
作品 0
广州
私信 提问
加载中
此博客有 2 条评论,请先登录后再查看。
我的架构演化笔记 功能1: 基本的用户注册

“咚咚”,一阵急促的敲门声, 我从睡梦中惊醒,我靠,这才几点,谁这么早, 开门一看,原来我的小表弟放暑假了,来南京玩,顺便说跟我后面学习一个网站是怎么做出来的。 于是有了下面的一段...

强子哥哥
2014/05/31
976
3
在多个浏览器上运行脚本--Queen

假设你想和朋友们玩这么个游戏:你写下某个数字,然后让朋友们猜你写的是什么数字。你的朋友们将不断的给你一些猜测的数字,直到猜中为止。 现在想象你的朋友都是使用的浏览器,这个游戏就相...

匿名
2013/01/24
4.5K
1
浏览器中的scheme解释器--SchemeScript

一个用javascript实现的scheme解释器,可以运行在浏览器中或node.js中。 刚刚看到编译原理与实践第二章,一时兴起,想写个以前就想写的scheme的解释器。昨天晚上开始写,到刚才为止,接近一天...

zoowii
2012/11/01
1.1K
0
php开源框架--CorePHP

简介: CorePHP框架是一个快速,安全,灵活的php开源框架,主要是为了简化和快速开发小型项目和开源系统二次开发而诞生。它既可以完美的支持MVC模式,又可以不受限制的支持传统编程模式。它是...

shooke
2012/12/27
2.8K
1
Sar数据转HTML--Sar2html

Sar2html 可以将 sar 程序执行的二进制结果数据转成图形的 HTML 格式,它提供了命令行工具、Web 接口和数据收集脚本。使用 sar2ascii 可从服务器 (HP-UX 11.11, 11.23, and 11,31, Redhat 3...

匿名
2013/01/10
1.2K
0

没有更多内容

加载失败,请刷新页面

加载更多

层次聚类与聚类树

聚类分析 在生态学研究当中,有些环境中的对象是连续(或者离散)的,而有些对象是不连续的,聚类的目的是识别在环境中不连续的对象子集,从而探索隐藏在数据背后的属性特征。聚类分析主要处...

SYSU星空
01/11
0
0
几个无聊但你可能忽略的C知识点

来源:公众号【编程珠玑】 作者:守望先生 ID:shouwangxiansheng C语言main函数的写法 标准中,只有下面两种写法: int main (void) { /**body**/ } 以及 int main (int argc, cha...

学以解忧
01/08
0
0
20个实战项目教你掌握OpenCV和图像处理,PDF开放下载

点击上方“小白学视觉”,选择加"星标"或“置顶” 重磅干货,第一时间送达 近期小白学视觉公众号推出了多篇OpenCV实战项目的文章,深受小伙伴们的喜爱。最近有小伙伴推荐,希望可以讲经典的项...

机器学习炼丹术
15分钟前
0
0
吃瓜!挂一个爬虫工作者

原本不打算撕逼的,可总感觉技术人员这么狗,不曝光他不合适。 此人微信号: YGMXMF 描述如下: 鉴于不可抗力因素,我删除了上篇文章! 此人想178买文章(早就关注了,当时没付费观看,现在要...

adminThorn
33分钟前
9
0
聊一聊一道关于线程池的面试题

网络上有这样一道关于线程池的面试题: 1. 高并发、任务执行时间短的业务怎样使用线程池? 2. 并发不高、任务执行时间长的业务怎样使用线程池? 3. 并发高、业务执行时间长的业务怎样使用线程...

黄小斜
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部