主要缘由:是在高并发状况下,因为来不及同步处理,请求每每会发生堵塞,好比诸多的insert、update之类的请求同时到达mysql,直接致使无数的行锁表锁,甚至最后请求会堆积不少,从而触发大量的too mang connnections错误。经过消息队列,咱们能够异步处理请求,从而缓解系统的压力。mysql
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------redis
MQ(message queue)是一种跨进程的通讯机制,用于上下游传递消息。sql
mq的特色:数据库
一、先进先出缓存
不能先进先出,都不能说是队列了,消息队列的顺序在入队时基本已经肯定,通常是不须要人工干预的。并且最重要的是,数据是只有一条数据在使用中,这也是mq在众多场景中被使用的缘由。服务器
二、发布订阅多线程
发布订阅是一种很高效的处理方式,若是不发生阻塞,基本能够当作是同步操做。这种处理方式能很是有效的提高服务器利用率,这样的应用场景很是普遍。架构
三、持久化并发
持久化确保MQ的使用不仅是一个部分场景的辅助工具,而是让MQ能像数据库同样存储核心的数据。异步
四、分布式
在如今大流量、大数据的使用场景下,只支持单体应用的服务器软件基本是没法使用的,支持分布式的部署,才能被普遍使用。并且,MQ的定位就是一个高性能的中间件。
应用场景
基于上文所述的特色,那么MQ就衍生出了不少的使用场景,在大型的系统中,应用很是普遍,这里咱们就列举一下常见的应用场景。
应用解耦(异步)
系统之间进行数据交互时,在时效性和稳定性之间咱们都要进行选择;基于线程的异步处理,能确保用户体验,但在极端状况下,可能会出现异常,影响系统的稳定性,而同步调用不少时候没法保证理想的性能,那么咱们就能够用mq来进行处理,上游系统将数据投递到mq,下游系统取mq的数据进行消费,投递和消费能够用同步的方式处理,由于mq接收数据的性能是很是高的,不会影响上游系统的性能,那么下游系统的及时率能保证吗?固然能够,否则就不会有下面的一个应用场景。
通知
这里就用到了前文一个重要的特色,发布订阅,下游系统一直在监听MQ的数据,若是MQ有数据,下游系统则会按照 先进先出 这样的规则, 逐条进行消费 ,而上游系统只须要将数据存入MQ里,这样既下降了不一样系统之间的耦合度,同时也确保了消息通知的及时性,并且也不影响上游系统的性能。
限流
上文有说了一个很是重要的特性,MQ 数据是只有一条数据在使用中。 在不少存在并发,而又对数据一致性要求高,并且对性能要求也高的场景,如何保证,那么MQ就能起这个做用了。无论多少流量进来,MQ都会让你遵照规则,排除处理,不会由于其余缘由,致使并发的问题,而出现不少意想不到脏数据。
数据分发
MQ的发布订阅确定不是只是简单的一对一,一个上游和一个下游的关系,MQ中间件基本都是支持一对多或者广播的模式,并且均可以根据规则选择分发的对象。这样上游的一份数据,众多下游系统中,能够根据规则选择是否接收这些数据,这样扩展性就很强了。
PS:上文中的上游和下游,在MQ更多的是叫作生产者(producer)和消费者(consumer)
分布式事务
分布式事务是咱们开发中一直尽可能避免的一个技术点,可是,如今愈来愈多的系统是基于微服务架构开发,那么分布式事务成为必需要面对的难题,解决分布式事务有一个比较容易理解的方案,就是二次提交。基于MQ的特色,MQ做为二次提交的中间节点,负责存储请求数据,在失败的状况能够进行屡次尝试,或者基于MQ中的队列数据进行回滚操做,是一个既能保证性能,又能保证业务一致性的方案,固然,这个方案的主要问题就是定制化较多,有必定的开发工做量。
应用示例
为了更加直观的展现MQ的应用场景,这里咱们就用一个常见的电商系统中的几个业务,来具体说明下MQ在实际开发中应用场景。
咱们的实际场景大概是一个基于微服务架构的电商系统,分为用户微服务、商品微服务、订单微服务、促销微服务等。基于微服务模式开发的系统,MQ的使用场景更多,下面咱们逐一说明:
一、注册后咱们可能须要作不少初始化的操做,如:调用邮件服务器发送邮件、调用促销服务赠送优惠劵、下发用户数据到客户关系系统等。那么这时候咱们将这些操做去监听MQ,当用户注册成功事后,经过MQ通知其余业务进行操做。确保注册用户的性能。
二、后台发布商品的时候,商品数据须要从数据库中转换成搜索引擎数据(基于elasticsearch),那么咱们应该将商品写入数据库后,再写入到MQ,而后经过监听MQ来生成elasticsearch对应的数据。
三、用户下单后,24小时未支付,须要取消订单。之前咱们多是定时任务循环查询,而后取消订单。实际上,我更推荐相似延迟MQ的方式,避免了不少无效的数据库查询,将一个MQ设置为24小时后才让消费者消费掉,这样很大程度上能减轻服务器压力。
四、支付完成后,须要及时的通知子系统(进销存系统发货,用户服务积分,发送短信)进行下一步操做,可是,支付回调咱们都是须要保证高性能的,因此,我应该直接修改数据库状态,存入MQ,让MQ通知子系统作其余非实时的业务操做。这样能保证核心业务的高效及时。
注意事项
其实,还有很是多的业务场景,是能够考虑用MQ方式的,可是不少时候,也会存在滥用的状况,咱们须要清楚认识咱们的业务场景:
发验证码短信、邮件,这种过度依赖外部,并且时效性能够接收几十秒延迟的,其实更好的方式是多线程异步处理,而不是过多依赖MQ。
秒杀抢购确保库存不为负数,更多的依赖高性能缓存(如redis),以及强制加锁,千万不要依赖消费者最终的返回结果。(实际工做中已经看到好几个这样的案例了)上游-下游 这种直接的处理方式效率确定是比 上游-MQ-下游 方式要高,MQ效率高,是由于,我只是上游-MQ 这个阶段就当作已经成功了