我的思路是:
成都創(chuàng)新互聯(lián)主營(yíng)鐵嶺網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,重慶APP開(kāi)發(fā)公司,鐵嶺h5成都小程序開(kāi)發(fā)搭建,鐵嶺網(wǎng)站營(yíng)銷推廣歡迎鐵嶺等地區(qū)企業(yè)咨詢
數(shù)據(jù)庫(kù)中新建一個(gè)表
is_showUpdate
字段:id、is_update
記錄 :id=1;is_update = false;
當(dāng)你的程序要修改顯示信息的時(shí)候(也就是展示數(shù)據(jù)),信息修改完畢將is_showUpdate表的記錄標(biāo)記為true
update is_showUpdate set is_update ='true' where id = 1;
展示頁(yè)面通瞎枯過(guò)js定時(shí)器通過(guò)ajax每五秒調(diào)取下你的接口磨則洞,接口只是查詢is_showUpdate 表的id為1的記錄 is_update 是否為true;如果該字盯槐段為true,則此接口將id=1的記錄的is_update修改為false,然后給前臺(tái)頁(yè)面反水?dāng)?shù)據(jù),刷新頁(yè)面;
1、建議你讀寫數(shù)據(jù)和下載圖片分開(kāi),各用不同的進(jìn)程完成。
比如說(shuō),取數(shù)據(jù)用get-data.php,下載圖片用get-image.php。
2、多進(jìn)程的話,php可以簡(jiǎn)單的用pcntl_fork()。這樣可以并發(fā)多個(gè)子進(jìn)程。
但是我不建議你用fork,我建議你安裝一個(gè)gearman worker。這樣你要并發(fā)幾個(gè),就啟幾個(gè)worker,寫代碼簡(jiǎn)單,根本不用在代碼里考慮thread啊,process等等。
3、綜上,解決方案這樣:
(1)安裝gearman worker。
(2)寫一個(gè)get-data.php,在crontab里設(shè)置它每5分鐘執(zhí)行一次,只負(fù)責(zé)讀數(shù)據(jù),然后把讀回來(lái)的數(shù)據(jù)一條一條的扔到 gearman worker的隊(duì)列里;
然后再寫一個(gè)處理數(shù)據(jù)的腳本作為worker,例如叫process-data.php,這個(gè)腳本常駐內(nèi)存。它作為worker從geraman 隊(duì)列里讀出一條一條的數(shù)據(jù),然后跟你的數(shù)據(jù)庫(kù)亂肆老數(shù)據(jù)比較,進(jìn)行你的業(yè)務(wù)邏輯。如果你要10個(gè)并發(fā),那就啟動(dòng)10個(gè)process-data.php好了。處理完后,如果圖片地址有變動(dòng)需要下載圖片,就把圖片地址扔到 gearman worker的另一個(gè)隊(duì)列里。
(3)再寫一個(gè)download-data.php,作為下載圖片的worker,同樣,你啟動(dòng)10個(gè)20個(gè)并發(fā)隨便鄭磨你。這個(gè)進(jìn)程也常駐內(nèi)存運(yùn)行,從gearman worker的圖片數(shù)據(jù)隊(duì)列里取數(shù)據(jù)出來(lái),下載圖片
4、常駐進(jìn)程的話,就是嘩叢轎在代碼里寫個(gè)while(true)死循環(huán),讓它一直運(yùn)行好了。如果怕內(nèi)存泄露啥的,你可以每循環(huán)10萬(wàn)次退出一下。然后在crontab里設(shè)置,每分鐘檢查一下進(jìn)程有沒(méi)有啟動(dòng),比如說(shuō)這樣啟動(dòng)3個(gè)process-data worker進(jìn)程:
* * * * * flock -xn /tmp/process-data.1.lock -c '/usr/bin/php /process-data.php /dev/null 21'
* * * * * flock -xn /tmp/process-data.2.lock -c '/usr/bin/php /process-data.php /dev/null 21'
* * * * * flock -xn /tmp/process-data.3.lock -c '/usr/bin/php /process-data.php /dev/null 21'
不知道你明白了沒(méi)有
網(wǎng)頁(yè)一般是單向主動(dòng)短鏈接,實(shí)時(shí)更新實(shí)在有些不便,即使一方掉線,另一方也不能及時(shí)感知。一般所謂的實(shí)時(shí)刷新,大多采用定時(shí)刷新(輪詢),或長(zhǎng)輪詢的方式做,ajax用于更新數(shù)據(jù)確實(shí)是比較簡(jiǎn)單方便的。
輪納信詢你就settimeout,長(zhǎng)輪詢你就每次接收數(shù)據(jù)成功后,再來(lái)一次長(zhǎng)輪詢。但你鏈接別人的數(shù)據(jù),了解一下供應(yīng)商洞禪輪的刷新機(jī)制、周期再做考慮。
當(dāng)然這襲槐些都是偽實(shí)時(shí),真的實(shí)時(shí)用http協(xié)議是不合適的,你得用flash插件做。而你用的是api供應(yīng)商的東西,這條路就基本走不通了。
對(duì)于任何一個(gè)網(wǎng)站肯定是少不了下載功能,常見(jiàn)的下載功能有圖片、視頻、Excel表格,如果文件比較小的話,那么不會(huì)遇到任何的問(wèn)題,但是當(dāng)文件信息而超明銀過(guò)了PHP的最大內(nèi)存,那么在這個(gè)時(shí)候它就會(huì)有的內(nèi)存溢出的問(wèn)題。
那么它們是因?yàn)槭裁炊l(fā)生的?對(duì)于這個(gè)過(guò)程的原理才是埋碧我們應(yīng)該真正要去弄明白的事情
下載大數(shù)據(jù)量的EXCEL文件為何要報(bào)錯(cuò)?
PHP在下載大Excel表格的時(shí)候,那么首先它是需要去把MySQL的數(shù)據(jù)從硬盤上面讀取到內(nèi)存,但讀取它是一次性載入到我們的內(nèi)存,如果說(shuō)它一次性載入的數(shù)據(jù)量遠(yuǎn)遠(yuǎn)大于最大內(nèi)存,然后再來(lái)執(zhí)行瀏覽器的業(yè)務(wù)下載。那么這個(gè)時(shí)候它就會(huì)發(fā)生我們這個(gè)內(nèi)存溢出。
就比如:說(shuō)我們現(xiàn)在有100M的數(shù)據(jù)量,但是我們PHP內(nèi)存最大只有64M,那么這個(gè)它肯定是裝不了的,我們可以把那個(gè)內(nèi)存比喻為一個(gè)水杯,這個(gè)水杯的容量比喻為內(nèi)存,現(xiàn)在杯子最大容量為64L。你要存放100L??隙ǚ挪幌?/p>
大事化小,小事化了。拆分成段
從上面可以看到文件下載,它是分為兩步,首先是載入內(nèi)存然后執(zhí)行瀏覽器的輸出下載,那么既然大型文件一次性載入不了,那可以采用“大事化小,小事化了”思路,我們可以實(shí)現(xiàn)邊寫邊下載,也激液宴就是分批次的讀取與寫入。
因?yàn)橛脩舻脑挘灰罱K拿到這個(gè)文件就可以,對(duì)于瀏覽器的下載原理不需要關(guān)心。只需要給到文件下載提示給用戶即可,然后后端在實(shí)時(shí)的分批次的寫入到要下載的文件當(dāng)中。
實(shí)現(xiàn)思路步驟:
1、一設(shè)置瀏覽器下載Excel需要的Header
2、打開(kāi)php://output流,并設(shè)置寫入文件句柄。
注:(php://output,是一個(gè)可寫的輸出流,允許程序像操作文件一樣將輸出寫入到輸出流中,PHP會(huì)把輸出流中的內(nèi)容發(fā)送給web服務(wù)器并返回給發(fā)起請(qǐng)求的瀏覽器)
3、獲取數(shù)據(jù)庫(kù)所有數(shù)據(jù)量,并設(shè)置每次查詢的條數(shù),通過(guò)這兩個(gè)值計(jì)算分批查詢的次數(shù)
4、基于分批查詢的次數(shù)循環(huán)查詢數(shù)據(jù)庫(kù),然后寫入到文件中,同時(shí)清除本次操作變量?jī)?nèi)存,刷新緩沖到瀏覽器,讓瀏覽器的文件始終實(shí)時(shí)保持到最新的大小
注:刷新用ob_flush、flush()
PHP的I/O流
在這里我們用到了PHP的一個(gè)IO的輸入輸出,也就是我們常用的
php://inputphp://output。
php://input
php://input可以讀取原始的POST數(shù)據(jù)。相較于$form-data”.
注:p
php://output是一個(gè)只寫的數(shù)據(jù)流,允許你以print和echo一樣的方式寫入到輸出緩沖區(qū)。
綜上:實(shí)現(xiàn)思維與原理很重要如有感悟,歡迎在線咨詢