微服务笔记(三):通信

当我们找到了微服务边界,将应用分解成了多个微服务,那么接下来一个重要的问题就是这些微服务的集成了。

一个健壮的微服务集成环境需要考虑多方面要素:

  • 通信协议
  • 接口协议
  • 服务注册、发现
  • 服务版本控制
  • 负载均衡
  • 服务可用性
  • 服务幂等性
  • 服务扩展性
  • 服务安全性
  • 服务弹性伸缩
  • 服务降级、熔断
  • 调用链可追溯

头大了?别愁,其实也不是一定要面面俱到,还是那句话:“架构不是设计出来的,而是演进出来的”,所以只要满足当下的需要就够了,适合的就是最好的,过早优化往往只会带来更多痛苦。

微服务通信

此篇我想先谈谈在通信方面我的一些思考,因为通信是集成的基础,所以选择合适的通信方案至关重要。

通信方案选型

可能有人会说服务提供者完全可以提供多种通信方案,由服务的消费者根据其偏好自行选择。那么我想问问,你见过一部手机提供了多种数据线接口么?即便真的有过这种手机,你觉得它更好用更合理么?可能这个比方并不很恰当,你明白我要表达的意思就好。

同时提供多种通信方案可能带来哪些问题,我大概列了一下:

  • 开发和维护成本增加
  • 可能带来潜在的性能问题
  • 加大了系统耦合性

所以选择合适的通信方案是要从多角度多层面来考量的,

  • 首先,前篇说过好的微服务是松耦合高内聚的,在选择通信方案时也要围绕这一核心
  • 其次,服务的消费者在调用服务时不应该有大量工作要做,所以要选择一个易于使用的通信方案
  • 此外,微服务由于是高度自治的,允许技术异构的,所以通信方案也不应该受到具体技术的限制,即技术无关

所以,选用什么通信方案最好?答案是没有。但是可以将上述几点作为参考,结合自己的实际情况,比如业务特点、服务规模、性能压力、团队结构等,来找寻合适的方案。所以本文中只有思考过程,没有现成的答案。

针对具体的通信方案,我们可能要进一步考虑其细分的一些方面,包括通信协议、接口风格、数据封装、同步异步等,下面说说我的理解。

通信协议

通信协议有很多,常用的比如 HTTP、TCP、UDP等,此外还有如 WebSockets、XMPP、MQTT等,这些都是网络通信,非网络通信的还包括 串口通信、USB等等。

现今除非是极为特殊的环境,一般应该都是使用网络通信协议的,所以就不说非网络通信了。要说网络通信协议就离不开TCP/IP四层模型(现已基本淘汰OSI七层模型),总不能连 HTTP 和 TCP 有什么区别都不知道就做选择吧。对四层模型我们一般只需要关注上面两层:应用层传输层,应用层协议(HTTP、XMPP等)是建立在传输层协议(TCP、UDP)上的。

  • 应用层协议:针对一些特定应用采用特定的格式进行数据传输,数据被编码成标准协议,并传送到下一层。该层的协议相比下层协议提供了更多特性,如QoS、安全性等都要比下层丰富,这些特性为我们提供了很多方便。
  • 传输层协议:目前主要使用的就是TCPUDP两个协议。前者是一个较可靠的、面向连接的传输机制,它提供一种可靠的字节流保证数据完整、无损并且按顺序到达。后者是一个无连接的数据报协议,它是一个“不可靠”协议,因为它不检查数据包是否已经到达目的地,并且不保证它们按顺序到达。相比应用层协议,该层缺少了很多特性,因此需要一些特性的时候就只能自己实现。

所以通信协议的选择最好是结合自己的应用场景所需的特性,考虑是否有较为匹配的协议,如无匹配则考察是否有一些其他工具或技术可以提供相关特性,或者自己是否能够轻松实现这些特性,总之要做到:

  1. 清楚了解自己在通信层面需要什么样的特性
  2. 对各种主要的网络通信协议的特点和特性有所掌握

接口风格

应用最广泛的接口风格当属 RPC(远程过程调用)了,从当年的基于SOAP和WSDL的WebServices,到现在的Thrift、Dubbo等,RPC 技术和工具在 SOA 生态中一直扮演着重要的角色。RPC 技术和工具帮助我们解决了网络通信和数据序列化/反序列化的问题,让我们像调用本地方法一样调用远程服务,有些 RPC 框架会帮你生成服务端和客户端桩代码(Thrift等),让你可以快速开发,有些 RPC 框架甚至提供了服务注册、发现能力(Dubbo等),便于你对服务进行水平伸缩。但是 RPC 多多少少会增加一定的耦合性,比如有时服务端的修改也会引起客户端的修改,而且修改后要求服务提供者和消费者要同时发布。

随着万维网技术的日新月异,REST 架构风格也越来越被推崇,但我发现实际上大部分人(包括我)都并没有真正理解 REST 精髓并加以应用。很多人以为使用 HTTP + JSON 并使用了 PUT、DELETE 等方法就是 RESTful 服务了,实际上这只是一种表面形式。首先 REST 并没有说一定是要用 HTTP 协议,也没有说要用 JSON 数据格式,只不过 HTTP 的特性为 REST 提供了更好的支持,所以使用 HTTP 对 REST 来说是一种较好的实践。REST 包含了非常多内容,我也尚在学习中,所以要深入了解 REST 还是建议读读 Roy Fielding 博士论文 以及 Richardson 成熟度模型。不过在使用 REST + HTTP 风格时,相比一些 RPC 方案,自己可能要做更多的工作。

异步通信也是现在的一个主流技术,因为它使得系统资源利用率更高,并有助于降低耦合性,提高系统的扩展性。一些 RPC 框架和 REST 框架也同时提供了同步和异步通信的能力,事件驱动架构(EDA)则能够借助异步技术(如消息系统)实现更加松耦合且易于扩展的应用系统。

在选择接口风格时我认为需要考虑:

  1. 自己当前最需要什么,如易用性、开发速度、熟悉程度、通信性能、系统扩展性、水平伸缩性、同步异步、高可用等等。
  2. 尽可能多的了解各种接口风格及相关技术和工具提供的能力,学习曲线,优缺点等,筛选较为满足自己需要的方案。
  3. 评估筛选出来的技术和工具如果应用到自己的系统中,需要做些什么样的工作,花费多大成本,带来的效果和好处是否值得,有必要的话做一些基准测试,用数据说话。

数据封装

如果你是用的是 RPC,十有八九你都不需要考虑数据如何封装,因为 RPC 框架基本都已经实现了数据的序列化/反序列化,例如 Protocol buffers、Hession 等。不同的框架在不同场景下的性能表现也各不相同,相关的文章有很多,这里不多赘述。

若你需要自己来选取一种数据封装方案,比如使用 REST + HTTP 时,面对 JSON、XML 或 二进制 等格式该如何选择?我认为可以从以下几方面思考:

  1. 技术无关性。JSON 和 XML 这类格式天生是技术无关的,如果使用 二进制 格式则要避免使用特定技术,比如Java自带的序列化/反序列化。
  2. 数据大小。相比 JSON,XML 可能会略大一点,如果传输的数据量较大,那么不同数据格式封装的结果可能会相差很多。
  3. 性能。不同数据格式各自都有多种序列化/反序列化工具,它们的实现方式使得性能也存在很大差别,有些对较小的数据量处理很高效,对较大数据量则性能低下,有些则恰恰相反。
  4. 使用场景。如果有的客户端可能不对数据反序列化,而是直接取用其中的某个特定部分数据,则使用 XML、JSON 这类格式会更方便,实际上消费方如何使用数据是它自己的事情,服务提供者理应提供这种便利。

同步异步

何时用同步何时用异步?我觉得这个问题现今已经没有多少意义了。因为同步能做到的,异步也都能做到,例如在异步调用中注册一个回调,或者使用 Future + Listener 这种模型,而相比异步,同步会产生大量阻塞,带来延迟,对系统资源的利用率低下。

那么为什么很多系统仍然在使用同步?因为简单。同步的开发能够很快上手,需要做的工作也相对较少,而异步技术对很多开发者尚存在一定的壁垒,如果完全自己来实现异步要做的工作也不少。

前篇提到了领域驱动设计(DDD),我们可以使用其中的思想来将单块应用分解为多个微服务,在 DDD 中较为推崇的一种协作方式是事件驱动架构(EDA),在微服务中这种架构更是如鱼得水。基于事件的协作能让微服务更加松耦合,业务完全内聚在各个微服务中,不需要有一个集中控制业务逻辑的中枢,从而大大提高系统的可扩展性。

所以我的想法是,

  1. 如果开发团队了解EDA那么尽可能使用EDA。
  2. 如果开发团队不了解EDA但是熟悉异步,那么结合业务的实际情况合理使用异步技术。
  3. 如果开发团队即不了解EDA也不熟悉异步,那么可以用同步快速开发,然后逐步建立异步的知识体系,随着业务的开展针对系统中对低延迟、低耦合要求高的地方用异步一步步进行重构。

结语

本篇主要针对微服务集成中的基础——通信——该如何选择合适方案谈了我的思路,指出了一些方面是我在做选择时会去考量的,不是十分全面,更不敢说都是正确的,有什么不妥之处欢迎和我交流。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容