=======开篇吐槽:最近一段时间刚好碰上中秋国庆双节,而且工作任务繁重,基本很难保证有时间来写文章了=======
《可伸缩服务架构 框架与中间件》与《分布式服务架构 原理、设计与实战》是要配套捆绑着看,这营销手段,服。
这书主要介绍了在分布式系统中常规用到的一些框架组件,比如分布式ID、消息队列、缓存、RPC框架、ES等。书中大部分内容的作用更多的是整体介绍、知识点扩展、初步入门,书中贴的源代码其中很难让人认真一行一行去阅读学习。想要更深入的学习,需要在平时工作多积累丰富的项目经验,或者多看看开源项目,从而去总结和提取。
每一章介绍一个组件,摘抄一些自己觉得有用的内容,归纳整理,然后加以理解。(主要还是强迫自己形成总结成文的习惯,看的书很多,都总是很容易忘记,效果甚微)
第1章 如何设计一款永不重复的高性能分布式发号器
1. 为什么不直接采用UUID?
虽然UUID能够保证唯一性,但无法满足业务系统需要的很多其他特性,比如时间粗略有序性、可反解和可制造性(说人话,就是分布式ID需要体现根据时间递增的特点,并且从ID串中能解析出一定的业务含义),同时UUID比较长,占空间大,性能较差。
2. 那基于数据库来实现呢?
即通过调整自增字段或者数据库sequence的步长来确保跨数据库的ID的唯一性,但这种方案强依赖于数据库。
实现方案,可见我:重构 - 分布式ID设计方案
3. 分布式ID的基本需求
(1)全局唯一
分布式系统保证唯一的一个悲观策略是使用锁或者分布式锁,但是这样会大大降低性能。因此利用时间的有序性,并且在时间的某个单元下采用自增序列,来达到全局唯一。
(2)粗略有序
UUID最大的问题是无序。
(3)可反解
即能从ID串能看出一定的业务含义,比如什么时候产生的,跟哪些业务功能模块相关的。
(4)可制造
不依赖发号器(如果系统崩了),也能通过一定的规律来手工处理数据。
(5)高性能
产生一个新业务,就要生成一个新ID,所以对性能要求非常高。ID的生成取决于网络I/O和CPU的性能,网络I/O一般不是瓶颈。
(6)高可用
发号器应该是满足HA的集群,同时拥有重试机制。在极端情况下,还要有本地的容错方案。
4. 如何保证性能需求?
在项目初期提出性能需求,在项目进行中做性能测试来验证。
5. 获取分布式ID的几种方法
(1)REST方法
提供一个HTTP接口来获取
(2)RPC服务化方法
服务化模式通过Dubbo导出RPC服务
(3)嵌入方法
将发号器服务嵌入到业务项目中,并且提供JVM进程内的本地服务
第2章 可灵活扩展的消息队列框架的设计与实现
1. 背景介绍
消息队列多应用于异步处理、模块之间的解耦和高并发系统的削峰等场景中。
2. 线程模型
(1)同步线程模型
客户端为每个消费者流使用一个线程,每个线程负责从Kafka队列里消费消息,并且在同一个线程里处理业务。
(2)异步线程模型
客户端为每个消费者流使用一个线程,每个线程负责从Kafka队列里消费消息,并且传递消费得到的消息到后端的异步线程池中,在异步线程池中处理业务。
而后端的异步业务线程池又可细分为:
1> 所有消费者流共享线程池
此种模式可以创建更少的线程池对象,节省些许内存
2> 每个流独享线程池
使用不同的异步业务线程池来处理不同的流里面的消息,互相隔离、互相独立、不互相影响。比如,区分普通用户的消息,和VIP用户的消息,这样可以在不同业务线程池中来处理。
3. 异常处理
对于在消息处理过程中产生的业务异常,当前在业务处理的上层捕捉了Throwable,在专用的错误恢复日志中记录了出错的信息,后续可根据错误恢复日志人工处理错误消息,也可重做或者清洗数据。也可考虑采用Listener体系,对异常处理采用监听者模式来实现异常处理器的可插拔等。
4. 优雅关机
通过注册JVM退出钩子进行优雅关机。
=========================继续看下篇==========================