0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

高并发服务的几条优化经验

马哥Linux运维 来源:马哥Linux运维 2023-02-09 15:32 次阅读

如何优化高并发服务,这里指的是qps在20万以上的在线服务,注意不是离线服务,在线服务会存哪些挑战呢?

无法做离线缓存,所有的数据都是实时读的

大量的请求会打到线上服务,对于服务的应时间要求较高,一般都是限制要求在300ms以内,如果超过这个时间那么对用户造成的体验就会急剧降

数据量较大,单次如果超过50W的qps,单条1kb,50万就是5GB了,1分钟30G,对于底层的数据存储与问都有巨大的压力~

如何应对这些棘手的问题,本篇博客来讨论一下

一:向关系型数据库 say no

一个真正的大型互联网面向c端的服务都不会直接使用数据库作为自己的存储系统,无论你是采用的是分库分表还是底层用了各种优秀的连接池等,mysql/oracle在面对大型在线服务是存在天然的劣势,再如何优化,也难以抵挡qps大于50万流量带来的冲击。所以换个思路,我们必须使用nosql类缓存系统,比如redis/mermCache等作为自己的"数据库",而mysql等关系型数据库只是一种兜底,用于异步去写作为数据查询的备份系统。

场景举例:京东双11主会场,上架了部分商品,这部分商品都是在会场开始上架的时候直接写入redis中的,当上架完成之后,通过异步消息写入到mysql中。面向c端的查询都是直接读redis,而不是数据库.而b端的查询,可以走数据库去查询。这部分流量不是很高,数据库绝对可以抵挡的住。

二:多级缓存

都知道缓存是高并发提高性能的利器之一。而如何使用好缓存进而利用好多级缓存,是需要我们去思考的问题。

redis目前是缓存的第一首选.单机可达6-8万的qps,在面对高并发的情况下,我们可以手动的水平扩容,以达到应对qps可能无线增长的场景。但是这种做法也存在弊端,因为redis是单线程的,并且会存在热点问题。虽然redis内部用crc16算法做了hash打散,但是同一个key还是会落到一个单独的机器上,就会使机器的负载增加,redis典型的存在缓存击穿和缓存穿透两个问题,尤其在秒杀这个场景中,如果要解决热点问题,就变的比较棘手。这个时候多级缓存就必须要考虑了,典型的在秒杀的场景中,单sku商品在售卖开始的瞬间,qps会急剧上升.而我们这时候需要用memeryCache来挡一层,memeryCache是多线程的,比redis拥有更好的并发能力,并且它是天然可以解决热点问题的。有了memeryCache,我们还需要localCache,本地缓存,这是一种以内存换速度的方式。本地缓存会接入用户的第一层请求,如果它找不到,接下来走memeryCache,然后走redis,这套流程下来可以挡住百万的qps.

三:多线程

我记得在刚开始入行的时候,每次面试都会被问到多线程,那时候是一脸懵逼,多线程有这么厉害吗?干嘛都说多线程,为什么要使用多线程,不用行不行?要讲明这个道理,我先来说一个实例.曾经我优化过一个接口,很典型的一个场景。原始的方式是循环一个30-40万的list,list执行的操作很简单,就是读redis的数据,读一次大概需要3ms左右,这是同步的方式,在预览环境测试,直接30秒+超时。后来优化的方式就是把原有的同步调用改为线程池调用,线程池里的线程数或阻塞队列大小需要自己调优,最后实测接口rt只需要3秒。足以见多线程的威力。在多核服务的今天,如果还不用多线程就是对服务器资源的一种浪费。这里需要说一句,使用多线层一定要做好监控,你需要随时知道线程的状态,如果线程数和queueSize设置的不恰当,将会严重影响业务~ 当然多线程也要分场景,如果为了多线程而多线程反而是一种浪费,因为多线程调度的时候会造成线程在内核态和用户态之间来回切换,如果使用不当反而会有反作用

四: 降级和熔断

降级和熔断是一种自我保护措施,这和电路上的熔断器的基本原理是一样的,防止电流过大引起火灾等,面对不可控的巨大流量请求很有可能会击垮服务器的数据库或者redis,使服务器宕机或者瘫痪造成不可挽回的损失。因为我们服务的本身需要有防御机制,以抵挡外部服务对于自身的侵入导致服务受损引起连带反应。降级和熔断有所不同,两者的区别在于降级是将一些线上主链路的功能关闭,不影响到主链路.熔断的话,是指A请求B,B检测到服务流量多大启动了熔断,那么请求会直接进入熔断池,直接返回失败。如何抉择使用哪一个需要在实际中结合业务场景来考虑.

五: 优化IO

很多人都会忽视IO这个问题,频繁的建联和断联都是对系统的重负。在并发请求中,如果存在单个请求的放大效那么将会使io呈指数倍增加。举个例子,比如主会场的商品信息,如果需要商品的某个具体的详情,而这个详情需要调用下游来单个获取.随着主会场商品的热卖,商品越来越多,一次就要经过商品数X下游请求的数量,在海量的qps请求下,IO数被占据,大量的请求被阻塞,接口的响应速度就会呈指数级下降。所以需要批量的请求接口,所有的优化为一次IO

六: 慎用重试

重试作为对临时异常的一种处理的常见手法,常见应对的方式是请求某个服务失败或者写数据库了重新再试,使用重试一定要注意以下几点

控制好重试次数

重试的间隔时间得衡量好

是否重试要做到配置化。之前我们线上出了一个bug,kafka消费出现了严重的lag,单词消耗时间是10几秒,看代码之后发现是重试的次数过多导致的,并且次数还不支持配置化修改,所以当时的做法只能是临时改代码后上线.重试作为一种业务的二次尝试,极大提升了程序的请求success,但是也要注意以上几点。

七:边界case的判断和兜底

作为互联网老手,很多人写出的代码都不错,但是在经历过几轮的故障review之后发现很多酿成重大事故的代码背后都是缺少对一些边界问题的处理,所犯的错误非常简单,但是往往就是这些小问题就能酿成大事故.曾经review过一次重大的事故,后来发现最终的原因居然是没有对空数组进行判空,导致传入下游的rpc是空的,下游直接返回全量的业务数据,影响数百万用户。这个代码改动起来很简单,但是是令人需要反省的,小小的不足酿成了大祸

八:学会优雅的打印日志

日志作为追溯线上问题的最佳利器,可谓保留bug现场的唯一来源。虽然有arthas这样的利器方便我们排查问题,但是对于一些比较复杂的场景,还是需要日志来记录程序的数据.但是在高流量的场景中,如果全量打印日志对于线上来说就是一种灾难,有以下缺点:

严重占用磁盘,估算以下,如果接口的qps在20万左右,日志一秒就几千兆,一天下来就是上千GB

大量的日志需要输出,占用了程序IO,增加了接口的RT(响应时间) 如果需要解决这个问题,我们可以利用限流组件来实现一个基于限流的日志组件,令牌桶算法可以限制打印日志的流量,比如一秒只允许打印一条日志 - 基于白名单的日志打印,线上配置了白名单用户才可以打印出来,节省了大量了无效日志输出

总结

本篇博客讨论了高并发服务在面对大流量时的一些基本注意事项和应对的点,当然实际线上的比前的更复杂,这里只是给出几条建议,希望我们在高并发的路上保持敬畏,继续探索.更好的深耕c端服务做更好的互联网应用,加油!

审核编辑 :李倩

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 缓存
    +关注

    关注

    1

    文章

    232

    浏览量

    26645
  • 数据库
    +关注

    关注

    7

    文章

    3759

    浏览量

    64266
  • 线程
    +关注

    关注

    0

    文章

    504

    浏览量

    19646

原文标题:高并发服务的几条优化经验

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    android 稳定性并发全平台社交聊天IM对外合作支持源码

    稳定性并发全平台社交聊天IM对外合作支持源码成熟的消息收发确认机制,支持万人大群支持开发自定义的消息sdk接口,扩展性超强支持单/群聊,支持红包/文件等功能模块 支持朋友圈分享等功能同步增加商城
    发表于 03-28 15:20

    在DragonBoard 410c上实现并发处理TCP服务

    ) testServer.serve_forever()到这里我们就完成了整个测试服务器的搭建,该服务器能够借助于gevent实现并发的处理,并且支持异常处理,可以在dragonba
    发表于 09-25 15:53

    服务端视角看并发难题

    `所谓服务器大流量并发指的是:在同时或极短时间内,有大量的请求到达服务端,每个请求都需要服务端耗费资源进行处理,并做出相应的反馈。 从
    发表于 11-02 15:11

    高性能并发服务器架构分享

    由于自己正在做一个高性能大用户量的论坛程序,对高性能并发服务器架构比较感兴趣,于是在网上收集了不少这方面的资料和大家分享。希望能和大家交流 msn: ——————————————————————————————————————
    发表于 09-16 06:45

    Lite Actor:方舟Actor并发模型的轻量级优化

    设备的不断增多,并发模型显得举足轻重,本期我们将为大家带来方舟编译器对传统Actor并发模型的轻量级优化。 一、什么是并发模型?在操作系统中,并发
    发表于 07-18 12:00

    Tomcat7性能优化 强力提升网站并发能力

    Tomcat7性能优化 强力提升网站并发能力
    发表于 09-08 08:34 9次下载
    Tomcat7性能<b class='flag-5'>优化</b> 强力提升网站<b class='flag-5'>并发</b>能力

    大型网站如何解决并发带来的问题

    在不使用消息队列服务器的时候,用户的请求数据直接写入数据库,在并发的情况下数据库压力剧增,使得响应速度变慢。
    发表于 06-28 17:07 2440次阅读
    大型网站如何解决<b class='flag-5'>高</b><b class='flag-5'>并发</b>带来的问题

    一文详谈并发

    并发,几乎是每个程序员都想拥有的经验。原因很简单:随着流量变大,会遇到各种各样的技术问题,比如接口响应超时、CPU load升高、GC频繁、死锁、大数据量存储等等,这些问题能推动我们在技术深度上不断精进。
    的头像 发表于 06-30 17:18 1705次阅读

    阻抗匹配的几条经验分享

    阻抗匹配有点“门当户对”的意思,输入输出阻抗都跟电路的具体设计有关。这里先提供几条经验,大家以后可以慢慢理解。
    的头像 发表于 05-01 16:24 7042次阅读

    几条for循环的常见优化方式

    前言我们都经常使用一些循环耗时计算的操作,特别是for循环,它是一种重复计算的操作,如果处理不好,耗时就比较大,如果处理书写得当将大大提高效率,下面总结几条for循环的常见优化方式。 首先,我们
    的头像 发表于 08-20 09:36 3761次阅读
    <b class='flag-5'>几条</b>for循环的常见<b class='flag-5'>优化</b>方式

    服务器的并发能力如何提升?

    服务器的并发能力如何提升? 服务并发能力体现着服务
    的头像 发表于 03-17 17:07 978次阅读

    存储服务器在并发环境下该如何优化

    在这个信息化时代,每时每刻都有人在访问数据,这就造成了存储服务器的并发,使得存储服务器工作的效率变低。
    的头像 发表于 03-27 15:49 599次阅读

    服务并发的概念

    自己调整系统的相关参数 并发的概念是什么?什么是并发? 对于服务并发的概念,下面几点是错误的定义 ①服务器处理客户端请求的数量:没有时间、
    的头像 发表于 11-10 10:05 4946次阅读
    <b class='flag-5'>服务</b>器<b class='flag-5'>并发</b>的概念

    并发系统的艺术:如何在流量洪峰中游刃有余

    前言 我们常说的三并发可用、高性能,这些技术是构建现代互联网应用程序所必需的。对于京东618备战来说,所有的中台系统服务,无疑都是
    的头像 发表于 08-05 13:43 225次阅读
    <b class='flag-5'>高</b><b class='flag-5'>并发</b>系统的艺术:如何在流量洪峰中游刃有余

    并发物联网云平台是什么

    来看,并发物联网云平台需要具备高效的处理能力和优秀的扩展性,以应对大量的并发请求。这通常需要采用分布式架构,比如微服务架构,以及高效的数据处理技术,如流处理、大数据处理等。 其次,从
    的头像 发表于 08-13 13:50 215次阅读