如果某个进程需要持续地接收新任务,那么其在执行耗时过长的锁或者阻塞操作时,就会出现问题。

  最为常见的例子之一就是:某个进程使用了TCP socket,阻塞在了接收新的连接或者等待消息上面。在执行此类阻塞操作时,消息会不受限制地堆积在消息队列中。 一个更为糟糕的例子是我曾经为lhttpc库的某个分支写的http连接池管理器。在大多数测试用例下,它都工作正常,我们甚至把连接的超时时间设置为10ms,以确保不会耗费太多的时间40。正常工作了几周后,该HTTP连接池导致了一次服务中断,原因是有个远程服务器down机了。 这次恶化背后的原因是:当远程服务器down机后,突然之间,所有的连接操作都至少要耗费10ms的时间,也就是连接超时时间。每秒大约有9,000个消息发给中心进程,通常每个消息的处理时间在5ms之内,这个超时的影响等同于每秒18,000个消息,情况变得失控。 我们的解决方案是,把进行HTTP连接的任务放到调用进程中,并加以限制,感觉仍像是管理器自己在做这件事一样。现在,阻塞操作分布到库的所有使用者之中,管理器要做的工作更少了,可以接受更多的请求。
  当程序中有任何一个点,最终成为接收消息的中心点时,耗时的任务要尽可能从中移出。对于可以预见的过载41,增加更多的进程(它们或者处理阻塞的操作,或者在主进程阻塞时充当缓冲)往往是个不错的方法。 如果某些活动并没有内在的并发要求,那么这种方法会增加进程管理方面的复杂性,所以在这样做之前要确定自己确实有这个需要。 另外一种做法是,把阻塞任务变成异步的。如果场景适用,服务器可以启动一个进程来执行耗时(等待资源)的任务,赋予该进程一个唯一的令牌,把令牌和原始请求者保存起来。当资源可用时,这个进程会把令牌附带在消息中发送给服务器。服务器最终会得到这个消息,通过令牌匹配原始请求者,并发送回应,期间不会被其他请求所阻塞42。 这种做法要比使用多个进程的方法更晦涩一些,也很容易造成回调地狱(callback hell),但是使用的资源要更少些。

最新文章

  1. golang中string以及slice之间的一些问题
  2. Python小练习四
  3. JavaScript语言精粹学习笔记
  4. CameraFlash手电筒
  5. .net framework 4.0 从 GAC 卸载 程序集
  6. OpenCms 集成外部Solr Server
  7. Could not write to output file 'c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\xx'
  8. Web Service-- 使用 JDK 发布 WS
  9. 一些常用的JS函数
  10. WPF 3D:使用GeometryModel3D的BackMaterial
  11. win8和ubuntu双系统
  12. react-native —— 在Mac上配置React Native Android开发环境排坑总结
  13. SPI驱动调试感悟
  14. MySQL5.7基于binary log的主从复制
  15. Android Studio buildGrade文件注解
  16. [CodeForces 471A] MUH and Sticks
  17. 【CSS】元素样式
  18. GCC 多文件编辑
  19. k8s一点
  20. 数字和表达式(python)

热门文章

  1. python 匹配中文和英文
  2. ubuntu 18. use gnome-tweaks
  3. ORM框架greenDao 2 (用于了解旧版本的使用方法,目前最新版本为3.2.2,使用注释的方式来生成)
  4. 让vs IIS Express支持本地静态Json文件
  5. 1-17-Linux中计划任务与日志的管理
  6. nodejs pm2配置使用
  7. MySQL中文入库问题
  8. my.cnf 参数说明
  9. jquery下跨域请求之代码示例
  10. SQL server 数据库用户表名称