开发服务端程序,在存在并发请求场景下,需要考虑一些常规事项简单梳理和总结

来源:互联网 发布:软件下载模板 编辑:程序博客网 时间:2024/06/03 16:52

1.提升性能:


1.1 措施:

为了单机(单个机器(一般是虚拟机))单实例(单个程序进程)处理更多的网络请求,一般的做法是:
专门的线程负责接受请求搭配专门的工作线程进行业务处理和响应;

1.2 引入的问题

需要面对问题如下:

  • 专门接受请求的线程如何把请求传递给工作线程(即工作交接问题)

  • 由于请求需要被传递,再加上并发场景,请求那么多,如何唯一标识请求。唯一标识请求同时也是为了把相对应的业务处理结果响应给请求(如果请求是请求-应答的场景);

  • 针对不同的请求进行处理,处理的结果如何暂存(不暂存的话,直接由工作线程写socket等),并交付给进行响应的线程(这个响应的线程可能是接受请求的线程,也可能是工作线程,比如写socke,或者其他)

  • 由于业务处理模块引入了多线程,那么需要考虑共享资源的并发访问的安全问题,需要同步的进行同步(同步分为进程内多线程间的同步,可以叫做局部同步,也有多个进程间的同步,叫做分布式同步,或者全局同步),根据同步的粒度不同,可以搭配不同的技术,特别注意的是如果是分布式同步(比如减库存),那么就需要一个分布式同步(可以借鉴zookeeper的分布式同步或者redis的分布式同步技术,这些技术都有自己的使用优势劣势,需要仔细分析和权衡)

  • 服务端的代码不仅仅要提供更强大的服务能力,同时也要有保护自己以及下游(基础服务)的能力;具体的常规应对措施有:限流(可以从请求源的角度来限流,比如同一个ip每秒只能请求多少次;也可能从服务自身的处理能力做整体把控限流,比如每秒只能处理多少次请求,或者其他的限流策略),限流的技术有一些可以借鉴的,比如令牌桶算法,计数器,漏桶算法等

  • 上面的一条可以保护服务自己本身和下游(比如DB的压力,当然保护DB还有其他办法,比如缓存等,但是缓存会有引入其他的问题,比如实时性,一致性,这个需要具体分析和权衡),那么针对当前不能处理,但是接收到的请求如何处理,是直接丢弃(比如返回错误码和错误信息进行快速响应)还是缓存稍后合理的时候(比如按照请求时间早晚的优先级进行入队列进行暂存,等服务可以处理了再处理呢)进行再处理呢?针对这个问题,可以借鉴Java的多线程的饱和策略,然后具体问题具体权衡。

0 0
原创粉丝点击