導航:首頁 > 編程語言 > php耗時任務

php耗時任務

發布時間:2022-08-06 20:08:03

1. php怎麼處理高並發

以下內容轉載自徐漢彬大牛的博客億級Web系統搭建——單機到分布式集群

當一個Web系統從日訪問量10萬逐步增長到1000萬,甚至超過1億的過程中,Web系統承受的壓力會越來越大,在這個過程中,我們會遇到很多的問題。為了解決這些性能壓力帶來問題,我們需要在Web系統架構層面搭建多個層次的緩存機制。在不同的壓力階段,我們會遇到不同的問題,通過搭建不同的服務和架構來解決。

Web負載均衡

Web負載均衡(Load Balancing),簡單地說就是給我們的伺服器集群分配「工作任務」,而採用恰當的分配方式,對於保護處於後端的Web伺服器來說,非常重要。

負載均衡的策略有很多,我們從簡單的講起哈。

1.HTTP重定向

當用戶發來請求的時候,Web伺服器通過修改HTTP響應頭中的Location標記來返回一個新的url,然後瀏覽器再繼續請求這個新url,實際上就是頁面重定向。通過重定向,來達到「負載均衡」的目標。例如,我們在下載PHP源碼包的時候,點擊下載鏈接時,為了解決不同國家和地域下載速度的問題,它會返回一個離我們近的下載地址。重定向的HTTP返回碼是302

這個重定向非常容易實現,並且可以自定義各種策略。但是,它在大規模訪問量下,性能不佳。而且,給用戶的體驗也不好,實際請求發生重定向,增加了網路延時。

2. 反向代理負載均衡

反向代理服務的核心工作主要是轉發HTTP請求,扮演了瀏覽器端和後台Web伺服器中轉的角色。因為它工作在HTTP層(應用層),也就是網路七層結構中的第七層,因此也被稱為「七層負載均衡」。可以做反向代理的軟體很多,比較常見的一種是Nginx。

Nginx是一種非常靈活的反向代理軟體,可以自由定製化轉發策略,分配伺服器流量的權重等。反向代理中,常見的一個問題,就是Web伺服器存儲的session數據,因為一般負載均衡的策略都是隨機分配請求的。同一個登錄用戶的請求,無法保證一定分配到相同的Web機器上,會導致無法找到session的問題。

解決方案主要有兩種:

1.配置反向代理的轉發規則,讓同一個用戶的請求一定落到同一台機器上(通過分析cookie),復雜的轉發規則將會消耗更多的CPU,也增加了代理伺服器的負擔。

2.將session這類的信息,專門用某個獨立服務來存儲,例如redis/memchache,這個方案是比較推薦的。

反向代理服務,也是可以開啟緩存的,如果開啟了,會增加反向代理的負擔,需要謹慎使用。這種負載均衡策略實現和部署非常簡單,而且性能表現也比較好。但是,它有「單點故障」的問題,如果掛了,會帶來很多的麻煩。而且,到了後期Web伺服器繼續增加,它本身可能成為系統的瓶頸。

3. IP負載均衡

IP負載均衡服務是工作在網路層(修改IP)和傳輸層(修改埠,第四層),比起工作在應用層(第七層)性能要高出非常多。原理是,他是對IP層的數據包的IP地址和埠信息進行修改,達到負載均衡的目的。這種方式,也被稱為「四層負載均衡」。常見的負載均衡方式,是LVS(Linux Virtual Server,Linux虛擬服務),通過IPVS(IP Virtual Server,IP虛擬服務)來實現。

在負載均衡伺服器收到客戶端的IP包的時候,會修改IP包的目標IP地址或埠,然後原封不動地投遞到內部網路中,數據包會流入到實際Web伺服器。實際伺服器處理完成後,又會將數據包投遞回給負載均衡伺服器,它再修改目標IP地址為用戶IP地址,最終回到客戶端。

上述的方式叫LVS-NAT,除此之外,還有LVS-RD(直接路由),LVS-TUN(IP隧道),三者之間都屬於LVS的方式,但是有一定的區別,篇幅問題,不贅敘。

IP負載均衡的性能要高出Nginx的反向代理很多,它只處理到傳輸層為止的數據包,並不做進一步的組包,然後直接轉發給實際伺服器。不過,它的配置和搭建比較復雜。

4. DNS負載均衡

DNS(Domain Name System)負責域名解析的服務,域名url實際上是伺服器的別名,實際映射是一個IP地址,解析過程,就是DNS完成域名到IP的映射。而一個域名是可以配置成對應多個IP的。因此,DNS也就可以作為負載均衡服務。

這種負載均衡策略,配置簡單,性能極佳。但是,不能自由定義規則,而且,變更被映射的IP或者機器故障時很麻煩,還存在DNS生效延遲的問題。

5. DNS/GSLB負載均衡

我們常用的CDN(Content Delivery Network,內容分發網路)實現方式,其實就是在同一個域名映射為多IP的基礎上更進一步,通過GSLB(Global Server Load Balance,全局負載均衡)按照指定規則映射域名的IP。一般情況下都是按照地理位置,將離用戶近的IP返回給用戶,減少網路傳輸中的路由節點之間的跳躍消耗。

「向上尋找」,實際過程是LDNS(Local DNS)先向根域名服務(Root Name Server)獲取到頂級根的Name Server(例如.com的),然後得到指定域名的授權DNS,然後再獲得實際伺服器IP。

CDN在Web系統中,一般情況下是用來解決大小較大的靜態資源(html/Js/Css/圖片等)的載入問題,讓這些比較依賴網路下載的內容,盡可能離用戶更近,提升用戶體驗。

例如,我訪問了一張imgcache.gtimg.cn上的圖片(騰訊的自建CDN,不使用qq.com域名的原因是防止http請求的時候,帶上了多餘的cookie信息),我獲得的IP是183.60.217.90。

這種方式,和前面的DNS負載均衡一樣,不僅性能極佳,而且支持配置多種策略。但是,搭建和維護成本非常高。互聯網一線公司,會自建CDN服務,中小型公司一般使用第三方提供的CDN。

Web系統的緩存機制的建立和優化

剛剛我們講完了Web系統的外部網路環境,現在我們開始關注我們Web系統自身的性能問題。我們的Web站點隨著訪問量的上升,會遇到很多的挑戰,解決這些問題不僅僅是擴容機器這么簡單,建立和使用合適的緩存機制才是根本。

最開始,我們的Web系統架構可能是這樣的,每個環節,都可能只有1台機器。

我們從最根本的數據存儲開始看哈。

一、 MySQL資料庫內部緩存使用

MySQL的緩存機制,就從先從MySQL內部開始,下面的內容將以最常見的InnoDB存儲引擎為主。

1. 建立恰當的索引

最簡單的是建立索引,索引在表數據比較大的時候,起到快速檢索數據的作用,但是成本也是有的。首先,佔用了一定的磁碟空間,其中組合索引最突出,使用需要謹慎,它產生的索引甚至會比源數據更大。其次,建立索引之後的數據insert/update/delete等操作,因為需要更新原來的索引,耗時會增加。當然,實際上我們的系統從總體來說,是以select查詢操作居多,因此,索引的使用仍然對系統性能有大幅提升的作用。

2. 資料庫連接線程池緩存

如果,每一個資料庫操作請求都需要創建和銷毀連接的話,對資料庫來說,無疑也是一種巨大的開銷。為了減少這類型的開銷,可以在MySQL中配置thread_cache_size來表示保留多少線程用於復用。線程不夠的時候,再創建,空閑過多的時候,則銷毀。

其實,還有更為激進一點的做法,使用pconnect(資料庫長連接),線程一旦創建在很長時間內都保持著。但是,在訪問量比較大,機器比較多的情況下,這種用法很可能會導致「資料庫連接數耗盡」,因為建立連接並不回收,最終達到資料庫的max_connections(最大連接數)。因此,長連接的用法通常需要在CGI和MySQL之間實現一個「連接池」服務,控制CGI機器「盲目」創建連接數。

建立資料庫連接池服務,有很多實現的方式,PHP的話,我推薦使用swoole(PHP的一個網路通訊拓展)來實現。

3. Innodb緩存設置(innodb_buffer_pool_size)

innodb_buffer_pool_size這是個用來保存索引和數據的內存緩存區,如果機器是MySQL獨占的機器,一般推薦為機器物理內存的80%。在取表數據的場景中,它可以減少磁碟IO。一般來說,這個值設置越大,cache命中率會越高。

4. 分庫/分表/分區。

MySQL資料庫表一般承受數據量在百萬級別,再往上增長,各項性能將會出現大幅度下降,因此,當我們預見數據量會超過這個量級的時候,建議進行分庫/分表/分區等操作。最好的做法,是服務在搭建之初就設計為分庫分表的存儲模式,從根本上杜絕中後期的風險。不過,會犧牲一些便利性,例如列表式的查詢,同時,也增加了維護的復雜度。不過,到了數據量千萬級別或者以上的時候,我們會發現,它們都是值得的。

二、 MySQL資料庫多台服務搭建

1台MySQL機器,實際上是高風險的單點,因為如果它掛了,我們Web服務就不可用了。而且,隨著Web系統訪問量繼續增加,終於有一天,我們發現1台MySQL伺服器無法支撐下去,我們開始需要使用更多的MySQL機器。當引入多台MySQL機器的時候,很多新的問題又將產生。

1. 建立MySQL主從,從庫作為備份

這種做法純粹為了解決「單點故障」的問題,在主庫出故障的時候,切換到從庫。不過,這種做法實際上有點浪費資源,因為從庫實際上被閑著了。

2. MySQL讀寫分離,主庫寫,從庫讀。

兩台資料庫做讀寫分離,主庫負責寫入類的操作,從庫負責讀的操作。並且,如果主庫發生故障,仍然不影響讀的操作,同時也可以將全部讀寫都臨時切換到從庫中(需要注意流量,可能會因為流量過大,把從庫也拖垮)。

3. 主主互備。

兩台MySQL之間互為彼此的從庫,同時又是主庫。這種方案,既做到了訪問量的壓力分流,同時也解決了「單點故障」問題。任何一台故障,都還有另外一套可供使用的服務。

不過,這種方案,只能用在兩台機器的場景。如果業務拓展還是很快的話,可以選擇將業務分離,建立多個主主互備。

三、 MySQL資料庫機器之間的數據同步

每當我們解決一個問題,新的問題必然誕生在舊的解決方案上。當我們有多台MySQL,在業務高峰期,很可能出現兩個庫之間的數據有延遲的場景。並且,網路和機器負載等,也會影響數據同步的延遲。我們曾經遇到過,在日訪問量接近1億的特殊場景下,出現,從庫數據需要很多天才能同步追上主庫的數據。這種場景下,從庫基本失去效用了。

於是,解決同步問題,就是我們下一步需要關注的點。

1. MySQL自帶多線程同步

MySQL5.6開始支持主庫和從庫數據同步,走多線程。但是,限制也是比較明顯的,只能以庫為單位。MySQL數據同步是通過binlog日誌,主庫寫入到binlog日誌的操作,是具有順序的,尤其當SQL操作中含有對於表結構的修改等操作,對於後續的SQL語句操作是有影響的。因此,從庫同步數據,必須走單進程。

2. 自己實現解析binlog,多線程寫入。

以資料庫的表為單位,解析binlog多張表同時做數據同步。這樣做的話,的確能夠加快數據同步的效率,但是,如果表和表之間存在結構關系或者數據依賴的話,則同樣存在寫入順序的問題。這種方式,可用於一些比較穩定並且相對獨立的數據表。

國內一線互聯網公司,大部分都是通過這種方式,來加快數據同步效率。還有更為激進的做法,是直接解析binlog,忽略以表為單位,直接寫入。但是這種做法,實現復雜,使用范圍就更受到限制,只能用於一些場景特殊的資料庫中(沒有表結構變更,表和表之間沒有數據依賴等特殊表)。

四、 在Web伺服器和資料庫之間建立緩存

實際上,解決大訪問量的問題,不能僅僅著眼於資料庫層面。根據「二八定律」,80%的請求只關注在20%的熱點數據上。因此,我們應該建立Web伺服器和資料庫之間的緩存機制。這種機制,可以用磁碟作為緩存,也可以用內存緩存的方式。通過它們,將大部分的熱點數據查詢,阻擋在資料庫之前。

1. 頁面靜態化

用戶訪問網站的某個頁面,頁面上的大部分內容在很長一段時間內,可能都是沒有變化的。例如一篇新聞報道,一旦發布幾乎是不會修改內容的。這樣的話,通過CGI生成的靜態html頁面緩存到Web伺服器的磁碟本地。除了第一次,是通過動態CGI查詢資料庫獲取之外,之後都直接將本地磁碟文件返回給用戶。

在Web系統規模比較小的時候,這種做法看似完美。但是,一旦Web系統規模變大,例如當我有100台的Web伺服器的時候。那樣這些磁碟文件,將會有100份,這個是資源浪費,也不好維護。這個時候有人會想,可以集中一台伺服器存起來,呵呵,不如看看下面一種緩存方式吧,它就是這樣做的。

2. 單台內存緩存

通過頁面靜態化的例子中,我們可以知道將「緩存」搭建在Web機器本機是不好維護的,會帶來更多問題(實際上,通過PHP的apc拓展,可通過Key/value操作Web伺服器的本機內存)。因此,我們選擇搭建的內存緩存服務,也必須是一個獨立的服務。

內存緩存的選擇,主要有redis/memcache。從性能上說,兩者差別不大,從功能豐富程度上說,Redis更勝一籌。

3. 內存緩存集群

當我們搭建單台內存緩存完畢,我們又會面臨單點故障的問題,因此,我們必須將它變成一個集群。簡單的做法,是給他增加一個slave作為備份機器。但是,如果請求量真的很多,我們發現cache命中率不高,需要更多的機器內存呢?因此,我們更建議將它配置成一個集群。例如,類似redis cluster。

Redis cluster集群內的Redis互為多組主從,同時每個節點都可以接受請求,在拓展集群的時候比較方便。客戶端可以向任意一個節點發送請求,如果是它的「負責」的內容,則直接返回內容。否則,查找實際負責Redis節點,然後將地址告知客戶端,客戶端重新請求。

對於使用緩存服務的客戶端來說,這一切是透明的。

內存緩存服務在切換的時候,是有一定風險的。從A集群切換到B集群的過程中,必須保證B集群提前做好「預熱」(B集群的內存中的熱點數據,應該盡量與A集群相同,否則,切換的一瞬間大量請求內容,在B集群的內存緩存中查找不到,流量直接沖擊後端的資料庫服務,很可能導致資料庫宕機)。

4. 減少資料庫「寫」

上面的機制,都實現減少資料庫的「讀」的操作,但是,寫的操作也是一個大的壓力。寫的操作,雖然無法減少,但是可以通過合並請求,來起到減輕壓力的效果。這個時候,我們就需要在內存緩存集群和資料庫集群之間,建立一個修改同步機制。

先將修改請求生效在cache中,讓外界查詢顯示正常,然後將這些sql修改放入到一個隊列中存儲起來,隊列滿或者每隔一段時間,合並為一個請求到資料庫中更新資料庫。

除了上述通過改變系統架構的方式提升寫的性能外,MySQL本身也可以通過配置參數innodb_flush_log_at_trx_commit來調整寫入磁碟的策略。如果機器成本允許,從硬體層面解決問題,可以選擇老一點的RAID(Rendant Arrays of independent Disks,磁碟列陣)或者比較新的SSD(Solid State Drives,固態硬碟)。

5. NoSQL存儲

不管資料庫的讀還是寫,當流量再進一步上漲,終會達到「人力有窮時」的場景。繼續加機器的成本比較高,並且不一定可以真正解決問題的時候。這個時候,部分核心數據,就可以考慮使用NoSQL的資料庫。NoSQL存儲,大部分都是採用key-value的方式,這里比較推薦使用上面介紹過Redis,Redis本身是一個內存cache,同時也可以當做一個存儲來使用,讓它直接將數據落地到磁碟。

這樣的話,我們就將資料庫中某些被頻繁讀寫的數據,分離出來,放在我們新搭建的Redis存儲集群中,又進一步減輕原來MySQL資料庫的壓力,同時因為Redis本身是個內存級別的Cache,讀寫的性能都會大幅度提升。

國內一線互聯網公司,架構上採用的解決方案很多是類似於上述方案,不過,使用的cache服務卻不一定是Redis,他們會有更豐富的其他選擇,甚至根據自身業務特點開發出自己的NoSQL服務。

6. 空節點查詢問題

當我們搭建完前面所說的全部服務,認為Web系統已經很強的時候。我們還是那句話,新的問題還是會來的。空節點查詢,是指那些資料庫中根本不存在的數據請求。例如,我請求查詢一個不存在人員信息,系統會從各級緩存逐級查找,最後查到到資料庫本身,然後才得出查找不到的結論,返回給前端。因為各級cache對它無效,這個請求是非常消耗系統資源的,而如果大量的空節點查詢,是可以沖擊到系統服務的。

在我曾經的工作經歷中,曾深受其害。因此,為了維護Web系統的穩定性,設計適當的空節點過濾機制,非常有必要。

我們當時採用的方式,就是設計一張簡單的記錄映射表。將存在的記錄存儲起來,放入到一台內存cache中,這樣的話,如果還有空節點查詢,則在緩存這一層就被阻擋了。

異地部署(地理分布式)

完成了上述架構建設之後,我們的系統是否就已經足夠強大了呢?答案當然是否定的哈,優化是無極限的。Web系統雖然表面上看,似乎比較強大了,但是給予用戶的體驗卻不一定是最好的。因為東北的同學,訪問深圳的一個網站服務,他還是會感到一些網路距離上的慢。這個時候,我們就需要做異地部署,讓Web系統離用戶更近。

一、 核心集中與節點分散

有玩過大型網游的同學都會知道,網游是有很多個區的,一般都是按照地域來分,例如廣東專區,北京專區。如果一個在廣東的玩家,去北京專區玩,那麼他會感覺明顯比在廣東專區卡。實際上,這些大區的名稱就已經說明了,它的伺服器所在地,所以,廣東的玩家去連接地處北京的伺服器,網路當然會比較慢。

當一個系統和服務足夠大的時候,就必須開始考慮異地部署的問題了。讓你的服務,盡可能離用戶更近。我們前面已經提到了Web的靜態資源,可以存放在CDN上,然後通過DNS/GSLB的方式,讓靜態資源的分散「全國各地」。但是,CDN只解決的靜態資源的問題,沒有解決後端龐大的系統服務還只集中在某個固定城市的問題。

這個時候,異地部署就開始了。異地部署一般遵循:核心集中,節點分散。

·核心集中:實際部署過程中,總有一部分的數據和服務存在不可部署多套,或者部署多套成本巨大。而對於這些服務和數據,就仍然維持一套,而部署地點選擇一個地域比較中心的地方,通過網路內部專線來和各個節點通訊。

·節點分散:將一些服務部署為多套,分布在各個城市節點,讓用戶請求盡可能選擇近的節點訪問服務。

例如,我們選擇在上海部署為核心節點,北京,深圳,武漢,上海為分散節點(上海自己本身也是一個分散節點)。我們的服務架構如圖:

需要補充一下的是,上圖中上海節點和核心節點是同處於一個機房的,其他分散節點各自獨立機房。
國內有很多大型網游,都是大致遵循上述架構。它們會把數據量不大的用戶核心賬號等放在核心節點,而大部分的網游數據,例如裝備、任務等數據和服務放在地區節點里。當然,核心節點和地域節點之間,也有緩存機制。

二、 節點容災和過載保護

節點容災是指,某個節點如果發生故障時,我們需要建立一個機制去保證服務仍然可用。毫無疑問,這里比較常見的容災方式,是切換到附近城市節點。假如系統的天津節點發生故障,那麼我們就將網路流量切換到附近的北京節點上。考慮到負載均衡,可能需要同時將流量切換到附近的幾個地域節點。另一方面,核心節點自身也是需要自己做好容災和備份的,核心節點一旦故障,就會影響全國服務。

過載保護,指的是一個節點已經達到最大容量,無法繼續接接受更多請求了,系統必須有一個保護的機制。一個服務已經滿負載,還繼續接受新的請求,結果很可能就是宕機,影響整個節點的服務,為了至少保障大部分用戶的正常使用,過載保護是必要的。

解決過載保護,一般2個方向:

·拒絕服務,檢測到滿負載之後,就不再接受新的連接請求。例如網游登入中的排隊。

·分流到其他節點。這種的話,系統實現更為復雜,又涉及到負載均衡的問題。

小結

Web系統會隨著訪問規模的增長,漸漸地從1台伺服器可以滿足需求,一直成長為「龐然大物」的大集群。而這個Web系統變大的過程,實際上就是我們解決問題的過程。在不同的階段,解決不同的問題,而新的問題又誕生在舊的解決方案之上。

系統的優化是沒有極限的,軟體和系統架構也一直在快速發展,新的方案解決了老的問題,同時也帶來新的挑戰。

2. php 耗時請求 如何非同步處理

可以使用消息隊列。
非同步執行一個任務,訂閱消息頻道。
有耗時的任務直接發布一個通知就可以了。

3. php怎麼用

推薦閱讀:騰訊T3-T4標准精品PHP架構師教程目錄大全,只要你看完保證薪資上升一個台階(持續更新)點擊此處

4. PHP+MYSQL 實現隊列 進行發送簡訊怎麼做

最近遇到一個批量發送簡訊的需求,簡訊介面是第三方提供的。剛開始想到,獲取到手機號之後,循環調用介面發送不就可以了嗎?

但很快發現問題:當簡訊數量很大時,不僅耗時,而且成功率很低。

於是想到,用PHP和MySQL實現一個消息隊列,一條一條的發送簡訊。下面介紹具體的實現方法:

首先,建立一個數據表sms,包含以下欄位:

id,
phone, //手機號
content //簡訊內容
將需要發送的簡訊和手機號存入sms表中。

接下來,需要用PHP實現一個定時器,定時讀取一條記錄,並發送簡訊:

<?php
$db = new Db();
$sms = new Sms();
while(true){
$item = $db->getFirstRecord(); //獲取數據表第一條記錄
if(!$item){
//如果隊列中沒有數據,則結束定時器
break;
}
$res = $sms->send($item['phone'],$item['content']); //發送簡訊
if($res){
$db->deleteFristRecord(); //刪除發送成功的記錄
echo $item['phone'].'發送成功';
}else{
echo $item['phone'].'發送失敗,稍後繼續嘗試';
}
sleep(10); //每隔十秒循環一次
}

echo '發送完畢!';
?>
將代碼保存為timer_sms.php,打開命令行,執行定時器:

php timer_sms.php
好了,php定時器將會根據設定的時間間隔(這里設的是10秒),自動完成發送簡訊的任務。任務完成後將自動退出定時器,不再佔用伺服器資源。

根據我的測試,PHP定時器佔用資源並不多,不會對伺服器造成壓力。而且是非同步訪問資料庫,也不會影響資料庫的運行。

這種方式的優點是:

1、後台運行,前台無需等待

2、成功率高,失敗的記錄會自動重發,直到成功

5. php都是學什麼內容啊想學php有必要報php培訓班嗎

首先,必須會一部分前端
需要了解的知識包括HTML、CSS、JavaScript,不需要深入地學習,有個概念性的理解即可。至於可以推薦的書籍還真沒有沒有,因為這一部分主要是練習,熟能生巧。如果是沒有任何基礎的,需要帶領入門的話,可以去視頻網站搜索相關課程視頻,網上很多。
其次,關於知識學習有三個階段
1. PHP入門段
可以在網上找到各類PHP熱門視頻,基本上這些視頻裡面都會講到如何使用編輯,配置環境等一系列基礎教程。能擼出一個個人站點/ 企業小站 就可以進入下一步了這樣可以先對編程有一個初步的認識,如果沒有任何電腦基礎不推薦直接看書。
2. 進步段
這時候需要PHP手冊了,了解常用函數。學習MySQL( 資料庫 ),了解PHP各大框架 --thinkPHP,Yii,Laravel等, 然後選一款框架嘗試搭建一blog,實現常規登錄、注冊、文章發布和修改。
3. 提高段
這一階段的知識點主要包括:了解Linux ,在Linux下搭建 PHP環境(這時候要脫離 xamp,wamp等之流了);知道&&使用版本控制:git svn;
詳細的了解之後需要的就是不斷地去補充這些自己不懂的東西,多學,多問,多練,如果喜歡編程,想成為一名PHP程序員,想看PHP視頻教程的話推薦扣丁學堂的,最重要的就是盡快入手,不要拖。

6. ignore_user_abort 之後 其他php程序無法運行了 怎麼樣才能讓他們都運行

問題:ajax非同步請求php後台處理耗時任務之後,ajax之後的js都可以正常運行,但是當前瀏覽器不能再點擊瀏覽被ajax請求的地址的其他頁面(卡死、阻塞)。
解決:
第一、前端正常ajax請求。
第二、 PHP後台方法裡面必須加入這三句:
ignore_user_abort();//脫離客戶端
set_time_limit(0);//不限時間執行
session_write_close();//session解鎖
session_write_close()是重點,後台沒有執行完成,session是被鎖住的,所以要添加session_write_close — Write session data and end session。

我剛解決~~

7. 如何使用workerman處理後台耗時操作

mail_worker.php
<?php
use Workerman\Worker;
require_once './Workerman/Autoloader.php';

// mail worker,和調用端使用Text協議通訊
$mail_worker = new Worker('Text://0.0.0.0:12345');
// 如果發送郵件很慢,mail進程數可以根據需要多開一些
$mail_worker->count = 80;
$mail_worker->name = 'MailWorker';
$mail_worker->onMessage = function($connection, $mail_data)
{
// 直接返回ok,避免調用端長時間等待
$connection->send('ok');
// 假設發來的是json數據
$mail_data = json_decode($mail_data, true);
// 根據mail_data發郵件,如果需要失敗重發,
// 可以把失敗的郵件任務放到mysql裡面,
// 做個定時器定時掃描失敗郵件重新發送
your_send_mail_func($mail_data);
};
if(!defined('GLOBAL_START'))
{
Worker::runAll();
}

在你的項目中這樣與mail_worker通訊發郵件。
//$ip = "mail_worker 的ip" ,本機的話為127.0.0.1
$socket = stream_socket_client("tcp://$ip:12345", $errno, $errmsg, 5);
if(!$socket) echo $errmsg;
$mail_data = array("from"=>"...", "to"=>"...", "content"=>"...");
// 注意,Text協議後面"\n"換行符是必須的
$mail_buffer = json_encode($mail_data)."\n";
// 發送給mail worker
fwrite($socket, $mail_buffer);

這樣就可以非同步發郵件了,防止主流程被發郵件阻塞,大大加快下單響應時間。

其實下單後能夠在網站上實時通知也是個不錯的體驗,用戶這邊下單後,商家在網站上立刻得到通知,效果圖類似

接入非常簡單

8. Asp、Php、Jsp區別

ASP全名Active
Server
Pages,是一個WEB伺服器端的開發環境,利用它可以產生和執行動態的、互動的、高性能的WEB服務應用程序。ASP採用腳本語言VBScript(Java
script)作為自己的開發語言。
PHP是一種跨平台的伺服器端的嵌入式腳本語言。它大量地借用C,Java和Perl語言的語法,
並耦合PHP自己的特性,使WEB開發者能夠快速地寫出動態產生頁面。它支持目前絕大多數資料庫。還有一點,PHP是完全免費的,不用花錢,你可以從PHP官方站點(http:
//www.php.net)自由下載。而且你可以不受限制地獲得源碼,甚至可以從中加進你自己需要的特色。
JSP是Sun公司推出的新一代開發語言,Sun公司藉助自己在Java上的不凡造詣,將Java從Java應用程序和Java
Applet之外,又有新的碩果,就是JSP,Java
Server
Page。JSP可以在Serverlet和JavaBean的支持下,完成功能強大的站點程序。
ASP.NET
ASP
最新的版本
ASP.NET
並不完全與
ASP
早期的版本後向兼容,因為該軟體進行了完全重寫。早期的
ASP
技術實際上與
PHP
的共同之處比與ASP.NET

PHP的共同之處多得多,ASP.NET
是用於構建
Web
應用程序的一個完整的框架。這個模型的主要特性之一是選擇編程語言的靈活性。ASP.NET
可以使用腳本語言(如
JScript、VBScript、Perlscript

Python)以及編譯語言(如
VB、C#、C、Cobol、Smalltalk

Lisp)。新框架使用通用的語言運行環境
(CLR);先將您語言的源代碼編譯成
Microsoft
中間語言代碼,然後
CLR
執行這些代碼。
這個框架還提供真正的面向對象編程
(OOP),並支持真正的繼承、多態和封裝。.NET
類庫根據特定的任務(例如,使用
XML
或圖像處理)組織成可繼承的類。
除了編程語言和方法之外,當您用
ASP.NET
編程時,可以用
ODBC
來集成資料庫;ODBC
提供了一組一致的調用函數來訪問您的目標資料庫。
優勢和弱點:
ASP.NET
的優勢很明顯在於它簡潔的設計和實施。這是面向對象的編程人員的夢想:語言靈活,並支持復雜的面向對象特性。在這種意義下,它真正能夠與編程人員現有的技能進行互操作。
ASP.NET
的另一個優勢是其開發環境。例如,開發人員可以使用
WebMatrix(一個社區支持的工具)、Visual
Studio
.NET
或各種
Borland
工具(如
Delphi

C++
Builder)。例如,Visual
Studio
允許設置斷點、跟蹤代碼段和查看調用堆棧。總而言之,它是一個復雜的調試環境。許多其他第三方的
ASP.NET
IDE
解決方案也將必然出現。
但是ASP.NET強健性,是以損失效率為代價的。ASP.NET
在內存使用和執行時間方面耗費非常大,這大部分歸因於較長的代碼路徑。對基於
Web
的應用程序,這些局限可能是一個嚴重的問題,因為在
Web
上,您的應用程序可能擴展為每秒成千上萬的用戶。內存使用率還可能成為
Web
伺服器上的一個問題。
這幾個都提供在
HTML代碼中混合某種程序代碼、由語言引擎解釋執行程序代碼的能力。但JSP代碼被編譯成
Servlet並由Java虛擬機解釋執行,這種編譯操作僅在對JSP頁面的第一次請求時發生。在ASP
、PHP、JSP環境下,HTML代碼主要負責描述信息的顯示樣式,而程序代碼則用來描述處理邏輯。普通的
HTML頁面只依賴於Web伺服器,而ASP
、PHP、JSP頁面需要附加的語言引擎分析和執行程序代碼。程序代碼的執行結果被重新嵌入到HTML代碼中,然後一起發送給瀏覽器。ASP
、PHP、JSP三者都是面向Web伺服器的技術,客戶端瀏覽器不需要任何附加的軟體支持。
性能比較:
有人做過試驗,對這ASP、PHPP、JSP三種語言分別做迴圈性能測試及存取Oracle資料庫測試。在循環性能測試中,JSP只用了令人吃驚的四秒鍾就結束了20000*20000的迴圈。而ASP、PHP測試的是2000*2000循環(少一個數量級),卻分別用了63秒和84秒。(參考PHPLIB)。
資料庫測試中,三者分別對
Oracle
8
進行
1000

Insert,Update,Select和Delete:
JSP
需要
13
秒,PHP
需要
69
秒,ASP則
需要
73
秒。
前景分析:
目前在國內PHP與ASP應用最為廣泛。而JSP由於是一種較新的技術,國內採用的較少。但在國外,JSP已經是比較流行的一種技術,尤其是電子商務類的網站,多採用JSP。採用PHP的網站如新浪網(sina)、中國人(Chinaren)等,但由於PHP本身存在的一些缺點,使得它不適合應用於大型電子商務站點,而更適合一些小型的商業站點。首先,PHP缺乏規模支持。其次,缺乏多層結構支持。對於大負荷站點,解決方法只有一個:分布計算。資料庫、應用邏輯層、表示邏輯層彼此分開,而且同層也可以根據流量分開,群組成二維數組。而PHP則缺乏這種支持。還有上面提到過的一點,PHP提供的資料庫介面支持不統一,這就使得它不適合運用在電子商務中。
ASP和JSP則沒有以上缺陷,ASP可以通過Microsoft
Windowsd的COM/DCOM獲得ActiveX規模支持,通過DCOM和Transcation
Server獲得結構支持;JSP可以通過SUN
Java的Java
Class和EJB獲得規模支持,通過EJB/CORBA以及眾多廠商的Application
Server獲得結構支持。三者中,JSP應該是未來發展的趨勢。世界上一些大的電子商務解決方案提供商都採用JSP/Servlet。比較出名的如IBM的E-business,它的核心是採用JSP/Servlet的Web
Sphere。它們都是通過CGI來提供支持的。但去年10月後它推出了Enfinity,一個採用JSP/Servlet的電子商務Application
Server,而且聲言不再開發傳統軟體。
總之,ASP,PHP,JSP,.Net都有相當數量的支持者,由此也可以看出各有所長。正在學習或使用動態頁面的朋友可根據他們的特點選擇一種適合自己的語言。
參考資料:www.laoqiang.net

9. PHP函數執行時間過長無響應,有什麼優化的辦法

可以採用MQ,首先將task丟進Q裡面,然後給出用戶提示,前台頁面輪詢後台結果。
如果數據量過大建議分批處理,拆分成多個task即可。

閱讀全文

與php耗時任務相關的資料

熱點內容
現代鋼琴教程pdf 瀏覽:25
客戶端框架源碼 瀏覽:210
python自動辦公能幹嘛 瀏覽:873
程序員追愛 瀏覽:252
程序員邏輯故事 瀏覽:768
加密icsot23i2c 瀏覽:713
你們有什麼好的解壓軟體 瀏覽:607
常州空氣壓縮機廠家 瀏覽:241
安卓如何關閉app內彈出的更新提示 瀏覽:409
e4a寫的app怎麼裝蘋果手機 瀏覽:201
海立壓縮機海信系 瀏覽:210
社保如何在app上合並 瀏覽:220
小米加密照片後綴 瀏覽:236
我的世界網易手機怎麼創伺服器 瀏覽:978
載入單頁源碼 瀏覽:930
阿里雲伺服器seo 瀏覽:777
海洋斗什麼時候上線安卓 瀏覽:86
中行app如何查每日匯款限額 瀏覽:840
輸入伺服器sn是什麼意思 瀏覽:725
sha1演算法java 瀏覽:90