php讀寫分離
㈠ 什麼是php
PHP是一個基於服務端來創建動態網站的腳本語言,您可以用PHP和HTML生成網站主頁。當一個訪問者打開主頁時,服務端便執行PHP的命令並將執行結果發送至訪問者的瀏覽器中,這類似於ASP和CoildFusion,然而PHP和他們不同之處在於PHP開放源碼和跨越平台,PHP可以運行在WINDOWS NT和多種版本的UNIX上。它不需要任何預先處理而快速反饋結果,它也不需要mod_perl的調整來使您的伺服器的內存映象減小。PHP消耗的資源較少,當PHP作為Apache Web伺服器一部分時,運行代碼不需要調用外部二進製程序,伺服器不需要承擔任何額外的負擔。
除了能夠操作您的頁面外,PHP還能發送HIIP的標題。您可以設置cookie,管理數字簽名和重定向用戶,而且它提供了極好的連通性到其它資料庫(還有ODBC),集成各種外部庫來做用PDF文檔解析XML的任何事情。
有了PHP就無需特殊的開發環境和IDE,您可以以<?php 作為程序塊的開始,可以以 ?>作為PHP代碼塊的結束,當然您也可以用帶有<% %>的標記甚至用<SCRIPT LANGUAGE=「php」></script>的ASP的格式來配置PHP,PHP會在那些標志間處理所有的事情。
PHP的編程語言類似與C和Perl。在使用它們之前您沒必要聲明任何變數,而且建立數組和Hash是很簡單的事情。PHP還有一些面向對象的特徵,可以為組織和打包您的代碼提供很好的幫助。
雖然PHP在Apache里能快速運行,但是在PHP網站里有一些用來對Microsoft IIS 和Netscape Enterprise Server無縫結合的指令集。如果您還沒有 PHP的話,您可以在 http://www.php.com 下載,您也可以使用操作手冊,它里邊包括了所有的關於PHP的功能和特性的說明。
㈡ php是干什麼用的
PHP,一個嵌套的縮寫名稱,是英文超級文本預處理語言(PHP:Hypertext Preprocessor)的縮寫。PHP 是一種 HTML 內嵌式的語言,PHP與微軟的ASP頗有幾分相似,都是一種在伺服器端執行的嵌入HTML文檔的腳本語言,語言的風格有類似於C語言,現在被很多的網站編程人員廣泛的運用。
PHP 獨特的語法混合了C、Java、Perl 以及 PHP 自創新的語法。它可以比 CGI 或者 Perl 更快速的執行動態網頁。PHP是全球范圍內應用廣泛的開發語言,PHP因其開發周期短、免費、穩定、安全、簡單易學、跨平台性等因素入選全球五大受歡迎的編程語言!
㈢ php中::代表什麼意思
php中的::是調用類中的靜態方法或者常量,屬性的符號
例如
class aaa{
static function ar(){
}
function br(){}
}
使用非靜態方法,要先創建實例
$obj = new aaa();
$obj -> br();
使用靜態方法,無需創建實例,直接使用類名
aaa::ar();
㈣ php是什麼
PHP 是一種易於學習和使用的伺服器端腳本語言。只需要很少的編程知識你就能使用PHP 建立一個真正交互的WEB 站點。本教程並不想讓你完全了解這種語言,只是能使你盡快加入開發動態web站點的行列。我假定你有一些HTML(或者HTML編輯器)的基本知識和一些編程思想。
簡介
PHP 是能讓你生成動態網頁的工具之一。PHP 代表:超文本預處理器(PHP:Hypertext Preprocessor)。PHP 是完全免費的,不用花錢,你可以從PHP 官方站點(http://www.php.net)自由下載。PHP 遵守GNU 公共許可(GPL),在這一許可下誕生了許多流行的軟體諸如linux和Emacs。你可以不受限制的獲得源碼,甚至可以從中加進你自己需要的特色。PHP 在大多數Unix 平台,GUN/Linux和微軟Windows平台上均可以運行。怎樣在Windows環境的PC 機器或Unix機器上安裝PHP 的資料可以在PHP 官方站點上找到,也可以查閱網頁陶吧的「PHP 安裝全攻備」專題文章。安裝過程很簡單。
如果你的機器解決了2000問題,那麼PHP 也一樣沒有千年蟲問題!
歷史
三年前,Rasmus Lerdorf為了創建他的在線簡歷而創造了"個人主頁工具"(Personal Home Page Tools)。這是一種非常簡單的語言。其後越來越多的人們注意到了這種語言並對其擴展提出了各種建議。在許多人的無私奉獻下以及這種語言本身的源代碼自由性質,它演變成為一種特點豐富的語言,而且現在還在成長中。
PHP 雖然很容易學習,但是速度上比mod_perl(植入web伺服器的perl模塊)慢。現在有了可以與mod_perl 速度想媲美的被稱作Zend 的新引擎,而PHP4 就可以充分利用這個引擎。現在,PHP4 正式版已經發布,大家可以到php 的官方站點上去下載。Andy Gutmans 和Zeev Suraki 是Zend 的主要作者。可以去Zend 站點(http://www.zend.com)了解更多。
PHP 的應用在個人性質的web工程中增長顯著。根據Netcraft在1999 年10月的報告,有931122個域和321128 個IP 地址利用PHP 技術。
PHP 的先進之處
應用PHP 有許多好處。當然已知的不利之處在於PHP 由於是開放源碼項目,沒有什麼商業支持,並且由此而帶來的執行速度緩慢(直到PHP4 之前)。但是PHP 的郵件列表很是有用而且除非你正在運行像Yahoo!或者Amazon.com 這樣的極受歡迎的站點,你不會感覺出PHP 的速度與其他的有什麼不同。最起碼我就沒有感覺出來!好了,讓我們來看看PHP 有那些優點:
學習過程
我個人更喜歡PHP 的非常簡單的學習過程。與Java和Perl 不同,你不必把頭埋進100 多頁的文檔中努力學習才可以寫出一個象樣的程序。只要了解一些基本的語法和語言特色,你就可以開始你的PHP 編碼之旅了。之後你在編碼過程中如果遇到了什麼麻煩,還可以再去翻閱相關文檔。
PHP 的語法類似於C,Perl,ASP 或者JSP。對於那些對上述之一的語言較熟悉的人來說,PHP 太簡單了。相反的,如果你對PHP 了解較多,那麼你對於其他幾種語言的學習都很簡單了。
你只需要30分鍾就可以將PHP 的核心語言特點全部掌握,你可能已經非常了解HTML,甚至你已經知道怎樣用編輯設計軟體或者手工來製作好看的WEB 站點。由於PHP 代碼能夠無障礙的添加進你的站點,在你設計和維護站點的同時,你可以很輕松的加入PHP 使得你的站點更加具有動態特性。
資料庫連接
PHP 可以編譯成具有與許多資料庫相連接的函數。PHP 與Mysql是現在絕佳的組合。你還可以自己編寫外圍的函數取間接存取資料庫。通過這樣的途徑當你更換使用的資料庫時,可以輕松的更改編碼以適應這樣的變化。PHPLIB就是最常用的可以提供一般事務需要的一系列基庫。
可擴展性
就像前面說的那樣,PHP 已經進入了一個高速發展的時期。對於一個非程序員來說為PHP 擴展附加功能可能會比較難,但是對於一個PHP 程序員來說並不困難。
面向對象編程
PHP 提供了類和對象。基於web的編程工作非常需要面向對象編程能力。PHP支持構造器、提取類等。
可伸縮性
傳統上網頁的交互作用是通過CGI來實現的。CGI程序的伸縮性不很理想,因為它為每一個正在運行的CGI程序開一個獨立進程。解決方法就是將經常用來編寫CGI程序的語言的解釋器編譯進你的web伺服器(比如mod_perl,JSP)。PHP 就可以以這種方式安裝,雖然很少有人願意這樣以CGI方式安裝它。內嵌的PHP 可以具有更高的可伸縮性。
更多特點
PHP 的開發者們為了更適合web編程,開發了許多外圍的流行基庫,這些庫包含了更易用的層。你可以利用PHP 連接包括Oracle,MS-Access,Mysql在內的大部分資料庫。你可以在蒼蠅上畫圖,編寫程序下載或者顯示e-mail。你甚至可以完成網路相關的功能。最好的是,你可以選擇你的PHP 安裝版本需要哪些功能。引用Nissan 的Xterra 的話來說就是PHP 可以做到你想讓它做到的一切而且無所不能!
㈤ PHP是什麼
PhP通過協議也支持與其他服務的"交談",像imap, snmp, nntp, pop3, 甚至是 http. 你也可以打開晦澀的 網路介面和其他協議交互.
php的簡要歷史
1994年秋季, rasmus lerdorf 開始構思 php. 早期的非發行版本被用在他的主頁上,以追蹤誰在看他的在線簡歷. 1995年年初第一版本出台,當時php只被認為是個人主頁開發工具.它由一個非常單純的只能理解很少數特殊宏的分析引擎和 一些用在主頁後端通用的工具組成.如留言簿,計數器和其他一些東西.這個分析器在1995年年中被重寫並被命名為 php/fi 第二版. fi來自 rasmus 寫的另外一個包, 用於解釋 html 形式的數據.他結合了個人主頁工具腳本和形式解析器,並加 上msql支持.這樣就產生 php/fi 了. php/fi以令人驚奇的步調成長,人們開始把自己的代碼貢獻給它.
很難給出它的硬統計表,但可以估計在1996年末,整個世界至少有15,000個網站在用php/fi.到1997年年中,這個 數字已經超過50,000了. 而在此時php的發展也發生了變化.由rasmus自己偏愛的和幾個人開發的項目變成一個更有組織的團 體成就.ev suraski和andi gutmans重寫了解析器.這個新的解析器成為php版本3的基礎.許多有用的代碼從php/fi 繼承到php3,並且很多是完全重寫的.
今天(1999年年中)不管是php/fi或php3與很多商業產品捆綁在一塊,例如c2級強度的web伺服器和紅帽子linux. 根據netcraft提供的數據推斷,保守估計全世界應用php的網站已超過150,000個.由此看來,它比在網際網路上運行netscape 的旗艦企業伺服器的站點還多.
1.php是網頁文件.需要有支持php的web伺服器,才能通過瀏覽器打開.如果你實在要打開,用記事本也可以打開,不過裡面是些網頁代碼.你不一定讀得懂 .
2.你所下載的只不過是一個指向(或包含)那個手機鈴聲的網頁,你要真正得到那個鈴聲的地址才能下載它 .
3.應該不是php,是pdf,你把後綴改一下,php文件是網頁格式,用文本編輯器打開,但是本站提供的大部分是pdf格式的,安裝一個pdf閱讀器就能正常打開了.
4.「把擴展名改成 html ,然後用IE打開。」
5.如果安裝了dreamwaver,php文件會顯示dreamwaver可以打開的樣式
不過用不著
到你下載過的貼子里,看你下載的那個東西的擴展名是什麼,比如word文檔後面就是.doc, pdf文檔後面就是.pdf, 壓縮文檔後面就是.rar或 .zip之類的
然後把擴展名替換.php就能開了
我以前好像遇到過這種問題,好像是用下載工具下載的時候有些不默認修改回原來的擴展名吧。
一般論壇里的東西都不是很大,直接點擊保存就行了,就不會遇到這種情況了
6.記事本其實就可以了
你要用Word、Fontpage也可以~
反正都是PHP腳本語言~
7.PHP文件是動態網頁文件,它的運行需要ISS服務的支持,如果你想在IE瀏覽器中打開的話,必須安裝ISS服務,否則無法運行。
ISS服務是INTERNET信息服務,安裝步驟:
(1)控制面板--添加刪除程序--添加刪除組件---Internet信息服務--安裝。安裝完成後,會在管理工具中生成Internet信息服務組件,還會在C盤生成Inetpub文件夾,裡面有一個WWWROOT文件夾。
(2)將你PHP文件放到WWWROOT文件夾中,必須是這個文件夾,放在其它文件夾無效.
(3)打開IE瀏覽器,在地址欄中輸入:http://127.0.0.1/****
****是你的PHP文件名,也可以將PHP文件名改為 default.asp,這樣就不用輸入文件名,直接回車就行了,127.0.0.1是指本地機器。
㈥ PHP主要應用那些方面
1、服務端腳本。
這是 PHP 最傳統,也是最主要的目標領域。開展這項工作需要具備以下三點:
A、PHP 解析器(CGI 或者伺服器模塊)、
B、web 伺服器、
C、web 瀏覽器。
需要在運行 web 伺服器時,安裝並配置 PHP,
然後,可以用 web 瀏覽器來訪問 PHP 程序的輸出,即瀏覽服務端的 PHP 頁面。
如果只是實驗 PHP 編程,所有的這些都可以運行在自己家裡的電腦中。
2、命令行腳本。
可以編寫一段 PHP 腳本,並且不需要任何伺服器或者瀏覽器來運行它。
通過這種方式,僅僅只需要 PHP 解析器來執行。
這種用法對於依賴 cron(Unix 或者 Linux 環境)
或者 Task Scheler(Windows 環境)的日常運行的腳本來說是理想的選擇。
這些腳本也可以用來處理簡單的文本。
3、編寫桌面應用程序。
對於有著圖形界面的桌面應用程序來說,PHP 或許不是一種最好的語言,
但是如果用戶非常精通 PHP,並且希望在客戶端應用程序中使用 PHP 的一些高級特性,
可以利用 PHP-GTK 來編寫這些程序。用這種方法,還可以編寫跨平台的應用程序。
PHP-GTK 是 PHP 的一個擴展,在通常發布的 PHP 包中並不包含它。
如果對 PHP-GTK 感興趣,請訪問其網站以獲取更多信息。
㈦ php是干什麼用的
PHP主要用來做網站開發,許多小型網站都用PHP開發,PHP是開源的,這是使得PHP經久不衰的原因。
在電商、社區等方面,PHP具備非常成熟的開源代碼和模板,因此使得PHP應用極為廣泛。
PHP可以完成任何CGI腳本可以完成的任務,但它的功能的發揮取決於它和各種資料庫的兼容性。
㈧ PHP有什麼優勢嗎,想轉行做軟體開發,朋友建議學PHP
1、良好的安全性
PHP是開源軟體,所有PHP的源代碼每個人都可以看得到,代碼在許多工程師手中進行了檢測,同時它與Apache編繹在一起的方式也可以讓它具有靈活的安全設定,PHP具有了公認的安全性能。開源造就了強大,穩定,成熟的系統。
2、跨平台特性
PHP幾乎支持所有的操作系統平台及資料庫系統,並廣為流行。
3、執行速度快, 效率高
PHP是一種強大的CGI腳本語言,語法混合了C、Java、Perl和PHP式的新語法,執行網頁速度比CGI、Perl和ASP更快,而且內嵌Zend加速引擎,性能穩定快速,佔用系統資源少,代碼執行速度快。PHP消耗相當少的系統資源。的源代碼: 所有的PHP源代碼事實上都可以得到。
4、很好的移植性和 擴展性強
PHP具有很好的開放性和可擴展性,PHP可以運行在任何伺服器上(不管是windows還是Linux)屬於自由軟體,其源代碼完全公開,任何程序員為PHP擴展附加功能都非常容易。在很多網站上都可以下載到最新版本的PHP。目前,PHP主要是基於Web伺服器運行的,支持PHP腳本運行的伺服器有多種,其中最有代表性的為Apache和IIS。
5、降低網站開發成本
PHP不受平台束縛,可以在UNIX、Linux等眾多不同的操作系統中架設基於PHP的Web伺服器。採用Linux+Apache+PHP+MySQL這種開源免費的框架結構可以為網站經營者節省很大一筆開支.
6.支持面向對象
面向對象編程(OOP)是當前的軟體開發趨勢,PHP對OOP提供了良好的支持。可以使用OOP的思想來進行PHP的高級編程,對於提高PHP編程能力和規劃好Web開發構架都非常有意義。
7.功能強大
PHP在Web項目開發過程中具有極其強大的功能,而且實現相對簡單,主要表現在如下幾點:
可操縱多種主流與非主流的資料庫,例如:MySQL、Access、SQL Server、Oracle、DB2等,其中,PHP與MySQL是現在絕佳的組合,可以跨平台運行。
可與輕量級目錄訪問協議進行信息交換。
可與多種協議進行通信,包括IMAP、POP3、SMTP、SOAP和DNS等。
使用基於POSIX和Perl的正則表達式庫解析復雜字元串。
可以實現對XML文檔的有效管理及創建和調用Web服務等操作。
8.可選擇性
PHP可以採用面向過程和面向對象兩種開發模式,並向下兼容,開發人員可以從所開發網站的規模和日後維護等多角度考慮,選擇所開發網站應採取的模式。
PHP進行Web開發的過程中使用最多的是MySQL資料庫。PHP 5.0以上版本中不僅提供了早期MySQL資料庫操縱函數,而且提供了MySQLi擴展技術對MySQL資料庫的操縱,這樣開發人員可以從穩定性和執行效率等方面考慮操縱MySQL資料庫的方式。
9.版本更新速度快
與數年才更新一次的ASP相比,PHP的更新速度要快得多,因為PHP幾乎每年更新一次。
10.模板化
實現程序邏輯與用戶界面的分離。
11.應用范圍廣
目前在互聯網有很多網站的開發都是通過PHP語言來完成的,例如,搜狐、網易和網路等,在這些知名網站的創作開發中都應用到了PHP語言。
㈨ 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系統變大的過程,實際上就是我們解決問題的過程。在不同的階段,解決不同的問題,而新的問題又誕生在舊的解決方案之上。
系統的優化是沒有極限的,軟體和系統架構也一直在快速發展,新的方案解決了老的問題,同時也帶來新的挑戰。