天天看點

《MySQL DBA修煉之道》——3.4 PHP開發

本節書摘來自華章出版社《mysql dba修煉之道》一書中的第3章,第3.4節,作者:陳曉勇,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視

3.4.1 概述

一般的流行語言,如php、c、perl、java都對mysql提供了完善支援,這其中php是最常用的使用mysql資料庫的語言,網際網路普遍使用的是lamp/lnmp架構,這裡的p可以了解為就是php,可以說php的應用範圍相當廣泛,尤其是在web程式的開發上,比如,我們熟知的facebook,就是php、mysql的重度使用者。作為網際網路開發者,我們有必要熟悉mysql在各種語言環境下的使用,尤其是php。

以下簡要介紹php與mysql開發,php(全稱為hypertext preprocessor,即超文本預處理器)是一種開源的通用計算機腳本語言,它是伺服器端的解釋語言,可以嵌入到html頁面中,這些代碼在每次頁面通路時都将被執行。php代碼将在web伺服器中被解釋并且生成html或通路者看到的其他輸出界面。

如果想要學習php+mysql開發,那麼首先需要搭建一個适合練習的開發環境。對于作業系統,建議使用linux;web伺服器建議使用apache或nginx;資料庫當然是mysql了。網上有很多搭建lamp(linux、apache、mysql、php)環境的文檔,大家可以搜尋檢視。

也有一些內建的自動安裝包,如xampp,可以一鍵安裝幫你部署好所有環境,但還是建議手動部署下環境,進而對web伺服器的配置檔案、php的配置檔案有一定的了解。

3.4.2 用戶端通路過程

下面簡單介紹下傳統網站的通路資料流。在用戶端(使用者)與資料庫伺服器之間往往還會涉及web伺服器和負載均衡裝置。作為一個開發者,需要清楚資料是如何在用戶端和伺服器之間進行傳遞的。下面簡單說明下用戶端通路資料庫伺服器中間經過的環節,這裡以windows pc浏覽器為例進行說明,并解釋一些軟硬體基礎概念。

1.通路dns服務

使用者在浏覽器的位址欄輸入網址域名,浏覽器會查詢這個域名與ip的對應關系是否已經存在于本機的host檔案中,如果沒有,則會把請求發送給本機指定的域名系統(domain name system,dns)伺服器。

什麼是域名系統伺服器呢?

計算機世界是以ip位址來定位伺服器或pc的,dns這項服務的目的就是将域名翻譯成ip,使使用者可以更友善地通路網際網路。dns伺服器有一定的層級,如果某個dns伺服器不知道如何翻譯,就會問另外一個,再不知道,再問下一個,這樣就會有一個遞歸的過程。幸運的是,dns可以緩存查詢結果,這樣我們就不需要經曆重複冗長的過程去查找一個域名映射的ip位址。

dns系統中,常見的資源記錄類型有如下兩種。

主機記錄(a記錄):用于名稱解析的重要記錄,它将特定的主機名映射到對應主機的ip位址上。

别名記錄(cname記錄):用于将某個别名指向到某個a記錄上,這樣的好處是修改ip的時候改a記錄就可以了,對于有大量子域名的網站可以簡化操作、統一維護域名指向。

dns查詢有兩種方式:遞歸和疊代。dns用戶端設定使用的dns伺服器一般都是遞歸伺服器,它負責全權處理用戶端的dns查詢請求,直到傳回最終結果。而dns伺服器之間一般采用疊代查詢的方式。

下面以查詢 zh.wikipedia.org 為例。

用戶端發送查詢封包“query zh.wikipedia.org”至dns伺服器,dns伺服器首先檢查自身緩存,如果存在記錄則直接傳回結果。

如果記錄老化或不存在,則dns伺服器向根域名伺服器發送查詢封包“query zh.wikipedia.org”,根域名伺服器傳回“.org”域的權威域名伺服器位址。

dns伺服器向“.org”域的權威域名伺服器發送查詢封包“query zh.wikipedia.org”,得到“.wikipedia.org”域的權威域名伺服器位址。

dns伺服器向“.wikipedia.org”域的權威域名伺服器發送查詢封包“query zh.wikipedia.org”,得到主機zh的a記錄,存入自身緩存并傳回給用戶端。

dns系統還有一個很重要的概念:ttl(time to live的縮寫),簡單地說,它表示的是一條域名解析記錄在dns伺服器上的緩存時間。當一個遞歸域名伺服器查詢權威域名伺服器擷取某個域名的映射時,它會将該記錄緩存上一定的時間,這個時間就是ttl指定的時間(以秒為機關)。如果在一台linux機器上反複運作指令“dig www.mysql.com”,就會發現這個緩存時間在減少,為什麼呢?因為在你的dns緩存中,這筆記錄能夠儲存的時間開始倒計數,如果ttl沒有歸零,緩存伺服器會簡單地用已緩存的記錄答複查詢請求。若這個數字歸零後,下次再有人重新搜尋這筆記錄時,你的dns就需要從權威域名伺服器重新擷取記錄。也就是說,如果更改了域名的指向,那麼最長需要ttl時間才會完全

生效。

了解dns系統不僅僅是運維團隊的事情,研發人員也有必要清楚其大概的機制。我們在部署程式或設計遷移方案的時候,需要清楚是否要申請域名、建立新的cname記錄,是否需要修改ttl生效時間,是否需要修改a記錄。另外需要注意的是,雖然有ttl的機制,但由于國内移動網絡的特殊性,dns的修改可能長期不能生效,由于其特殊的分布式資料庫的設計,如果遭到域名污染,往往也會造成巨大的影響,這種問題很難解決。

2.經過負載均衡軟硬體裝置

經過負載均衡軟硬體裝置如f5、haproxy、lvs後,再把請求轉發給後端的網絡服務。

負載均衡(load balance),即将負載(工作任務)進行平衡、分攤到多個操作單元上進行執行,例如web伺服器、ftp伺服器、企業關鍵應用伺服器和其他關鍵任務伺服器等,進而共同完成工作任務。當後端的一台伺服器當機或過載,負載均衡軟硬體裝置将不再轉發流量到這台伺服器,轉而發送到備用的伺服器上,進而實作自動故障備援切換。

最早的負載均衡技術是通過dns來實作的,在dns中為多個位址配置同一個名字,因而查詢這個名字的客戶機将得到其中的一個位址,進而使得不同的客戶通路不同的伺服器,達到負載均衡的目的。dns負載均衡是一種簡單而且有效的方法,但是它不能區分伺服器的差異,也不能反映伺服器的目前運作狀态,對于高并發、大流量的請求,很容易導緻負載并不均衡。現實中,它可能作為更上層的負載均衡存在,完成粗粒度的流量排程任務,比如在機房之間使用dns負載均衡,在機房内部使用其他負載均衡方式。

f5負載均衡器是應用傳遞網絡的全球上司者f5 networks公司提供的一個負載均衡器專用裝置,一般需要配置雙機故障備援切換。f5主要應用于傳統行業内,如電信、移動、銀行等,也有許多網際網路公司使用f5裝置,雖然f5裝置比較昂貴,但在一定規模下,它可以降低企業的成本,代替系統管理者、工程師管理各種資源。網際網路公司用得比較多的是f5 big-ip ltm(本地流量管理器),由于國内網絡的複雜性,也有使用big-ip廣域網流量管理器(big-ip gtm)的。f5裝置除了負載均衡外,還有一些其他的功能,如利用壓縮技術降低帶寬支出、減少連接配接數等。

f5等硬體裝置畢竟是商業化的産品,比較昂貴,在一定規模下使用可以獲得比較好的投資回報率,但在公司初創時,或者公司已經流量很大的時候,f5裝置的成本優勢則并不明顯,目前很多公司的f5裝置已經逐漸被lvs等其他軟體替代,是以,對于網際網路公司,一般建議使用開源軟體實作負載均衡,常用的有lvs、haproxy等,它們和其他技術配合使用可以實作很好的擴充性,無論是在流量很小還是流量很大的情況下,都能夠滿足需要。網上有很多關于lvs、haproxy的資料,這裡不再贅述。

3.經過反向代理服務

反向代理是代理伺服器的一種,比如squid、vanish等。它根據用戶端的請求,從後端的伺服器上擷取資源,然後再将這些資源傳回給用戶端。常用的代理服務為squid,它可以作為緩存伺服器,可以過濾流量保證網絡安全,也可以作為代理伺服器鍊中的一環,向上級代理轉發資料或直接連接配接網際網路,一些網站往往在前端增加squid反向代理加速響應、提高吞吐量。squid可以緩存内容,特别是一些靜态的資料,比如圖檔和檔案,如果反向代理靠近使用者的網絡,那麼使用者就會得到延時很低的高品質通路,這正是cdn技術的核心。

4.到達web伺服器

web伺服器包括nginx、apache、lighttpd、tomcat、resin等。

apache http server(簡稱apache)是apache軟體基金會的一個開放源代碼的網頁伺服器,是使用最廣泛、最流行web伺服器端軟體之一。apache功能最完備,但占用的資源比較多,支援的連接配接數也比nginx少,是以目前在網際網路界,已經被nginx搶了風頭。

nginx(發音同engine x)是一款由俄羅斯程式員igor sysoev所開發的輕量級的網頁伺服器,它也可以用作反向代理、負載均衡器,但更常見的功能是web伺服器。它是一款面向性能設計的http伺服器,以事件驅動的方式編寫,很注重效率,是以在許多評測中,相比于apache都有更高的性能,能支撐更多的并發請求。

在常見的網絡架構中,nginx往往配合php-fpm使用,nginx負責處理靜态請求,把php等動态請求抛給後端的php-fpm處理。或者nginx處理前端的靜态請求,把apache放在後端處理一些動态請求。是以各種web伺服器之間可能也有一定的層級關系或功能分工,這點需要了解清楚。

5.調用應用伺服器

應用程式伺服器是通過很多協定來為應用程式提供商業邏輯的伺服器。

根據我們的定義,作為應用程式伺服器,它将通過各種協定(包括http),把商業邏輯暴露給用戶端應用程式。web伺服器主要是處理向浏覽器發送html以供浏覽,而應用程式伺服器則提供通路商業邏輯的途徑以供用戶端應用程式使用。

這裡所說的應用伺服器更多地屬于内部調用的範疇。一般web伺服器可以高效地處理簡單的響應請求,但如果有複雜的商業邏輯的話,把這些業務邏輯放到獨立的應用伺服器上,然後通過調用的方式來擷取資訊會更安全、性能更高、開發也更友善。

6.通路資料庫

用戶端不直接和資料庫打交道,如果處理邏輯需要通路資料,則由應用伺服器或web伺服器通路資料庫,擷取資料。

以上架構是比較普通的三層/四層架構,架構中也可能有一個緩存(cache)服務,以減輕資料庫的壓力。web伺服器、應用伺服器到資料庫伺服器中間可能存在資料中間件,但更正常的做法是通過在web伺服器、應用服務程式配置檔案裡指定ip或内網域名來配置資料庫路由。

生産環境裡,如果出現了性能問題,研發人員往往第一時間就會懷疑是資料庫出現了性能問題,但事實往往并非如此,從上面的叙述可知,使用者的通路請求經過了許多環節,有dns、負載均衡裝置、web伺服器,而且長距離網絡中的資料傳輸實體上還需要經過許多裝置,如路由器、交換機等,由于國内網絡的特殊性和複雜性,有時會碰到網絡丢包,丢包很可能導緻性能問題。是以,如果出現了性能問題或通路異常,研發、運維人員就需要仔細甄别到底是哪個環節出現了問題,配合各種監控和日志記錄,是有可能快速定位到問題症結所在的。

《MySQL DBA修煉之道》——3.4 PHP開發

3.4.3 開發工具

這裡主要介紹一款常用的基于web的管理工具phpmyadmin。

phpmyadmin 是一個以php為基礎的mysql的資料庫管理工具。讓管理者可以通過web接口操作資料庫,也就是于遠端管理mysql資料庫。

研發人員并不像dba那樣經常通過指令行來操作資料庫,是以往往會不熟悉指令行,借由這套圖形工具,可以友善地建立、修改、删除資料庫及表、浏覽資料、插入資料、删除資料。

phpmyadmin也是很好的學習工具,可以生成sql語句,驗證文法,也可以生成常用的php文法。對于研發人員,若要求熟練使用指令行操作資料庫,那麼這個要求确實高了些,他們應該把更主要的精力放在程式代碼的編寫上,是以,建議熟悉此類圖形工具。

需要注意的是,未經配置的phpmyadmin不安全,容易受到攻擊,建議隻将其部署在開發和測試環境中。在生産環境中,如果需要部署phpmyadmin,那麼一定要先經過安全評估,确認沒有安全漏洞,而這往往是需要通過改造phpmyadmin來實作的。

還有一些用戶端工具,如workbench、toad for mysql、sqlyog、navicat for mysql。這其中,sqlyog功能最強大,但是,它是收費軟體,workbench出自官方,對比以前的版本功能已經有了長足的進步,而且也一直在努力改進中,建議大家優先使用這個工具。

3.4.4 操作資料

如果想要做web開發,那麼讀者需要熟悉html、xml、javascript、ajax等知識。關于這些知識和php的基本文法和特性這裡不做介紹,本章主要講述php相對于資料的一些常用操作。如果需要詳細了解php開發知識,可以參考官方文檔或《php與mysql web開發》一書。

php提供了3種api可用于通路mysql,分别是mysql擴充、mysqli擴充、pdo擴充。官方的建議是使用mysqli或pdo,因為mysql擴充在未來可能被廢棄掉。mysqli隻支援mysql資料庫,如果有跨資料庫平台的需要,那麼就要使用pdo了。由于目前mysql擴充仍然有廣泛的應用,以下示例仍以mysql擴充為例,同時也将列出mysqli的代碼供讀者參考。

1. php連接配接資料庫

在通路并處理資料庫中的資料之前,必須先建立到達資料庫的連接配接。

php提供了兩個連接配接mysql的函數mysql_pconnect() 和 mysql_connect()。

mysql_connect() 函數的文法如下。

<code>mysql_connect(servername,username,password);</code>

涉及的參數詳見表3-14。

《MySQL DBA修煉之道》——3.4 PHP開發

腳本一結束,就會關閉連接配接。如需提前關閉連接配接,請使用mysql_close()函數。

2.選擇資料庫

在執行語句前,需要先選擇資料庫。通過mysql_select_db()函數可選取資料庫,它的文法如下。

《MySQL DBA修煉之道》——3.4 PHP開發

使用mysqli連接配接資料庫,語句如下。

《MySQL DBA修煉之道》——3.4 PHP開發
《MySQL DBA修煉之道》——3.4 PHP開發
《MySQL DBA修煉之道》——3.4 PHP開發

3.查詢資料

先使用mysql_query()函數向 mysql 發送查詢或指令。然後使用mysql_fetch_array函數傳回資料。

示例test_select.php語句如下。

《MySQL DBA修煉之道》——3.4 PHP開發

上面這個例子在$result變量中存放了由mysql_query()函數傳回的資料。接下來,使用mysql_fetch_array()函數以數組的形式從記錄集傳回第一行。随後對于mysql_fetch_array()函數的每個調用都會傳回記錄集中的下一行。while loop語句會循環記錄集中的所有記錄。為了輸出每行的值,這裡使用了php的$row變量($row['dept_no']和$row['dept_name'])。

4.使用mysqli查詢資料

首先建立連接配接(new mysqli),然後預處理查詢語句(使用prepare方法),執行這個語句(使用execute方法),最後,把結果集的列綁定到兩個變量(使用bind_result方法),并擷取實際資料(使用fetch方法),列印輸出。

示例test_select2.php語句如下。

5.插入記錄

類似select查詢,先連接配接資料庫(使用mysql_connect函數),然後選擇資料庫(使用mysql_select_db函數),最後發送insert語句給mysql(使用mysql_query函數)。

示例test_insert.php語句如下。

6. 使用mysqli插入記錄

建立連接配接(new mysqli),然後使用mysqli_query方法操作資料庫,執行查詢。

示例test_insert2.php語句如下。

3.4.5 php資料庫開發建議

對于開發人員來說,了解資料流和生産環境的實體部署是很重要的,開發人員不應該局限于自己的領域。

能夠熟練查閱mysql官方文檔,雖然研發人員不必熟悉mysql的每一個細節,但要善于查找資料,找到答案,一般我們經曆的問題都是可以從文檔或網絡中找到答案的。

注意安全問題,防止sql注入、跨站腳本攻擊等惡意攻擊。詳細内容可參考4.2節“權限機制和安全”。

閱讀源碼,了解它們是如何通路資料的。一些網站,如sourceforge提供了許多優秀的源碼。

注重使用者體驗,資料庫的通路優化,往往和使用者體驗相關。如果要通路資料庫或資料接口,優化的方式不外乎兩個,或者減少對資料的通路,或者讓查詢執行得更快。比如一些大頁面隻改動了幾行字,那麼查詢時可能就隻需要檢索小部分資料,而不是重載整個頁面查詢很多資料。比如地圖,隻需要加載部分塊區域,而不是整個圖重新繪制。比如翻頁,傳統的一些算法效率往往很差,影響使用者體驗。

要有性能分析器,如果想要開發高品質的程式,那麼需要對自己的程式進行分析,特别是對于資料庫通路的分析,比如記錄資料庫性能通路日志。一些工具也有助于分析網站的響應,如firebug。