浅谈后端高并发的几种设计方法

在高并发的应用场景中,前端需要更快的渲染速度,而后端不仅需要更快的接口速度,而且还需要保证数据的一致性。

前端设计中可能会有静态页面,cdn等的优化手段,在后端架构中,通常也需要引用高并发程序的解决方案。下面主要谈谈后端的处理方案。

分层

后台主要有两块,一块是数据库,一块的业务块,当然业务层里面还可能包含对别的服务调用。

数据库层使用的优化手段

1.分库分表。但是在做设计的时候最好考虑到在不停机的状态下可以对库表进行扩容。

2.sql的优化。查询时指定列名,使用索引,用between代替in......

业务层优化

1.数据来源

这一层是主要讲解的点,其实它可以细分为很多小类。你们姑且认为从前端的请求到请求结束都算业务层,当然这里需要去除掉数据来源。

数据来源分三种:数据库数据其他接口数据缓存中数据

针对数据库数据,上面已经给出了相应的解决方法。

针对调用其他接口数据,当然是依赖的接口响应越快越好,但是需要注意如果下游接口迟迟没有响应结果,需要做超时或者重试机制。说白了就是要cut掉当次请求,不能让这个请求造成整个服务器崩溃(当然这里有点夸张的成分)。

针对缓存中数据,需要考虑到缓存的新鲜度,但是一般来说都是不经常变动的数据适合做缓存。还需要考虑到缓存数据的大小在事先应该做一个评估,不能造成内存不足。解决办法也很简单,要么减少缓存,要么加机器内存。有一点建议需要提一下,尽量对同一个数据缓存一次,比如有一个用户对象,一会用名字和性别做key,一会用名字和年龄做key,一会又。。。这样一个数据被缓存了多次,白白占用内存大小,直接用用户id缓存数据就可,判断逻辑不应该作为key,而应该方法在程序里面去做判断。缓存还需要注意的点有缓存穿透,缓存雪崩,当然有时还会用热点数据。

在自身程序处理的过程中,需要区分业务场景,有些场景是需要及时返回数据的,比如X宝的商品列表页,X东的商品列表页。有些场景是可以不及时相应,比如下单之后半小时之内有短信通知。

针对需要及时响应的场景,接口返回的数据应尽量简单,比如可以做分页返回,相同报文进行抽离等等。

针对不需要及时响应的场景,在高并发的场景下,可以借助消息队列,业界有名的mq有kafka,rabbitmq,rocketmq,zonemq,activemq等等,它们处理1w/s插入应该是没有任何问题的,具体还需要根据自身的业务做进一步的评估。

2.事务的一致性

但是有一个问题似乎忽略掉了,如何保证事务的一致性?

在分布式事务中,有一个有名的cap(一致性,可用性,分区容忍性)理论,事实告诉我们很难三个特性都满足,一般业界用的最多就是使用mq来保证事务的最终一直性(可以有延迟,但是最终正确结果用户还是可以看到的);当然还有x宝的GTX解决方案,它底层是基于2pc来实现了,解决分布式事务也很强劲。

代码设计中如果可以不要锁最好就不使用,如果要使用也优先考虑乐观锁。

3.控制请求

有可能访问量就是很大,而你的服务最多只能承受住1000万的访问量,其他请求你可以用队列做延时等待处理(最好考虑到时效性),也可以抛弃请求。如果有用户恶意刷流量,可以通过代码限制ip访问量,也可以通过nginx限控。

4.服务宕机

服务有的时候并不是100%可靠的,这是需要做服务的熔断处理。服务在一定的时间端内发送的请求都不能响应,那么应该从服务器集群中将这个服务设置到为未可完全使用状态。通过定时机制向集群发送自身的健康状况,如果过一段时间服务好了,那它可以从集群中分一部分流量响应,响应正常的话,使它重新加入集群变为可用状态。如果过一段时间服务还是没有好,集群就将它彻底从服务中删除,并发出告警邮件!

5.响应速度

在高并发的访问中,接口的响应速度需要尽可能的快。从两个方面来谈谈这个问题:

1.jvm层

尽量不要触发full gc,这个过程耗时非常严重,同时young gc的时间也需要尽可能的短,超过1s就要找找耗时点。

2.代码层

使用缓存服务(本地缓存,redis...),使用异步方式(线程池...)调用。

3.系统层

集群....

猜你喜欢

转载自blog.csdn.net/u011381576/article/details/80045119