Java 微服务实用指南(一)( 三 )

于是 , 你实际上是将一个 Java 方法调用包装成一个 HTTP 调用 , 而这么做并没有特别明显的理由 。 而一个可能的原因是:缺乏经验而试图强行采用 Java 微服务方法 。 建议:不要这样做 。
面向工作流的微服务体系架构下一个常见的方法是 , 在工作流之后对 Java 微服务进行模块化 。
举个现实生活中的例子:在德国 , 当你去看(公共)医生时 , 他需要在他的健康软件 CRM 中把你的预约记录下来 。
为了让保险报销 , 他将把你的治疗数据和他所治疗的所有其他患者的数据通过 XML 发送给仲裁机构 。
仲裁机构会看一下那个 XML 文件并做出处理(已做简化):

  1. 验证该文件是否是正确的 XML
  2. 验证它的合理性:一个 1 岁大的孩子每天从妇科医生做三次牙齿清洁 , 这合理吗?
  3. 使用其他一些形式数据对 XML 加以补充
  4. 将 XML 转发给保险以触发报销
  5. 然后向医生反馈结果 , 其中包括“成功”的消息或“数据有异常 , 请重新核实修改后再次发送”
现在 , 如果你尝试使用微服务对这个工作流进行建模 , 至少会包括以上内容 。
注意:在本例中 , 微服务之间的通信与主题无关 , 但如果真要提一下的话 , 可以通过 RabbitMQ 之类的消息代理异步完成 , 因为医生不需立即得到反馈 。
Java 微服务实用指南(一)文章插图
同样的 , 从纸面上看 , 这似乎看起来挺不错的 , 但我们马上会发现以下几个问题:
  • 你觉得需要部署六个应用程序来处理一个 xml 文件吗?
  • 这些微服务真的相互独立吗?它们每一个可以独立部署吗?每个都具有不同的版本和 API 模式?
  • 如果验证微服务停了 , 那么合理性微服务会做什么?系统还会保持运行吗?
  • 这些微服务现在是否共享同一个的数据库(它们确实需要数据库表中的一些公共数据) , 或者你是否会采取更大的动作来为它们提供属于自己的数据库?
  • 以及 , 基础设施或运维方面其他的大量问题 。
有趣的是 , 对于一些架构师来说 , 上面的图理解起来更简单 , 因为现在每个服务都有它确切的、定义良好的用途 。 以前 , 它看起来像这个可怕的大型独体应用:
Java 微服务实用指南(一)文章插图
虽然这些图画起来简单 , 但是你肯定需要解决些额外的运维挑战 。
你……
  • 不仅需要部署一个应用程序 , 而是需要至少部署六个 。
  • 甚至可能需要部署多个数据库 , 这取决于你希望微服务体系架构走多远 。
  • 必须确保每个系统都保持在线、健康和工作 。
  • 必须确保微服务之间的调用实际上是有弹性的(参见如何使 Java 微服务具有弹性? )
  • 以及这么部署带来的一切差异——从本地开发配置到集成测试 。
建议
除非:
  • 你是 Netflix(但显示 , 你不是)……
  • 你拥有超强的运维技能包:你打开开发 IDE , 就会跳出一只调皮猴 , 删掉你的生产数据库 , 你能轻易在 5 秒内自动恢复 。
  • 或者你觉得自己像 @monzo, 仅仅因为认为自己能行 , 就尝试了 1500 个微服务 。
否则:
不要这么做 。
尽管 , 没那么夸张 。
尝试根据领域边界对微服务建模是一种非常明智的方法 。 但是 , 领域边界(比如用户管理和发票)并不意味着拿来一条工作流将其分解为几个最小的部分(接收 XML、验证 XML、转发 XML) 。
因此 , 每当你开始一个新的、领域边界还非常模糊的 Java 微服务项目时 , 且领域边界仍然非常模糊 , 请尽量保持微服务的规模 。 你总是能够在之后添加更多模块的 。
确保在整个团队 / 公司 / 部门都拥有非常强大的 DevOps 技能 , 以支持你新的基础架构 。
多语言或面向团队的微服务架构还有第三种 , 几乎是以自由意志主义的方法来开发微服务:让你的团队甚至个人有可能使用他们想用的任何语言或微服务来实现用户故事(行业术语:多语言编程) 。
因此 , 上面的合理性微服务是用 Haskell 编写的(为了让它看上去更数学) , 保险的转发微服务应该用 Erlang 编写(因为它确实需要扩展) , 而 XML 验证服务可以用 Java 编写 。
从开发人员的角度来看很有趣的东西(即在一套隔离的环境中使用你的完美语言开发一个完美的系统) , 基本上不是组织想要的同质化和标准化 。
这意味着 , 应该有一套相对标准化的语言、库和工具 , 这样即便你不在了 , 其他开发人员将来也可以继续维护 Haskell 微服务 。