译者:程超

译文:http://www.jianshu.com/p/c76f7f234a31

上篇:《都在说微服务,那么微服务的反模式和陷阱是什么(一)》

六、无因的开发者陷阱

名字来自詹姆斯·迪恩演的电影《无因的反叛》(Rebel Without a Cause),一个问题青年因为错误的原因做了错误的决定。

很多架构师和开发者在微服务的开发中权衡利弊, 比如服务粒度和运维工具,但是基于错误的原因,做了错误的决定。

6.1 做出错误的决定

图6-1说明了一种情况是通过测试发现服务划分的太细了,因此非常影响性能,主要是由于服务划分的太细导致增加了通信工作量也在一定程度上对稳定性造成一定影响。在这种情况下,开发人员或架构师决定将这些服务整合到一个更粗粒度的服务中,以解决性能和可靠性问题。

这个方案看起来似乎合情合理,但是之后的布署、更改控制和测试都会受到影响。

再看图6-2,这种场景是左边的服务太粗了,影响了服务的测试和布署,于是进行了拆分,减少了每个服务的范围。

通过以上二个场景我们可以看出,如果服务太细我们就需要考虑将服务合并,如果服务太粗,我们又会考虑将服务进行拆分。太细的话会增加通信成本和容易造成可靠性不稳定,太粗的话又容易导致不容易测试和上线布署,所以这就要看我们如何来权衡利弊。

6.2 了解业务驱动

了解业务驱动对于合理设计微服务至关重要,每一个架构师或者开发者都应该先回答以下三个问题:

  • 我们为什么要设计微服务架构?

  • 主要的业务驱动是什么?

  • 最重要的架构特点是什么?

使用可布署、性能、健壮性和可扩展作为主要的架构特性,我们其实最先需要考虑的是如何利用业务来进行服务的整合和拆分。

场景一:迁移到微服务主要是想达到快速上线和布署

在这种场景下服务的可布署能力相对要大于性能、稳定性因素,所以要拆分服务的时候可以考虑稍微细粒度一些。

场景二:迁移到微服务主要是想提高系统的性能和健壮性

这种场景是从单一应用程序迁移到微服务架构的一个常见因素,很多公司都是业务驱动,那么就需要考虑服务的可靠性和健壮性,因此倾向于更粗粒度的服务,而不是细粒度的服务。

我经常使用的一种方式借助白板和团队成员一起讨论,如图6-3所示,每当有服务粒度的划分问题的时候,我们经常在白板上做草稿讨论清楚。

七、赶潮流陷阱

你必须拥抱微服务,因为这是目前的趋势,而且其他人和公司目前都已经这么做了。

我们盲目的使用微服务,却还没有仔细分析业务需求、组织架构和技术环境,这就是随大流陷阱。

避免这个陷阱的方式充分理解微服务的好处和短处,俗话说,知己知彼,百战不殆。

7.1 微服务的优点和缺点

优点:

  • 发布:易于发布

  • 测试:易于测试

  • 改变控制:更容易的改变一个服务的功能

  • 模块

  • 规模可扩展

缺点:

  • Team组织改变

  • 性能

  • 可靠性降低

  • 运维难度加大

7.2 其他架构模型

微服务的架构很好,但是不是唯一的架构模式,比如下面还有一些其它的架构模式:

  • Service-Based Architecture

  • Service-Oriented Architecture

  • Layered Architecture

  • Microkernel Architecture

  • Space-Based Architecture

  • Event-Driven Architecture

  • Pipeline Architecture

当然你并不一定只使用唯一的一种架构模式,你可能在系统中混用这些架构模式。

下面有一些架构的参考资料:

  • Software Architecture Fundamentals: Understanding the Basics

  • Software Architecture Fundamentals: Beyond the Basics

  • Software Architecture Fundamentals: Service-Based Architecture

  • Software Architecture Patterns

  • Microservices vs. Service-Oriented Architecture

八、静态契约陷阱

在微服务的消费者和提供者之间提供了一种契约,契约主要包括输入和输出数据、以及操作的名称,契约通常是以XML、JSON或者JAVA对象等来表示。但是这些契约永远不会改变吗?

这里举个例子来说明因为服务契约版本控制而发生的问题: 假如你有一个服务是由三个不同的客户端访问(client1、client2和client3),这时client1想更改服务契约,你要检查client2和client3能否适应这个改变,并且client2和client3告诉我适应不了这个改变,需要数周时间才能调整完成。这时候我需要告诉client1,client2和client3需要数周时间才能适应调整完成,但是client1却不能等待这么长时间。

可以在你的服务契约中提供版本控制,实现向后兼容。现在我们可以根据client1的请求做一些灵活的控制,我们可以创建一个新版本的契约,比如v1.1,client2和client3依然使用v1版本,这样client1就可以立刻作为契约更改,而不必纠结于client2和client3需要适应调整的时间。

有两种实现方式:在header中加入版本号,或者在契约自身scheme中加入版本号。

8.1 header版本控制

契约版本的第一种办法是把版本号放在远程访问协议头,如图8-1所示,远程访问协议包括REST, SOAP, AMQP, JMS, MSMQ等等。

例如在使用REST的时候,可以使用MIME类型来指定协议版本,如下代码:

  1. POST /trade/buy

  2. Accept: application/vnd.svc.trade.v2+json

通过在header的MIME类型中指定契约版本号,服务端就可以通过header的MINE类型解析得到相应的版本号。

8.2 Schema版本控制

第二种版本控制方式是在契约自身中进行,不需要在header中指定版本号,如图8-2所示。

请先看如下json格式数据:

  1. {

  2.        "$schema": "http://json-schema.org/draft-04/schema#",

  3.        "properties": {

  4.          "version": {"type": "integer"},

  5.          "acct": {"type": "number"},

  6.          "cusip": {"type": "string"},

  7.          "sedol": {"type": "string"},

  8.          "shares": {"type": "number", "minimum": 100}

  9.       },

  10.        "required": ["version", "acct", "shares"]

  11. }

该模式直接将版本号定义在契约的输入数据中,这种模式最大的优点是与协议无关,只与数据格式有关。

  1. POST /trade/buy

  2. Accept: application/json

  3. {

  4.    "version": "2",

  5.    "acct": "12345",

  6.    "sedol": "2046251",

  7.    "shares": "1000"

  8. }

  9. String msg = createJSON(

  10.      "version","2",

  11.      "acct","12345",

  12.      "sedol","2046251",

  13.      "shares","1000")};

  14. jmsContext.createProducer().send(queue, msg);

这种方式也有一些不足就是每一次都需要对消息数据进行解析,提取出版本号进行校验,而且数据格式也有可能会改变也不太容易做到自动映射到JAVA对象中。

未完待续


优秀人才不缺工作机会,只缺适合自己的好机会。但是他们往往没有精力从海量机会中找到最适合的那个。100offer 会对平台上的人才和企业进行严格筛选,让「最好的人才」和「最好的公司」相遇。扫描下方二维码,注册 100offer,谈谈你对下一份工作的期待。一周内,收到 5-10 个满足你要求的好机会!

都在说微服务,那么微服务的反模式和陷阱是什么(二)相关推荐

  1. 都在说微服务,那么微服务的反模式和陷阱是什么(三)

    前文导读: <都在说微服务,那么微服务的反模式和陷阱是什么(一)> <都在说微服务,那么微服务的反模式和陷阱是什么(二)> 九.通信协议使用的陷阱 在微服务架构体系中要求每个服 ...

  2. 都在说微服务,那么微服务的反模式和陷阱是什么(一)

    译者:程超 译文:http://www.jianshu.com/p/3986239138fe 中文目录 1.数据驱动的迁移反模式 1.1.太多的数据迁移 1.2.功能分割优先,数据迁移最后 2.超时反 ...

  3. 微服务设计 10 大反模式和陷阱

    数据驱动迁移反模式(Data-Driven Migration) ​ 如上图所示,此种反模式的问题在于微服务的粒度没有最终确定之前就做了数据迁移,如此当不断的调整服务粒度时,那么数据库就免不了频繁迁移 ...

  4. 03 | 微服务反模式与陷阱:代码共享反模式

    译者简介:ASCE1885, <Android 高级进阶>作者. 本文首发于Source Code Chain开发者社区,欢迎使用我的专属邀请链接加入一起交流. 微服务被称为"无 ...

  5. rpc框架都有哪些_这六种微服务RPC框架,你知道几个?

    开源 RPC 框架有哪些呢? 一类是跟某种特定语言平台绑定的,另一类是与语言无关即跨语言平台的. 跟语言平台绑定的开源 RPC 框架主要有下面几种. Dubbo:国内最早开源的 RPC 框架,由阿里巴 ...

  6. 单体仓库与多仓库都有哪些优势劣势,微服务选择哪种方案比较好?

    这段时间在研究bilibili泄露出来的源码,发现bilibili虽然使用了微服务的设计理念但是所有服务都是放在同一个仓库底下的,而我司和bilibili恰恰相反,我司所有项目都是分开独立的,也出现了 ...

  7. 大家都在谈的SOA和微服务 你真的理解吗

    微服务是什么? 微服务是一种架构设计模式.在微服务架构中,业务逻辑被拆分成一系列小而松散耦合的分布式组件,共同构成了较大的应用.每个组件都被称为微服务,而每个微服务都在整体架构中执行着单独的任务,或负 ...

  8. 应用量化时代 | 微服务架构的服务治理之路

    技术随业务而生,业务载技术而行. 近些年来,伴随数字经济的发展,在众多企业的数字化转型之路上,云原生.DevOps.微服务.服务治理等成为行业内不断被探讨的新话题.人们在理解和接受这些新型概念的同时, ...

  9. Spring Cloud构建微服务架构:服务容错保护(Hystrix断路器)

    断路器 断路器模式源于Martin Fowler的Circuit Breaker一文."断路器"本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生短路时," ...

最新文章

  1. linux 文本行倒叙,Linux基础(4)之文本处理
  2. (剑指Offer)面试题61:按之字形顺序打印二叉树
  3. 分享5个可视化的正则表达式编辑工具
  4. scjp考试准备 - 4 - 关于数组
  5. 中国电子用LCP树脂市场未来发展展望及十四五规划咨询建议报告2022-2028年版
  6. mongodb授权登录,经过自己修改后的授权登录方式
  7. RabbitMQ六种工作模式:simple work publish routing topic rpc
  8. 网络编程练习 -- NSURLConnection -- get/post请求
  9. 990. Satisfiability of Equality Equations
  10. 《数据结构》c语言版学习笔记——单链表结构(线性表的链式存储结构Part1)
  11. 2015年创业中遇到的技术问题:41-50
  12. jquery实现截取pc图片_如何优雅的对网页截取长图
  13. CF1028F. Make Symmetrical
  14. 计算机一级b考试教程,全国计算机等级考试一级B教程
  15. android app启动过程
  16. mysql innodb 多核cpu_没有改变,但MySQL InnoDB超载CPU
  17. zookeeper进行leader选举
  18. 斯坦福大学公开课IOS 7学习笔记 (1)
  19. 2022-2028年中国现代服务行业企业投资项目指引及机会战略分析报告
  20. DOORS和Reqtify — 需求管理和需求追溯工具

热门文章

  1. linux 自动化交互套件 expect 介绍 shell非交互
  2. python3 读写文件
  3. VS Debug和Release版本的区别
  4. 牛博威:成熟的反外挂系统一般企业未必能承受
  5. Shell脚本的调试技术
  6. xen tools代码结构
  7. windows mysql dump_mysql在Windows下使用mysqldump命令手动备份数据库和自动备份数据库...
  8. linux 5 防火墙,CentOS 5 Linux iptables防火墙的配置
  9. android studio 自动try,Catch Try让我在Android Studio调试中感到困惑
  10. c++运算符的全局重载