阿里巴巴网站建设论文wordpress招聘
- 作者: 五速梦信息网
- 时间: 2026年03月21日 10:00
当前位置: 首页 > news >正文
阿里巴巴网站建设论文,wordpress招聘,网络营销推广咨询收费标准,网站推广网络领域拆分#xff1a;如何合理地拆分系统#xff1f; 一般来说#xff0c;强一致性的系统都会牵扯到“锁争抢”等技术点#xff0c;有较大的性能瓶颈#xff0c;而电商时常做秒杀活动#xff0c;这对系统的要求更高。业内在对电商系统做改造时#xff0c;通常会从三个方面…领域拆分如何合理地拆分系统 一般来说强一致性的系统都会牵扯到“锁争抢”等技术点有较大的性能瓶颈而电商时常做秒杀活动这对系统的要求更高。业内在对电商系统做改造时通常会从三个方面入手系统拆分、库存争抢优化、系统隔离优化。
业务拆分的方法有很多最简单便捷的方式是先从上到下做业务流程梳理将流程归类聚合然后从不同的领域聚合中找出交互所需主要实体根据流程中主要实体之间的数据依赖程度决定是否拆分从下到上看把不同的实体和动作拆分成多个模块后再根据业务流程归类划分出最终的模块最终汇总。这个拆分过程用一句话总结就是从上往下看流程从下往上看模块最后综合考虑流程和模块的产出结果。用这种方式能快速拆出模块范围拆分出的业务也会十分清晰。 强一致锁如何解决高并发下的库存争抢问题
由于秒杀场景是库存争抢非常经典的一个应用场景接下来我会结合秒杀需求带你看看如何实现高并发下的库存争抢相信在这一过程中你会对锁有更深入的认识。 锁争抢的错误做法
public class ThreadCounter {private static int count 0;public static void main(String[] args) throws Exception {Runnable task new Runnable() {public void run() {for (int i 0; i 1000; i) {count 1;}}};Thread t1 new Thread(task);t1.start();Thread t2 new Thread(task);t2.start();t1.join();t2.join();cout count count endl;}
}这段代码,count预期是2000但是一般都会小于2000。对于这个情况我们一般都会用到锁或原子操作来保护库存变量 如果是简单 int 类型数据可以使用原子操作保证数据准确 如果是复杂的数据结构或多步操作可以加锁来保证数据完整性。 不过锁操作是很影响性能的在讲锁方式之前我先给你介绍几个相对轻量的方式。
前面我们提到当有大量用户去并行修改一个变量时只有用锁才能保证修改的正确性但锁争抢性能很差那怎么降低锁的粒度、减少锁的争枪呢 举个例子当前商品库存有 100 个我们可以把它放在 10 个 key 中用不同的 Redis 实例保存每个 key 里面保存 10 个商品库存当用户下单的时候可以随机找一个 key 进行扣库存操作。如果没库存就记录好当前 key 再随机找剩下的 9 个 key直到成功扣除 1 个库存。 除了这种方法以外我个人更推荐的做法是使用 Redis 的原子操作因为原子操作的粒度更小并且是高性能单线程实现可以做到全局唯一决策。而且很多原子操作的底层实现都是通过硬件实现的性能很好
redis decr prod_1475_stock_1 incr、decr 这类操作就是原子的我们可以根据返回值是否大于 0 来判断是否扣库存成功。但是这里你要注意如果当前值已经为负数我们需要考虑一下是否将之前扣除的补偿回来。并且为了减少修改操作我们可以在扣减之前做一次值检测整体操作如下
//读取当前库存确认是否大于零
//如大于零则继续操作小于等于拒绝后续
redis get prod_1475_stock_1
1//开始扣减库存、如返回值大于或等于0那么代表扣减成功小于0代表当前已经没有库存
//可以看到返回-2这可以理解成同时两个线程都在操作扣库存并且都没拿到库存
redis decr prod_1475_stock_1
-2//扣减失败、补偿多扣的库存
//这里返回0是因为同时两个线程都在做补偿最终恢复0库存
redis incr prod_1475_stock
0这看起来是个不错的保护库存量方案不过它也有缺点相信你已经猜到了这个库存的数值准确性取决于我们的业务是否能够返还恢复之前扣除的值。如果在服务运行过程中“返还”这个操作被打断人工修复会很难因为你不知道当前有多少库存还在路上狂奔只能等活动结束后所有过程都落地再来看剩余库存量。 而要想完全保证库存不会丢失我们习惯性通过事务和回滚来保障。但是外置的库存服务 Redis 不属于数据库的缓存范围这一切需要通过人工代码去保障这就要求我们在处理业务的每一处故障时都能处理好库存问题。所以很多常见秒杀系统的库存在出现故障时是不返还的并不是不想返还而是很多意外场景做不到。
令牌库存 具体是使用 Redis 中的 list 保存多张令牌来代表库存一张令牌就是一个库存用户抢库存时拿到令牌的用户可以继续支付
//放入三个库存 redis lpush prod_1475_stock_queue_1 stock_1 redis lpush prod_1475_stock_queue_1 stock_2 redis lpush prod_1475_stock_queue_1 stock_3
//取出一个超过0.5秒没有返回那么抢库存失败 redis brpop prod_1475_stock_queue_1 0.5 在没有库存后用户只会拿到 nil。当然这个实现方式只是解决抢库存失败后不用再补偿库存的问题在我们对业务代码异常处理不完善时仍会出现丢库存情况。同时我们要注意 brpop 可以从 list 队列“右侧”中拿出一个令牌如果不需要阻塞等待的话使用 rpop 压测性能会更好一些。 不过当我们的库存成千上万的时候可能不太适合使用令牌方式去做因为我们需要往 list 中推送 1 万个令牌才能正常工作来表示库存。如果有 10 万个库存就需要连续插入 10 万个字符串到 list 当中入库期间会让 Redis 出现大量卡顿。
多库存秒杀 如果产品侧提出“一个商品可以抢多个库存”这样的要求也就是一次秒杀多个同种商品比如一次秒杀两袋大米
这时候你应该发现了在“一个商品可以抢多个库存”这个场景下拆分并没有减少锁争抢次数同时还加大了维护难度。当库存越来越少的时候抢购越往后性能表现越差这个设计已经不符合我们设计的初衷 系统隔离如何应对高并发流量冲击 我曾经在一家教育培训公司做架构师在一次续报活动中我们的系统出现了大规模崩溃。在活动开始有五万左右的学员同时操作大量请求瞬间冲击我们的服务器导致服务端有大量请求堆积最终系统资源耗尽停止响应。我们不得不重启服务并对接口做了限流服务才恢复正常。究其原因我们习惯性地将公用的功能和数据做成了内网服务这种方式虽然可以提高服务的复用性但也让我们的服务非常依赖内网服务。当外网受到流量冲击时内网也会受到放大流量的冲击过高的流量很容易导致内网服务崩溃进而最终导致整个网站无法响应。事故后我们经过详细复盘最终一致认为这次系统大规模崩溃核心还是在于系统隔离性做得不好业务极易相互影响。 如果系统隔离性做得好在受到大流量冲击时只会影响被冲击的应用服务即使某个业务因此崩溃也不会影响到其他业务的正常运转。这就要求我们的架构要有能力隔离多个应用并且能够隔离内外网流量只有如此才能够保证系统的稳定。 为了提高系统的稳定性我们决定对系统做隔离改造具体如下图 也就是说每个内、外网服务都会部署在独立的集群内同时每个项目都拥有自己的网关和数据库。而外网服务和内网必须通过网关才能访问外网向内网同步数据是用 Kafka 来实现的。 网关隔离和随时熔断 网关隔离和随时熔断在这个改造方案中有两种网关外网网关和内网网关。每个业务都拥有独立的外网网关可根据需要调整来对外网流量做限流。当瞬时流量超过系统承受能力时网关会让超编的请求排队阻塞一会儿等服务器 QPS 高峰过后才会放行这个方式比起直接拒绝客户端请求来说可以给用户更好的体验。外网调用内网的接口必须通过内网网关。外网请求内网接口时内网网关会对请求的来源系统和目标接口进行鉴权注册授权过的外网服务只能访问对其授权过的内网接口这样可以严格管理系统之间的接口调用. 同时我们在开发期间要时刻注意内网网关在流量增大的时候要做熔断这样可以避免外网服务强依赖内网接口保证外网服务的独立性确保内网不受外网流量冲击。并且外网服务要保证内网网关断开后仍旧能正常独立运转一小时以上。但是你应该也发现了这样的隔离不能实时调用内网接口会给研发造成很大的困扰。要知道常见外网业务需要频繁调用内网服务获取基础数据才能正常工作而且内网、外网同时对同一份数据做决策的话很容易出现混乱。
减少内网 API 互动 为了防止共享的数据被多个系统同时修改我们会在活动期间把参与活动的数据和库存做推送然后自动锁定这样做可以防止其他业务和后台对数据做修改。若要禁售则可以通过后台直接调用前台业务接口来操作活动期间也可以添加新的商品到外网业务中但只能增不能减。 这样的实现方式既可以保证一段时间内数据决策的唯一性也可以保证内外网的隔离性. 只有保证数据同步是单向的才能取消相互锁定操作。我们可以规定所有库存决策由外网业务服务决定后台对库存操作时必须经过外网业务决策后才能继续操作这样的方式比锁定数据更加灵活。而外网交易后要向内网同步交易结果只能通过队列方式推
后台系统推送数据到 Redis 或数据库中外网服务通过 Kafka 把结果同步到内网扣减库存需通知外网服务扣减成功后方可同步操作。
外网与内网的区别 外网是一般是针对用户端直接对接用户使用需要做公网解析 内网一般是公司技术服务节点不需要公网解析且不对外服务都是外网服务上做单独解析才能访问内网服务访问内网会比公网获取数据速度更快减少了一层解析。
一般大点的公司都会做外网和内网隔离以保障服务安全和稳定。
分布式事务多服务的2PC、TCC都是怎么实现的 目前业界流行微服务DDD 领域驱动设计也随之流行起来。DDD 是一种拆分微服务的方法它从业务流程的视角从上往下拆分领域通过聚合根关联多个领域将多个流程聚合在一起形成独立的服务。相比由数据表结构设计出的微服务DDD 这种方式更加合理但也加大了分布式事务的实现难度。 在传统的分布式事务实现方式中我们普遍会将一个完整的事务放在一个独立的项目中统一维护并在一个数据库中统一处理所有的操作。这样在出现问题时直接一起回滚即可保证数据的互斥和统一性。不过这种方式的服务复用性和隔离性较差很多核心业务为了事务的一致性只能聚合在一起。为了保证一致性事务在执行期间会互斥锁定大量的数据导致服务整体性能存在瓶颈。 好在目前业内有很多实现分布式事务的方式比如 2PC、3PC、TCC 等但究竟用哪种比较合适呢这是我们需要重点关注的。 XA 协议 XA 协议是一个很流行的分布式事务协议可以很好地支撑我们实现分布式事务比如常见的 2PC、3PC 等。而理解了 XA 协议对我们深入了解分布式事务的本质很有帮助。 支持 XA 协议的数据库可以在客户端断开的情况下将执行好的业务结果暂存起来直到另外一个进程确认才会最终提交或回滚事务这样就能轻松实现多个数据库的事务一致性。
在 XA 协议里有三个主要的角色 应用AP应用是具体的业务逻辑代码实现业务逻辑通过请求事务协调器开启全局事务在事务协调器注册多个子事务后业务代码会依次给所有参与事务的子业务下发请求。待所有子业务提交成功后业务代码根据返回情况告诉事务协调器各个子事务的执行情况由事务协调器决策子事务是提交还是回滚有些实现是事务协调器发请求给子服务。 事务协调器TM用于创建主事务同时协调各个子事务。事务协调器会根据各个子事务的执行情况决策这些子事务最终是提交执行结果还是回滚执行结果。此外事务协调器很多时候还会自动帮我们提交事务 资源管理器RM是一种支持事务或 XA 协议的数据资源比如 MySQL、Redis 等。 另外XA 还对分布式事务规定了两个阶段Prepare 阶段和 Commit 阶段。 在 Prepare 阶段事务协调器会通过 xid事务唯一标识由业务或事务协调器生成协调多个资源管理器执行子事务所有子事务执行成功后会向事务协调器汇报。这时的子事务执行成功是指事务内 SQL 执行成功并没有执行事务的最终 commit提交所有子事务是提交还是回滚需要等事务协调器做最终决策。接着分布式事务进入 Commit 阶段当事务协调器收到所有资源管理器成功执行子事务的消息后会记录事务执行成功并对子事务做真正提交。如果 Prepare 阶段有子事务失败或者事务协调器在一段时间内没有收到所有子事务执行成功的消息就会通知所有资源管理器对子事务执行回滚的操作。
我们以购物场景为例在购物的整个事务流程中需要协调的服务有三个用户钱包、商品库存和用户购物订单它们的数据都放在私有的数据库中。
按照业务流程用户在购买商品时系统需要执行扣库存、生成购物订单和扣除用户账户余额的操作 。其中“扣库存”和“扣除用户账户余额”是为了保证数据的准确和一致性所以扣减过程中要在事务操作期间锁定互斥的其他线程操作保证一致性然后通过 2PC 方式对三个服务实现事务协调。 2PC 事务不仅容易理解实现起来也简单。不过它最大的缺点是在 Prepare 阶段很多操作的数据需要先做行锁定才能保证数据的一致性。并且应用和每个子事务的过程需要阻塞等整个事务全部完成才能释放资源这就导致资源锁定时间比较长并发也不高常有大量事务排队。除此之外在一些特殊情况下2PC 会丢数据比如在 Commit 阶段如果事务协调器的提交操作被打断了XA 事务就会遗留在 MySQL 中。而且你应该已经发现了2PC 的整体设计是没有超时机制的如果长时间不提交遗留在 MySQL 中的 XA 子事务就会导致数据库长期被锁表。
3PC 简述。与 2PC 相比3PC 主要多了事务超时、多次重复尝试以及提交 check 的功能。但因为确认步骤过多很多业务的互斥排队时间会很长所以 3PC 的事务失败率要比 2PC 高很多。为了减少 3PC 因资源锁定等待超时导致的重复工作3PC 做了预操作整体流程分成三个阶段CanCommit 阶段为了减少因等待锁定数据导致的超时情况提高事务成功率事务协调器会发送消息确认资源管理器的资源锁定情况以及所有子事务的数据库锁定数据的情况。PreCommit 阶段执行 2PC 的 Prepare 阶段DoCommit 阶段执行 2PC 的 Commit 阶段。总体来说3PC 步骤过多过程比较复杂整体执行也更加缓慢所以在分布式生产环境中很少用到它这里我就不再过多展开了。
TCC 是 Try-Confirm-Cancel 的缩写从流程上来看它比 2PC 多了一个阶段也就是将 Prepare 阶段又拆分成了两个阶段Try 阶段和 Confirm 阶段。TCC 可以不使用 XA只使用普通事务就能实现分布式事务。 首先在 Try 阶段业务代码会预留业务所需的全部资源比如冻结用户账户 100 元、提前扣除一个商品库存、提前创建一个没有开始交易的订单等这样可以减少各个子事务锁定的数据量。业务拿到这些资源后后续两个阶段操作就可以无锁进行了。 在 Confirm 阶段业务确认所需的资源都拿到后子事务会并行执行这些业务。执行时可以不做任何锁互斥也无需检查直接执行 Try 阶段准备的所有资源就行。请注意协议要求所有操作都是幂等的以支持失败重试因为在一些特殊情况下比如资源锁争抢超时、网络不稳定等操作要尝试执行多次才会成功。 最后在 Cancel 阶段如果子事务在 Try 阶段或 Confirm 阶段多次执行重试后仍旧失败TM 就会执行 Cancel 阶段的代码并释放 Try 预留的资源同时回滚 Confirm 期间的内容。注意Cancel 阶段的代码也要做幂等以支持多次执行 最后我们总结一下 TCC 事务的优点并发能力高且无长期资源锁定当然它的缺点也很明显只适合短事务不适合多阶段的事务相关事务逻辑要求幂等存在执行过程被打断时容易丢失数据的情况。
目前市面上有很多优秀的中间件比如 DTM、Seata它们对分布式事务协调做了很多的优化比如过程中如果出现打断情况它们能够自动重试
- 上一篇: 阿里巴巴网站建设公司长沙整合推广
- 下一篇: 阿里巴巴网站建设目标英文搜索网站
相关文章
-
阿里巴巴网站建设公司长沙整合推广
阿里巴巴网站建设公司长沙整合推广
- 技术栈
- 2026年03月21日
-
阿里巴巴网站icp编号怎么查做卡盟网站
阿里巴巴网站icp编号怎么查做卡盟网站
- 技术栈
- 2026年03月21日
-
阿里巴巴外贸网站首页合肥优化推广公司
阿里巴巴外贸网站首页合肥优化推广公司
- 技术栈
- 2026年03月21日
-
阿里巴巴网站建设目标英文搜索网站
阿里巴巴网站建设目标英文搜索网站
- 技术栈
- 2026年03月21日
-
阿里巴巴网站建设销售苏州百度
阿里巴巴网站建设销售苏州百度
- 技术栈
- 2026年03月21日
-
阿里巴巴网站开发用dw制作个人简介网页步骤
阿里巴巴网站开发用dw制作个人简介网页步骤
- 技术栈
- 2026年03月21日






