概念说明:1. MINIT:Php扩展的初始化方法,整个模块启动时候被调用一次 2. RINIT:Php扩展的初始化方法,每个请求会调用一次 3. ClusterMap(简称CM):提供服务定位和集群地图功能,通过接收心跳和主动探测方式收集节点状态信息,统一管理多种异构集群,替换硬负载均衡设备 4. CMSubProxy:ClusterMap内部的一个订阅者客户端代理,定期和Server端通讯,获取最新的集群信息,更新内部维护的机器列表 问题描述
问题分析总结一下上述问题,说白了就是多个服务进程,每个进程在接到请求后,首先需要服务定位,获得最新的机器列表(需要一次网络开销),然后再转发请求给其他的服务,接下来我们以Fpm-Php为例介绍如果解决上述问题 案一:RInit中每个请求都先到Server端获取最新的机器列表1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 10秒钟过去了 如果这时你还没有发现问题,那么你就没有必要学习Nginx这个骑着比驴都快的玩意了,很明显,RInit中每个请求都要多一次网络开销,去Server端获取最新的机器列表,大大增加了整个请求的响应时间。 这时有人说了这个问题好解决,我不需要这么频繁的更新就好了,10请求,100请求更新一次,或者1s秒钟,10s更新一次,既不影响性能,又能达到更新效果,在性能和更新频率上做Trade-Off,这样总可以吧,于是就有了方案二 方案二:RInit中每个请求都先到Server端获取最新的机器列表,同时从Server端拿到一个过期时间,后面的请求如果没有超过过期时间则不需要再次去Server端获取更新了 方案二可以说是能解决问题,严格来说只能是部分问题,治标不治本 因为如果你想要更好性能,对于每个进程来说,就必须把更新周期变慢,失去准确性,如果想要更高的准确行,就需要每个进程频繁更新,在搜索和广告这种大并发,超时敏感的服务面前这种方案太不友好了,最重要的事,每个Worker进程都要去更新,虽然每个进程拿到的都是完全相同的信息,这里不是说Nginx的多进程模式不好,这种模式有它存在的意义,而且事实也证明了,多进程正是Nginx的高明之处,每个Worker都是独立的进程,编程简单且不需要加锁,进程间又互不影响,降低风险。 方案三:使用共享内存方式,单独启动一个更新进程,实时更新集群节点信息,写入共享内存,RInit中每个请求先读取共享内存获取最新的机器列表 方案三利用了多个Worker进程获取的机器列表相同这个特点,通过共享内存的方式在进程间共享数据,这样Worker进程既不需要网络开销,又可以快速的获取最新机器列表 解决方式目前ClusterMap中采用的是方案三,通过共享内存的方式解决这个问题的
CMSubProxy写入共享内存中的数据是分全量和增量的,增量数据写在全量数据之后,这里就不详细讲述了 转载请保留固定链接: https://linuxeye.com/Linux/2293.html |