PHP高併發與大數據

web資源防盜鏈

  • 盜鏈是什麼? 爲什麼要防?

在自己頁面上顯示一些不是自己服務器的資源圖片音頻視頻cssjs等)
由於別人盜鏈你的資源會加重你的服務器負擔,所以我們需要防止
可能會影響統計

  • 防盜鏈是什麼? 有哪幾種方式?

防止別人通過一些技術手段繞過本站的資源展示頁,盜用本站資源,讓繞開本站資源展示頁面的資源鏈接失效
大大減輕服務器壓力

 
1、Referer (易僞造referer,安全性低)
2、加密簽名 (安全性高)
  • 防盜鏈的工作原理

通過Referer,服務器可以檢測到訪問目標資源的來源網站,如果是資源文件,則可以跟蹤到顯示它的網頁地址。一旦檢測到來源網站不是本站進行阻止

通過簽名,根據計算簽名的方式,判斷請求是否合法,如果合法則顯示,否則返回錯誤信息

  • Referer實現

Nginx爲例,前提加載ngx_http_referer_module模塊

 
//指令valid_referers  全局invalid_referer
location ~* \.(gif|jpg|png|webp)$ {
   valid_referers none blocked domain.com *.domain.com ;
   if ($invalid_referer) {
        return 403;
        #rewrite ^/ http://www.domain.com/403.jpg;
   }
}

注意:爲什麼要none呢?因爲如果通過瀏覽器直接訪問資源,referer就是爲空,所以這種方式不能徹底阻擋住盜鏈。

  • 加密簽名

Nginx爲例,前提加載第三方模塊HttpAccessKeyModule實現防盜鏈

 
location ~* \.(gif|jpg|png|webp)$ {
    accesskey on;
    accesskey_hashmethod md5;
    accesskey_arg key;
    accesskey_signature "mysrc$remote_addr";
}

減少HTTP請求次數

  • 發現問題

80~90%是花費在頁面引用控件的加載上,只有10~20%是花費在文檔的加載上
HTTP/1.1協議規定請求只能串行發送,換句話就是100個請求,只能一個一個發送,上一個請求完成才能進行下一個請求

  • 如何改善?

減少引用控件數量,從而達到減少HTTP請求次數

  • 如何實現減少請求?

1、圖片地圖

原理把多張圖片合成一張,再使用<map>標籤來實現對圖片上不同區域的鏈接

 
<img src="img/planets.gif" width="145" height="126" alt="Planets" usemap="#planetmap">
<map name="planetmap">
  <area shape="rect" coords="0,0,82,126" alt="Sun" href="sun.htm">
  <area shape="circle" coords="90,58,3" alt="Mercury" href="mercur.htm">
  <area shape="circle" coords="124,58,8" alt="Venus" href="venus.htm">
</map>

圖片地圖

2、CSS Sprites(雪碧圖)

原理合拼圖片,再使用css的background-image和background-position來指定顯示元素

 
CSS Sprites與圖片地圖性能差不多,但CSS Sprites更加簡單靈活

CSS Sprites

3、合併JS與CSS文件

加載一個JS文件比加載多個JS文件要快

 
一般會使用前端自動構建工具打包合併

4、圖片使用base64編碼

注意:圖片base64除了可以使用在<img>中,還可以使用在css的background-image中

CDN加速

  • 什麼是CDN加速?

CDN 就是內容分發網絡,在各處放置服務器來構成一層智能虛擬網絡,此處服務器稱之爲節點服務器。所謂智能就是會自動根據用戶請求信息把請求重新分配到離客戶端最近的服務器。

CDN的作用: 解決由於服務端與客戶端所在區域的不同,導致影響數據傳輸速度和穩定性問題,一句話總結就是讓數據傳輸更快更穩定

  • CDN有什麼優勢?

1、智能Cache加速,提高企業站點的訪問速度(含大量圖片或靜態頁面最適合,因爲CDN相當於是服務器的一個鏡像)
2、跨運營商的網絡加速,保證不同網絡的用戶都能得到很好的訪問速度
3、加速用戶遠程訪問服務器,根據DNS負載均衡技術自動智能選擇Catch服務器
4、自動生成遠程服務器的鏡像(Catch服務器),加速訪問速度,減輕Web服務器的負擔,分擔流量

  • CDN的工作原理是什麼?


 

  • CDN適用場景有哪些?

1、網站或應用中大量靜態資源的加速分發 (例如:css/js/圖片等)
2、大文件下載
3、直播網站

  • CDN如何實現?

瀏覽器緩存

高併發下只能通過提高服務器負載來解決? NO,流量、前端、服務器、數據庫
緩存只能是數據庫緩存嗎? NO,還有瀏覽器緩存

  • HTTP緩存分類(2種)

1.200 OK (from memory cache) 直接從本地緩存中獲取響應,最快速、最省流量,因爲沒有向服務器發送請求


2.304 Not Modified 協商緩存,瀏覽器在本地沒有命中的情況下,請求頭中會發送一定的校驗數據到服務器。如果服務端數據沒有改變,服務端直接響應(通知瀏覽器從本地緩存獲取),返回304(快速、發送數據很少,只返回最基本的響應頭,不發送響應體)


PS: 以上兩種緩存全部失敗,服務器返回完整響應體(200 OK),沒有用到緩存,速度最慢

  • 瀏覽器本地緩存相關的header

Pragma


Cache-Control


Expires

前端代碼和資源壓縮優化

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

  • 壓縮方式

JS、CSS、HTML、圖片壓縮和Gzip壓縮

  • JS代碼壓縮
 
去除一些多餘的空格和回車,替換長變量名,簡化一些代碼寫法
壓縮工具:在線版和安裝版

在線壓縮工具

  • CSS代碼壓縮
 
與JS壓縮原理一樣,去除空白符、註釋和優化一下語義化

在線壓縮工具

  • HTML代碼壓縮(不推薦,鎮用)
 
不推薦使用,因爲會破壞代碼結構。
  • 圖片(JPG、PNG)壓縮

壓縮工具:tinypng/JpegMini/ImageOptim

  • Gzip壓縮

Gzip壓縮是Web服務器對純文本文件(JS/CSS/XML/HTML)進行壓縮
注意:千萬不要對圖片進行Gzip壓縮

 
//以Nginx爲例

# 開啓gzip
gzip on;
# 啓用gzip壓縮的最小文件,小於設置值的文件將不會壓縮
gzip_min_length 1k;
# gzip 壓縮級別,1-10,數字越大壓縮的越好,也越佔用CPU時間,後面會有詳細說明,推薦6
gzip_comp_level 6;
# 進行壓縮的文件類型。javascript有多種形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php;
# 是否在http header中添加Vary: Accept-Encoding,建議開啓
gzip_vary on;
# 禁用IE 6 gzip
gzip_disable "MSIE [1-6]\.";
# 壓縮存儲的緩衝
gzip_buffers 16 64k;
# 開啓壓縮的http版本
gzip_http_version 1.1;

動態語言靜態化

將現代動態語言的邏輯代碼生成爲靜態HTML文件(靜態化實際作用:緩存成一個html文件),再次訪問時就會重定向到靜態文件

  • 適用場景

對實時性要求不高的頁面

  • 爲什麼要使用靜態化?

解決高併發,減輕Web服務器和數據庫服務器壓力

  • 靜態化實現方式有幾種?

1、使用Smarty模板引擎
2、使用ob系列函數

  • 使用Smarty模板引擎
 
//緩存存放目錄
$smarty->cache_dir=$ROOT.'/cache'; 
//開啓緩存
$smarty->caching=true; 
//緩存過期時間
$smarty->cache_lifetime=3600;
//加載模板
$smarty->display();
//清除所有緩存文件
$smarty->clearAllCache();
//清除特定模板的緩存
$smarty->clearCache('index.tpl');
  • 使用ob系列函數(重點,實現靜態化基礎)
 
//開啓輸出緩衝區
ob_start(); 
//獲取輸出緩衝區內容
ob_get_contents();
//清空(擦掉)輸出緩衝區
ob_clean();
//送出輸出緩衝區內容並關閉緩衝
ob_end_flush();
//得到當前緩衝區的內容並刪除輸出緩衝區
ob_get_clean();

動態語言的併發處理

  • 什麼是進程?什麼是線程?什麼是協程?

進程:是一個“執行中的程序”,程序不執行就不會產生進程。一個執行中的程序至少會產生一個進程,當進程獲得了處理機時纔會從就緒狀態變爲運行狀態,處理機不斷切換地分配到每個進程中。決定同時有多少個進程處於運行狀態的是處理器數量(CPU核數)

 
進程的三態模型:多個程序在系統中運行時,進程在處理機中交替運行,狀態在不斷切換。
三態分別是:就緒、運行、阻塞

 

 
進程的五態模型(在三態的基礎上發展而來):新建態、運行態、終止態、就緒態、等待態

線程:稱之爲輕量級的進程,程序執行流的最小單元。線程依賴於進程(一個進程可以有多個線程),線程不擁有系統資源。與同屬一個進程的其他線程共享進程擁有的全部資源一個線程可以創建和撤銷另一個線程,同一個進程中的多個線程可以併發執行。一個進程下有多個線程來完成不同的工作稱之爲多線程。(一個進程下至少會有一個線程)

 
線程由來:由於用戶併發請求,爲每個請求都創建一個進程顯然太浪費系統資源和影響響應用戶請求的效率,所以引進線程的概念。

協程:是一種用戶態輕量級的線程。

 
//協程與線程的區別
1、協程是由用戶自己調度,而線程是用系統調度
2、協程是異步的,而進程線程是同步的
3、一個線程可以有多個協程,一個進程也可以單獨擁有多個協程
4、協程會保留上一次調用的狀態
  • 什麼是多線程?什麼是多進程?

多進程:2個或2個以上的進程處於運行狀態,進程間通信不方便


多線程:把一個進程分爲很多片,每一片都是一個獨立的流程,線程間可以互相通訊

  • 同步阻塞模型
  • 異步非阻塞模型
  • PHP併發編程實戰

1.使用swoole擴展


2.使用消息隊列


3.接口的併發請求

 
curl_multi_init()

數據緩存

  • 什麼是數據緩存?
 
傳統關係型數據庫都是把數據存儲到硬盤中,在高併發情況下,對數據庫服務器會造成巨大壓力(巨大IO操作),爲了解決此問題,數據緩存由此而生!

作用:
1、極大地緩解數據庫服務器的壓力
2、提高數據的響應速度


緩存形式有:內存緩存、文件緩存
推薦使用內存緩存

  • 爲什麼要使用數據緩存?(答案如上)

第一次訪問:

 

再次訪問:

 

  • 如何使用Mysql查詢緩存?
  • 如何使用Memcache緩存?
  • 如何使用redis緩存?

Web服務器負載均衡

  • 實現方式

1、七層負載均衡(Nginx)
2、四層負載均衡(LVS/硬件設備)

  • 七層負載均衡

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

 
// 一般使用Nginx來實現
功能強大、性能卓越、運行穩定
配置簡單靈活
上傳文件使用異步模式
多種分發策略
自動剔除不正常工作設備
  • Nginx負載均衡策略

內置

 
加權輪詢、IP Hash

外置

 
fair策略、通用Hash、一致性Hash
  • Nginx配置負載均衡
 
http{
    upstream cluster{
        server srv1;
        server srv2;
        server srv3;
    }
    server{
        listen 80;
        location / {
            proxy_pass http://cluster;
        }
    }
}
  • 四層負載均衡

有2種方式實現:
1、LVS
2、硬件設備

 
LVS負載均衡的三種方式:NAT、DR和TUN

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

MySQL數據庫優化

  • 優化方向

字段數據類型優化

 
tinyint/smallint/int/bigint的選擇
char/varchar
enum 固定分類
IP地址數據如何存?
答案:把IP地址轉整型類型存儲

索引


SQL語句優化


存儲引擎優化


表結構設計優化


數據庫服務器架構優化

  • 列表項目

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章