绿林网

《分布式服务架构:原理、设计与实战》读后感摘抄

《分布式服务架构:原理、设计与实战》读后感摘抄

《分布式服务架构:原理、设计与实战》是一本由李艳鹏 / 杨彪著作,电子工业出版社出版的平装图书,本书定价:89.00,页数:400,特精心收集的读后感,希望对大家能有帮助。

《分布式服务架构:原理、设计与实战》读后感(一):微服务的一些套路

前一二章介绍了微服务架构设计原理,分布式一致性性问题;第三章介绍了非功能性质量需求的评估与设计;第四五介绍了些互联网技术的常用套路,包括日志系统、调用链;第六章介绍了些互联网技术的trouble shooting技巧;第七章介绍了容器化技术;第八章介绍了敏捷开发的常用自动化工具。总体感觉逻辑性不强,并未围绕“分布式服务架构”来展开介绍,但是作为“开阔视野,增加知识面”的目的,还是可以一阅的! ps:第二章写的很清楚!

《分布式服务架构:原理、设计与实战》读后感(二):架构师入门第一课

曾几何时,我还是一个看着别人的架构 PPT 不知道别人说的是什么的懵懂少年,也不知道服务器的使用量该怎么配置。一切的一切都从这本书和58同城沈剑的微信公众号开始改变。这本书里详细的记录了该怎么计算服务器使用量等等基本架构知识,另外也讲解了分布式服务框架。当好 CTO 不能只会工程或者算法或者后端,也得懂架构。

当好 CTO,从认真研读这本书开始迈出第一步。

《分布式服务架构:原理、设计与实战》读后感(三):分布式服务架构:原理、设计与实战

《分布式服务架构:原理、设计与实战》全面介绍了分布式服务架构的原理与设计,并结合作者在实施微服务架构过程中的实践经验,总结了保障线上服务健康、可靠的最佳方案,是一本架构级、实战型的重量级著作。

《分布式服务架构:原理、设计与实战》以分布式服务架构的设计与实现为主线,由浅入深地介绍了分布式服务架构的方方面面,主要包括理论和实践两部分。理论上,首先介绍了服务架构的背景,以及从服务化架构到微服务架构的演化;然后提出了保证分布式服务系统架构一致性的方案和模式,并介绍了互联网架构评审的方法论;最后给出了一个简要的非功能质量的技术评审提纲。实践上,首先提供了一个互联网项目的性能和容量评估的真实案例,介绍了压测的方案设计和最佳实践,这些技术能够全面保证大规模、高并发项目的一致性、可用性和高并发性;然后讲解了大规模服务的日志系统的原理、设计与实践,包括ELK等框架的特点和使用方式等,并介绍了当前流行的APM系统的设计与实现,主要包括调用链和业务链的跟踪与恢复,涵盖了线上应急和技术攻关的流程及重点,也结合服务化系统线上应急过程进行分析并总结了其中需要用到的Java虚拟机、Linux和定制化脚本等命令,这些命令都是每个开发人员都会用到的解决线上问题的利器;最后,阐述了系统服务的容器化过程,并详细介绍了敏捷开发流程和实现自动化的常用工具等,让读者既能学到架构设计的基础理论,也能结合书中的原理、设计与方法论来解决大规模、高并发互联网项目中的现实问题。

无论是对于软件工程师、测试工程师、运维工程师、软件架构师、技术经理、技术总监,还是对于资深IT人士来说,《分布式服务架构:原理、设计与实战》都有很强的借鉴性和参考价值。

《分布式服务架构:原理、设计与实战》读后感(四):分布式计算形离神不离

能利用当前流行的技术对复杂问题进行技术选型并给出合理架构方案的人更是凤毛麟角。

第1章 分布式服务架构设计原理

较新的架构思想是基于原有的架构思想在某个特定领域下满足特定需求演化而来的。

JEE架构

JEE将企业级软件架构分为三层:

1、Web层:负责与用户交互或者对外提供接口。

2、业务逻辑层:为了实现业务逻辑而设计的流程处理和计算处理模块。

3、数据存取层:将业务逻辑层处理的结果持久化以待后续查询,并维护领域模型中对象的生命周期。

JEE二八原则

将80%通用的与业务无关的逻辑和流程封装在应用服务器的模块化组件里,通过配置的模式提供给应用程序访问,应用程序实现20%的专用逻辑,并通过配置的形式来访问应用服务器提供的模块化组件。

事实上,应用服务器提供的对象关系映射服务、数据持久服务、事务服务、安全服务、消息服务等通过简单的配置即可在应用程序中使用。

单体架构 —— 服务化架构 —— 微服务架构

Spring框架有两个核心思想:IOC和AOP

AOP代表面向切面的编程,通常适用于使用面向对象方法无法抽象的业务逻辑,例如:日志、安全、事务、应用程序性能管理(APM)等。

AOP的实现方式有三种:

1、对Java字节码进行重新编译,将切面插入字节码的某些点和面上,可以使用cglib库实现。

2、定制类加载器,在类加载时对字节码进行补充,在字节码中插入切面,增加了除业务逻辑外的功能,JVM自身提供的Java Agent机制就是在加载类的字节码时,通过增加切面来实现AOP的。

3、JVM本身提供了动态代理组件,可以通过它实现任意对象的代理模式,在代理的过程中以插入切面的逻辑。可以使用Java提供的APIProxy.newProxyInstance()和InvocationHandler来实现。

AspectJ是实现AOP的专业框架和平台。

SOA的两个主流实现方式:WebService和ESB。

WebService问题:

1、依赖中心化的服务发现机制。

2、使用SOAP通信协议,通常使用XML格式来序列化通信数据,XML格式的数据冗余太大,协议太重。

3、服务化管理和治理设施并不完善。

ESB问题:

1、ESB虽然是SOA实现的一种方式,却更多地体现了系统集成的便利性,通过统一的服务总线将服务组合在一起,并提供组合的业务流程服务。

2、组合在ESB上的服务本身可能是一个过重的整体服务,或者是传统的JEE服务等。

3、ESB视图通过总线来隐藏系统内部的服务性,但是系统内部的复杂性仍然存在。

4、对于总线本身的中心化的管理模型,系统变更影响的范围经常会随之扩大。

问题是驱动人类进步的原动力。

微服务通过RESTful风格的API和轻量级的消息通信协议来完成

微服务不是为了拆分而拆分,真正的目的是通过对微服务进行水平扩展解决传统的单体应用在业务急剧增长时遇到的问题。

单体架构特点:

1、传统单体架构将所有模块化组件混合后运行在同一个服务JVM进程中。

2、可对包含多个模块化组件的整体JVM进程进行水平扩展,而无法对某个模块化组件进行水平扩展。

3、某个模块组件发生变化时,需要所有的模块化组件进行编译、打包和上线。

4、久而久之,模块间的依赖将会不清晰,互相耦合、互相依赖成为家常便饭。

微服务的去中心化治理

如果Dubbo服务化出现了大面积的崩溃,则服务化体系会切换到点对点的hession远程调用,这被称为服务化降级,降级后点对点的hession远程调用时没有中心化节点,整体上符合微服务的原理。

微服务的交互模式

1、读者容错模式

读者容错模式(Tolerant Reader)指微服务化中服务提供者和消费者之间如何对接口的改变进行容错。

从字面上来讲,消费者需要对提供者提供的功能进行兼容性设计,尤其对服务提供者返回的内容进行兼容,或者解决在服务提供者改变接口或者数据的格式的情况下,如何让服务消费者正常运行。

2、消费者驱动契约模式

消费者驱动契约模式用来定义服务化中服务之间交互接口改变的最佳规则。

服务契约分为:提供者契约、消费者契约及消费者驱动的契约,它从期望与约束的角度描述了服务提供者与服务消费者之间的联动关系。

3、去数据共享模式

微服务之间的交互通过定义良好的接口来实现,不允许使用共享数据来实现。

共享存在以下问题:

使得微服务之间的交互除了接口契约,还存在数据存储契约。

上游的数据格式发生变化时,可能导致下游的处理逻辑出现问题。

多个服务共享一个资源服务,对资源服务的运维难以划清职责和界限。

在做双机房独立部署时,需要考虑服务和资源的路由情况,跨机房的服务调用不能使用独立的资源部署模式,因此难以实现服务自治。

微服务的分解和组合模式

1、服务代理模式

服务代理模式是最简单的服务组合模式,它根据业务的需求选择调用后端的某个服务。在返回给使用端之前,代理可以对后端服务的输出进行加工,也可以直接把后端服务的返回结果返回给使用端。

2、服务聚合模式

服务聚合模式是最常用的服务组合模式,它根据业务流程处理的需要,以一定的顺序调用依赖的多个微服务,对依赖的微服务返回的数据进行组合、加工和转换,最后以一定的形式返回给使用方。

每个被依赖的微服务都有自己的缓存和数据库,聚合服务本身可以有自己的数据存储,包括缓存和数据库等,也可以是简单的聚合,不需要持久化任何数据。

3、服务串联模式

服务串联模式类似于一个工作流,最前面的服务1负责接收请求和响应使用方,串联服务后再与服务1交互,随后服务1与服务2交互,最后,从服务2产生的结果经过服务1和串联服务逐个处理后返回给使用方。

4、服务分支模式

服务分支模式是服务代理模式、服务聚合模式和服务串联模式相结合的产物。

由于分支模式放大了服务的依赖关系,因此在现实的微服务设计中尽量保持服务调用级别的简单,在使用服务组合和服务代理模式时,不要使用服务串联模式和服务分支模式,以保持服务依赖关系的清晰明了,这也减少了日后维护的工作量。

5、服务异步消息模式

所有的组合模式都是使用同步的RESTful风格的同步调用来实现,同步调用模式在调用的过程中会阻塞线程,如果服务提供方迟迟没有返回,则服务消费方会一直阻塞,在严重情况下会撑满服务的线程池,出现雪崩效应。

在构建微服务架构系统时,通常会梳理核心的最小化服务集合,这些核心的系统服务使用同步调用,而其他核心链路以外的服务可以使用异步消息队列进行异步化。

6、服务共享数据模式

服务共享数据模式其实是反模式。

两种场景仍然需要数据共享模式:

单元化架构

遗留的整体服务

微服务的容错模式

1、舱壁隔离模式

在微服务架构中,主要体现如下:

微服务容器分组

线程池隔离

2、熔断模式

3、限流模式(计数器、令牌筒、信号量)

4、失效转移模式

Java平台微服务架构的项目组合形式

1、微服务项目的依赖关系

每个服务上线后,对外输出的接口为一个Jar包。在微服务领域,Jar包被分为一方库、二方库、三方库。

2、微服务项目的层级结构

服务导出层、服务接口层和服务实现层。

每个层级的职责和最终的表现形式:

服务导出层:最后会打包成一个War包,包含服务的实现Jar包、接口Jar包,以及Web项目导出RPC服务所需要的配置文件等。

服务接口层:包含业务接口、依赖的DTO及需要的枚举类等,最后打包成Jar包,并发布到Maven服务器上,也包含在服务导出层的War包中。

服务实现层:包含业务逻辑实现类、依赖的第三方服务包装类,以及下层数据库访问的DAO类等,最后打包成Jar包,包含在服务导出层的War包中。

服务化管理和治理框架的技术选型

1、RPC

JDK RMI

一个Java进程内的服务可以调用其他Java进程内的服务,使用JDK内置的序列化和反序列化协议。

JDK内置的RMI服务并没有得到广泛使用,原因如下:

RMI采用JDK自带的专用序列化协议,不能跨语言。

使用了底层的网络协议,不如基于文本的HTTP可读,也不如HTTP被广泛认可和应用。

开源框架的飞速发展,严重削弱了JDK资深技术的流行程度。

Hession及Burlap

两者都是与语言无关的,可以在多种语言的服务中互相调用。

Hession及Burlap都适合传输较小的对象,对较大、复杂的对象,无论是在序列化方式上还是在传输通道上都没有RMI有优势。

由于服务化架构中大量的服务调用都是大规模、高并发的短小请求,因此,Hession和Burlap协议在服务化架构中得到了广泛应用。

Spring HTTP Invoker

Spring HTTP Invoker重用了JDK内置的对象序列化技术传输对象,这与RMI的原理一致,但是,它通过HTTP通道传输数据,在效率上应该略低于RMI,并且由于使用了JDK内置的序列化机制,因此也是不能跨语言的。

服务化

Dubbo

提供了高性能和透明化的RPC远程服务调用,还提供了基本的服务监控、服务治理和服务调度等能力。

默认支持多种序列化协议和通信编码协议,默认使用Dubbo协议传输Hession序列化的数据。

Dubbo缺点:

Dubbo开发得较早,近些年已经没有开发者维护和升级。

早期留下的Bug一直没有得到修复,需要使用自己发现和修复。

Dubbo没有经过全面优化,在服务量级到达一定程度时,会出现通知系统携带过多的冗余信息,在极端情况下会导致网络广播风暴。

Dubbo服务框架是SOA服务化时代的产物,对微服务化提出的各种概念如熔断、限流、服务隔离等没有做精细的设计和实现。

Dubbo的监控和服务治理模块比较简单,难以满足复杂业务的需求。

HSF

HSF以高性能网络通信框架为基础,提供了诸如服务发布与注册、服务调用、服务路由、服务鉴权、服务限流、服务降级和服务调用链路跟踪等一系列久经考验的功能特性。

Thrift

Thrift是Facebook实现的一种高性能并且支持多语言的远程服务调用框架,由Apache开源,它采用中间的接口描述语言定义并创建服务,支持跨语言服务开发和调用,并且包含中间的接口描述语言与代码生成和转化工具,支持包括C++、Java、Python、PHP、Ruby、Erlang、Perl、Haskell、C#、Cocoa、Smalltalk等在内的流行语言,传输数据时采用二进制序列化格式,相对于JDK本身的序列化、XML和JSON等,尺寸更小,在互联网高并发、海量请求和跨语言的环境下更有优势。

Axis

基于Web Service应用的框架,基本不用。

Mule ESB

通过异构模式集成系统。

微服务

1、Spring Boot

提供了产品化特点,如:性能分析、健康检查和外部化配置。

全程没有XML配置,也不需要代码生成。

2、Netflix

提供服务发现、断路器和监控、智能路由、客户端负载均衡、易用的REST客户端等服务化必须的功能。

3、Spring Cloud Netflix

服务发现组件Eureka、容错性组件Hystrix、智能路由组件Zuul和客户端负载均衡组件Ribbon。

Netflix具有如下特点:

服务在Eureka实例中注册,由Spring管理的Bean来发现和调用。

通过配置的方式可以启动嵌入式的Eureka服务器。

Feign客户端通过声明的方式即可导入服务代理。

Zuul使用Ribbon服务实现客户端的负载均衡。

通过声明的方式即可插入Hystrix的客户端。

通过配置的方式即可启动Hystrix面板服务器。

在Spring环境中可以直接配置Netflix的组件。

Zuul可以自动注册过滤和路由器,形成一个反向代理服务器。

Hystrix面板可以对服务的状态进行监控,并提供了容错机制。

第2章 彻底解决分布式系统一致性的问题

什麽是一致性

服务器节点池化

人多不一定能解决所有的事情,还得有序、合理地分配任务,并进行有效的管理,于是互联网时代谈论最多的话题就是拆分。拆分一般分为水平拆分和垂直拆分,这并不单指对数据库或者缓存的拆分,主要是表达一种分而治之的思想和逻辑。

水平拆分指由于单一节点无法满足性能需求,需要扩展为多个节点,多个节点具有一致的功能,组成一个服务池,一个节点服务一部分的请求量,所有节点共同处理大规模的并发的请求量。

垂直拆分指按照功能进行拆分,按专业的人干专业的事的原则,把一个复杂的功能拆分为多个单一、简单的功能,不同的单一功能组合在一起,和未拆分前完成的功能是一样的。由于每个功能职责单一、简单,使得维护和变更都变得更简单、容易、安全,所以更易于产品版本的迭代,还能够快速地进行敏捷发布和上线。

如何保证它们的信息、工作进度、状态一致并且协调有序地工作呢?

一致性问题:

1、下订单和扣库存

2、同步调用超时

3、异步调用超时

4、掉单

5、系统间状态不一致

6、缓存和数据库不一致

7、本地缓存节点间不一致

8、缓存数据结构不一致

解决一致性问题的模式和思路

1、酸碱平衡理论

ACID在英文中的意思是“酸”,BASE的意思是“碱”,这里讲的酸碱平衡的故事。

ACID 酸

具有ACID特性的数据库支持强一致性,强一致性代表数据库本身不会出现不一致。

Oracle、MySQL、DB2都能保证强一致性,通常是通过多版本控制协议MVCC来实现的。

交易的存储应该只考虑关系型数据库。

NoSQL完全不适合交易场景,主要用来做数据分析、ETL、报表、数据挖掘、推荐、日志处理、调用链跟踪等非核心交易场景。

2、CAP 帽子原理

CAP原理证明,任何分布式系统只可同时满足两点,无法三者兼顾。

3、BASE 碱

BASE思想解决了CAP提出的分布式系统的一致性和可用性不可兼得的问题,如果想全面地学习BASE思想,则参考维基百科的Eventual consistency页面。

BASE模型包含如下三个元素:

BA:Basically Available,基本可用。

S:Soft State,软状态,状态可以在一段时间内不同步。

E:Eventually Consistent,最终一致,在一定的时间窗口内,最终数据达成一致即可。

4、对酸碱平衡的总结

解决一致性问题的三条实践经验

使用向上扩展(强悍的硬件)并运行专业的关系型数据库能够保证强一致性,能用向上扩展解决的问题都不是问题。

如果向上扩展的成本很高,则可以对廉价硬件运行的开源关系型数据库进行水平伸缩和分片,将相关数据分到数据库的同一个片上,仍然能够使用关系型数据库保证事务。

如果业务规则限制,无法将相关数据分到同一个分片上,就需要实现最终一致性,在记录事务的软状态(中间状态、临时状态)时若出现不一致,则可以通过系统自动化或者人工干预来修复不一致问题。

分布式一致性协议

国际开放标准组织Open Group定义了DTS(分布式事务处理模型),模型中包含4种角色:

应用程序、事务管理器、资源管理器和通信资源管理器。事务管理器是统管全局的管理者,资源管理器和通信资源管理器是事务的参与者。

两阶段提交协议、三阶段提交协议及阿里巴巴提出的TCC,都是基于DTS这一思想演变而来的。

两阶段提交协议在准备阶段锁定资源,这是一个重量级的操作,能保证强一致性,但是实现起来复杂、成本较高、不够灵活,更重要的是有如下致命问题:

1、阻塞

对于任何一次指令都必须收到明确的响应,才会继续进行下一步,否则处于阻塞状态,占用的资源被一直锁定,不会被释放。

2、单点故障

如果协调宕机,参与者没有协调者指挥,则会一直阻塞。

3、脑裂

协调者发送指令提交,有的参与者接收到并执行了事务,有的参与者没有接收到事务就没有执行事务,多个参与者之间是不一致的。

三阶段提交协议

是对两阶段提交协议的改进版本,它通过超时机制解决了阻塞的问题,并且把两阶段增加为三个阶段。

1、询问阶段

超时会导致中止

2、准备阶段

询问阶段所有参与者都返回可以执行操作,则协调者相参与者发送预执行请求,然后参与者写redo和undo日志。

3、提交阶段

如果每个参与者在准备阶段返回准备成功,则协调者向参与者发起提交指令。

三阶段提交协议与两阶段提交协议主要有以下两点不同:

1、增加一个询问,可以确保尽早发现无法执行操作而需要中止的行为,但是不能发现所有情况,只能减少。

2、准备阶段以后,协调者和参与者执行的任务中都增加了超时,一旦超时,则协调者和参与者都会继续提交事务,默认为成功。

这是根据概率统计超时后默认为成功的正确性最大。

TCC

在互联网的高并发系统中,鲜有使用两阶段提交和三阶段提交协议的场景。

TCC协议将一个任务拆分成Try、Confirm、Cancel三个步骤,正常的流程会先执行Try,如果执行没有问题,则再执行Confirm,如果执行过程中出了问题,则执行操作的逆操作Cancel。

正常流程上讲,这仍然是一个两阶段提交协议,但是在执行出现问题时有一定的自我修复能力,如果任何参与者出现了问题,则协调者通过执行操作的逆操作来Cancel之前的操作,达到最终的一致状态。

保证最终一致性的模式

1、查询模式

任何服务操作都需要提供一个查询接口,用来向外部输出操作执行的状态。

服务操作的使用方可以通过查询接口得知服务操作执行的状态,然后根据不同的状态来做不同的处理操作。

为了实现查询,每个服务操作都需要有唯一的流水号标识,也可以使用此次服务操作对应的资源ID来标识。

2、补偿模式

查询模式,在任何情况下,都能得知具体的操作所处的状态。为了让系统最终达到一致状态而做的努力都叫做补偿。

补偿操作根据发起形式分为以下几种

自动恢复:程序根据发生不一致的环境,通过继续进行未完成的操作,或者回滚已经完成的操作,来自动达到一致状态。

通知运营:如果程序无法自动恢复,并且设计时考虑了不一致的场景,则可以提供运营功能,通过运营手工进行补偿。

技术运营:如果很不巧,系统无法自动恢复,又没有运营功能,那么必须通过技术手段来解决,技术手段包括进行数据库变更或者代码变更,这是最糟的一种场景。

3、异步模式

对于使用对响应时间要求不太高的场景中,通常把这类操作从主流程中摘除,通过异步的方式进行处理,处理后把结果通过通知系统通知给使用方。

这个方案最大好处是能够对高并发流量进行削峰。

4、定期校对模式

想在分布式系统中快速定位问题时,可通过分布式系统的调用链跟踪系统进行,它能够跟踪一个请求的调用链。调用链是从二维的维度跟踪一个调用请求,最后形成一个调用树,其原理可参考谷歌的Dapper论文及它的一个流行的开源实现项目Pinpoint。

通过定期校对模式发现问题,并通过补偿模式来修复,最后达到系统间的最终一致性。

5、可靠消息模式

让异步操作的调用方和被调用方充分解耦,专业的消息队列本身具有可伸缩、可分片、可持久等功能,通常通过消息队列实现异步化。

对于消息队列,需要建立特殊的设施来保证可靠的消息发送及处理机的幂等性。

消息的可靠发送

消息处理器的幂等性

如果我们要保证可靠地发送消息,简单来说就是要保证消息一定发送出去,那么需要有重试机制。有了重试机制后,消息就一定会重复,那么我们需要对重复的问题进行处理。

保证操作幂等性的常用方法:

1、使用数据库表的唯一键进行滤重,拒绝重复的请求。

2、使用分布式表对请求进行滤重。

3、使用状态流转的方向性来滤重,通常使用数据库的行级锁来实现。

4、根据业务的特点,操作本身就是幂等的,例如:删除一个资源、增加一个资源、获得一个资源等。

6、缓存一致性模式

互联网的经典做法就是使用缓存来扛住读流量。

如果性能要求不是非常高,则尽量使用分布式缓存,而不要使用本地缓存。

写缓存时数据一定要完整,如果缓存数据的一部分有效,另一部分无效,则宁可在需要时回源数据库,也不要把部分数据放入缓存中。

使用缓存牺牲了一致性,为了提供性能,数据库与缓存只需要保持弱一致性,而不需要保持强一致性,否则违背了使用缓存的初衷。

读的顺序是先读缓存,后读数据库,写的顺序是先写数据库,后写缓存。

超时处理模式

由于网络通信不稳定,设计系统时必须考虑到对网络通信的容错,特别是对调用超时问题的处理。

微服务的交互模式

1、同步调用模式

同步调用模式适用于大规模、高并发的短小操作,而不适用于后端负载较高的场景,例如:几乎所有JDBC的实现完全使用BIO同步阻塞模式。

2、接口异步调用模式

接口异步调用模式适用于非核心链路上负载较高处理环节,环节经常耗时较长,并且对时效性要求不高。

3、消息队列异步处理模式

大规模、高并发的微服务系统中,消息队列对流量具有削峰的功能。

同步异步的抉择

1、尽量使用异步来替换同步操作

从业务功能的角度出发,如果业务逻辑允许,用户对产品的交互形态没有异议,可以将一些耗时较长的、用户对响应没有特别要求的操作异步化,以此来减少核心链路的层级,释放系统的压力。

2、能用同步解决的问题,不要引入异步

从技术和架构的角度出发,如果性能不是问题,或者所处理的操作是短小的轻量级处理逻辑,同步调用方式是最理想不过的,因为这样不需要引入异步化的复杂处理流程。

为什麽不推荐将大数据存储到关系型数据库中,关系型数据库只存储交易相关的最小化核心信息。

交互模式下超时问题的解决方案

1、同步调用模式下的解决方案

两状态的同步接口

三状态的同步接口

2、异步调用模式下的解决方案

异步调用接口超时

异步调用内部超时

异步调用回调超时

3、消息队列异步处理模式的解决方案

消息队列生产者超时

消息队列消费者超时

超时补偿的原则

1、调用方补偿

2、接收方补偿

第3章 服务化系统容量评估和性能保障

所有技术最终体现在计算机知识的基本功上,这些基本功是技术的易筋经,是内功。

我们不但要练好内功,修炼好易筋经,还要学习可高效生产的各类技术框架。对框架的掌握程度则体现在剑术上,作为工程师和架构师的我们,在练好内功的基础上,也要修炼好剑术。

互联网技术不一定比传统行业的技术高深很多。

传统行业更偏向于企业级开发,项目具有业务复杂、流程完善、中心化管理、企业级抽象度高、业务重用率高等特点。

互联网技术侧向于把复杂的业务拆分成单一职责模块,并对各个模块的非功能质量进行大幅度优化,包括高可用性、高性能、可伸缩、可扩展、安全性、稳定性、可维护性、健壮性等。

互联网架构权衡分析方法(Architecture Tradeoff Analysis Method,ATAM)是评价软件架构的一种综合且全面的方法,它不仅可以揭示架构满足特定质量目标的情况,而且可以使我们更情况认识到质量与目标之间的制约和权衡。

非功能质量需求

1、高性能:运行效率高、性价比高

2、可用性:持续可用性、缩短宕机时间、出错恢复、可靠性

3、可伸缩性:垂直伸缩、水平伸缩

4、可扩展性:可插拔、组件重用

5、安全性:数据安全、加密、熔断、防攻击

其他非功能质量指标

1、可监控性:快速发现、定位和解决

2、可测试性:可灰度、可预览、可Mock、可拆解

3、鲁棒性:容错性、可恢复性

4、可维护性:易于维护、监控、运营和扩展

5、可重用性:可移植性、解耦

6、易用性:可操作性

非功能质量需求的具体指标针对不同的系统主要分为4部分:

1、应用服务器

应用服务器是服务的入口,请求流量从这里进入系统,数据库、缓存和消息队列的访问量取决于应用服务器的访问量。

对应用服务器的访问量进行评估至关重要,应用服务器主要关心每秒请求的峰值及对请求的响应时间等指标,通过这些指标可以评估我们需要的应用服务器资源的数量。

部署结构

1)、负载均衡策略

2)、高可用策略

3)、I/O模型(NIO/BIO)

4)、线程池模型

5)、线程池中线程数量

6)、是否多业务混合部署

容量和性能

1)、每天请求量

2)、各接口的访问峰值

3)、平均的请求响应时间

4)、最大的请求响应时间

5)、在线的用户量

6)、请求的大小

7)、网卡的I/O流量

8)、磁盘的I/O负载

9)、内存的使用情况

10)、CPU的使用情况

其他指标

1)、请求的内容是否包含大对象

2)、GC收集器的选型和配置

2、数据库

根据应用层的访问量和访问峰值,计算出需要的数据库资源的吞吐量、每天的数据总量等。

由此来评估所需数据库资源的数量和配置、部署结构等。

部署结构

1)、复制模型

2)、失效转移策略

3)、容灾策略

4)、归档策略

5)、读写分离策略

6)、分库分表(分片)策略

7)、静态数据和半静态数据是否使用缓存

8)、有没有考虑缓存穿透并压垮数据库的情况

9)、缓存失效和缓存数据预热策略

容量和性能

1)、当前的数据容量

2)、每天的数据增量

3)、每秒的读峰值

4)、每秒的写峰值

5)、每秒的事务量峰值

其他指标

1)、查询是否走索引

2)、有没有大数据量的查询和范围查询

3)、有没有多表关联,关联是否用到索引

4)、有没有使用悲观锁,是否可以改造成乐观锁,是否可以利用数据库内置行级锁

5)、事务和一致性级别

6)、使用的JDBC数据源类型及连接数据等配置

7)、是否开启JDBC诊断日志

8)、有没有存储过程

9)、伸缩策略(分区表、自然时间分表、水平分库分表)

10)、水平分库分表实现方法(客户端、代理、NoSQL)

3、缓存

根据应用层的访问量和访问峰值,通过评估热数据占比,计算缓存资源的大小并估算缓存资源的峰值,由此来计算所需缓存资源的数量、部署结构、高可用方案等。

部署结构

1)、复制模型

2)、失效转移

3)、持久策略

4)、淘汰策略

5)、线程模型

6)、预热方法

7)、哈希分片策略

容量和性能

1)、缓存内容的大小

2)、缓存内容的数量

3)、缓存内容的过期时间

4)、缓存的数据结构

5)、每秒的读峰值

6)、每秒的写峰值

其他指标

1)、冷热数据比例

2)、是否有可能发生缓存穿透

3)、是否有大对象

4)、是否使用缓存实现分布式锁

5)、是否使用缓存支持脚本(Lua)

6)、是否避免了Race Condition

7)、缓存分片方法(客户端、代理、集群)

4、消息队列

根据应用层的访问量和访问峰值,计算出需要消息队列传递的数据量,进而计算出所需的消息队列资源的数量、部署结构、高可用方案等。

部署结构

1)、复制模型

2)、失效转移

3)、持久策略

容量与性能

1)、每天平均的数据增量

2)、消息持久的过期时间

3)、每秒的读峰值

4)、每秒的写峰值

5)、每条消息的大小

6)、平均延迟

7)、最大延迟

其他指标

1)、消费者线程池模型

2)、哈希分片策略

3)、消息的可靠投递

4)、消费者的处理流程和持久机制

中间件架构(应用服务器、数据库、缓存、消息队列等)

逻辑架构(模块划分、模块通信、信息流、时序等)

数据架构(数据结构、数据分布、拆分策略、缓存策略、读写分离策略、查询策略、数据一致性策略)

异常处理、容灾策略、灰度发布、上线方案、回滚方案等

有用的压测工具

1、ab

ab是一种针对Http实现的服务进行性能压测的工具,它最初被设计用于测量Apache服务器的性能指标,特别是测试Apache服务器每秒能够处理多少请求及响应时间等,但此命令也可以用来测试一切通用的Http服务器性能。

2、jmeter

jmeter是Apache开发的基于Java的性能压力测试工具,用于对Java开发的软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到通用的性能测试领域。

可以用于测试静态和动态资源,例如静态文件、Java Applet、CGI脚本、Java类库、数据库、FTP服务器,HTTP服务器等。

3、mysqlslap

mysqlslap是mysql自带的一款性能压测工具,通过模拟多个并发客户端访问MySQL来执行压力测试,同时提供了详细的数据性能报告。

4、sysbench

CPU性能测试

线程锁性能测试

磁盘随机I/O测试

内存性能测试

MYSQL事务性操作测试

5、dd

可以用于测试磁盘顺序I/O的存取速度。

6、LoadRunner

7、hprof

第4章 大数据日志系统的构建

日志用于记录系统中硬件、软件、系统、进程和应用运行时的信息,同时可以监控系统中发生的各种事件。

日志可以分为系统日志、容器日志和应用日志等。

按照应用目标的不同,日志可以分为性能日志、安全日志等。

按照级别的不同,日志可以分为调试日志、信息日志、警告日志和错误日志等。

日志管理平台能够监控所有这些问题,并能处理各种服务器的日志,包括:七层Nginx的日志、应用日志、访问日志、性能日志、安全日志、技术日志等。

大数据通用日志架构:

Logstash、Fluentd、Flume、Scribe和Rsyslog等都是采集日志的常用工具。

第5章 基于调用链的服务治理系统的设计与实现

优秀的开源APM系统

APM系统的实现:Pinpoint、Zipkin和CAT。

Pinpoint:Pinpoint是基于Java语言编写的APM工具,用于大规模分布式服务化系统或者实施了微服务架构的系统。

Pinpoint具有如下特点:

1、安装的采集端代理组件对原有的服务代码无侵入。

2、对性能的影响较小,只增加约3%的资源利用率。

3、根据请求的流量自动生成微服务调用的拓扑结构。

4、通过可视化结构显示网络微服务调用的关系,下钻可显示该服务的详细信息页面。

5、实时监控活动线程,并通过图形的形式展示。

6、可视化地显示请求超时发生的位置,帮助快速定位问题。

7、可以收集和现实CPU、内存、垃圾收集、请求吞吐量和JVM运行情况等。

8、使用异步线程推送和UDP协议减少对程序处理性能的影响。

Zipkin

是一个分布式服务的调用链跟踪系统,也是一个基于谷歌Dapper论文的开源实现。能够收集服务调用的时序数据,解决在微服务架构中定位超时等性能问题。

它通过在应用程序中挂载字节码增强库来实时数据汇报给Zipkin,目前支持Java、Go和Scala等语言。

CAT

CAT聚焦于对Java应用的全链路监控方面,目前支持的各种中间件,例如:MVC框架、RPC服务平台、数据库访问、缓存访问等,可以实时处理有时间价值的日志数据,并全量采集应用产生的数据,具有高可用、容错性、高吞吐量和可横向扩展等特性。

调用链跟踪的原理

一次调用过程:

1、调用端发送请求的调用信息。

2、被调用端接收请求的调用信息。

3、被调用端接收发送响应的调用信息。

4、调用端接收响应的调用信息。

每种类型的远程调用信息包含:调用端或者被调用端的IP、系统ID;本次请求的TraceID、SpanID和ParentSpanID;时间戳、调用的方法名称及远程调用信息的类型,等等。

TraceID,在前端接收用户的请求后,会为用户的请求分配一个TraceID,在内部服务调用时,会通过应用层的协议将TraceID传递到下层服务,直到整个调用链的每个节点都拥有了TraceID,这样,在系统出现问题时,可以使用这个唯一的TraceID迅速找到系统间发生过的所有交互请求和响应,并定位问题发生的节点。

Vesta

http://vesta.cloudate.net/ 是一款原创的多场景的互联网发号器,此发号器可以作为全局唯一的流水号,也就是TraceID。

SpanID

调用链跟踪系统通常由采集器、处理器和分布式存储系统组成,经过几个模块处理后的调用数据会在调用链展示系统中对外提供查看和查询等功能,整体的调用链跟踪系统的通用实现架构。

每个模块的功能职责:

1、采集器,负责把业务系统的远程服务调用信息从业务系统中传递给处理器。

2、处理器,负责从业务系统的采集器中接收服务调用信息并聚合调用链,将其存储在分布式数据存储中,以及对调用链进行分析,并输出给监控和报警系统。

3、分布式存储系统,存储海量的调用链数据,并支持灵活的查询和搜索功能。

4、调用链展示系统,支持查询调用链、业务链等功能。

TraceID和SpanID在服务间的传递

主要解决Java应用内传递、服务间传递、多线程间传递、应用与消息队列、缓存和数据库间传递TraceID和SpanID的问题。

1、Java进程内传递

在Java应用系统内部通常通过ThreadLocal来传递TraceID和SpanID。

2、服务间传递

在应用层的网络通信协议中传递TraceID和SpanID。在RESTful风格的API服务,则HTTP头是传递TraceID和SpanID的最佳位置。

在RPC的远程调用,则通常需要在RPC的序列化协议上增加定制化的字段。

3、主子线程间传递

创建新的线程或者子线程时,将TraceID和SpanID一起传递过去,并放在子线程的ThreadLocal中。

4、消息队列的传递

调用链跟踪消息队列的实现通常以下3种方法:

通过更改消息队列实现的底层协议,将TraceID和SpanID在底层透明地传递,这样就不需要应用层有感知,但是更改底层消息队列协议的实现复杂、消息队列产品多样化,这样的方案实现不太容易。

在应用层的报文上增加附加字段,应用层在发送消息时,手工将TraceID和SpanID通过报文传递,这种方案入侵了业务系统,但是实现起来比较简单、快捷。

在消息队列客户端的库上定制化,在每次发送消息时将TraceID和SpanID增加到消息报文中,在消息队列的处理机的库中先对报文进行解析,再将业务报文传递给应用层处理。

5、缓存、数据库访问

第6章 Java服务的线上应急和技术攻关

电影《深海浩劫》里讲述了石油公司为了赶进度和工期,不按照既定流程和规范进行生产作业,对已经发生的问题视而不见,最终导致了海上油井爆炸,酿成了多人死亡的严重事故。

地震是由不可抗力导致的,而事故与之不同,任何大的生产事故在发生之前都有迹可循,而且事故的发生并不是偶然的,我们应该善于从现象中总结规律,找到发现、止损和避免的方法。

海恩法则和墨菲法则

海恩法则:每一起严重事故的背后,必然有29次轻微事故和300起未遂先兆及1000起事故隐患。

强调两点

1、事故的发生是量的积累的结果

2、再好的技术、再完美的规章,在实际操作层面也无法取代人自身的素质和责任心。

墨菲定律:如果有两种或两种以上方式去做某件事情,而选择其中一种方式将导致灾难,则必定有人会做出这种选择。

1、任何事情都没表面看起来那么简单。

2、所有事情的发展都会比你预计的时间长。

3、会出错的事总会出错。

4、如果你担心某种情况发生,那么它更有可能发生。

线上应急的目标、原则和方法

1、应第一时间恢复系统而不是彻底解决问题,快速止损。

2、有明显的资金损失时,要在第一时间升级,快速止损。

3、应急指挥要围绕目标,快速启动应急过程和快速决策止损方案。

4、当前应急责任人如果在短时间内不能解决问题,则必须进行升级处理。

5、应急过程中在不影响用户体验的前提下,要保留部分现场和数据。

发现问题:

发现问题通常通过自动化的监控和报警系统来实现。

对系统层面、应用层面和数据库层面进行监控。

1、对系统层面的监控包括对系统的CPU利用率、系统负载、内存使用情况、网络I/O负载、磁盘负载、I/O等待、交互区的使用、线程数及打开的文件句柄等进行监控,一旦超出阀值,就需要报警。

2、对应用层面的监控包括对服务接口的响应时间、吞吐量、调用频次、接口成功率及接口波动率等进行监控。

3、对资源层的监控包括对数据库、缓存和消息队列的监控。通常会对数据库的负载、慢SQL、连接数等进行监控;对缓存的连接数、占用内存、吞吐量、响应时间等进行监控;以及对消息队列的响应时间、吞吐量、负载、积压情况等进行监控。

技术攻关的方法论

对于任何问题,必须收集发生这些问题的现象,考虑如下问题:

1、When:什麽时候出的问题?

2、What:什麽出了问题?

3、Who:谁在什麽时间里发现了问题?问题影响了谁?

4、Where:哪里出了问题?哪里又没出现问题?

5、Why:为什麽出现了问题?

本文由作者上传并发布(或网友转载),绿林网仅提供信息发布平台。文章仅代表作者个人观点,未经作者许可,不可转载。
点击查看全文
相关推荐
热门推荐