一篇文了解分布式队列编程:从模型、实战到优化(4)
典型的后台任务处理应用包括工单处理、火车票预订系统、机票选座等.我们所面对的问题是为运营人员创建工单.一次可以为多个运营人员创建多个工单.这个应用场景和火车票购买非常类似.工单相对来说更加抽象,所以,下文会结合火车票购买和运营人员工单分配这两种场景同时讲解. 典型的工单创建要经历两个阶段:数据筛选阶段、工单创建阶段.例如,在火车票预订场景,数据筛选阶段用户选择特定时间、特定类型的火车,而在工单创建阶段,用户下单购买火车票. 挑战工单创建往往会面临如下挑战:
构思如果将用户筛选的最终规则做为消息存储下来,并发送给工单创建系统.此时,工单创建系统将具备创建工单所需的全局信息,具备在满足各种约束的条件下进行统筹优化的能力.如果工单创建阶段采用单实例部署,就可以避免数据锁定问题,同时也意味着没有锁冲突,所以也不会有死锁或任务延迟问题. 居于以上思路,在多工单处理系统的模型中,筛选阶段的规则创建系统将充当生产者角色,工单创建系统将充当消费者角色,筛选规则将作为消息在两者之间进行传递.这就是典型的分布式队列编程架构.根据工单创建量的不同,可以采用数据库或开源的分布式消息中间件作为分布式队列. 架构该架构流程如下图:
采用该架构,我们在数据锁定、运筹优化、原子性问题都能得到比较好成果:
3.优化篇接下来重点阐述工程师运用分布式队列编程构架的时候,在生产者、分布式队列以及消费者这三个环节的注意点以及优化建议. 确定采用分布式队列编程模型之后,主体架构就算完成了,但工程师的工作还远远未结束.天下事必做于细,细节是一个不错的架构向一个优秀的系统进阶的关键因素.优化篇选取了作者以及其同事在运用分布式队列编程模型架构时所碰到的典型问题和解决方案. 这里些问题出现的频率较高,如果你经验不够,很可能会“踩坑”.希望通过这些讲解,帮助读者降低分布式队列编程模型的使用门槛.本文将对分布式队列编程模型的三种角色:生产者(Producer),消费者(Consumer)分别进行优化讨论. 生产者优化在分布式队列编程中,生产者往往并非真正的生产源头,只是整个数据流中的一个节点,这种生产者的操作是处理-转发(Process-Forward)模式. 这种模式给工程师们带来的第一个问题是吞吐量问题.这种模式下运行的生产者,一边接收上游的数据,一边将处理完的数据发送给下游.本质上,它是一个非常经典的数学问题,其抽象模型是一些没有盖子的水箱,每个水箱接收来自上一个水箱的水,进行处理之后,再将水发送到下一个水箱. 工程师需要预测水源的流量、每个环节水箱的处理能力、水龙头的排水速度,最终目的是避免水溢出水箱,或者尽可能地减小溢出事件的概率.实际上流式编程框架以及其开发者花了大量的精力去处理和优化这个问题.下文的缓存优化和批量写入优化都是针对该问题的解决方案. 第二个需要考虑的问题是持久化.由于各种原因,系统总是会宕机.如果信息比较敏感,例如计费信息、火车票订单信息等,工程师们需要考虑系统宕机所带来的损失,找到让损失最小化的解决方案.持久化优化重点解决这一类问题. 缓存优化处于“处理-转发”模式下运行的生产者往往被设计成请求驱动型的服务,即每个请求都会触发一个处理线程,线程处理完后将结果写入分布式队列.如果由于某种原因队列服务不可用,或者性能恶化,随着新请求的到来,生产者的处理线程就会产生堆积.这可能会导致如下两个问题:
(编辑:ASP站长网) |