SpringCloud有哪些常用组件,作用是什么?
一、Eureka:注册中心
二、Nacos:注册配置中心
三、Consul注册配置中心
四、SpringCloud Config:配置中心
五、Feign/OpenFeigh:RPC调用
六、Kong:服务网关
七、Zuul:服务网关
八、SpringCloud Gateway:服务网关
九、Ribbon:负载均衡
十、SpringCloud Sleuth:链路追踪
十一、Zipkin:链路追踪
十二、Seata:分布式事务
十三、Dubbo:RPC调用
十四、Sentinel:服务熔断
十五、Hystrix:服务熔断
分布式ID
在开发中,我们需要一个唯一ID来标识数据。如果是单体系统,可以通过数据库的主键,或者在内存中维护一个自增数字作为ID。但在分布式系统中,可能出现ID冲突,有以下解决方案:
一、UUID:实现简单,但影响存储空间和性能。
二、单机数据库自增主键作为分布式ID,ID长度比UUID短,但数据库性能差,无法处理高并发。
三、利用redis,zk的特性来生成ID,比如redis的自增命令,zk的顺序结点,比mysql性能高。
四、雪花算法:利用雪花算法生成ID,最好。
雪花算法原理:利用64位bit位来生成ID,在Java中相当于一个longlong类型。
第一位固定为0,41位事件戳,10位机器ID,12位序列位。
优点:
一、每毫秒包含id值很多,不够可变动位数,性能好
二、顺序为时间戳,机器码,自增序列位,整个ID趋势递增。
三、可根据业务场景灵活调整bit位划分,很灵活。
缺点:
依赖于机器时钟,如果时钟回拨,会导致重复ID生成。所以一般发现时钟回拨,会抛异常阻止ID生成,可能导致服务不可用。
分布式锁使用场景,以及有哪些实现方案?
在单体架构中,多个线程属于同一进程,资源竞争时,可使用sync、lock等方案作为锁控制共享资源的使用。
但分布式架构中,多个线程属于不同进程,这些线程并发竞争资源时,sync、lock等方案无法控制,所以需要分布式锁。意思是,需要一个分布式锁生成器,分布式中的应用程序都使用这个生成器生成的锁,达到不同进程的多个线程使用同一把锁。
方案:
一、zk,利用zk的临时结点,顺序结点、watch机制来实现。zk分布式锁的特点是高一致性,因为zk保证的是CP,所以实现的分布式锁更可靠,一致性强。
二、redis,利用redis的setnx、lua脚本、消费订阅机制来实现。redis分布式锁到特点是高可用,因为保证的是AP,所以可能不可靠,不稳定(一旦redis中出现了不一致)可能会出现多个客户端同时加到锁的情况。
分布式事务?实现方案?
在分布式系统中,一次业务处理可能需要多个应用来实现。比如用户发送一次下单请求,就涉及到订单系统创建和减库存。要保证同时失败或成功就需要用到分布式事务。解决方案如下:
一、本地消息表:在创建订单时,将减库存消息加入到本地事务中,一起提交数据存入本地消息表,然后调用库存系统减库存,若调用成功则修改本地消息状态为成功;若失败,在本地消息表中取出数据,重新调用库存系统。
二、消息队列:MQ支持分布式事务。
原理:
a:订单系统作为生产者发送一条消息到Broker,该消息对消费者不可见。
b:再创建订单,根据订单成功与否,向broker发送提交或回滚。
c:并且订单系统可以提供回调接口,若Broker一段时间内没有收到任何操作命令,会主动调用该接口来查询订单是否创建成功。
d:如果消息提交,消费者库存系统会进行消费减库存,消费完,消息销毁,事务结束。
e:如果消费失败,则会重试,若还是失败,会进入死信队列,等待处理。
三、Seata:阿里开源的Seata分布式框架,支持AT、TCC多种模式,底层是两阶段提交理论。
说一下分布式事务,并说一下实现方案。
分布式事务是指跨越多个数据库或应用程序的一组事务操作。在分布式系统中,由于涉及到多个节点之间的数据交互和资源协调此需要对事务进行特殊处理,以保证数据的一致性和完整性。
常见的分布式事务实现方案包括以下几种:
-
两阶段提交(2PC):2PC是一种经典的分布式事务实现方案,它通过协调器(coordinator)来协调各个参与者(participant)之间的事务操作。在2PC中,事务分为两个阶段:准备阶段和提交阶段。在准备阶段,协调器会向所有参与者发送“准备提交”请求,参与者执行事务操作并将结果返回给协调器。如果所有参与者都准备就绪,则协调器会向所有参与者发送“提交”请求,参与者执行提交操作。如果其中任何一个参与者出现问题,则协调器会向所有参与者发送“回滚”请求,参与者执行回滚操作,以保证数据的一致性和完整性。
-
补偿事务(TCC):TCC是一种基于补偿机制的分布式事务实现方案,它通过预留资源和补偿操作来保证数据的一致性。在TCC中,事务分为三个阶段:尝试阶段、确认阶段和取消阶段。在尝试阶段,参与者会预留所需的资源,并执行相应的业务逻辑。在确认阶段,协调器会向所有参与者发送“确认提交”请求,参与者执行提交操作。如果其中任何一个参与者出现问题,则协调器会向所有参与者发送“取消提交”请求,参与者执行补偿操作,以保证数据的一致性和完整性。
-
最大努力通知(Best Effort Notification,BEN):BEN是一种基于消息通知的分布式事务实现方案,它通过异步通知和重试机制来保证数据的一致性。在BEN中,事务分为两个阶段:提交阶段和通知阶段。在提交阶段,参与者执行相应的业务逻辑,并将结果存储到本地数据库中。在通知阶段,协调器会向所有参与者发送通知消息,参与者异步地将本地数据发送给其他参与者。如果其中任何一个参与者出现问题,则协调器会重新发送通知消息,直到所有参与者都收到了相应的数据。
4.分布式事务AT(Atomic Transaction)是指在分布式环境下,将多个参与方的本地事务封装成一个全局事务,确保全局事务的原子性。AT分布式事务通常由一个事务协调器(Transaction Coordinator)和多个事务参与方(Transaction Participant)组成。
AT分布式事务的执行过程如下:
-
事务协调器向所有事务参与方发送预提交请求。
-
事务参与方执行本地事务,并将事务执行结果和undo/redo日志记录到本地日志文件中。
-
事务参与方向事务协调器发送确认或回滚请求,确认请求中包含本地事务执行结果和undo/redo日志记录。
-
事务协调器收到所有事务参与方的确认请求后,判断是否所有参与方都执行成功,如果有任何一个参与方执行失败,则向所有参与方发送回滚请求。
-
事务参与方收到回滚请求后,执行undo操作,撤销之前的本地事务操作。
-
如果所有参与方都执行成功,则事务协调器向所有参与方发送提交请求。
-
事务参与方收到提交请求后,执行redo操作,将之前的本地事务操作提交到数据库中。
AT分布式事务的优点是实现简单,性能高,能够保证全局事务的原子性。但是,由于需要进行undo/redo操作,所以系统的可用性会受到一定的影响。同时,如果事务协调器出现故障,整个系统的可用性也会受到影响。
4. Seata是一个开源的分布式事务解决方案,支持多种分布式场景下的事务处理,包括Spring Cloud、Dubbo、SOFARPC等,提供了高效的事务管理、事务状态监控、故障恢复等功能。
Seata的原理是将全局事务分解成多个本地事务,通过事务协调器来管理和协调本地事务的执行,保证全局事务的原子性、一致性和隔离性。Seata的架构包括三个核心组件:事务协调器(Transaction Coordinator)、事务管理器(Transaction Manager)和资源管理器(Resource Manager)。
- 事务协调器(Transaction Coordinator)
事务协调器负责全局事务的协调和管理,包括事务的创建、提交、回滚等。当一个全局事务发起时,事务协调器会生成一个全局事务ID,同时将该事务ID和事务类型(commit或rollback)发送给所有的事务参与方,以便所有事务参与方可以协调执行本地事务。
- 事务管理器(Transaction Manager)
事务管理器负责本地事务的管理,包括本地事务的创建、提交、回滚等。当一个本地事务执行完成后,事务管理器会将事务ID、本地事务ID和事务执行结果发送给事务协调器,以便事务协调器可以协调和管理全局事务。
- 资源管理器(Resource Manager)
资源管理器负责管理分布式事务中的资源,包括数据库、消息队列、缓存等。当一个本地事务执行时,资源管理器会将本地事务ID和事务执行结果记录到本地日志文件中,以便在回滚时可以撤销之前的操作。
总之,Seata通过将全局事务分解成多个本地事务,并通过事务协调器来管理和协调本地事务的执行,保证了分布式场景下的事务处理的原子性、一致性和隔离性。
总之,分布式事务是分布式系统中的重要问题,需要采用适当的实现方案来保证数据的一致性和完整性。不同的实现方案有各自的优缺点,需要根据具体的应用场景进行选择。
SpringCloud和Dubbo有什么区别
SpringCloud是一个微服务框架,提供了很多功能组件,Dubbo是一个RPC调用框架,核心是解决服务调用间的问题、SpringCloud大而全,Dubbo注重服务调用。两者并不对立,可以结合起来一起使用,只需集成即可。
Dubbo的架构设计
Dubbo的分层设计
负载均衡算法、类型
##算法 轮询法、随机法、原地址哈希法、加权轮询法、加权随机法、最小连接数法。
类型
DNS负载均衡:通过域名解析,效率高。
硬件负载均衡
软件负载均衡:Nginx
如何实现接口幂等性
在高并发场景下,相同的参数重复点击保证数据正确。
解决:
唯一ID:每次都根据操作和内容生成唯一ID,执行前判断ID是否存在,如果不存在才会进行后续操作。
服务端提供发送Token的接口,业务调用调用方法前先获取token然后调用方法。服务端收到请求会首先判断token是否在redis中,若存在表示第一次请求,可继续执行业务。业务执行完将token删除。
建去重表:将业务中的唯一字段保存在去重表,如果表中存在,表示已处理过。
版本控制:增加版本号,版本号符合才会执行操作。
状态控制:例如订单中有未支付、支付中、支付失败、已支付等。