Java程序员须知:分布式微服务为什么很难?

现在,我们不断地赞美云原生cloud native架构(容器化和微服务),然而现实是大多数公司仍然运行单体系统。为什么?这不是因为我们非常不时尚,而是因为分布式是非常困难的。尽管如此,它仍然是创建超大规模的、真正弹性的和快速响应的系统的唯一途径,因此我们必须围绕它进行整合。


在这篇文章中,我们将介绍分布式系统中一些障碍以及人们应对方法。

忘记康威定律(Conway’s Law),分布式系统遵循的是墨菲定律:“任何可能出错的地方都会出错。

在分布式系统的大规模上看,统计不是你的朋友(事后诸葛亮)。你所拥有的任何服务器实例越多,其中一个或多个当机的可能性就越高。而且极可能在同一时间。

在你收到警报邮件之前,服务器已经当机,网络将会丢失数据包,磁盘将失败,虚拟机将意外终止。

有一些在单体架构中的保证在分布式系统中就不再会得到保障。组件(现在的服务)不再以可预测的顺序启动和停止。服务可能意外重新启动,更改其数据库状态或版本。结果是,没有服务可以对另一个服务进行假设 - 系统不依赖于1对1的通信。

许多从故障中恢复的传统机制可能会使分布式环境恶化。强力重试可能会使您的网络被洪水般数据包淹没,备份恢复也并不简单。过去解决所有这些问题的设计模式,都需要重新思考和测试。

如果没有错误,分布式系统会很容易。乐观主义会造成对安全的错觉。分布式系统的设计必须具有弹性,能够容纳接受所有可能的发生错误,而不影响日常业务。

这里通讯会失败

在不可靠(即分布式)系统中,传统应用程序消息传递有两种高级方法:

  1. 可靠但缓慢:保存每条消息复制副本,直到您确认职责链中的下一个进程已经为此承担全部责任。
  2. 不可靠但快速:将多个复制副本发送给潜在的多个接受人,并允许消息丢失和重复。

我们在这里讨论的可靠和不可靠的应用级通信与网络可靠性(例如TCP与UDP)是不同。想象一下,两个通过TCP直接发送消息(比如RPC通讯)的无状态服务。即使TCP是可靠的网络协议,这也不是可靠的应用级通信。任何服务都可能会丢失并丢失正在处理的消息,因为无状态服务不能安全地保存正在处理的数据。(banq注:这是针对同步的RPC框架,比如国内的Dubbo或谷歌的gRPC)

我们可以通过在每个服务之间放置有状态的队列来使此设置应用程序级别可靠,以保存每个消息,直至其完全处理(banq注:引入消息队列)。这样做的不足之处在于它会慢一点,但是我们可能很乐意与之相处,因为如果它使生活更简单,特别是如果我们使用可管理的有状态的队列服务时,那么我们就不必担心规模和弹性问题。

可靠的方法是可预测的,但会涉及到延迟(延迟)和复杂性:大量确认消息和弹性保存数据(状态),直到您已经从职责链中的下一个服务确认完成了他们已经承担责任。

一个可靠的方法却不能保证快速的传递,但它确保所有的消息将最终至少一次传递。在每个消息至关重要且不能容忍丢失(例如信用卡交易)的环境中,这是一个很好的方法。AWS简单队列服务(Amazon的托管队列服务)是以可靠方式使用状态服务的一个例子。(banq注: Apache kafka提供类似正好一次的有效一次传递也是适用类似信用卡之类的交易)

第二种情况是,使用不可靠的方法可以实现端对端通讯得更快(比如RPC同步方式),但这意味着服务通常不得不期待重复和无序消息,并且一些消息将丢失。当消息是时间敏感的(即,如果他们不迅速采取行动,就不值得采取行动)或稍后的数据只是覆盖早期的数据,这种情况下可能会使用不可靠的通信。对于非常大规模的分布式系统,可以使用不可靠的消息传递,因为它的开销小且要快得多。然而,微服务设计却需要处理应对消息的丢失和重复。

在上述每种情况方法中,存在许多变量(例如,有保证和不保证的顺序性),所有这些变量需要在速度、复杂性和故障率方面进行不同的权衡。

一些系统可以同时使用上述多种方法,这取决于正在发送的消息的类型甚至系统上的当前负载。如果您有很多行为不同的服务,就很难正确恰当使用这些方法。需要在其API中明确定义服务的行为。为您的系统中的服务进行约束或推荐的通信行为的定义通常是有意义的,以获得一定程度的一致性。

现在时间是几点?

在分布式系统中没有这样的常见的所谓全球时钟。例如,在团体聊天中,我的评论和我的朋友在澳大利亚、哥伦比亚和日本发表的评论的出现将不会遵循严格顺序先后出现。没有任何保证机制保证我们看到的都是相同的时间表 - 虽然总有一个顺序,但是前提是我们有段时间先不说话。

基本上,在分布式系统中,每台机器都有自己的时钟,整个系统没有一个正确的时间。机器时钟可能会进行同步,但是即使在同步时传输时间也会不同,物理时钟也会以不同的速率运行,所以一切都会立即失去同步。

在单个机器上,一个时钟可以为所有线程和进程提供通用的时间。在分布式系统中,这在物理上都不可行。

在我们的新世界中,时钟时代不再提供无可置疑的顺序定义。在微服务世界中并不存在“什么时候”的单一概念,所以,我们的设计不应该依赖于服务间消息。

真相就在那里?

在分布式系统中,没有全局共享内存,因此没有单一版本的真相。数据将分散在不同物理机器上。此外,任何指定的数据在机器之间更可能处于相对较慢和无法访问的传输中,而不像在单体架构下的情况。因此,真正运行情况需要基于当前的当地的信息。

这意味着系统的不同部分的运行情况并不总是一致的。在理论上,它们最终应该在整个系统中传播消息时变得一致,但是如果数据不断变化,我们可能永远不会达到完全一致的状态,除非关闭所有新的输入和等待。因此,服务必须处理这样一个事实,即他们相互调用时可能会因为自己的问题而获得“旧”的或者不一致的信息。

说话快点!

在一个单体的应用程序中,大多数重要的通信发生在一个组件和另一个组件之间的单个进程中。流程内部的通信非常快,所以很多内部消息的传递不是问题。但是,一旦将单体组件拆分成单独的服务,通常会在不同的机器上运行,那么事情变得越来越复杂。

假设你知道如下背景知识:

  1. 在最好的情况下,将消息从一台机器发送到另一台机器比将内部从一个组件传递到另一个组件时要花费大约100倍的时间。
  2. 许多服务使用基于文本的RESTful消息进行通信。RESTful消息是跨平台的,易于使用,读取和调试,但传输速度慢。相比之下,与二进制消息协议配对的远程过程调用(RPC)消息不是人类可读的,因此更难调试和使用,但传输和接收速度要快得多。通过RPC方式发送消息的速度快20倍,比如gRPC相对RESTful而言。

在分布式环境中的结果却是

  1. 你应该发送更少的消息。您可以选择在分布式微服务器之间发送的消息数量少于在单件中的组件之间发送的消息量,因为每个消息都会引入延迟(即延迟)。
  2. 考虑更有效地发送消息。对于您发送的内容,您可以通过使用RPC而不是REST来传输消息来帮助您的系统运行得更快。或者甚至就使用UDP并手工自己处理不可靠性。(banq注:RPCC通讯属于通讯快但不可靠类型)

状况报告?

如果您的系统可以次秒级(时间上短于1秒)速度更改,这是动态管理的分布式架构的目标,那么您需要以这种速度了解问题。许多传统的日志工具并不是为了跟踪这种情况而设计的。你需要确保能使用它们。

测试破坏

了解您的分布式系统是否正常工作并从不可预测的错误中恢复的唯一方法是:持续攻克这些错误并持续修复系统。Netflix使用Chaos Monkey(混沌猴)随机造成故意的崩溃测试。您的系统的弹性和完整性是需要测试的,同样重要的是,测试您的日志记录,以确保如果发生错误,您可以追溯地诊断和修复它 - 即使您的系统已经恢复在线运行。

这听起来很困难 我一定需要吗?

创建分布式、可扩展的、有弹性的系统是非常困难的,特别是对于有状态的服务(服务需要写数据库保存变动的数据)。现在是决定是否需要它的时候了。你的客户需求是否可以容忍慢一点响应还是小型规模系统?这样,您可以先设计一个更小、更慢、更简单的系统,并在构建专业知识同时逐步增加更多的复杂性。

像AWS,Google和Azure这样的云计算提供商也正在开发和推出这些大部分功能,特别是弹性状态(托管的消息队列和数据库)。这些服务似乎是昂贵的,但构建和维护复杂自己的分布式服务也是昂贵的。

任何虽然可能限制您但是会处理这些复杂性的框架(如Linkerd或Istio或Azure的服务架构)是非常值得考虑的。

关键的挑战是不要低估建立正确的弹性和高度可扩展的服务的难度。如果决定你真的需要它,那么全面教育大家,引入有用的约束,逐渐做好一切,并期待挫折和成功。

原文地址:https://blog.51cto.com/13754022/2364098

时间: 2024-10-12 15:30:06

Java程序员须知:分布式微服务为什么很难?的相关文章

Java程序员须知的七个日志管理工具(转)

Splunk vs. Sumo Logic vs. LogStash vs. GrayLog vs. Loggly vs. PaperTrails vs. Splunk>Storm 英文原文:The 7 Log Management Tools You Need To Know 日志管理工具有 Splunk.Sumo Logic.LogStash.GrayLog.Loggly 和 PaperTrails 等等,数不胜数.日志就像石油,二十多年了我们一直想摆脱它,却一直没有做到. 为了处理日益增长

java b2b2c电子商务 springcloud分布式微服务-Session

通常情况下,Tomcat.Jetty等Servlet容器,会默认将Session保存在内存中.如果是单个服务器实例的应用,将Session保存在服务器内存中是一个非常好的方案.但是这种方案有一个缺点,就是不利于扩展.目前越来越多的应用采用分布式部署,用于实现高可用性和负载均衡等.那么问题来了,如果将同一个应用部署在多个服务器上通过负载均衡对外提供访问,如何实现Session共享?实现Session共享的方案很多,其中一种常用的就是使用Tomcat.Jetty等服务器提供的Session共享功能,

专访《Java程序员修炼之道》作者Ben Evans

转帖这篇文章,很大成分就是认同"保守的设计思想是Java的最大优势"这句话 ------------------------------------------------------------------ [编者按]Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言,它几乎是每个程序员的入门语言,而<Java程序员修炼之道>更是深受程序员欢迎的学习书籍.该书作者之一Ben Evans最近参加了上海QCon大会,图灵社区采访了这位大牛级人物. Ben Evans

Springcloud分布式微服务多用户商城系统b2b2c-Spring Cloud常见问题

在使用Spring Cloud的过程中,难免会遇到一些问题.所以对Spring Cloud的常用问题做一些总结.需要JAVA Spring Cloud大型企业分布式微服务云构建的B2B2C电子商务平台源码:三五三六二四七二五九 一.Eureka常见问题 Eureka 注册服务慢 默认情况下,服务注册到Eureka Server的过程较慢.在开发或测试时,常常希望能够加速这一过程,从而提升工作效率. 该问题的原因及解决方案: 服务的注册涉及周期性心跳,默认30秒一次(通过客户端配置的service

9本java程序员必读的书

来源:http://mp.weixin.qq.com/s?__biz=MjM5NzA1MTcyMA==&mid=202904638&idx=2&sn=21dd20438e32a24e78e8c33dd4a0991e&scene=1#rd 本文列出的9本书在Java程序员界都是被认为很棒的书.当一个程序员开始初学Java时,他的第一个问题应该是如何选择一本书来作为指导学习Java.这个问题也就表明,相对于其他的教程和博客,Java书籍还是很重要的参考,主要表现在以下两点 ●通

Java程序员学习之路

1. Java语言基础 谈到Java语 言基础学习的书籍,大家肯定会推荐Bruce Eckel的<Thinking in Java>.它是一本写的相当深刻的技术书籍,Java语言基础部分基本没有其它任何一本书可以超越它.该书的作者Bruce Eckel在网络上被称为天才的投机者,作者的<Thinking in C++> 在1995年曾获SoftwareDevelopment Jolt Award最佳书籍大奖,<Thinking in Java>被评为1999年Java

女生当Java程序员好不好

越来越多的女生都觉得编程很有意思,Java语言作为编程语言中相当受程序员喜爱的语言,很多女生对Java编程感兴趣,想要成为一名女Java程序员,但是很多人提出:女生不适合学Java,女生更不适合当Java程序员.真的是这样吗?女生当Java程序员好不好?这就是我们今天要讨论的主题.跟长沙尚学堂小编一起往下看. 女生当Java程序员好不好?很多人觉得女生不适合学Java,提出的跟当初大家反对女生学IT技术是一个理由,什么女生逻辑能力比较差.什么女生动手实践能力不如男生等等,现在都什么年代了,还用老

Java程序员必读的9本书

本文列出的9本书在Java程序员界都是被认为很棒的书.当一个程序员开始初学Java时,他的第一个问题应该是如何选择一本书来作为指导学习Java.这个问题也就表明,相对于其他的教程和博客,Java书籍还是很重要的参考,主要表现在以下两点 通常书籍是由比较权威的程序员来撰写的. 相比其他媒介,书籍对于内容的描述更加详细,解释更加明确. 本文列出的九本书是我个人非常喜欢的Java书籍,当我有时间的时候,我就会将它们捧在手里阅读.甚至有些书我反复读过很多遍,每次重新读的时候总会有新的收获.因此这些书也是

Java程序员需要具备的几个软实力,你具备了吗?

有很多关于Java程序员的调侃,比如"智商很高情商却很感人,思维缜密,极客,加班严重,没有对象只能new一个--",虽然不是所有Java程序员都是这样,但这也说明了Java程序员这个群体中存在这种情况.我身边的Java程序员小伙伴就有不少这种情况,我认为工作特点影响了这种性格标签. Java程序员的很多工作都是需要"单打独斗",任务分工之后每个人要独立完成部分功能设计,相互沟通比其他岗位少很多.小编的这篇文章能对于Java程序员避免愈发孤独的状态很有帮助.在工作之外