PHP面試-複習知識點整理

false的七種狀況

  1. 整型0php

  2. 浮點0.0css

  3. 布爾falsehtml

  4. 空字符串'',""前端

  5. 字符串'0'mysql

  6. 空數組[]react

  7. NULLnginx

超全局數組

  1. $GLOBALS,包含下面8個超全局數組的值web

  2. $_GET正則表達式

  3. $_POSTredis

  4. $_REQUERT,包含$_GET,$_POST,$_COOKIE

  5. $_SEESION

  6. $_COOKIE

  7. $_SERVER

$_SERVER['SERVER_ADDR'] //服務器地址
$_SERVER['SERVER_NAME'] //服務名稱
$_SERVER['REQUEST_TIME'] //請求時間
$_SERVER['QUERY_STRING'] //請求地址中問號後的內容
$_SERVER['HTTP_REFERER'] //上次請求地址
$_SERVER['HTTP_USER_AGENT'] //瀏覽器信息
$_SERVER['REMOTE_ARRR'] //客戶端請求ip
$_SERVER['REQUEST_URI'] // 請求中腳本名稱
$_SERVER['PATH_INFO'] // 請求中路徑
  1. $_FIELS

  2. $_ENV

null的三種狀況

  1. 直接賦值NULL

  2. 未定義變量

  3. unset銷燬後的變量

常量

必定定義,不可刪除和修改

  1. const 更快,是語言結構,可定義類常量

  2. define 是函數

預約義常量

  1. FILE 文件所在路徑+文件名

  2. LINE 所在代碼行

  3. DIR 所在文件夾路徑

  4. FUNCTION 方法名

  5. CLASS 類名

  6. TRAIT TRAIT的名稱

  7. METHOD 類名+方法名

  8. NAMESPACE 命名空間名

引用變量

用不一樣名字訪問同一個變量內容,用『&』符號表示

抽象類和接口

抽象類:

  1. 定義爲抽象的類不能被實例化.

  2. 任何一個類,若是它裏面至少有一個方法是被聲明爲抽象的,那麼這個類就必須被聲明爲抽象的。

  3. 被定義爲抽象的方法只是聲明瞭其調用方式(參數),不能定義其具體的功能實現。

  4. 繼承一個抽象類的時候,子類必須定義父類中的全部抽象方法;另外,這些方法的訪問控制必須和父類中同樣(或者更爲寬鬆)。

  5. 例如某個抽象方法被聲明爲受保護的,那麼子類中實現的方法就應該聲明爲受保護的或者公有的,而不能定義爲私有的。此外方法的調用方式必須匹配,即類型和所需參數數量必須一致。例如,子類定義了一個可選參數,而父類抽象方法的聲明裏沒有,則二者的聲明並沒有衝突。

  6. 這也適用於 PHP 5.4 起的構造函數。在 PHP 5.4 以前的構造函數聲明能夠不同的.

接口:

  1. 使用接口(interface),能夠指定某個類必須實現哪些方法,但不須要定義這些方法的具體內容。

  2. 接口是經過 interface 關鍵字來定義的,就像定義一個標準的類同樣,但其中定義全部的方法都是空的。

  3. 接口中定義的全部方法都必須是公有,這是接口的特性。

  4. 要實現一個接口,使用 implements 操做符。類中必須實現接口中定義的全部方法,不然會報一個致命錯誤。類能夠實現多個接口,用逗號來分隔多個接口的名稱。

  5. 實現多個接口時,接口中的方法不能有重名。

  6. 接口也能夠繼承,經過使用extends操做符.

  7. 類要實現接口,必須使用和接口中所定義的方法徹底一致的方式。不然會致使致命錯誤.

區別:

  1. 對接口的繼承使用implements,抽象類使用extends.

  2. 接口中不能夠聲明變量,但能夠聲明類常量.抽象類中能夠聲明各類變量

  3. 接口沒有構造函數,抽象類能夠有

  4. 接口中的方法默認爲public,抽象類中的方法能夠用public,protected,private修飾

  5. 一個類能夠繼承多個接口,但只能繼承一個抽象類

運算符優先級

優先級由高到低排序

  1. ==遞增/遞減==

  2. 非(!)

  3. ==算術運算符==

  4. ==大小比較==

  5. (不)相等比較

  6. 引用

  7. 位運算符(^)

  8. 位運算符(|)

  9. ==邏輯與==

  10. ==邏輯或==

  11. ==三目==

  12. ==賦值==

  13. and

  14. oxr

  15. or

浮點數值得精度丟失問題

緣由:由於計算機存儲是二進制,準換進制時會有精度丟失

解決方案:先將浮點字符串化,再進行整數獲取,輸出可經過print

$f = 0.57;
$f = $f * 100;
// 輸入可經過print
print('%d', $f);

// 用於存儲或二次計算,先將浮點字符串化,再進行整數獲取
$f = strval($f);
var_dump($f);
echo floor($f);
echo intval($f);
echo (int)($f);

switch 只能判斷整型、浮點、字符

變量類型

  1. 普通變量

  2. 全局變量,經過 global 定義,能夠在局部域調用全局變量,可經過 $_GLOBAL['XXX'] 讀取變量的值

  3. 靜態變量,經過 static 定義,僅在局部域中存在,執行函數離開做用域,其值也不會消失

ip處理函數

  1. ip2long()

  2. long2ip()

時間日期處理函數

  1. date()

  2. strtotime()

  3. mktime()

  4. time()

  5. microtime()

  6. date_default_timezone_set()

打印處理

  1. print() 僅輸出單個變量

  2. printf() 按格式輸出

  3. print_r() 格式化輸出

  4. echo 輸出多個變量

  5. sprintf() 按格式返回

  6. var_dump() 格式化輸出,並輸出變量類型

  7. var_export() 將格式化輸出,加true可返回,返回內容可直接作變量使用

序列化

  1. serialize()

  2. unserialize()

字符串處理

  1. implode(),join()

  2. explode()

  3. strrev() 反轉字符

  4. trim(),ltrim(),rtrim()

  5. strstr() 獲取第一次出現指定字符串的字符串

  6. number_format() 數字格式化爲金錢格式

數組處理

  1. array_keys()

  2. array_values()

  3. array_diff()

  4. array_megre()

  5. array_shift()

  6. array_unshift()

  7. array_pop()

  8. array_push()

  9. sort(), rsort() 對數組升降序排序

  10. asort(),arsort() 對數組鍵值升降序排序

  11. ksort(),krsort() 對數組鍵名升降序排序

文件操做

fopen() 打開文件並指定模式

  1. r/r+ 只讀打開/讀寫打開,指針在文件開頭

  2. w/w+ 只寫打開/讀寫打開,文件存在會清空,不存在會建立

  3. a/a+ 寫入追加寫入/讀寫的追加寫入,指針在文件末尾

  4. x/x+ 寫入/讀寫打開,指針開頭,文件存在返回false,不存在就直接建立

  5. b 二進制打開

寫入

  1. fwrite()

  2. fputs()

讀取

  1. fread() 獲取指定長度字符

  2. fgets() 獲取一行字符

  3. fgetc() 獲取一個字符

關閉 fopen()

文件大小 filesize()

文件複製 copy()

文件刪除 unlink()

文件類型 filetype()

重命名或移動 rename()

文件屬性

  1. file_exist()

  2. is_readable()

  3. is_writable()

  4. is_executable()

  5. filectime() 建立時間

  6. fileatime() 訪問時間

  7. filemtime() 更新時間

其餘不須要fopen()打開的函數

  1. file_get_contents()

  2. file_put_contents()

其餘

  1. file()整個文件內容按行讀取到一個數組裏

  2. readfile()整個文件讀取出來,並輸出

遠程訪問

php.ini 中打開 allow_url_fopen 配置,http協議只能使用只讀,ftp協議,只能只讀或只寫

目錄操做

名稱相關

  1. basename() 文件基礎名稱

  2. dirname() 文件夾名稱

  3. pathinfo() 文件信息數組

目錄讀取

  1. opendir()

  2. readdir()

  3. closedir()

  4. rewinddir() 重置句柄

  5. disk_free_space()

  6. disk_total_space()

目錄刪除 rmdir()

目錄必須爲空

目錄建立 mkdir()

重命名或移動 rename()

設計模式

  1. 工廠模式

  2. 單例模式

  3. 適配器模式

  4. 觀察者模式

  5. 策略模式

  6. 註冊樹模式

魔術方法

  1. __construct()

  2. __destruct()

  3. __call()

  4. __callStatic()

  5. __get()

  6. __set()

  7. __isset()

  8. __unset()

  9. __sleep()

  10. __wakeup()

  11. __toString()

  12. __close()

網絡協議

http狀態碼

  1. 200 請求成功

  2. 204 not content

  3. 206 reset content

  4. 301 永久重定向

  5. 302 臨時重定向

  6. 307 臨時重定向

  7. 400 錯誤請求

  8. 401 缺乏認證信息

  9. 403 拒絕

  10. 404 不存在

  11. 500 服務器異常

  12. 502 Bad Gateway

  13. 503 服務器超負載或停機維護

OSI七層協議

  1. 物理層 創建、維護、斷開物理鏈接

  2. 數據鏈路層 創建邏輯鏈接,進行硬件地址尋址,差錯校驗等功能

  3. 網絡層 進行邏輯地址尋址,師兄不一樣網絡之間的路徑選擇

  4. 傳輸層 定義傳輸數據的協議端口號,一級流控和差錯校驗。協議有TCP/UDP,數據包一旦離開網卡即進入網絡傳輸層

  5. 會話層 創建、管理、終止會話

  6. 表示層 數據的表示、安全、壓縮

  7. 應用層 網絡服務與最終用戶的一個藉口,協議有:http(80),ftp(21),tftp,smtp(25),snmp,dns(53),telnet(23),https(443),pop3(110),dhcp

HTTP協議的工做特色和工做原理

工做特色:

  1. 基於B/S模式

  2. 通訊開銷小,簡單快速,傳輸成本低

  3. 使用靈活,可以使用超文本傳輸協議

  4. 節省傳輸時間

  5. 無狀態

工做原理:

客戶端發送請求給服務器,創建一個TCP鏈接,指定端口號,默認80,鏈接到服務器,服務器監聽到瀏覽器的請求,一旦監聽到客戶端的請求,分析請求類型後,服務器會向客戶端發送狀態信息和數據內容

HTTP協議常見請求頭/響應頭

  1. Content-Type 指定數據內容類型

  2. Accept 指定客戶端能接受數據內容類型

  3. Origin 最初請求來源(POST)

  4. Cookie

  5. Cache-Control 指定請求的緩存機制

  6. User-Agent 用戶瀏覽器信息

  7. Referrer 上級請求路徑

  8. X-Forwarded-For 請求端真實ip

  9. Access-Control-Allow-Origin 容許其餘請求域名,用於跨域

  10. Last-Modified 最後響應時間

HTTPS的工做原理

HTTPS是一種基於SSL/TLS的HTTP協議,全部的HTTP數據都是SSL/TLS協議封裝之上傳輸的

HTTPS是在HTTP協議的基礎上,添加了SSL/TLS握手一級數據加密傳輸,也屬於應用層協議

mysql相關知識

數據表引擎

  1. innodb引擎

默認事務型引擎,最重要最普遍的存儲引擎,性能很是優秀

數據存儲在共享表空間,可經過配置分開

對主鍵查詢的性能高於其餘類型的存儲引擎

內部作了不少優化,從磁盤讀取數據時自動在內存構建hash索引,插入數據時自動構建插入緩衝區

經過一些機制和工具支持真正的熱備份

支持崩潰後的安全恢復

支持行級鎖

支持外鍵

  1. MyISAM引擎

5.1版本前是默認引擎

擁有全文索引、壓縮、空間函數

不支持事務和行級鎖,不支持奔潰後安全恢復

表存儲在兩個文件,MYD和MYI

設計簡單,某些場景下性能很好

  1. 其餘引擎:

Archive、Blackhole、CSV、Memory

MySQL鎖機制

當多個查詢同一時刻進行數據修改時,會產生併發控制的問題

  1. 共享鎖(讀鎖)

  2. 排他鎖(寫鎖)

鎖粒度

  1. 表鎖

系統性能開銷最小,會鎖定整張表,myisam使用表鎖

  1. 行鎖

最大程度的支持併發處理,可是也帶來了最大的鎖開銷,innodb實現行級鎖

char與varchar

  1. char

char是定長的,根據定義的字符串長度分配足量空間
char會根據須要採用空格進行填充以方便比較
char適合存儲很短的字符串,或者全部值都接近同一個長度
char長度超過設定的長度,會被截斷
  1. varchar

varchar用於存儲可變長字符串,比定長類型更加節省空間
varchar使用1或2個額外字節記錄字符串的長度,列長度小於255字節用1個字節表示,不然用2個
varchar長度超過設定的長度,會被截斷
  1. 比較

對於常常變動的數據,char比varchar更好,char不容易產生碎片
對於很是短的列,char比varchar在存儲空間上更有效率
只分配真正須要的空間,更長的列會消耗更多的內存

索引

  1. 大大減小服務器須要掃描的數據量

  2. 幫助服務器避免排序和臨時表

  3. 將隨機I/O變順序I/O

  4. 大大提升查詢速度,下降寫的速度,佔用磁盤空間

索引類型

  1. 普通索引

  2. 主鍵索引

  3. 惟一索引

  4. 組合索引

  5. 外鍵索引

  6. 全文索引

索引建立原則

  1. 最適合索引的列是出如今where子句的列,或鏈接子句中的列,而不是出如今select的關鍵字後的列

  2. 索引列的基數越大,索引效果越好

  3. 對字符串進行索引,應指定一個前綴長度,能夠節省大量的索引空間

  4. 根據狀況建立複合索引,複合索引能夠提升查詢效率

  5. 避免建立過多索引,索引會額外佔用磁盤空間,減低寫操做效率

  6. 主鍵儘量選擇較短的數據類型,能夠有效減小索引的磁盤佔用,提升效率

索引的注意事項

  1. 複合索引遵循前綴原則

  2. like查詢,%不能在前,可使用全文索引

  3. column is null 可使用索引

  4. 若是MySQL估計使用索引比全表掃描更慢,會放棄使用索引

mysql優化

查詢速度慢的緣由

  1. 打開慢查詢日誌,經過pt-query-dugest分析

  2. show profile,經過 set profiling=1; 開啓,服務器上執行的全部語句消耗時間都會記錄到臨時表。 show profile for query QUERY_ID 查詢指定查詢

  3. show status,查詢一些計數器,猜出哪些代價高或消耗時間多

  4. show processlist,查詢線程狀態進行分析

  5. explain,分析單個SQL語句查詢

優化查詢過程當中的數據訪問

  1. 訪問數據太多致使性能降低

  2. 肯定應用程序是否檢索大量超過須要的數據,多是太多列或者行

  3. 肯定mysql是否分析大量沒必要要的數據行

  4. 查詢不須要的記錄,使用limit限制

  5. 奪標關聯返回所有列指定A.id,A.name

  6. 總數取出所有列,select * 會讓優化器沒法完成全部覆蓋掃碼的優化

  7. 重複查詢相同的數據,能夠緩存數據

  8. 改變數據庫和表的結構,修改數據表範式

  9. 重寫SQL語句,讓優化器能夠更優的執行

優化長可貴查詢語句

  1. MySQL內部每秒能掃描內存中上百萬行數據,相比之下,響應數據給客戶端就要慢得多

  2. 使用盡量少的查詢是好的,可是有時將一個大的查詢分解爲多個小的查詢是頗有必要的

  3. 分解關聯查詢,將一個關聯查詢分解爲多個sql來執行,讓緩存效率更高,執行單個查詢能夠減小鎖的競爭,在應用層作關聯能夠更容易對數據庫進行拆分,查詢效率會有大幅提高,較少冗餘記錄的查詢

優化特定類型的查詢語句

  1. 優化count()查詢, count(*) 會忽略全部列,直接統計全部列數,所以不要用 count(列名)

  2. 優化關聯查詢,肯定ON或者USING子句的列上有索引;確保 GROUP BY 和 ORDER BY 中只有一個表的列,這樣MySQL纔有可能使用索引

  3. 優化子查詢 建議使用關聯查詢替代

  4. 優化 GROUP BY 和 DISTINCT ,創建索引進行優化

  5. 優化 LIMIT 分頁,能夠經過記錄上次查詢的最大ID,若是根據id排序時,下次查詢根據該ID來查詢(如:ID > maxID)

  6. 優化 UNION 查詢, UNION ALL 性能比 UNION 高

MySQL提高(高可擴展和高可用)

分區表

工做原理

對用戶而言,分區表是一個獨立的邏輯表,可是底層MySQL將其分紅了多個物理子表,對於用戶來講是透明的,每個分區表都會使用一個獨立的表文件。

建立表的時候使用 partition by 子句定義每一個分區存放的數據,執行查詢時,優化器會根據分區定義過濾那些沒有咱們須要數據的分區,這樣查詢只須要查詢所需數據在的分區便可

分區的主要目的是將數據按照一個較粗的粒度分在不一樣的表中,這樣能夠將相關的數據存放在一塊兒,並且若是想一次性刪除整個分區的數據也很方便

適用場景

  1. 表很是大,沒法所有存在內容,或者只有表的最後有熱點數據,其餘都是歷史數據

  2. 分區表的數據更易維護,能夠對獨立的分區進行獨立操做

  3. 分區表的數據能夠分佈在不一樣機器上,從而高效使用資源

  4. 可使用分區表來避免某些特殊瓶頸

  5. 能夠備份和恢復獨立分區

限制

  1. 一個表最多隻能有1024個分區

  2. 5.1版本中,分區表表達式必須是整數,5.5可使用列分區

  3. 分區字段中若是有主見和惟一索引列,那麼主鍵和惟一列都必須包含進來

  4. 分區表中沒法使用外鍵約束

  5. 須要對現有表的結構進行改變

  6. 全部分區都必須使用相同的存儲引擎

  7. 分區函數中可使用的函數和表達式會有一些限制

  8. 某些存儲引擎不支持分區

  9. 對於MyISAM的分區表,不能使用load index into cache

  10. 對於MyISAM表,使用分區表時須要打開更多的文件描述符

分庫分表

工做原理:

經過一些HASH算法或者工具實現將一張數據表垂直或者水平物理切分

適用場景

  1. 單表記錄條數達到百萬到千萬級別時

  2. 解決表鎖的問題

分別方式

  1. 水平切分:表很大,分割後能夠減低在查詢時須要讀的數據和索引的頁數,同時也減低了索引的層數,提升查詢速度

使用場景:
1. 表中數據自己就有獨立性,例如表中分別記錄各個地區的數據或者不一樣時期的數據,特別是有些數據經常使用,有些不經常使用
2. 須要把數據存放在多個介質

缺點:
1. 給應用增長複雜度,一般查詢時須要多個表名,查詢全部數據都須要UNION操做
2. 在許多數據庫應用中,這種複雜性會超過他帶來的優勢,查詢時會增長讀一個索引層的磁盤次數
  1. 垂直分表:把主鍵和一些列放在一個表,而後把主鍵和另外的列放在另外一張表中

使用場景:
1. 若是一個表中某些列經常使用,而另一些列不經常使用
2. 可使數據行變小,一個數據頁能存儲更多數據,查詢時減小I/O次數

缺點:
1. 管理冗餘列,查詢全部數據須要JOIN操做
2. 有些分表的策略基於應用層的邏輯算法,一旦邏輯算法改變,整個分表邏輯都會改變,擴展性較差
3. 對於應用層來講,邏輯算法無疑增長開發成本

主從複製

工做原理

  1. 在主庫上把數據更改記錄到二進制日誌

  2. 從庫將主庫的日誌複製到本身的中繼日誌

  3. 從庫讀取中繼日誌中的事件,將其重放到從庫數據中

解決問題

  1. 數據分佈:隨意中止或開始複製,並在不一樣地理位置分佈數據備份

  2. 負載均衡:減低單個服務器壓力

  3. 高可用和故障切換:幫助應用程序避免單點失敗

  4. 升級測試:可使用更高版本的MySQL做爲從庫

MySQL安全

安全操做

  1. 使用預處理語句防SQL這幾日

  2. 寫入數據庫的數據要進行特殊字符轉移

  3. 查詢錯誤信息不要返回給用戶,將錯誤記錄到日誌

安全設置

  1. 按期作數據備份

  2. 不給查詢用戶root權限,合理分配權限

  3. 關閉遠程訪問數據庫權限

  4. 修改root口令,不用默認口令,使用較複雜的口令

  5. 刪除多餘的用戶

  6. 改變root用戶的名稱

  7. 限制通常用戶瀏覽其餘庫

  8. 限制用戶對數據文件的訪問權限

MVC

MVC工做原理

  1. model 數據模型操做層,是應用程序中用於處理應用程序數據邏輯的部分

  2. view 視圖層,是應用程序中處理數據顯示的部分。

  3. controller 業務處理層,是應用程序中處理用戶交互的部分。

單一入口

工做原理

用一個處理程序文件處理全部的HTTP請求,根據請求時的參數的不一樣區分不一樣的模塊和操做請求

優點

  1. 能夠進行統一的安全性檢查

  2. 集中處理程序

劣勢

  1. URL不美觀(解決方法:URL重寫)

  2. 處理效率會下降(可忽略)

模板引擎

PHP是一種HTML內嵌式在服務端執行的腳本語言,可是PHP又不少可使PHP代碼和HTML代碼分開的模板引擎,例如:smarty

工做原理

模板引擎就是龐大的完善的正則表達式替換庫

算法

排序算法

冒泡排序

原理:兩兩相鄰的數進行比較,若是反序就交換,不然不交換

時間複雜度:最壞(O(n^2)), 平均(O(n^2))

空間複雜度:O(1)

快速排序

原理:經過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的全部數據和另外一部分的全部數據都要笑,而後按照此方法對這兩部分數據分別進行快速排序,整個排序過程能夠遞歸完成

時間複雜度:最壞(O(n^2)), 平均(O(nlog2n))

空間複雜度:最差(O(n)),平均(O(log2n))

直接插入排序

原理:每次從無序表中取出第一個元素,把他插入到有序表的合適位置,使有序表仍然有序

時間複雜度:最壞(O(n^2)), 平均(O(n^2))

空間複雜度:O(1)

選擇排序

原理:每次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,知道所有待排序的數據元素排外

時間複雜度:最壞(O(n^2)), 平均(O(n^2))

空間複雜度:O(1)

希爾排序

原理:把待排序的數據根據增量分紅幾個子序列,對子序列進行插入排序,知道增量爲1,直接插入進行插入排序;增量的排序,通常是數組的長度的一半,再變爲原來增量的一半,直到增量爲1

時間複雜度:最壞(O(n^2)), 平均(O(nlog2n))

空間複雜度:O(1)

堆排序

原理:把待排序的元素按照大小在二叉樹位置上排序,排序好的元素要知足:父節點的元素要大於子節點;這個過程叫作堆化過程,若是根節點存放的最大的數,則叫作大根堆,若是是最小,就叫小跟堆,能夠把根節點拿出來,而後再堆化,循環到最後一個節點

時間複雜度:最壞(O(nlog2n)), 平均(O(nlog2n))

空間複雜度:O(1)

歸併排序

原理:將兩個(或兩個以上)有序表合併成一個新的有序表,即把待排序序列分爲若干個有序的子序列,再把有序的子序列合併爲總體有序序列

時間複雜度:最壞(O(nlog2n)), 平均(O(nlog2n))

空間複雜度:O(n)

查找算法

二分查找

原理:從數組的中間元素開始,若是中間元素正好是要查找的元素,搜索結果,若是某一個特定元素大於或者小於中間元素的那一半中查找,並且跟開始同樣從中間開始比較,若是某一步驟數組爲空,表明找不到

時間複雜度:最壞(O(nlog2n)), 平均(O(nlog2n))

空間複雜度:迭代(O(1)), 遞歸(O(log2n))

順序查找

原理:按必定的順序檢查數組中每個元素,直到要找到鎖要尋找的特定指爲止

時間複雜度:最壞(O(n)), 平均(O(n))

空間複雜度:O(1)

優化

高併發和大流量解決方案

高併發的問題,應關注

  1. QPS:每秒鐘請求或查詢數量,在互聯網領域指每秒響應的請求數(指HTTP請求)

  2. 吞吐量:單位時間內處理的請求數量(一般由QPS和併發數決定)

  3. 響應時間:從請求發出到收到響應花費時間

  4. PV:綜合瀏覽量(Page View),即頁面瀏覽量或者點擊量,一個訪客在24小時內訪問的頁面數量。同一我的瀏覽你的網站同一個頁面,只記做一次PV

  5. UV:獨立訪客(UniQue Visitor),即必定時間範圍內相同訪客屢次訪問網站,只能計算爲1個獨立訪客

  6. 帶寬:計算帶寬大小需關注兩個指標,峯值流量和頁面的平均大小

  7. 日網站帶寬=PV/統計時間(秒) 平均頁面大小(KB) 8

  8. 峯值通常是平均值的倍數

  9. QPS不等於併發併發鏈接數。QPS是每秒HTTP請求數量,併發鏈接數是系統同時處理的請求數量

  10. 二八定律(80%的訪問量集中在20%的時間):(總PV數 80%)/(6小時秒速 20%)=峯值每秒請求數(QPS)

  11. 壓力測試:能承受最大的併發數和最大承受的QPS值

經常使用性能測試工具

ab,wrk,Apache JMeter, http_load, Web Bench, Siege

ab

使用方法:

# 模擬併發請求100次,總請求5000次
ab -c 100 -n 5000 http://example.com

注意事項:

  1. 測試機器與被測機器分開

  2. 不要對線上服務作壓力測試

  3. 觀察測試工具所在機器,以及被測試的前端機的CPU、內存、網絡等都不超過最高限度的75%

QPS指標

  1. QPS達到50,能夠稱之爲小型網站,通常服務器均可以應付

  2. QPS達到100;瓶頸:MySQL查詢達到瓶頸;優化方案:數據庫緩存層,數據庫負載均衡

  3. QPS達到800;瓶頸:帶寬速度達到瓶頸;優化方案:CDN加速,負載均衡

  4. QPS達到1000;瓶頸:緩存服務器的帶寬達到瓶頸;優化方案:靜態HTML緩存

  5. QPS達到2000;瓶頸:文件系統訪問鎖成爲災難;優化方案:作業務分離,分佈式存儲

高併發優化方案

流量優化

  1. 防盜鏈處理

前端優化

  1. 減小HTTP請求

  2. 添加異步請求

  3. 啓用瀏覽器緩存和文件壓縮

  4. CDN加速

  5. 創建獨立的圖片服務器

服務端優化

  1. 頁面靜態化

  2. 併發處理

數據庫優化

  1. 數據庫緩存

  2. 分庫分表、分區操做

  3. 讀寫分離

  4. 負載均衡

web服務器優化

  1. 負載均衡

web資源防盜鏈

盜鏈定義

  1. 倒鏈是指在本身的頁面上展現一些並不在服務器上的內容

  2. 得到他人服務器上的資源地址,繞過別人的資源展現頁面,直接在本身的頁面上向最終用戶提供此內容

  3. 常見的是小站盜用大站的圖片、音樂、視頻、軟件等資源

  4. 倒鏈能夠減輕本身的服務器負擔

防盜鏈定義

防止別人經過一些技術手段繞過本站的資源展現頁面,盜用本站的資源,讓繞開本站資源展現頁面的資源連接失效,能夠大大減輕服務器及帶寬的壓力

防盜鏈的工做原理

  1. 經過Referer或者計算簽名,網站能夠檢測目標網頁訪問的來源網頁,若是是資源文件,則能夠跟蹤到顯示他的網頁地址

  2. 一旦檢測到來源不是本站即進行阻止或返回指定的頁面

防盜鏈實現方法

Referer

  1. NGINX模塊ngx_http_referer_module用來阻擋來源非法的域名請求

  2. NGINX指令valid_referers,全局變量$invalid_referer

配置:

valid_referers none|blocked|server_names|string...;
  1. none: Referer來源頭部爲空的狀況,好比直接打開

  2. blocked: Referer來源頭部不爲空,可是裏面的值被代理或者防火牆刪除了,這些值都不以 http://或者https ://開頭

  3. server_names: Referer來源頭部包含當前的server_names

配置例子:

location ~.*\.(gif|jpg|png|flv|swf|rar}zip)$
{
valid_referers none blocked imooc.com *.imooc.com;
if ($invalid_referer)
{
#return 403;
rewrite ^/ http://www.imooc.com/403.jpg;
}
}

減小HTTP請求

HTTP鏈接產生的開銷

  1. 域名解析

  2. TCP鏈接

  3. 發送請求

  4. 等待

  5. 下載資源

  6. 解析

解決方案

  1. 減小組件的數量,並由此減小HTTP請求的數量

  2. 圖片地圖:圖片地圖容許你在一個圖片上關聯多個URL。目標URL的選擇取決於用戶蛋雞了圖片上的哪一個位置

  3. CSS Sprites:css 精靈,經過使用合併圖片,經過指定css的background-image和background-position來顯示元素

  4. 合併腳本和樣式表適

  5. 圖片使用base64編碼減小頁面請求數

瀏覽器緩存和數據壓縮

HTTP緩存機制分類

  1. 200 from cache:直接從本地緩存中獲取響應,最快速,最省流量,由於根本沒有向服務器發送請求

  2. 304 Not Modified:協商緩存,瀏覽器在本地沒有命中的狀況下,請求頭中發送必定的校驗數據到服務端,若是服務端的數據沒有改變,瀏覽器從本地緩存響應,返回304。特色:快速,發送的數據不多,只返回一些基本的響應頭信息,數據量很小,不發送實際響應體

  3. 200 OK:以上兩種緩存所有失敗,服務器返回完整響應。沒有用到緩存,相對最慢

header設置HTTP緩存機制

  1. pragma:HTTP1.0時代的遺留產物,該字段被設置爲no-cache時,會告知瀏覽器禁用本地緩存,即每次都向服務器發送請求

  2. Expires:HTTP1.0時代用來啓用本地緩存的字段,設置值如‘Thu, 31 Dec 2037 23:55:55 GMT’的格林威治的時間。但瀏覽器與服務器的時間沒法保持一致,若是差距大就會影響緩存結果

  3. Cache-Control:HTTP1.1針對Expires時間不一致的解決方案,運用Cache-Control告知瀏覽器緩存過時的時間間隔而不是時刻,即便具體時間不一致,也不影響緩存的管理

優先級:Pragma > Cache-Control > Expires

Cache-Control配置

  1. no-store:禁止瀏覽器緩存響應

  2. no-cache:不容許直接使用本地緩存,先發起請求和服務器協商

  3. max-age=delta-seconds:告知瀏覽器該響應本緩存的有效的最長期限,以秒爲單位

協商緩存

  1. 當瀏覽器沒有命中本地緩存,如本地緩存過時或者響應中聲名不容許直接使用本地緩存,那麼瀏覽器確定會發起服務端請求

  2. 服務端會驗證數據是否修改,若是沒有就通知瀏覽器使用本地緩存

header設置協商緩存

  1. Last-Modified:通知瀏覽器資源的最後修改時間,設置值如‘Thu, 31 Dec 2037 23:55:55 GMT’的格林威治的時間

  2. If-Modified-Since:獲得資源的最後修改時間後,會將這個信息經過If-Modified-Since提交到服務器作檢查,若是沒有修改,返回304狀態碼,設置值如‘Thu, 31 Dec 2037 23:55:55 GMT’的格林威治的時間

  3. ETag:HTTP1.1推出,文件的指紋標識符,若是文件內容修改,指紋也會改變,設置值如‘5a643fc7-38a3’

  4. If-None-Match:本地緩存失效,會攜帶此值去請求服務端,服務端判斷該資源是否改變,若是沒有改變,直接使用本地緩存,返回304

緩存策略的選擇

適合緩存的內容

  1. 不變的圖像,如logo,圖標等

  2. js、css靜態文件

  3. 可下載的內容,媒體文件

適合協商緩存

  1. HTML文件

  2. 常常替換的圖片

  3. 常常修改的js、css文件,js、css文件的加載能夠加入文件的簽名來拒絕緩存,如‘index.css?簽名’,‘index.簽名.js’

不建議緩存的內容

  1. 用戶隱私等敏感數據

  2. 常常改變的API數據接口

NGINX配置緩存策略

本地緩存配置

add_header name value [always];
expires time;
etag on|off

前端代碼和資源壓縮

優點

  1. 讓資源文件更小,加快文件在網絡中的傳輸,讓網頁更快的展示,下降帶寬和流量的開銷

壓縮方式

  1. js、css、圖片、html代碼的壓縮

  2. gzip壓縮

gzip配置

gzip on|off; #是否開啓gzip
gzip_buffers 32 4K|16 8K; #緩衝(在內存中緩存幾塊?每塊多大)
gzip_comp_level [1-9] #推薦6,壓縮級別(級別越高,壓得越小,越浪費CPU計算資源)
gzip_disable #正則匹配UA,什麼樣的Uri不進行gzip
gzip_min_length 200 #開始壓縮的最小長度
gzip_http_version 1.0|1.1 #開始壓縮的http協議版本
gzip_proxied #設置請求者代理服務器,該如何緩存內容
gzip_types text/plain application/xml image/png #對哪些類型的文件壓縮,如txt、xml、css
gzip_vary on|off #是否傳輸gzip壓縮標誌

CDN加速

定義

  1. CDN的全稱content delivery network,內容分發網絡

  2. 儘量避開互聯網上有可能影響數據傳輸速度和穩定性的瓶頸和環節,使內容傳輸的更快、更穩定

  3. 在網絡各處放置節點服務器所構成的有的互聯網基礎之上的一層智能虛擬網絡

  4. CDN系統可以實現地根據網絡流量和各節點的鏈接、負載情況以及到用戶距離和響應時間等綜合信息將用戶的請求從新導向離用戶最近的服務節點上

優點

  1. 本地cache加速,提升了企業站點(尤爲含有大量圖片和靜態頁面站點)的訪問速度

  2. 跨運營商的網絡加速,保證不一樣網絡的用戶都能獲得良好的訪問質量

  3. 遠程訪問用戶根據DNS負載均衡技術只能選擇cache服務器

  4. 自動生成服務器的遠程Mirror(鏡像)cache服務器,遠程用戶訪問時從cache服務器上讀取數據,減小遠程訪問的帶寬、分擔網絡流量、減輕原站點web服務器負載等功能

  5. 普遍分佈的cdn節點加上節點之間的智能冗餘機制,能夠有效地預防黑客入侵

工做原理

  1. 用戶發起請求

  2. 智能DNS的解析(根據IP判斷地理位置、接入網類型、選擇路由最短和負載最輕的服務器)

  3. 取得緩存服務器ip

  4. 把內容返回給用戶(若是緩存中有,沒有就執行五、六、7)

  5. 向源站發起請求

  6. 將結果返回給用戶

  7. 將結果存入緩存服務器

適用場景

  1. 站點或者應用中大量靜態資源的加速分發,例如css、js、圖片和HTML

  2. 大文件下載

  3. 直播網站

獨立圖片服務器

必要性

  1. 分擔web服務器的I/O負載,將耗費資源的圖片服務器分離出來,提升服務器的性能和穩定性

  2. 可以專門對圖片服務器進行優化,爲圖片服務器設置針對性的緩存方案,減小帶寬成本,提升訪問速度

  3. 提升網站的可擴展性,經過增長圖片服務器,提升圖片吞吐能力

採用獨立域名

緣由:

  1. 同一域名下瀏覽器的併發鏈接數有限制,突破瀏覽器鏈接數的限制

  2. 因爲cookie的緣由,對緩存不利,大部分web cache都只緩存不帶cookie的請求,致使每次的圖片請求都不能命中cache

如何圖片上傳和同步

  1. NFS共享方式

  2. 利用FTP同步

動態語言靜態化

將現有的PHP等動態語言的邏輯代碼生成爲靜態的HTML文件,用戶訪問動態腳本重定向到靜態HTML文件的過程。對實時性要求不高

緣由:

  1. 動態腳本經過會作邏輯計算和數據查詢,訪問量越大,服務器壓力越大

  2. 訪問量大時可能會形成CPU負載太高,數據庫服務器壓力過大

  3. 靜態化能夠減低邏輯處理壓力,下降數據庫服務器查詢壓力

實現方法

  1. 使用模板引擎

  2. 利用ob系列函數

ob_start();//打開輸出控制緩衝
ob_get_content();//返回輸出緩衝區內容
ob_clean();//清空輸出緩衝區
ob_end_flush();//沖刷出(送出)輸出緩衝區內容並關閉緩衝

併發處理

進程(Process)

是計算機中程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單元,是操做系統結構的基礎。進程是一個執行中的程序

進程的三態模型:運行、就緒、阻塞

進程的五態模型:新建態、活躍就緒/靜止就緒、運行、活躍阻塞/靜止阻塞、終止態

  1. 新建態:對應於進程剛剛被建立時沒有被提交的狀態,並等待系統完成建立進程的全部必要信息

  2. 終止態:進程已結束運行,回收除進程控制塊以外的其餘資源,並讓其餘進程從進程控制塊中收集有關信息。

  3. 活躍就緒:是指進程在主存而且可被調度的狀態。

  4. 靜止就緒(掛起就緒):是指進程被對換到輔存時的就緒狀態,是不能被直接調度的狀態,只有當主存中沒有活躍就緒態進程,或者是掛起就緒態進程具備更高的優先級,系統將把掛起就緒態進程調回主存並轉換爲活躍就緒。

  5. 活躍阻塞:是指進程已在主存,一旦等待的事件產生便進入活躍就緒狀態。

  6. 靜止阻塞:進程對換到輔存時的阻塞狀態,一旦等待的事件產生便進入靜止就緒狀態。

線程

線程是進程中的一個實體,是被系統獨立調度和分派的基本單位,線程本身不擁有系統資源,只擁有一點兒在運行中必不可少的資源但它可與同屬一個進程的其它線程共享進程所擁有的所有資源。

一個線程能夠建立和撤消另外一個線程,同一進程中的多個線程之間能夠併發執行。

線程是程序中一個單一的順序控制流程。進程內一個相對獨立的、可調度的執行單元,是系統獨立調度和分派CPU的基本單位指運行中的程序的調度單位。

在單個程序中同時運行多個線程完成不一樣的工做,稱爲多線程。

協程

協程是一種用戶態的輕量級線程,協程的調度徹底由用戶控制。協程擁有本身的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其餘地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操做棧則基本沒有內核切換的開銷,能夠不加鎖的訪問全局變量,因此上下文的切換很是快。

區別

線程與進程

  1. 線程是進程內的一個執行單元,進程內至少有一個線程,它們共享進程的地址空間,而進程有本身獨立的地址空間

  2. 進程是資源分配和擁有的單位,同一個進程內的線程共享進程的資源

  3. 線程是處理器調度的基本單位但進程不是

  4. 兩者都可併發執行

  5. 每一個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口,可是線程不可以獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制

協程和線程

  1. 一個線程能夠多個協程,一個進程也能夠單獨擁有多個協程

  2. 線程進程都是同步機制,而協程則是異步

  3. 協程能保留上一次調用時的狀態,每次過程重入時,就至關於進入上一次調用的狀態

例子

  1. 單進程單線程:一我的在一個桌子上吃菜

  2. 單進程多線程:多我的在同一個桌子上一塊兒吃菜

  3. 多進程單線程:多我的每一個人在本身的桌子上吃菜

同步阻塞

多進程模式

  1. 建立一個 socket

  2. 進入 while循環,阻塞在進程accept操做上,等待客戶端鏈接進入主進程在多進程模型下經過fork刨建子進程

  3. 收到數據後服務器程序進行處理而後使用send向客戶端發送響應

  4. 當客戶端鏈接關閉時,子進程/線程退出並銷燬全部資源。主進程/線程會回收掉此子進程/線程。

多線程模式

  1. 多線程模型下能夠建立子線程

  2. 子進程/線程建立成功後進入while循環,阻塞在recv調用上,等待客戶端向服務器發送數據

  3. 收到數據後服務器程序進行處理而後使用send向客戶端發送響應

  4. 當客戶端鏈接關閉時,子進程/線程退出並銷燬全部資源。主進程/線程會回收掉此子進程/線程。

缺點

  1. 這種模型嚴重依賴進程的數量解決併發問題

  2. 啓動大量進程會帶來額外的進程調度消耗

異步非阻塞

如今各類高併發異步IO的服務器程序都是基於epoll實現的

IO複用異步非阻塞程序使用經典的Reactor模型,Reactor顧名思義就是反應堆的意思,它自己不處理任何數據收發。只是能夠監視一個 socket句柄的事件變化

reactor模型

  • Add:添加一個 SOCKET到 Reactor

  • Set:修改 SOCKET對應的事件,如可讀可寫

  • Del:從 Reactor中移除

  • Callback:事件發生後回調指定的函數

常見reactor模型

  1. Nginx:多線程 Reactor

  2. Swoole:多線程 Reactor+多進程Worker

數據庫緩存

mysql查詢緩存

查詢緩存能夠看作是SQL文本和查詢結果的映射,第二次查詢的SQL和第一次查詢的SQL全相同,則會使用緩存

表的結構或數據發生改變時,查詢緩存中的數據再也不有效

配置:

query_cache_type

查詢緩存類型,有0、一、2三個取值。0則不使用查詢緩存。1表示始終使用查詢緩存。2表示按需使用查詢緩存。

query_cache_size

默認狀況下 query_cache_size 爲0,表示爲查詢緩存預留的內存爲0,則沒法使用查詢緩存

SET GLOBAL query_cache_size= 134217728

使用

querycache_type 爲1時,亦可關閉查詢緩存

SELECT SQL_NO_CACHE FROM my_table WHERE condition;

query_cache_type 爲2時,可按需使用查詢緩存

SELECT SQL_CACHE FROM my_table WHERE condition;

其餘

查看命中次數

SHOW STATUS LIKE'Qcache_hits';

清理緩存

FLUSH QUERY CACHE∥清理查詢緩存內存碎片
RESET QUERY CACHE∥從查詢緩存中移出全部查詢
FLUSH TABLES;//關閉全部打開的表,同時該操做將會清空查詢
緩存中的內容

redis / memcache 緩存

  • Redis,依賴客戶端來實現分佈式讀寫

  • Memcache自己沒有數據冗餘機制

  • Redis支持(快照、AOF),依賴快照進行持久化,aof加強了可靠性的同時,對性能有所影響

  • Memcache不支持持久化,一般作緩存,提高性能;

  • Memcache在併發場景下,用cas保證一致性, redis事務支持比較弱,只能保證事務中的每一個操做連續執行

  • Redis支持多種類的數據類型

  • Redis用於數據量較小的高性能操做和運算上

  • Memcache用於在動態系統中減小數據庫負載,提高性能;適合作緩存,提升性能

mysql 優化

數據表數據類型優化

  • tinyint、 smallint、 bigint 考慮空間的問題,考慮範圍的問題

  • char、varchar

  • enum 特定、固定的分類可使用enum存儲,效率更快

  • ip地址 ip2long() 轉成長整型存儲

索引優化

索引建立原則

  • 索引不是越多越好,在合適的字段上建立合適的索引

  • 複合索引的前綴原則

索引注意事項

  • 複合索引的前綴原則

  • like查詢%的問題

  • 全表掃描優化

  • or條件索引使用狀況

  • 字符串類型索引失效的問題

SQL語句的優化

優化查詢過程當中的數據訪問

  • 使用 Limit

  • 返回列不用*

優化長難句的查詢語句

  • 變複雜爲簡單

  • 切分查詢

  • 分解關聯查詢

優化特定類型的查詢語句

  • 優化 count()

  • 優化關聯查詢

  • 優化子查詢

  • 優化 Group by和 distinct

  • 優化 limit和 union

存儲引擎的優化

儘可能使用 Inno DB存儲引擎

數據表結構設計的優化

分區操做

  • 經過特定的策略對數據表進行物理拆分

  • 對用戶透明

  • partition by

分庫分表

  • 水平拆分

  • 垂直拆分

數據庫服務器架構的優化

  • 主從複製

  • 讀寫分離

  • 雙主熱備

  • 負載均衡

負載均衡

  • 經過LVS的三種基本模式實現負載均衡

  • MyCat數據庫中間件實現負載均衡

web服務器的負載均衡、請求分發

七層負載均衡實現

基於URL等應用層信息的負載均衡

Nginx的 proxy是它一個很強大的功能,實現了7層負載均衡

nginx負載均衡

優勢

功能強大,性能卓越,運行穩定

配置簡單靈活

可以自動剔除工做不正常的後端服務器

上傳文件使用異步模式

支持多種分配策略,能夠分配權重,分配方式靈活

Nginx負載均衡策略

內置策略: IP Hash、加權輪詢

擴展策略:fair策略、通用hash、一致性hash

加權輪詢策略

首先將請求都分給高權重的機器,直到該機器的權值降到了比其餘機器低,纔開始將請求分給下一個高權重的機器

當全部後端機器都down掉時,Ngnx會當即將全部機器的標誌位清成初始狀態,以免形成全部的機器都處在 timeout的狀態

IP Hash策略

Nginx內置的另外一個負載均衡的策略,流程和輪詢很相似,只是其中的算法和具體的策略有些變化

IP Hash算法是一種變相的輪詢算法

fair策略

根據後端服務器的響應時間判斷負載狀況,從中選出負載最輕的機器進行分流

通用Hash、一致性Hash策略

通用hash比較簡單,能夠以 Nginx內置的變量爲key進行hash,

一致性hash採用 Nginx了內置的一致性hash環,支持 memcache

配置

http {
upstream cluster {
server srvl;
server srv2;
server srv3;
}
server {
listen 80;
location /
proxy_pass http: //cluster;
}
}

四層負載均衡實現

經過報文中的目標地址和端口,再加上負載均衡設備設置的服務器選擇方式,決定最終選擇的內部服務器

LvS實現服務器集羣負載均衡有三種方式,NAT,DR和TUN

相關文章
相關標籤/搜索