对于高并发问题,相信很多人都遇到的一个问题,不管是在开发中用到,还是在面试中被问到,为此小编也看过很多文档和博客,感觉感觉都没有真正解决过自己心里的迷惑,因为最近参与了一个分布式的项目,在项目中也用到了消息队列,缓存等一些技术,因此又整理了一下高并发问题的解决方法(这也是小编个人的理解,可能有理解不到位的地方,或者大家在实战当中处理过这样的问题,很欢迎大家能够提出,一起学习一起进步)。
一、什么是高并发
高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。
高并发相关常用的一些指标有响应时间(Response Time),吞吐量(Throughput),每秒查询率QPS(Query Per Second),并发用户数等。
响应时间:系统对请求做出响应的时间。例如系统处理一个HTTP请求需要200ms,这个200ms就是系统的响应时间。
吞吐量:单位时间内处理的请求数量。
QPS:每秒响应请求数。在互联网领域,这个指标和吞吐量区分的没有这么明显。
并发用户数:同时承载正常使用系统功能的用户数量。例如一个即时通讯系统,同时在线量一定程度上代表了系统的并发用户数。
高并发,其实就是使用技术手段使得系统可以并行处理很多的请求!相信对于出现高并发场景的问题大家也都比较清楚:想 抢票,秒杀商品等这些业务,极断的时间内,大量的请求涌向服务器,可能对导致服务器处理不过来,会到在服务器,数据崩溃等情况。
二、解决高并发思路
高并发问题大的方向个人觉得,硬件和软件 两个方面,硬件其实大家都明白了,也就是优化自己的硬件配置等,重点的还是在软件方面。
因为每台服务器的配置都是有峰值,所以这是一个瓶颈!已经达到顶配就没办法啦。所以小编觉得最重要的还是如何减少系统处理请求的时间。以下个个人理解的一个解决思路:
1、使用分布式系统:(目前来说,微服务springcloud比较流行,当然还是阿里的dubbo 等等其他的一些分布式框架,大家可以自行了解),分布式也就是可以将系统分为多个模块,没有模块单独做作为一个服务,这样的话每个服务只要处理改服务的业务就行,比如商城,有个订单服务,注册服务,那么所有的订单请求只走订单服务器,注册其他的一些业务走注册服务和其他服务,所以订单服务就不需要处理处了订单业务之外的其他请求。
2、负载均衡:由多台服务器组成一个服务器集群,处理请求的时候由负载均衡转发器来识别集群中每台服务器的负载量,从而合理的分配请求分发到不同的服务器(大家可以参考一下:https://blog.youkuaiyun.com/AngryFyj/article/details/86504932)。负载均衡和分布式,概念可能有些人会弄混淆,说直白点,负载均衡其实服务器集群中没有服务器做的都是同样的事,相当于copy,而分布式只是把不同模块作为一个服务,但是做的事情不一样。
这里讲一些为什么要用负载均衡处理,比如订单服务,秒杀业务属于订单服务的,也就是说高并发问题是发生在订单服务,所以虽然是分布式,也只是分担了订单服务的部分流量而已,当真正极端事件大量请求订单服务是,一台服务可能还是处理不过来,负载均衡处理也就是服务器集群做为订单服务,那怕中间一台服务器挂了,还有其他的可以继续。
3、消息队列(RabbitMQ):对高并发起到了泄峰的作用
消息(Message)是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象。
消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,由消息系统来确保消息的可靠传递。消息发布者只管把消息发布到 MQ 中而不用管谁来取,消息使用者只管从 MQ 中取消息而不管是谁发布的。这样发布者和使用者都不用知道对方的存在。
对了也就是把一些比较复杂,处理时间比较长的业务异步处理,发送到队列里,从而减少请求的等待响应时间。
4、缓存(redis):比如等待服务的秒杀活动,需要涉及到库存,扣除库存等数据的更新操作,如果直接面向数据库,数据的操作很慢,很容易造成数据崩溃,而还缓存的处理数据每秒十几万次,速度远远高于直接操作数据库,因此这里我们可以把缓存做为数据库来用,可以把一些业务处理写在缓存里来处理。
队列结合缓存,解决秒杀思路:减少数据库访问
- 系统初始化,把商品库存数量加载到redis
- 收到请求,redis预减库存,库存不够,直接返回,否则进入3
- 请求入队,立即返回排队中
- 请求出队,生成订单,减少库存
- 客户端轮询,是否秒杀成功
以上就是小编对高并发处理的一个理解,对应队列,和缓存,这里只讲了为什么要使用,但是是什么,怎么用,没用讲,大家可以自己了解,可能比较片面,大家有更好的建议和方法,欢迎指出。