高併發解決方案(下)

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

    獨立的圖片服務器有諸多好處,其中一個就是客戶端瀏覽器對一個主機下的鏈接數量限制,具體的鏈接數目忘記了,但基本都在10如下。也就是說,瀏覽器會控制一個站點下的併發請求數量在10如下,若是對於網站有不少樣式文件、腳本文件和圖片須要加載的話,請求的過程會被阻塞,影響網站的打開速度。  php

      創建圖片服務器,將圖片資源放在另一個域名下面,會在必定程度上提高網站的打開速度,這樣來講的話是否是說咱們獨立的服務器越多越好呢?也不盡然,解析域名並創建鏈接也須要很長的時間,獨立的主機多了的話,也不利於速度的提高。html

      圖片每每會消耗掉網站中的不少寬帶和IO資源,獨立的圖片服務器能夠在寬帶和IO性能上單獨提高,便於管理和拓展。nginx

6、動態語言靜態化

請求動態內容:web

php –>域名->DNS解析找到對應ip地址->返回給客戶端->客戶端找到真實的服務器->80端口web服務->nginx 判斷是否爲php->反向代理->php-fpm PHP解析器->php代碼內容解析->html代碼->瀏覽器算法

什麼是動態語言靜態化?sql

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

爲何要靜態化?編程

  動態腳本一般會作邏輯計算和數據查詢,訪問量越大,服務器壓力越大瀏覽器

  訪問量大時可能會形成CPU負載太高,數據庫服務器壓力過大靜態化能夠減低邏輯處理壓力,下降數據庫服務器查詢壓力。緩存

靜態化的實現方式

   1.使用模板引擎:常見的模板引擎可使用Smarty,Smarty的緩存機制生成靜態HTML緩存文件

$smarty->cache_dir = $ROOT."/cache"; //緩存目錄
$smarty->caching = true; //是否開啓緩存
$smarty->cache_lifetime = "3600"; //緩存時間
$smarty->display(string template[,string cache_id[,string compole_id]]);
$smarty->clear_all_cache();//清除全部緩存
$smarty->clear_cache('file.html'); //清除指定的緩存
$smarty->clear_cache('article.html',$art_id);//清除同一個模板下的指定緩存好的緩存

  2.利用ob系列的函數

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

//示例

ob_start();
輸出到頁面的HTML代碼...

ob_get_contents();
ob_end_flush();
fopen() 寫入

//1.判斷當前文件是否有修改,2.判斷是否存在緩存文件 3.判斷緩存文件是否過時
<?php
$cache_name  = md5(__FILE__).'.html'; $cache_lifetime = 3600;//緩存時間 if(filectime(__FILE__) <= filectime($cache_name)&&file_exists($cache_name) && filectime($cache_name)+ $cache_lifetime > time() ){ include $cache_name; exit; } ob_start(); ?> <b>html 代碼</b> <?php $content = ob_get_contents(); ob_end_flush(); $handle = fopen($cache_name, 'w'); fwrite($handle,$content); fclose($handle); //根據id 作不一樣緩存 $id = $_GET['id']; if(empty($id)){ $id = ''; } $cache_name = md5(__FILE__). '-'.$id.'.html';

 

7、動態語言併發處理

在瞭解併發處理以前須要瞭解相關概念:

  什麼是進程、線程、協程

  什麼是多進程、多線程

  同步阻塞模型

  異步非阻塞模型

進程:

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

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

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

  參考:https://www.cnblogs.com/xiawen/p/3328033.html

線程:

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

  線程的狀態: 參考:https://blog.csdn.net/kzadmxz/article/details/73437926

協程

     參考:http://www.sohu.com/a/237171690_465221 

進程與線程的區別:

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

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

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

4.兩者都可併發執行

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

 

線程與協程的區別:

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

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

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

多線程多進程:

https://zhidao.baidu.com/question/282409258.html

同步、異步、阻塞、非阻塞

https://www.cnblogs.com/George1994/p/6702084.html

 

瞭解完以上相關概念後,php相關的併發編程有哪些呢?

PHP的swoole拓展

  swoole是php的異步、並行、高性能網絡通訊引擎,使用純C語言編寫,提供了PHP語言的異步多線程服務器,異步TCP/UDP網絡客戶端,異步MySQL,異步Redis,數據庫鏈接池,AsyncTask,消息隊列,毫秒定時器,異步文件讀寫,異步DNS查詢,除了異步IO的支持以外,Swoole爲PHP多進程的模式設計了多個併發數據結構和IPC通訊機制,能夠大大簡化多進程併發編程的工做

消息隊列

  常見消息隊列產品:Kafka、ActiveMQ、ZeroMQ、RabbitMQ、Redis等

  應用場景:

  註冊:將註冊信息寫入數據庫成功後,將成功信息寫入隊列,此時直接返回成功給用戶,寫入隊列的時間很是短,能夠忽略不計,而後異步發送郵件和短信

  下單:用戶下單後,訂單系統完成持久化處理,將消息寫入消息隊列,返回用戶訂單下單成功,訂閱下單的消息,採用拉/推的方式,獲取下單信息,庫存系統根據下單信息進行庫存操做

  秒殺活動:用戶瞬時激增,用戶發起請求,服務器接收後,先寫入消息隊列,假如消息隊列長度超過最大值,則直接報錯或提示用戶

  解決大量日誌的傳輸:日誌採集程序將程序寫入消息隊列,而後經過日誌處理程序的訂閱消費日誌

  聊天室:多個客戶端訂閱同一主題,進行消息發佈和接收

接口的併發請求

  curl_multi_init

 

8、數據庫緩存優化

 什麼是數據庫緩存?

  MySQL等一些常見的關係型數據庫的數據都存儲在磁盤當中,在高併發場景下,業務應用對MySQL產生的增、刪、改、查的操做形成巨大的I/O開銷和查詢壓力,這無疑對數據庫和服務器都是一種巨大的壓力,爲了解決此類問題,緩存數據的概念應運而生。

  常見的緩存形式:內存緩存,文件緩存

 爲何要使用緩存?

  緩存數據是爲了讓客戶端不多甚至不訪問數據庫服務器進行數據的查詢,高併發下能最大程度地下降對數據庫服務器的訪問壓力

用戶請求-->數據查詢-->鏈接數據庫服務器並查詢數據-->將數據緩存起來(HTML、內存、JSON、序列化數據)-->顯示給客戶端

用戶再次請求或者新用戶訪問-->數據查詢-->直接從緩存中獲取數據-->顯示給客戶端

  

 MySQL的查詢緩存

  query_cache_type

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

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

  SELECT SQL_NO_CACHE * FROM my_table WHERE condition;

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

  SELECT SQL_CAHCE * FROM my_table WHERE condition;

  query_cache_type爲0時,表示爲查詢緩存預留的內存爲0,則沒法使用查詢緩存

  SET GLOBAL query_cache_size = 134217728

  查詢緩存能夠看作是SQL文本和查詢結果的映射

  第二次查詢的SQL和第一次查詢的SQL徹底相同,則會使用緩存SHOW STATUS LIKE 'Qcache_hits';查看命中次數

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

清理緩存:

  FLUSH QUERY CACHE;  //清理查詢訊緩存內存碎片

  RESET QUERY CACHE; //從查詢緩存中移出全部查詢

  FLUSH TABLES; //關閉全部打開的表,同時該操做將會清空查詢緩存中的內容

 

使用Memcache緩存查詢數據

  對於大型站點,若是沒有中間緩存層,當流量打入數據庫層時,即使有以前的幾層爲咱們擋住一部分流量,可是在大併發的狀況下,仍是會有大量請求涌入數據庫層,這樣對於數據庫服務器的壓力衝擊很大,響應速度也會降低,所以添加中間緩存層頗有必要

  memcache是一套分佈式的高速緩存系統,對於一些大型的、須要頻繁訪問數據庫的網站訪問速度提高效果十分顯著

  工做原理:

  memcache是一套高性能的分佈式的內存對象緩存系統,經過在內存裏維護一個統一的巨大的hash表,它可以用來存儲各類格式的數據,包括圖像、視頻、文件以及數據庫檢索的結果等。簡單的說就是將數據調用到內存,而後從內存中讀取,從而大大提升讀取速度

  工做流程:

  先檢查客戶端的請求數據是否在memcached中,若有,直接把請求數據返回,再也不對數據庫進行任何操做;若是請求的數據再也不memcached中,就去查數據庫,把從數據庫中獲取的數據返回給客戶端,同時吧數據緩存一份到memcached中

  方法:獲取:get(key)  設置:set(key,val,expire) 刪除:delete(key)

  通用緩存機制: 用查詢的方法名+參數做爲查詢時的key value對中的key值

使用Redis緩存查詢數據

  與Memcahce 的區別:

  性能相差不大

  Redis在2.0版本後增長了本身的VM特性,突破物理內存的限制,Memcache能夠修改最大的可用內存,採用LRU算法

  Redis,依賴客戶端來實現分佈式讀寫,Memcache自己沒有數據冗餘機制

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

  Redis用於數據量較小的高性能操做和運算上 Memcache用於在動態系統中減小數據庫負載,提高性能;適合作緩存,提升性能

  

 

 

9、Mysql數據層優化

數據表數據類型優化

  字段使用什麼樣的數據類型更合適

  字段使用什麼樣的數據類型性能更快

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

  char varchar   --- 存儲字符長度是否固定

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

  ip地址的存儲  使用整型存儲ip地址

索引優化

  創建合適的索引

  索引在什麼場景下效率最高

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

  複合索引的前綴原則   ---Abc三個字段複合索引  查詢條件爲a AND b 能夠 b AND c a AND c 不能夠

  like查詢%的問題    ---like 百分號在前索引失效

  全表掃描優化     ---全表掃描自動失效 

  or條件索引使用狀況         --- Or 前面有後面無則索引失效

  字符串類型索引失效問題  ---  字符串查要加引號

 

SQL語句的優化

  優化查詢過程當中的數據訪問    ---使用limit  返回列不用*

  優化長難句的查詢語句  ----變複雜爲簡單   切分查詢    分解關聯查詢   分次刪除   

  優化特定類型的查詢語句  ---優化count()   優化關聯查詢 優化子查詢 優化GROUP BY 和distinct 優化limit和union

存儲引擎的優化

  一、MyISAM:默認表類型,它是基於傳統的ISAM類型,ISAM是Indexed Sequential Access Method (有索引的順序訪問方法) 的縮寫,它是存儲記錄和文件的標準方法。不是事務安全的,並且不支持外鍵,若是執行大量的select,insert MyISAM比較適合。

  二、InnoDB:支持事務安全的引擎,支持外鍵、行鎖、事務是他的最大特色。若是有大量的update和insert,建議使用InnoDB,特別是針對多個併發和QPS較高的狀況

參考 https://www.cnblogs.com/y-rong/p/8110596.html

數據表結構設計的優化

  分區操做:經過特定的策略對數據表進行物理拆分   對用戶透明  partiton by

  分庫分表:水平拆分(活躍數據和不活躍數據 union)  垂直拆分(經常使用和不經常使用列 join)

數據庫服務器架構的優化

  主從複製

  讀寫分離

  雙主熱備

  負載均衡

10、MySQL的負載均衡 web服務器負載均衡 

 

MYSQL負載均衡: 經過LVS的三種基本模式實現負載均衡 MyCat數據庫中間件實現負載均衡

web服務器負載均衡七層負載均衡的實現  四層負載均衡的實現

相關文章
相關標籤/搜索