http://www.zhzq.site
分布式系统,就是一个业务拆分成多个子业务,分布在不同的服务器节点,共同构成的系统称为分布式系统。
服务是分散部署在不同的机器上的,一个服务可能负责几个功能,每个服务之间也是通过rpc或webservice来交互的。
集群:多个人在一起作同样的事。
分布式:多个人在一起作不同的事。
特点:无状态、廉价高效、弹性扩展、无单点故障、性能瓶颈在内部网络通信、并发、缺乏全局时钟
分布式系统存在的问题
数据在多份副本中存储时,各副本中的数据是一致的。
数据的ACID四原则:原子性、一致性、隔离性、持续性。
一致性分类
一个分布式系统不可能同时满足一致性(C:Consistency),可用性(A: Availability)和分区容错性(P:Partition tolerance)这三个基本需求,最多只能同时满足其中的2个。
一致性
目标:
1.商品服务写入主数据库成功, 则想从数据库查询数据也成功
2.商品服务写入主数据库失败,则向从数据库查询也失败
实现:
1.写入主数据库后要数据同步到从数据库,同步有一定延迟。
2.写入主数据库后,在向从数据库同步期间要将从数据库锁定, 等待同步完成后在释放锁,以免在写新数据后,向从数据库查询到旧的数据。
可用性
目标:
1.从数据库接收到数据库查询的请求则立即能够响应数据查询结果
2.从数据库不允许出现响应超时或错误
实现:
1.写入主数据库后要将数据同步到从数据
2.由于要保证数据库的可用性,不可以将数据库中资源锁定
3.即使数据还没有同步过来,从数据库也要返回查询数据, 哪怕是旧数据,但不能返回错误和超时.
分区容错性
目标:
1.主数据库想从数据库同步数据失败不影响写操作
2.其中一个节点挂掉不会影响另一个节点对外提供服务
实现:
1.尽量使用异步取代同步操作,如使用异步方式将数据从主数据库同步到从数据库, 这样节点之间能有效的实现松 耦合;
2.添加数据库节点,其中一个从节点挂掉,由其他从节点提供服务。
BASE:全称:Basically Available(基本可用),Soft state(软状态),和 Eventually consistent(最终一致性)
对CAP中一致性和可用性权衡的结果,即无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。
Basically Available(基本可用):
分布式系统在出现不可预知故障的时候,允许损失部分可用性,比如12306抢票,他给你延时查询,响应非常久,又比如双十一抢购,订单付款时内部出现某种错误,网页这边提示你数据加载失败,让你重试,即不失败也不成果,进入降级处理。
Soft state(软状态):允许系统中的数据存在中间状态,并认为该状态不影响系统的整体可用性,即允许系统在多个不同节点的数据副本之间进行数据同步的过程中存在延迟。
Eventually consistent(最终一致性):最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。
两阶段提交协议,是将整个事务流程分为两个阶段,准备阶段(Preparephase)、提交阶段(commit phase),2是指两个阶段,P是指准备阶段,C是指提交阶段。
准备阶段(Prepare phase):
事务管理器给每个参与者(节点)发送Prepare消息,每个数据库参与者在本地执行事务,并写本地的Undo/Redo日志,此时事务没有提交。(Undo日志是记录修改前的数据,用于数据库回滚, Redo日志是记录修改后的数据,用于提交事务后写入数据文件)
提交阶段(commit phase):
如果事务管理器收到了参与者的执行失败或者超时消息时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据事务管理器的指令执行提交或者回滚操作,并释放事务处理过程中使用的锁资源。
缺点
将 2PC 的提交阶段过程一分为三,形成了由 CanCommit、PreCommit和doCommit三个阶段组成的事务处理协议。
CanCommit:协调者给参与者发送事务响应等待全部回应。
PreCommit:协调者收到全部参与者响应,发送yes让参与者执行事务预提交,并反馈ACK,如果有一个参与者未反馈或者反馈no,中断事务。
doCommit:协调者收到所有参与者的ACK反馈,向所有参与者发送提交指令,参与者完成之后向协调者发送ACK响应,但是有一个问题,也就是进入第三阶段,如果协调者因宕机等原因没有向参与者发送提交doCommit请求或回滚abort请求,参与者到达超时时间自动提交,也就是如果是要准备回滚的话,就出现了问题。
2PC对比3PC
1) 协调者和参与者都设置了超时机制,降低了整个事务的阻塞时间和范围,解决了之前的同步阻塞。
2) 通过CanCommit、PreCommit、DoCommit三个阶段的设计,相较于2PC而言,多设置了一个缓冲阶段保证了在最后提交阶段之前各参与节点的状态是一致的。
3) 3PC协议并没有完全解决数据不一致问题。
此算法用于解决分布式系统一致性问题。
当出现多个参与者,要保证数据事务一致性,就引入了3PC进行协调,协调者也可能宕机,所以协调者也做了集群,当每个参与者发送了不同的指令给协调者,协调者就必须有一个真正的决策者来保证数据的一致性。
提案(Proposal)
提案 (Proposal):Proposal信息包括提案编号 (Proposal ID) 和提议的值 (Value),最终要达成一致的value就在提案里。
Paxos算法的角色
Client:客户端向分布式系统发出请求 ,并等待响应。
Proposer:提案发起者提倡客户请求,试图说服Acceptor对此达成一致,并在发生冲突时充当协调者以推动协议向前发展。
Acceptor:决策者可以接受(accept)提案;如果某个提案被选定(chosen),那么该提案里的value就被选定了。
Learners:最终决策学习者充当该协议的复制因素。
一致性算法的保证
1)在这些被提出的提案中,只有一个会被选定 。
2)如果没有提案被提出,就不应该有被选定的提案。
3)当一个提案被选定后,那么所有进程都应该能学习(learn)到这个被选定的value。
Proposer生成提案之前,应该先去『学习』已经被选定或者可能被选定的value,然后以该value作为自己提出的提案的value。如果没有value被选定,Proposer才可以自己决定value的值。
决策者必须接受收到的第一个提案,当只有一个决策者,那么第一个提案就是最终提案,当多个决策者,以半数以上决策者接收的提案为最终提案,当决策者选定了一个提案,后续提案只能增长序列编号,不能更改提案的值。
当决策者接受了一个提案,就会把这个提案发给所有学习者,来保证数据一致性。
举例,提案者1先发送一个prepare给决策者,并携带一个map,这个map只有key,编号n,value是null,当决策者接受了这个提案,就把当做了最终提案保存了下来,并返回了一个空value回来,这里有一个规则,如果决策者是多个,需要超过半数返回才行,如果没有超过半数,重新提交prepare给决策者,接着提案者1再往map里面放入值,提交给决策者,决策者就把这个map替换了之前的空null的map,并返回ack,如果超过半数返回了ack,此value就被确定,否则重新提交prepare给决策者,当完成后如果又有另一个提案者2提交了提案,他的编号是n+1,决策者接收了,但是决策者已经有最终提案了,这时候他会把value返回给提案者2,让提案者2学习,把自己map集合的value值替换成决策者返回的值,提案者学习完毕,再次提交,这时候决策者就接受了提案者2的提案,把之前的提案进行了替换,而且编号低于n+1的提案会被决策者直接拒绝,这样值没变,保证了数据的一致性,还可以通过编号实现对不符合规则的提案过滤。
保证Paxos算法的活性
假设,两个Proposer依次提出了一系列编号递增的提案,但是每次根据响应塞值提交又因为编号不一致,被另一个提案者编号给递增,导致又恢复到最开始提交prepare,最终陷入死循环,没有value被选定。
解决:通过选取主Proposer,并规定只有主Proposer才能提出议案。这样一来只要主Proposer和过半的Acceptor能够正常进行网络通信,那么只能是主Proposer提出一个编号更高的提案,该提案终将会被批准,这样通过选择一个主 Proposer,整套Paxos算法就能够保持活性。
Raft算法分为两个阶段,首先是选举过程,然后在选举出来的领导人带领进行正常操作,主要用于管理复制日志的一致性算法。
Raft算法三模块:领导人选举、日志复制、安全性。
领导人Leader选举
Raft通过选举一个领导人,然后给予他全部的管理复制日志的责任来实现一致性。
三个角色(任何服务器都可以当三个角色之一):
当服务启动的时候,所有服务器follower都是初始状态,每个服务器都有一个定时器,超时时间为election timeout(一般为150-300ms),当某个服务器达到超时时间,他就成为了候选者,先给自己投上一票,然后发送消息给其他服务器,当其他服务器超过半数收到了他的消息,相当于获取到了选票,他就成了领导者,而其他服务器全部成了跟随者,这时候领导者就开始根据间隔时间向跟随者发送心跳检测包,证明我还活在,也就是心跳机制,而跟随者每次接受到消息,就初始化自己内部的定时器,当某个服务器定时器达到超时时间,没有收到领导者的消息,那么跟随者会觉得领导者挂了,他就摇身一变称为候选者,开始篡位,重复之前的过程,成为领导者,当他成为领导者之后,当前任领导者就算回来了,也只能变成跟随者。
特殊情况:四个服务器,当其中两个服务器同时达到超时成为候选者,并且每个服务器拿到自己一票,另外一个服务器一票,这时候的机制就是这两个服务器重新定时,先达到超时的服务器成为候选者,并发送通知进一步成为选举者。
leader选出后,就开始接收客户端的请求。Leader把请求作为日志条目(Log entries)加入到它的日志中,然后并行的向其他服务器通知发来 AppendEntries RPC复制日志条目请求。每个日志复制请求包括状态机命令和任期号,同时还有前一个日志的任期号和日志索引。状态机命令表示客户端请求的数据操作指令,任期号表示leader的当前任期。follower会使用前一个日志的任期号和日志索引来对比自己的数据,决定是接收还是拒绝复制。leader如果收到follower的拒绝复制响应将会带上更上一次的日志任期号和索引再次要求follower发起复制,无限重试直到所有follower的索引号与leader一致,就表示leader的日志同步到了follower上,后面就等着follower复制请求的执行了。如果超过半数的节点复制日志成功,就可以认为当前数据请求达成了共识,即日志可以commite提交了,leader将这条日志应用到它的状态机,并向客户端返回执行结果。
简言之
1)客户端的每一个请求都包含被复制状态机执行的指令。
2)leader把这个指令作为一条新的日志条目添加到日志中,然后并行发起 RPC 给所有Follower,让他们复制这条信息。
3)Follower响应ACK,如果 follower 宕机或者运行缓慢或者丢包,leader会不断的重试,直到所有的 follower 最终都复制了所有的日志条目。
4)通知所有的Follower提交日志,同时leader提交这条日志到自己的状态机中,并返回给客户端。
注:Follower 不可能比 leader 多出一些已提交(committed)日志,这一点是通过选举上的限制来达成的。
leader 和 follower 日志不一致的场景
通过上述场景我们可以看到,真实世界的集群情况很复杂,那么 raft 是如何应对这么多不一致场景的呢?其实方式很简单暴力,想想 Strong Leader 这个词。
Raft 强制要求 follower 必须复制 leader 的日志集合来解决不一致问题。也就是说,follower 节点上任何与 leader 不一致的日志,都会被 leader 节点上的日志所覆盖。这并不会产生什么问题,因为某些选举上的限制,如果 follower 上的日志与 leader 不一致,那么该日志在 follower 上一定是未提交的。未提交的日志并不会应用到状态机,也不会被外部的客户端感知到。
要使得 follower 的日志集合跟自己保持完全一致,leader 必须先找到二者间最后一次达成一致的地方。因为一旦这条日志达成一致,在这之前的日志一定也都一致(回忆下前文)。这个确认操作是在 AppendEntries RPC 的一致性检查步骤完成的。
Leader 针对每个 follower 都维护一个 next index,表示下一条需要发送给该follower 的日志索引。当一个 leader 刚刚上任时,它初始化所有 next index 值为自己最后一条日志的 index+1。但凡某个 follower 的日志跟 leader 不一致,那么下次 AppendEntries RPC 的一致性检查就会失败。在被 follower 拒绝这次 Append Entries RPC 后,leader 会减少 next index 的值并进行重试。
最终一定会存在一个 next index 使得 leader 和 follower 在这之前的日志都保持一致。极端情况下 next index 为1,表示 follower 没有任何日志与 leader 一致,leader 必须从第一条日志开始同步。
针对每个 follower,一旦确定了 next index 的值,leader 便开始从该 index 同步日志,follower 会删除掉现存的不一致的日志,保留 leader 最新同步过来的。
整个集群的日志会在这个简单的机制下自动趋于一致。此外要注意,leader 从来不会覆盖或者删除自己的日志,而是强制 follower 与它保持一致。
这就要求集群票选出的 leader 一定要具备日志的正确性(原文是 Safety),这也就是前文提到的:选举上的限制。
分布式事务的实现比较复杂,有七种实现方案:
1、基于可靠消息服务(基于可靠消息中间件);
消息队列中间件中,只有阿里提供的RocketMQ在解决了消息的顺序性和重复消息幂等性的基础上,实现了对事务的支持。因而基于RocketMQ,可以实现两阶段提交的分布式事务。
2、最大努力尝试(基于消息中间件);
消息中间件不需要保证可靠性,分布式事务的实现是依靠额外的校对系统或者报警系统(报警后人工处理)来保障的。因而和基于可靠消息服务一样,最大努力尝试的分布式方案只能保证事务的最终原子性和持久性,无法保证一致性和隔离性。
3、TX-LCN(对LCN的实现);
LCN是lock、confirm和notify三个单词的缩写。
LCN的核心原理是通过协调本地事务来实现分布式事务,分布式事务的实现依赖于本地事务(要求本地必须支持事务)。因而基于LCN的分布式事务的ACID特性取决于本地事务的ACID特性。一般来说,如果本地事务都能保证ACID,那么基于LCN的分布式事务也能满足AID。
LCN的步骤是 1、分布式事务操作前先锁定(lock,性能差)所有资源直到异步通知(notify)释放资源;2、执行业务操作,根据操作结果确认(confirm)事务应该提交还是回滚;3、根据第2步中的操作结果异步通知(notify)事务的提交或回滚并最终释放资源。
4、X/Open DTP模型(XA规范,基于两阶段提交);
基于两阶段提交(XA规范),通过在整个提交过程中对资源进行锁定来实现分布式事务,能很好地满足AID特性,以及准实时的最终一致性。此外,该方案同LCN类似,性能低于TCC和TXC。因而在实际应用中,较少有系统会选择该方案。
5、阿里DTS(基于TCC);
在分布式事务操作中,先将所需资源预占,然后将锁释放,最后再根据资源预占的情况来决定使用资源还是退回资源。相比于XA规范,TCC方案采用预留资源的方式,将两阶段提交过程中的全局锁分成了两段本地事务锁,缩短了分布式资源锁定的时间,从而提高了事务的并发度。相对于后面即将介绍的SAGA而言,因为TCC采用预占资源的方式,其补偿动作实现比较简单。当然,TCC的缺点是业务入侵性大,尤其是已有业务如果想使用TCC方案,就需要修改原来的业务逻辑(后面介绍SAGA时还会再强调这一点)。
6、华为ServiceComb(对SAGA模式的实现);
将一个全局事务分成若干个能独立提交的本地事务,每个本地事务都对应一个反向补偿操作,当本地事务提交失败后,通过反向补偿操作来取消本地事务的影响。
相比于TCC,Saga缺少预留动作,导致某些业务的补偿动作的实现比较麻烦,比如业务是发送邮件,在TCC模式下,先保存草稿(Try)再发送(Confirm),撤销的话直接删除草稿(Cancel)就行了。而Saga则就直接发送邮件了(Ti),如果要撤销则得再发送一份邮件说明撤销(Ci)。当然,对于另外一些简单业务来说,Saga没有预留动作也可以认为是优点
7、阿里GTS(开源产品为Fescar,对XA协议改进后的实现)。
GTS,最初名为TXC,是Taobao Transaction Constructor的缩写。阿里分布式事务框架GTS开源了一个免费社区版Fescar。
对业务SQL进行解析,把业务数据在更新前后的数据镜像组织成回滚日志,利用本地事务的ACID特性,将业务数据的更新和回滚日志的写入在同一个本地事务中提交。除此之外,为了保证分布式事务的隔离性,在事务协调器侧还增加了一把全局锁,以保证回滚日志得以顺利执行
对比TCC和Fescar可知,TCC无论事务最终是提交还是回滚,本质上都需要对同一个资源执行两次操作,一次是try,另一次是confirm或者cancel;而对于Fescar来说,大多数情况下,分布式事务都不需要回滚,而对于不需要回滚的分布式事务,每个资源只需要执行一次操作。从这个角度来说,Fescar的平均性能将比TCC更高。
分布式常用设计策略:如何检测当前节点还活着? 如何保障高可用? 容错处理? 负载均衡?
心跳检测机制
心跳顾名思义,就是以固定的频率向其他节点汇报当前节点状态的方式。收到心跳,一般可以认为一个节点和现在的网络拓扑是良好的。心跳汇报时,一般也会携带一些附加的状态、元数据信息,以便管理。
Client请求Server,Server转发请求到具体的Node获取请求结果。Server需要与三个Node节点保持心跳连接,确保Node可以正常工作,若Server没有收到Node3的心跳时,Server认为Node3失联,当Node3不一定是宕机了,可能是网络中断、任务繁忙导致检测超时等等,通过周期检测心跳机制、累计失效检测机制来判断节点是否挂掉,如果真正挂掉,从集群中移除,等恢复后再加进来。
高可用设计
系统架构设计中必须考虑的因素之一,通常是指经过设计来减少系统不能提供服务的时间。
系统高可用性的常用设计模式包括三种:主备(Master-SLave)、互备(Active-Active)和集群(Cluster)模式。
主备模式
最常用的模式,当主机宕机时,备机接管主机的一切工作,待主机恢复正常后,按使用者的设定以自动(热备)或手动(冷备)方式将服务切换到主机上运行,数据库称为MS模式,MySQL、Redis就采用MS模式实现主从复制,保证高可用。
master中所有操作都会以事件的方式记录在二进制日志中,也就是bin-log,其他数据库作为slave通过一个I/O线程与主服务器保持通信,并监控master的二进制日志文件的变化,如果发现master二进制日志文件发生变化,则会把变化复制到自己的relay-log日志中,然后slave的一个SQL线程会把相关的事件执行到自己的数据库中,以此实现从数据库和主数据库的一致性,也就实现了主从复制。
互备模式
两台主机同时运行各自的服务工作且相互监测情况,开启互相备份同步,只有对写要求较高,需要多台数据库服务器存储写入数据,比如微博之类的网站。
集群模式
集群模式是指有多个节点在运行,同时可以通过主控节点分担服务请求。如Zookeeper。集群模式需要解决主控节点本身的高可用问题,一般采用主备模式来把某个节点当做master。
容错性设计
提高系统对于错误包容的能力,保障分布式环境下相应系统的高可用或者健壮性,也提升了系统的安全性。
比如Redis的缓存穿透。
当一个请求进来时,从缓存中查询不到,这时候就会进去数据库查,如果是一个恶意的请求,比如id为-1,这个值根本不存在,制造大量请求进行攻击,越过缓存,数据库服务器可能就会承受不住压力而宕机,这时候就需要一个容错性设计来保证数据库的安全,可以通过布隆过滤器或者在第一次请求,为null时仍然返回一个值存储缓存,并设置一定的过期时间,再次请求就会直接经过缓存返回,来保证系统的高可用。
使用多台集群服务器共同分担计算任务,把网络请求及计算分配到集群可用的不同服务器节点上,从而达到高可用性及较好的用户操作体验。
负载均衡器有硬件解决方案F5,也有软件解决方案Nginx、LVS等等。
负载均衡策略:
1) 轮询:默认就是轮询,根据Nginx配置文件中的顺序,依次把客户端的Web请求分发到不同的后端服务器。
2) 最少连接:当前谁连接最少,分发给谁。
3) IP地址哈希:确定相同IP请求可以转发给同一个后端节点处理,以方便session保持。
4) 基于权重的负载均衡:配置Nginx把请求更多地分发到高配置的后端服务器上,把相对较少的请求分发到低配服务器。
基本原理
网络通信就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络IO来实现,其中传输协议比较出名的有tcp、udp等等,tcp、udp都是在基于Socket概念上为某类应用场景而扩展出的传输协议,网络IO,主要有bio、nio、aio三种方式。其实就是使用不同的传输协议和IO技术实现服务器之间的远程方法调用。
TCP:面向连接的协议,速度不快,安全,因为他要经过三次握手,安全性要求更高四次握手。
UDP:广播协议,面向无连接,速度快,不安全,就是相当于广播一样只管发出去就完事了。
BIO:同步阻塞IO NIO:同步非阻塞IO AIO:异步IO
RPC远程过程调用,核心模块就是通讯和序列化,他不是具体的技术,而是指整个网络远程调用过程,常用RPC实现框架Dubbo、Hessian、HSF等等。
RPC四个核心的组件,分别是Client,Client Stub,Server以及Server Stub,即客户端、客户端存根、服务端、服务端存根。
1) 客户端以接口方式调用客户端存根。
2) 客户端存根收到调用后,把方法、参数等封装成消息体进行序列化成二进制文件,从而在网络中传输。
3) 客户端存根将请求发送给服务器存根。
4) 服务器存根收到消息后对消息体进行反向序列化。
5) 服务端存根根据解码结果调用本地服务端。
6) 服务端进行服务处理,即执行方法并返回结果。
7) 服务端存根收到结果,将结果封装成消息体,并进行序列化成二进制文件。
8) 服务端存根返回消息给客户端存根。
9) 客户端存根收到消息后对消息体进行反序列化解码。
10)客户端存根返回解码结果,客户端得到最终结果。
RPC的目标是要把2、3、4、7、8、9这些步骤都封装起来。
远程方法调用 (Remote Method Invocation),是java原生支持的远程调用 ,采用JRMP(Java Remote Messageing protocol)作为通信协议,纯java版本的分布式远程调用解决方案。
客户端
1)存根/桩(Stub):远程对象在客户端上的代理。
2)远程引用层(Remote Reference Layer):解析并执行远程引用协议。
3)传输层(Transport):发送调用、传递远程方法参数、接收远程方法执行结果。
服务端
1) 骨架(Skeleton):读取客户端传递的方法参数,调用服务器方的实际对象方法,并接收方法执行后的返回值。
2) 远程引用层(Remote Reference Layer):处理远程引用后向骨架发送远程方法调用。
3) 传输层(Transport):监听客户端的入站连接,接收并转发调用到远程引用层。
注册表
URL形式注册远程对象,并向客户端回复对远程对象的引用。
运行过程:首先启动server服务端,向注册表发布对象,再启动客户端,客户端就从注册表获取远程对象引用,接着客户端生成对应的代理对象,也就是Stub桩对象,他和远程对象具有相同的接口和方法列表,接着通过远程引用层Remote Reference Layer进行转化成远程引用对象,传递给传输层Transport,由传输层发送TCP协议到服务端的传输层Transport,接着服务端的传输层调用远程引用层Remote Reference Layer,把远程引用对象转化成服务端本地对象,然后传递给骨架Skeleton,骨架根据请求去调用服务端进行对应方法执行,并获取返回结果,接着骨架Skeleton又一层一层往回返,最终客户端获取结果。
微服务架构是一种架构模式,提倡将单一应用程序划分为一组小的服务,服务之间互相协调、配合,为用户提供最终价值
每个服务以进程方式独立运行,服务之间采用轻量级的通信机制互相协作(通常是HTTP协议的Restfil API)
每个服务围绕具体业务进行构建,并且能够独立的部署到生产环境、类生产环境等
应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据上下文,选择合适的语言、工具对其进行构建
所以测试环境下,多个微服务可以部署在一台机器上。生产环境下,微服务是分布式部署在多台机器的。
分布式服务顾名思义服务是分散部署在不同的机器上的,一个服务可能负责几个功能,是一种面向SOA架构的,服务之间也是通过rpc来交互或者是webservice来交互的。逻辑架构设计完后就该做物理架构设计,系统应用部署在超过一台服务器或虚拟机上,且各分开部署的部分彼此通过各种通讯协议交互信息,就可算作分布式部署。
微服务是将一个软件的功能进行拆分,比如某个功能经常使用或经常不使用,可以将该功能单独的设计为一个微服务。通过RPC(远程接口调用,一般通过网络进行调用不是部署在同一台机器的)对该功能进行调用(该句的内容包含了分布式的内容)。微服务之间可以使用不同的语言进行书写。只要按照约定的规范发送请求和接收数据。
分布式的意思分为两种,一种是将不同微服务进行部署,用以完成某个项目或应用。第二种意思是对同一个应用或功能部署在多台机器上,比如就是一个分布式的应用。还有就是该应用或服务的访问量特别的大,一台服务器可能无法承受该数量的访问,可以将同样的应用或服务部署到多个服务器上,再部署一个带有 负载均衡 算法的服务,就可以将访问的压力分布在各个服务器上,达到提高应用或服务系统抗压的能力。
所以,生产环境下的微服务肯定是分布式部署的,分布式部署的应用却不一定是微服务架构的,比如集群部署是把相同应用复制到不同服务器上,但是逻辑功能上还是单体应用。
Kratos 是一套轻量级 Go 微服务框架,包含大量微服务相关框架及工具。
特性
