目錄
解决Nginx和Fpm-Php等内部多进程之间共享数据问题
概念说明:
问题描述
问题分析
方案一:RInit中每个请求都先到Server端获取最新的机器列表
方案二:RInit中每个请求都先到Server端获取最新的机器列表,同时从Server端拿到一个过期时间,后面的请求如果没有超过过期时间则不需要再次去Server端获取更新了
方案三:使用共享内存方式,单独启动一个更新进程,实时更新集群节点信息,写入共享内存,RInit中每个请求先读取共享内存获取最新的机器列表
解决方式
首頁 php教程 php手册 解决Nginx和Fpm-Php等内部多进程之间共享数据问题

解决Nginx和Fpm-Php等内部多进程之间共享数据问题

Jun 06, 2016 pm 08:09 PM
nginx 共享 內部 數位 解決 行程

解决Nginx和Fpm-Php等内部多进程之间共享数据问题 概念说明: 1. MINIT :Php扩展的初始化方法,整个模块启动时候被调用一次 2. RINIT :Php扩展的初始化方法,每个请求会调用一次 3. ClusterMap(简称CM) :提供服务定位和集群地图功能,通过接收心跳和主动


解决Nginx和Fpm-Php等内部多进程之间共享数据问题

概念说明:

1. MINIT:Php扩展的初始化方法,整个模块启动时候被调用一次

2. RINIT:Php扩展的初始化方法,每个请求会调用一次

3. ClusterMap(简称CM):提供服务定位和集群地图功能,通过接收心跳和主动探测方式收集节点状态信息,统一管理多种异构集群,替换硬负载均衡设备

4. CMSubProxy:ClusterMap内部的一个订阅者客户端代理,定期和Server端通讯,获取最新的集群信息,更新内部维护的机器列表

问题描述

  1. Nginx或者Php-CGI都是使用多进程提供大并发服务的,如果服务内部想要提供一个通用的功能模块,需要用户自己写一个Extension或者Module, 最近在做ClusterMap的订阅者客户端,订阅者客户端即Php的一个扩展,请求到来时,Php扩展会与CMServer通讯获取最新的机器列表,但是如果每次请求都去获取机器列表开销又特别大

  2. 在Apache的Module模式下,实现是简单的,Apache首先启动父进程A会调用MINIT方法,调用完成后Fork其它Httpd子进程B,A和B是父子关系,这样父进程A就可以定期更新集群信息,然后通过管道方式和子进程通讯,子进程在每个请求过来时,读取管道消息(即机器列表),实现了服务定位;但是Php-fpm模式略有不同,Php-fpm进程管理器启动进程A会调用MINIT方法,然后Fork出一个Fpm-Master进程B,进程B启动多个Php-CGI子进程C,启动工作完成后,启动进程A就退出了,子进程在每个请求过来时调用RINIT,这时父子AC进程管道通讯建立不起来,管道的数据没有办法消费,使得子进程C如果写满就会阻塞。其实这个问题很普遍,如果用修改Php的源码方式解决不见得是一个好的解决方案。

问题分析

总结一下上述问题,说白了就是多个服务进程,每个进程在接到请求后,首先需要服务定位,获得最新的机器列表(需要一次网络开销),然后再转发请求给其他的服务,接下来我们以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中采用的是方案三,通过共享内存的方式解决这个问题的

  1. CMSubProxy是一个单独的更新进程,每隔500ms会向CMServer发送一个请求,获取最新的机器列表,收到响应消息后,CMSubProxy会更新进程内部维护的机器列表,更新成功后会写到共享内存中;
  2. Php-fpm进程在每个请求到来时,首先会读取共享内存中的机器列表,然后再将请求转发给列表中的某一台可用机器,机器的选择有多种策略(轮询,随机,权重,一致性哈希等);
  3. 共享内存是mmap打开的,需要注意的是,在更新和读取的时候需要读写锁,并且锁信号量要在共享内存中,关于多个进程间共享内存锁

     pthread_rwlockattr_t attr;
     pthread_rwlockattr_init(&attr);
     pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); 
     手册上对pthread_rwlockattr_setpshared的描述
     pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared);
     DESCRIPTION
       The pthread_rwlockattr_setpshared() function sets the process-shared attribute of attr to the value referenced by pshared.  pshared may be one of two values:
       PTHREAD_PROCESS_SHARED   Any thread of any process that has access to the memory where the read/write lock resides can manipulate the lock.
    
    登入後複製

CMSubProxy写入共享内存中的数据是分全量和增量的,增量数据写在全量数据之后,这里就不详细讲述了

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何使用 PHP 部署和維護網站 如何使用 PHP 部署和維護網站 May 03, 2024 am 08:54 AM

要成功部署和維護PHP網站,需要執行以下步驟:選擇Web伺服器(如Apache或Nginx)安裝PHP建立資料庫並連接PHP上傳程式碼到伺服器設定網域名稱和DNS監控網站維護步驟包括更新PHP和Web伺服器、備份網站、監控錯誤日誌和更新內容。

全球數字虛擬幣交易平台排行榜前十(2025權威排名) 全球數字虛擬幣交易平台排行榜前十(2025權威排名) Mar 06, 2025 pm 04:36 PM

2025年全球數字虛擬幣交易平台競爭激烈,本文根據交易量、安全性、用戶體驗等指標,權威發布2025年全球十大數字虛擬幣交易平台排行榜。 OKX憑藉強大的技術實力和全球化運營策略居首,Binance以高流動性和低費用緊隨其後。 Gate.io、Coinbase、Kraken等平台憑藉各自優勢穩居前列。榜單涵蓋Huobi、KuCoin、Bitfinex、Crypto.com和Gemini等交易平台,各有特色,但投資需謹慎。選擇平台需考慮安全性、流動性、費用、用戶體驗、幣種選擇及監管合規性等因素,理性投資

跟我一起來學習Linux安裝Nginx 跟我一起來學習Linux安裝Nginx Apr 28, 2024 pm 03:10 PM

而今天將來一起帶領大家在Linux環境安裝Nginx,這裡用的Linux系統是CentOS7.2.準備安裝工具1.從Nginx官網下載Nginx。這裡用的版本為:1.13.6.2.將下載下來的Nginx上傳到Linux上,這裡以/opt/nginx目錄為例。運行“tar-zxvfnginx-1.13.6.tar.gz”進行解壓縮。 3.切換到/opt/nginx/nginx-1.13.6目錄下,執行./configure進行初始化設定。如出現下面的提示,說明該機器沒有安裝PCRE,而Nginx需要依

如何實施 PHP 安全最佳實踐 如何實施 PHP 安全最佳實踐 May 05, 2024 am 10:51 AM

如何實施PHP安全最佳實踐PHP是最受歡迎的後端Web程式語言之一,用於建立動態和互動式網站。然而,PHP程式碼可能容易受到各種安全漏洞的攻擊。實施安全最佳實務對於保護您的網路應用程式免受這些威脅至關重要。輸入驗證輸入驗證是驗證使用者輸入並防止惡意輸入(如SQL注入)的關鍵第一步。 PHP提供了多種輸入驗證函數,例如filter_var()和preg_match()。範例:$username=filter_var($_POST['username'],FILTER_SANIT

WordPress站點文件訪問受限:為什麼我的.txt文件無法通過域名訪問? WordPress站點文件訪問受限:為什麼我的.txt文件無法通過域名訪問? Apr 01, 2025 pm 03:00 PM

Wordpress站點文件訪問受限:排查.txt文件無法訪問的原因最近有用戶在配置小程序業務域名時,遇到一個問題:�...

記錄一次用strace診斷php佔用系統資源過高的問題 記錄一次用strace診斷php佔用系統資源過高的問題 May 03, 2024 pm 04:31 PM

本機環境:redhat6.7系統。 nginx1.12.1,php7.1.0,程式碼使用yii2框架問題:本地的web站需要用到elasticsearch服務。當php使用本機伺服器搭建的elasticsearch時,本地的負載都是正常。當我使用aws的elasticsearchservice服務時,本地伺服器出現負載經常過高的情況。查看nginx和php日誌,發現沒有異常。系統的並發連線數也不高。這時候想到我們老闆跟我講的一個strace診斷工具。偵錯過程:找一個php的子程序idstrace-

如何在同一台服務器上通過Nginx配置讓PHP5.6和PHP7共存? 如何在同一台服務器上通過Nginx配置讓PHP5.6和PHP7共存? Apr 01, 2025 pm 03:15 PM

在同一系統中同時運行多個PHP版本是一個常見的需求,特別是當不同項目依賴於不同版本的PHP時。如何在同一台...

十大數字貨幣交易平台 數字貨幣交易平台top10榜單最新 十大數字貨幣交易平台 數字貨幣交易平台top10榜單最新 Mar 17, 2025 pm 05:57 PM

十大數字貨幣交易平台:1. OKX,2. Binance,3. Gate.io,4. Huobi Global,5. Kraken,6. Coinbase,7. KuCoin,8. Bitfinex,9. Crypto.com,10. Gemini,這些交易所各具特色,用戶可根據安全性、費用、幣種選擇、用戶界面和客戶支持等因素選擇適合自己的平台。

See all articles