目录
java基础
修饰符
反射
-
获取类对象
- 通过实例对象获得类对象,getClass
- CLass.forName(“类路径”)
- 通过具体类 Student.class
-
反射的使用
- 获取方法,私有方法,需要指定方法修饰符,同时取消安全检查
- 获取属性,设置属性时候,需要取消安全检查
- 获取构造函数,私有也需要关闭安全检查
异常
四种引用
NIO的工作流程
理解
跟IO的区别是,IO是面向流读写,NIO是面向缓存区,同时NIO是异步非阻塞的.
简单的理解JAVA代理的原理
JVM相关
0.) 类的生命周期
- 类的生命周期分为6个阶段,加载,验证,准备,解析,初始化,卸载.
- 验证,准备,解析属于连接阶段.
类的加载时间
:1 new的时候,2 子类被调用的时候,3 调用类中静态属性的时候,4 调用类中静态方法的时候,5 反射调用的时候- 如何加载: 首先三种类加载器和自定义类加载器.
- 双亲加载机制
- 验证阶段 :
- 准备:为静态变量创建空间
- 解析:将类中的符号引用改为直接引用
- 初始化:为类中的静态变量设置初始值
- 卸载:程序正常结束,永久代满了,执行fullGC.在1.8之后,取消永久代,采用元空间,将数据放入物理内存中.
多线程相关
0.) 多线程的生命周期
1.) 创建线程的方式
- 继承Thread类
- 实现Runnable接口,调用Thread(Runnable runnable)构造函数,调用start运行线程.
- 实现Callable接口,使用FuturaTask创建一个实现Runnable接口的类,放入Thread类中,运行线程,并回调.
- 使用线程池,实现多线程创建和管理.
2. ) 四种线程池
- 简单线程池,只有一个线程
- 可重用线程池
- 固定大小可重用线程池
- 定时任务线程池
3.) Synchronized 同步锁
Synchronize关键字保证被他修饰的方法和代码块在任意时间只有一个线程执行。属于重量级锁。
通过反编译synchronization修饰的代码块(修饰方法时,使用的是ACC_)synchronizatized标识),发现代码被monitor编辑,当执行到monitorenter指令时,线程会获取对象的monitor持有权。
而monitor监视器锁是通过操作系统的互斥锁实现的,所以每次线程切换都需要通过操作系统来实现。但是操作系统切换线程都需要从用户态转换为内核态,比较耗费时间,时间成本比较高。
- synchronized 它可以把任意一个非 NULL 的对象当作锁。 他属于独占式的悲观锁,同时属于可重入锁。
- Owner 线程会在 unlock 时,将 ContentionList 中的部分线程迁移到 EntryList 中,并指定EntryList 中的某个线程为 OnDeck 线程(一般是最先进去的那个线程)。Owner 线程并不直接把锁传递给 OnDeck 线程,而是把锁竞争的权利交给 OnDeck,OnDeck 需要重新竞争锁。OnDeck 线程获取到锁资源后会变为 Owner 线程,而没有得到锁资源的仍然停留在 EntryList中。
4.) 分级锁
synchronized的优化
文章
在1.6之后,对锁进行了升级优化,以减少锁竞争带来的上下文切换。
锁升级功能主要依赖于Mark Word中锁标志位和是否偏向锁标志位。
无缩状态->偏向锁->轻量锁->重量锁
5) 谈谈 synchronized 和 ReentrantLock 的区别
两者都是可重入锁,synchronize是居于jvm实现的,而ReentrantLock是依赖于lock接口实现的,需要显式的获取锁和释放锁。
6) 说说 synchronized 关键字和 volatile 关键字的区别
原子性 : 一个的操作或者多次操作,要么所有的操作全部都得到执行并且不会收到任何因素的干扰而中断,要么所有的操作都执行,要么都不执行。synchronized 可以保证代码片段的原子性。
可见性 :当一个变量对共享变量进行了修改,那么另外的线程都是立即可以看到修改后的最新值。volatile 关键字可以保证共享变量的可见性。
有序性 :代码在执行的过程中的先后顺序,Java 在编译器以及运行期间的优化,代码的执行顺序未必就是编写代码时候的顺序。volatile 关键字可以禁止指令进行重排序优化。
synchronized 关键字和 volatile 关键字是两个互补的存在,而不是对立的存在!
volatile 关键字是线程同步的轻量级实现,所以volatile 性能肯定比 synchronized 关键字要好。但是volatile 关键字只能用于变量而 synchronized 关键字可以修饰方法以及代码块。
volatile 关键字能保证数据的可见性,但不能保证数据的原子性。synchronized 关键字两者都能保证。
volatile 关键字主要用于解决变量在多个线程之间的可见性,而 synchronized 关键字解决的是多个线程之间访问资源的同步性。
7) ThreadLocal 简介
8.) AQS 介绍
AQS 是一个用来构建锁和同步器的框架。
AQS 核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制。
mysql
MySQL 基本架构概览
简单来说 MySQL 主要分为 Server 层和存储引擎层:
Server层:主要包括连接器、查询缓存、分析器、优化器、执行器等,所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图,函数等,还有一个通用的日志模块 binglog 日志模块。
存储引擎:主要负责数据的存储和读取,采用可以替换的插件式架构,支持 InnoDB、MyISAM、Memory 等多个存储引擎,其中 InnoDB 引擎有自有的日志模块 redolog 模块。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始就被当做默认存储引擎了。
- 一条Sql语句的执行
- 查询
- 连接器验证权限,进行分析器词法和语法分析 ,优化器进行优化SQL,执行器调用引擎获取数据.
- 更新(涉及到日志的写操作)
- 首先查询到这条要更新的数据,读入内存,修改值之后,记录redo.log文件中,标记文件为prepare,然后执行器写入binlog中,然后调用存储引擎,存入磁盘,并设redo日志为提交状态.
- 查询
mysql Limit优化
随着数据量的增多,limit 10000,10 和limit 0,10 不是一个时间量级,由于limit常常采用全表扫描的方式,所以数值越大,扫描时间越长.
Redis
Redis 哨兵
主要有两个作用
- 通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。
Spring
补充
什么是 Spring 框架?
Spring ( 5.3) SpringBoot 2.4
Spring 框架是一个为 Java 应用程序的开发提供了综合、广泛的基础性支持的 Java 平台。
Spring 帮助开发者解决了开发中基础性的问题,使得开发人员可以专注于应用程序的开发。
在我看来Spring就是功能的集合体,比如DATA模块,可以很方便的集成各种数据库,并开发使用.
使用Spring的优势
基于Spring框架的模块来说好处,比如Spring的Web模块,可以很方便的实现一个Web服务
0.) Spring框架架构图
1.) spring 支持集中 bean scope?
Spring bean 支持 5 种 scope:
Singleton – 每个 Spring IoC 容器仅有一个单实例。Prototype – 每次请求都会产生一个新的实例。Request – 每一次 HTTP 请求都会产生一
个新的实例,并且该 bean 仅在当前 HTTP 请求内有效。Session – 每一次 HTTP 请求都会产生一个新的 bean,同时该 bean 仅在当前
HTTP session 内有效。Global-session – 类似于标准的 HTTP Session 作用域,不过它仅仅在基于portlet 的 web 应用中才有意义.
2.) Spring 中的 bean 生命周期?
3.) Spring的AOP理解
4.) Spring 事务
Mycat
SpringCloud
0.) 体系架构图
1.) SpringCloud概述
Spring Cloud 就是微服务框架,在构建微服务的过程中需要做如 服务发现注册 、配置中心 、消息总线 、负载均衡 、断路器 、数据监控 等操作,Spring Cloud 为我们提供了一套简易的编程模型,使我们能在 Spring Boot 的基础上轻松地实现微服务项目的构建。
2.) 注册中心 Eureka
- Eureka重要概念
- Eureka和Zookeeper对比
Zookeeper保证了CP(C:一致性,P:分区容错性),Eureka保证了AP(A:高可用)当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的信息,但不能容忍直接down掉不可用。
也就是说,服务注册功能对高可用性要求比较高,但zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新选leader。问题在于,选取leader时间过长,30 ~ 120s,且选取期间zk集群都不可用,这样就会导致选取期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够恢复,但是漫长的选取时间导致的注册长期不可用是不能容忍的。- Eureka保证了可用性,Eureka各个节点是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点仍然可以提供注册和查询服务。
而Eureka的客户端向某个Eureka注册或发现时发生连接失败,则会自动切换到其他节点,只要有一台Eureka还在,就能保证注册服务可
用,只是查到的信息可能不是最新的。
3.) 负载均衡之 Ribbon
-
Ribbon概述
- Ribbon 是 Netflix 公司的一个开源的负载均衡 项目,是一个客户端/进程内负载均衡器,运行在消费者端。
-
Ribbon的工作原理
- 通过获取所有的服务列表,通过负载均衡算法,选取一个合适的服务,然后向这个服务发起请求.
-
Nginx 和 Ribbon 的对比
- Nignx ,它是一种集中式的负载均衡器。(运行在服务器端)
- Request ,在 Nginx 中请求是先进入负载均衡器,而在 Ribbon 中是先在客户端进行负载均衡才进行请求的。
-
Ribbon的负载均衡算法
- RoundRobinRule:轮询策略。Ribbon 默认采用的策略。若经过一轮轮询没有找到可用的 provider,其最多轮询 10 轮。若最终还没有找到,则返回 null。
- RandomRule: 随机策略,从所有可用的 provider 中随机选择一个。
- RetryRule: 重试策略。先按照 RoundRobinRule 策略获取 provider,若获取失败,则在指定的时限内重试。默认的时限为 500 毫秒。
4.) Open Feign
- Feign简介
- Feign是一种声明式、模板化的HTTP客户端.在Spring Cloud中使用Feign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问HTTP请求。 OpenFeign 也是运行在消费者端的,使用 Ribbon 进行负载均衡,所以 OpenFeign 直接内置了
Ribbon
。支持Hystrix
和它的Fallback。
- Feign是一种声明式、模板化的HTTP客户端.在Spring Cloud中使用Feign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问HTTP请求。 OpenFeign 也是运行在消费者端的,使用 Ribbon 进行负载均衡,所以 OpenFeign 直接内置了
5.) Hystrix
- Hystrix简介
- Hystrix 就是一个能进行 熔断 和 降级 的库,通过使用它能提高整个系统的弹性。
- 所谓 熔断 就是服务雪崩的一种有效解决方案。当指定时间窗内的请求失败率达到设定阈值时,系统将通过 断路器 直接将此请求链路断开。也就是我们上面服务B调用服务C在指定时间窗内,调用的失败率到达了一定的值,那么 Hystrix 则会自动将 服务B与C 之间的请求都断了,以免导致服务雪崩现象。其实这里所讲的 熔断 就是指的 Hystrix 中的 断路器模式 ,你可以使用简单的 @HystrixCommand 注解来标注某个方法,这样 Hystrix 就会使用 断路器 来“包装”这个方法,每当调用时间超过指定时间时(默认为1000ms),断路器将会中断对这个方法的调用。
- 降级是为了更好的用户体验,当一个方法调用异常时,通过执行另一种代码逻辑来给用户友好的回复。这也就对应着 Hystrix 的 后备处理 模式。你可以通过设置 fallbackMethod 来给一个方法设置备用的代码逻辑。
6.) Zuul网关
- 作为边界服务应用,ZUUL 是为了实现动态路由、监视、弹性和安全性而构建的。
7.) 总线Bus
- Spring Cloud Bus 的作用就是管理和广播分布式系统中的消息,也就是消息引擎系统中的广播模式。
微服务
0.) 微服务的 优点
独立开发 – 所有微服务都可以根据各自的功能轻松开发
独立部署 – 基于其服务,可以在任何应用程序中单独部署它们
故障隔离 – 即使应用程序的一项服务不起作用,系统仍可继续运行
混合技术堆栈 – 可以使用不同的语言和技术来构建同一应用程序的不同服务
粒度缩放 – 单个组件可根据需要进行缩放,无需将所有组件缩放在一起
1.) 微服务和SOA区别
ElasticsSearch
0.) ElasticSearch定义
Elasticsearch是一个高度可扩展的开源全文本搜索和分析引擎。它使您可以快速,近乎实时地存储,搜索和分析大量数据.
1.) 索引(插入数据)
请求节点,节点收到请求,根据文档ID(一般是我们存在数据库中的主键ID)的hash值,摩分片数等到具体的分片数值,找到对应分片,插入数据之后,想其他副本分片上同步数据,所有副本同步成功之后,向协助节点报告索引成功.协助节点(路由节点)向客户端表示插入成功.
1、当分片所在的节点接收到来自协调节点的请求后,会将请求写入到 Memory Buffer,然后定时(默认是每隔 1 秒)写入到 Filesystem Cache,这个从 MomeryBuffer 到Filesystem Cache 的过程就叫做 refresh;
2、当然在某些情况下,存在 Momery Buffer 和 Filesystem Cache 的数据可能会丢失,ES 是通过 translog 的机制来保证数据的可靠性的。其实现机制是接收到请求后,同时也会写入到 translog 中,当 Filesystem cache 中的数据写入到磁盘中时,才会清除掉,这个过程叫做 flush;
3、在 flush 过程中,内存中的缓冲将被清除,内容被写入一个新段,段的 fsync将创建一个新的提交点,并将内容刷新到磁盘,旧的 translog 将被删除并开始一个新的translog。
4、flush 触发的时机是定时触发(默认 30 分钟)或者 translog 变得太大(默认为 512M)时
2.) 搜索
1、搜索被执行成一个两阶段过程,我们称之为 Query Then Fetch;
2、在初始查询阶段时,查询会广播到索引中每一个分片拷贝(主分片或者副本分片)。 每个分片在本地执行搜索并构建一个匹配文档的大小为 from + size 的优先队列。
PS:在搜索的时候是会查询 Filesystem Cache 的,但是有部分数据还在 MemoryBuffer,所以搜索是近实时的。
3、每个分片返回各自优先队列中 所有文档的 ID 和排序值 给协调节点,它合并这些值到自己的优先队列中来产生一个全局排序后的结果列表。
4、接下来就是 取回阶段,协调节点辨别出哪些文档需要被取回并向相关的分片提交多个 GET 请求。每个分片加载并 丰富 文档,如果有需要的话,接着返回文档给协调节点。一旦所有的文档都被取回了,协调节点返回结果给客户端。
5、补充:Query Then Fetch 的搜索类型在文档相关性打分的时候参考的是本分片的数据,这样在文档数量较少的时候可能不够准确,DFS Query Then Fetch 增加了一个预查询的处理,询问 Term 和 Document frequency,这个评分更准确,但是性能会变差。*
3.)选举
1.Elasticsearch 的选主是 ZenDiscovery 模块负责的,主要包含 Ping(节点之间通过这个 RPC 来发现彼此)和 Unicast(单播模块包含一个主机列表以控制哪些节点需要 ping通)这两部分;
2、对所有可以成为 master(候选节点) 的节点(node.master: true)根据 nodeId 字典排序,每次选举每个节点都把自己所知道节点排一次序,然后选出第一个(第 0 位)节点,暂且认为它是 master 节点。
3、如果对某个节点的投票数达到一定的值(可以成为 master 节点数 n/2+1)并且该节点自己也选举自己,那这个节点就是 master。否则重新选举一直到满足上述条件。
4、补充:master 节点的职责主要包括集群、节点和索引的管理,不负责文档级别的管理;data 节点可以关闭 http 功能*
4. 更新和删除
1、删除和更新也都是写操作,但是 Elasticsearch 中的文档是不可变的,因此不能被删除或者改动以展示其变更;
2、磁盘上的每个段都有一个相应的.del 文件。当删除请求发送后,文档并没有真的被删除,而是在.del 文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。当段合并时,在.del 文件中被标记为删除的文档将不会被写入新段。
3、在新的文档被创建时,Elasticsearch 会为该文档指定一个版本号,当执行更新时,旧版本的文档在.del 文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文
档依然能匹配查询,但是会在结果中被过滤掉。
zookeeper
0.) Zookeeper概述
- ZooKeeper 是一个开源的
分布式协调服务
,它的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。
1.) ZooKeeper 典型应用场景
- 我们介绍到使用其通常被用于实现诸如
数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列
等功能。 - 下面选 3 个典型的应用场景来专门说说:
1. 分布式锁 : 通过创建唯一节点获得分布式锁,当获得锁的一方执行完相关代码或者是挂掉之后就释放锁。
2. 命名服务 :可以通过 ZooKeeper 的顺序节点生成全局唯一 ID
3. 数据发布/订阅 :通过 Watcher 机制 可以很方便地实现数据发布/订阅。当你将数据发布到 ZooKeeper 被监听的节点上,其他机器可通过监听 ZooKeeper 上节点的变化来实现配置的动态更新。
2.) ZooKeeper 特点
顺序一致性
: 从同一客户端发起的事务请求,最终将会严格地按照顺序被应用到 ZooKeeper 中去。原子性
: 所有事务请求的处理结果在整个集群中所有机器上的应用情况是一致的,也就是说,要么整个集群中所有的机器都成功应用了一个事务,要么都没有应用。单一系统映像
: 无论客户端连到哪一个 ZooKeeper 服务器上,其看到的服务端数据模型都是一致的。可靠性
: 一旦一次更改请求被应用,更改的结果就会被持久化,直到被下一次更改覆盖。
3.) ZNode的数据结构
-
每个 znode 由 2 部分组成:
stat :状态信息(包含大量信息) data : 节点存放的数据的具体内容
-
通过 get 命令来获取 根目录下的 dubbo 节点的内容。
[zk: 127.0.0.1:2181(CONNECTED) 6] get /dubbo //该数据节点关联的数据内容为空 null //下面是该数据节点的一些状态信息,其实就是 Stat 对象的格式化输出 cZxid = 0x2 ctime = Tue Nov 27 11:05:34 CST 2018 mZxid = 0x2 mtime = Tue Nov 27 11:05:34 CST 2018 pZxid = 0x3 cversion = 1 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 0 numChildren = 1
-
stat中包含的信息
4.) Watcher(事件监听器)
- Watcher(事件监听器),是 ZooKeeper 中的一个很重要的特性。ZooKeeper 允许用户在指定节点上注册一些 Watcher,并且在一些特定事件触发的时候,ZooKeeper 服务端会将事件通知到感兴趣的客户端上去,该机制是 ZooKeeper 实现分布式协调服务的重要特性。
5.) 会话
- Session 可以看作是 ZooKeeper 服务器与客户端的之间的一个 TCP 长连接,通过这个连接,客户端能够通过心跳检测与服务器保持有效的会话,也能够向 ZooKeeper 服务器发送请求并接受响应,同时还能够通过该连接接收来自服务器的 Watcher 事件通知。
- Session 有一个属性叫做:sessionTimeout ,sessionTimeout 代表会话的超时时间。当由于服务器压力太大、网络故障或是客户端主动断开连接等各种原因导致客户端连接断开时,只要在sessionTimeout规定的时间内能够重新连接上集群中任意一台服务器,那么之前创建的会话仍然有效。
- 另外,在为客户端创建会话之前,服务端首先会为每个客户端都分配一个 sessionID。由于 sessionID是 ZooKeeper 会话的一个重要标识,许多与会话相关的运行机制都是基于这个 sessionID 的,因此,无论是哪台服务器为客户端分配的 sessionID,都务必保证全局唯一。
6.) ZAB 协议介绍
ZAB(ZooKeeper Atomic Broadcast 原子广播) 协议是一种支持崩溃恢复的原子广播协议。 主要依赖 ZAB 协议来实现分布式数据一致性,基于该协议,ZooKeeper 实现了一种主备模式的系统架构来保持集群中各个副本之间的数据一致性。
- ZAB 协议两种基本的模式:崩溃恢复和消息广播
- 崩溃恢复 :当整个服务框架在启动过程中,或是当 Leader 服务器出现网络中断、崩溃退出与重启等异常情况时,ZAB 协议就会进入恢复模式并选举产生新的Leader服务器。当选举产生了新的 Leader 服务器,同时集群中已经有过半的机器与该Leader服务器完成了状态同步之后,ZAB协议就会退出恢复模式。其中,所谓的状态同步是指数据同步,用来保证集群中存在过半的机器能够和Leader服务器的数据状态保持一致。
- 消息广播 :当集群中已经有过半的Follower服务器完成了和Leader服务器的状态同步,那么整个服务框架就可以进入消息广播模式了。 当一台同样遵守ZAB协议的服务器启动后加入到集群中时,如果此时集群中已经存在一个Leader服务器在负责进行消息广播,那么新加入的服务器就会自觉地进入数据恢复模式:找到Leader所在的服务器,并与其进行数据同步,然后一起参与到消息广播流程中去。
KAFKA
为什么KAFKA那么快
主要从读写两方面.
- 写
- 顺序写入:kafka的消息都写入 分片中,采用的是追加方式.每个消费者对应一个topic都维护一个偏移量offset,这个offset保存在客户端的SDK中,kafka将SDK保存在zookeeper中.
- memory Mapper file (mmap):将磁盘中的文件映射到内存中,对内存的修改会直接(适当)修改磁盘文件.
- 读
- sendfile技术 零复制,减少cope次数,减少读取时间
- 批量压缩,减少网络IO时间,读取时候,直接将分区文件压缩之后发送.
总结:Kafka速度的秘诀在于,它把所有的消息都变成一个批量的文件,并且进行合理的批量压缩,减少网络IO损耗,通过mmap提高I/O速度,写入数据的时候由于单个Partion是末尾添加所以速度最优;读取数据的时候配合sendfile直接暴力输出。
高并发解决方案
高并发解决思路与手段
扩容:水平扩容、垂直扩容
缓存:Redis(削峰,减少同时请求的数目)
队列:Kafka、RabitMQ、RocketMQ等(异步,同样达到削峰的操作)
应用拆分:服务化Dubbo与微服务Spring Cloud
限流:Guava RateLimiter使用、常用限流算法、自己实现分布式限流等
服务降级与服务熔断:服务降级的多重选择、Hystrix
数据库切库,分库分表:切库、分表、多数据源(mycat)
设计模式
设计 原则
- 开闭原则,对扩展开发,对修改关闭
- 里氏代换原则,基类出现的地方,子类一定可以出现
- 依赖倒转原则,依赖于抽象,而不依赖与具体.
- 接口隔离原则,多个接口比一个接口要好,解耦
- 迪米特法则,一个实体类应该尽量少知道其他实体,解耦
- 合成复用法则,尽量使用聚合而不是继承,
- 单一职责:一个类只负责一个职责
设计模式
- 静态工厂模式(根据参数,返回不同的具体对象)
- 工厂模式,每次需要产品实例,通过实现工厂接口创建具体工厂类,返回对应的产品实例.
- 抽象工厂模式,引入产品族概念,一个工厂 可以产出多个产品.
分布式相关概念
分布式系统的经典基础理论
- CAP定理
- 一致性(Consistency) : 客户端知道一系列的操作都会同时发生(生效)
- 可用性(Availability) : 每个操作都必须以可预期的响应结束
- 分区容错性(Partition tolerance) : 即使出现单个组件无法可用,操作依然可以完成
- BASE
- Basically Available(基本可用)
- Soft state(软状态)
- Eventually consistent(最终一致性)
常见的分布式事务解决方案
-
XA两阶段提交
XA协议比较简单,而且一旦商业数据库实现了XA协议,使用分布式事务的成本也比较低。但是,XA也有致命的缺点,那就是性能不理想,特别是在交易下单链路,往往并发量很高,XA无法满足高并发场景。XA目前在商业数据库支持的比较理想,在mysql数据库中支持的不太理想,mysql的XA实现,没有记录prepare阶段日志,主备切换回导致主库与备库数据不一致。许多nosql也没有支持XA,这让XA的应用场景变得非常狭隘。 -
消息事务+最终一致性
基于消息中间件的两阶段提交往往用在高并发场景下,将一个分布式事务拆成一个消息事务(A系统的本地操作+发消息)+B系统的本地操作,其中B系统的操作由消息驱动,只要消息事务成功,那么A操作一定成功,消息也一定发出来了,这时候B会收到消息去执行本地操作,如果本地操作失败,消息会重投,直到B操作成功,这样就变相地实现了A与B的分布式事务.
-
本地消息表
-
TCC编程模式
所谓的TCC编程模式,也是两阶段提交的一个变种。TCC提供了一个编程框架,将整个业务逻辑分为三块:Try、Confirm和Cancel三个操作。以在线下单为例,Try阶段会去扣库存,Confirm阶段则是去更新订单状态,如果更新订单失败,则进入Cancel阶段,会去恢复库存。总之,TCC就是通过代码人为实现了两阶段提交,不同的业务场景所写的代码都不一样,复杂度也不一样,因此,这种模式并不能很好地被复用。
网络
TCP首部20字节,UDP首部8字节。
TCP 协议
熟悉TCP报文结构
三次握手和四处回收涉及的位置.
SYN是状态位,seq是序号位,ACK是接受状态位,ack是确认状态位,FIN结束报文段,RST重新建立连接
三次握手
第三次握手的时候丢包
服务器收到SYN包后发出SYN+ACK数据包,服务器进入SYN_RECV状态。而这个时候客户端发送ACK给服务器失败了,服务器没办法进入ESTABLISH状态,这个时候肯定不能传输数据的,不论客户端主动发送数据与否,服务器都会有定时器发送第二步SYN+ACK数据包,如果客户端再次发送ACK成功,建立连接。如果一直不成功,服务器肯定会有超时设置,超时之后会给客户端发RTS报文,进入CLOSED状态,这个时候客户端应该也会关闭连接。
四次挥手
UDP
UDP是传输层的协议,功能即为在IP的数据报服务之上增加了最基本的服务:复用和分用以及差错检测。