消息中间件
背景
系统的稳定性一直以来是所有企业研发人员所追求的,当出现系统问题时,这时候可以通过日志、系统监控、性能指标等来进行排查,但系统的复杂性、分布式、高并发等导致了很多信息的堆积,这个时候,可能对于工作人员来说,是一件非常头痛的事情。消息中间件,英文简称 MQ,这个名词的出现,可以解决很多事情:比如:复杂的业务中通过 MQ 来减少频繁的业务交互。高并发下,不必及时处理的事务都可以交给 MQ。交易过程中,更是存在很多的事务处理,如果长时间保持长链接以及锁的状态,很有可能造成锁表、锁库,形成死锁。这时候也需要 MQ 来进行消息的缓冲、异步进行,保证系统的稳定、持续的进行下去。不会因为死锁等长时间的循环而导致 cpu、内存的增耗,从而避免出现服务挂掉、宕机等问题。
形形色色的 MQ
事实上,消息中间件的种类越来越多:RabbitMQ、RocketMQ、Kafka 等等。下面给出了一张表展示各种 MQ 特点:
说到这,大家可能要说,还有一种中间件:Redis,的确,Redis 也作为一种中间件,一般用来作为缓存中间件。缓存一些信息,以便数据信息共享、也可以利用其来实现分布式锁,例如实现秒杀、抢单等功能。还会被用作一些订单信息的缓存,防止大量的订单信息被积压而导致服务器的负载很高。总之,Redis 常被用来作为一种缓冲剂使用。
除了上面说的,消息中间件还可以用来抢红包,交易系统的账单记录、流程推送、通知等等。Redis 作为缓存处理器,它的使用,大大的提升了应用的性能与效率,特别是在查询数据的层面上,大大降低了查询数据库的频率。但这也带来了一些问题,其中比较典型的,比如:缓存穿透、缓存击穿、缓存雪崩。
什么是缓存穿透呢?
我们先来看看缓存的查询流程:前端发来请求查询数据时,后端首先会在缓存 Redis 中查询,如果查询到数据,直接返回给前端,流程结束;如果在缓存中未查到数据,则前往数据库查找,此时查询数据后返回给前端,同时会塞进缓存中。还有一种可能就是:查询数据库未查到数据时,会直接返回 NULL。 这种情况下,如果用户不停滴发起请求时,恶意提供数据库中不存在的信息,则在数据库中查到的数据永远都是 NULL。这种数据是不会被塞进缓存的,这种的数据永远会被从数据库中访问,即为恶意攻击式,则很有可能对数据库造成极大的压力,搞哭数据库。这个过程被称为:缓存穿透。缓存永远被直接穿透而直接访问数据库。
解决方案
目前对于缓存穿透,比较典型的解决方案是:当在数据库查询未找到时,将 NULL 返给前端,同时,会将 NULL 塞入缓存,并对对应的 Key 设置一定的过期时间。 这种处理方式在电商的话,用到的较多。
什么是缓存击穿呢?
缓存击穿,是指缓存中某个 Key 在不停的、频繁的被请求,当这个 Key 在某个时刻失效时,持续的高并发请求就会击穿缓存,直接请求数据库,导致数据库的压力在那一时刻猛增。就像水滴石穿。
解决方案
既然这种 key 会被不停的访问、请求,那么可以将其有效期设为一万年,这样,不停的高并发请求,就永不会落在数据库层。
什么是缓存雪崩呢?
缓存雪崩,是指在某个时刻,缓存的 key 集体发生失效,这样导致大量的查询请求落在了数据库层,导致数据库负载过高,甚至会压垮数据库。
解决方案
雪崩的现象,主要在于大量的 key 在同一时刻处于失效状态,所以为了避免这种情况:一般会为 key 设置不同的、随机的失效时间,错开缓存中 key 的失效时间点,从而最终减少数据库压力。
结束福利
开源实战利用 k8s 作微服务的架构设计代码:
欢迎大家 star,多多指教。
关于作者
笔名:Damon,技术爱好者,长期从事 Java 开发、Spring Cloud 的微服务架构设计,以及结合 Docker、K8s 做微服务容器化,自动化部署等一站式项目部署、落地。目前主要从事基于 K8s 云原生架构研发的工作。Golang 语言开发,长期研究边缘计算框架 KubeEdge、调度框架 Volcano 等。公众号 程序猿Damon
发起人。个人微信 MrNull008
,个人网站:Damon | Micro-Service | Containerization | DevOps,欢迎來撩。
欢迎关注:InfoQ
欢迎关注:腾讯自媒体专栏
精彩推荐
欢迎关注
版权声明: 本文为 InfoQ 作者【Xiao8】的原创文章。
原文链接:【http://xie.infoq.cn/article/b61f59e0da98bbd127339bd8c】。文章转载请联系作者。
评论