背景:
基于openresty + opencv的图片处理服务,lua cpp binding的方式使用opencv。 逻辑为: 请求 -> 取原图 -> 处理图片 -> 返回处理后图片。 这个过程中等于同时有IO-bounding task和CPU-bounding task。 该nginx同时配置了较大proxy cache使得大部分的原图实际都取自本地文件,也即作为原图和处理图片的cache server角色。
后来出现获取原图超时(对端发现write timeout然后close conn)的问题,推断是处理图片耗时太长导致IO-bounding部分操作被“不公平对待”。
于是打算重构把图片处理部分拆出来,为了尽量减少代码修改,单纯的图片处理服务仍然是openresty + opencv方案,只是原图从POST body里读取(下面叫做image server)。 原来的openresty服务提供原图服务和获取原图后post给图片处理服务请求处理图的功能(下面叫做cache server)。
问题:
发现,新的方案和老的方案性能接近(latency、qps),这个不是问题,因为拆分的目的不是提高性能,而是让cache server只负责IO-bounding task。 新出现的问题是: 新的image server的latency波动较为明显,开发机条件下大约5%的请求的latency接近2倍平均latency而另有5%的请求的latency接近于3-4倍latency。 相比之下,老方案里latency分布在 90%-110%平均latency之间。
测试方式为ab -> image server(ab -> cache server -> image server方式下数据基本接近)。
疑问:
两种情况下的区别只在于 老方案openresty是(主要)从本地FS读原图 而 新方案是从socket(tcp or unix)读原图。 为什么后者会导致 部分请求被“不公平对待”呢? 是否与nginx调度模型有关?本地文件IO是不是不会导致切换到另一个req-handling?该情况与此有关吗?是的话有没有改善方式?
谢谢。