最近想縷縷互聯網架構方面的知識,因此這裏先宏觀的看看關於互聯網架構下的問題和相關實現,分佈式架構中,咱們知道最重要的就是高可用,和高併發,因此我會從這裏着手。nginx
【架構可用性】:redis
所謂高可用就是咱們在整個架構的過程當中不能存在單點故障:(若是是個人服務節點在整個架構中只部署了一個,那麼咱們就說這個節點是單點的),當咱們把只部署了一個節點,那服務器掛了,那咱們的服務則是不可用狀態。咱們能夠:算法
集羣:所謂的集羣就是把一個服務部署了多個節點,例如咱們發現Tomcat不夠用,那就部署多個,這就是一個例子,那說到集羣就要聊一下負載,誰來對請求進行分發,採用那種方式進行請求分發。數據庫
【負載均衡】:後端
- 硬件負載;F五、netscaler
- 軟件負載:Apache、Nginx、Lvs、Happrox
那請求多了,咱們咱們的負載均衡的服務器也扛不住了,那咱們就要對負載均衡的服務器進行集羣緩存
- 硬件:會有一個主機和一個備機,主機和備機經過一個心跳線進行鏈接,若是發現備機發現主機沒有心跳了,則接管主機的工做。
- 軟件:Lvs+keeplived
【負載均衡算法】:隨機、hash、輪詢、最小鏈接數安全
【常見的負載】:DNS輪詢、二層負載(MAC層)、三層負載(IP層,根據傳遞的數據報文中的ip進行負載)、ip+端口負載(好比nginx中upstream)、七層負載(應用層負載->url的負載)服務器
【應用層負載】:ribbon、dubbo、SpringCloud loadbalance網絡
熱備:多個節點在本身內部進行選舉,當發現一個節點掛了後,其內部的選舉策略會推選出新的mastersession
- zookeeper:zab協議
- redis-sentinel:raft算法
多機房部署: 同城災備、異地災備
【應用可用性】:
微服務的集羣部署
容錯性:
服務容錯性:當某個服務出現錯誤的時候,整個系統必須正常運行,解決方法(請求隔離)
接口容錯性:保證外部接口傳遞數據的安全性,解決辦法(數據校驗),以及冪等性(可能處理一個請求屢次,舉個例子,一個請求其實後端已經成功處理,但是調用者並不知道),解決辦法(事務處理)
自我保護能力:(好比系統只能接受1000tps可是給了我2000tps)解決辦法(熔斷、限流、緩存、主動降級)
監控:
- 系統資源的監控:(cpu、內存、磁盤)
- 告警手段:發短信、郵件、電話(可使用alertManager)
- 應用監控:應用吞吐量、訪問量(進行數據埋點、數據上報到統一的一個監控系統中)、系統的執行狀況(elk)
- 鏈路監控:好比一個請求通過了不少鏈路,咱們想知道那個鏈路的響應時間最久(pinpoint、zipkin)
單位時間內能夠同時處理的請求數量, 如下有幾個名詞是衡量一個系統併發的指標。
RT(response time-> 響應時間):當咱們發送一個http請求後獲得數據的系統響應時間,這是影響用戶體驗的一個重要因素
throughput(吞吐量):系統單位時間內的請求數量,經過QPS來決定的
QPS\TPS(每秒的事務數、查詢數):每秒同時承載的事務的處理數量 == 併發數/平均響應時間 使用 Jmeter 能夠壓測出
用戶體驗:
瀑布流、異步化、進行限額(針對支付)
【架構層面】:
【微服務】:
【服務進行拆分】(單個計算機的計算的性能是有限的,進行服務拆分就等於多個計算機共同工做,這樣就提升了性能。)
【SLA】:服務拆分後,咱們能夠針對重要的模塊提供更大規模的集羣
【數據庫(關係型數據庫)】:
- 數據分片(分庫分表)
- 讀寫分離
【存儲(非結構化存儲)】:MongoDB、Redis等
【服務的無狀態化設計】:當訪問峯值來臨,咱們不得不增長服務器,可是若是增減了服務器,有時候有的數據是存儲在a服務器上的,可是增長了B服務器那數據不統一如何處理
session -> Redis 數據的存儲->數據庫部署到第三方節點
【分佈式緩存】: 熱點數據進行緩存
【容量規劃】;
【容量】指的是好比一個網站超過1000w的Page View就開始變慢,或者返回錯誤,那咱們就認爲10000w的PV就是咱們網站的容量,從這幾個方面進行考慮:
- 何時應該加機器 、
- 當前的吞吐量是多少、
- 承載多少容量須要增長多少服務器
【步驟】:壓測集羣、節點達到一個臨界值
【目標】:
- 最大的負載狀態(服務器級別的):cpu的使用率、內存的使用率、磁盤io的延時
- 最大能接受的請求閾值:(qps、tps、錯誤率、平均響應時間)
【指標的收集】:壓力測試 (獲得更精準的數據 )、產線壓測(可能傳遞用戶真實數據進行測試)
【趨勢的預測】:使用往年的數據和今年的數據增加進行一些預判(以峯值進行一個比較標準)
【擴容】:水平擴容、垂直擴容
【異步化架構】::一些實時性要求不是很高的場景,咱們能夠經過把流量分發到mq中,從而對高併發進行一個好的處理
【冗餘】:增長副本、CDN內容分發網絡(部署不一樣的節點,在不一樣的地方,用戶距離那個地方近就訪問哪一個地方的節點)
【代碼層面】:
- 不要在循環中調用rpc
- hashmap的初始數據,若是初始數據過小,那可能就形成了頻繁的擴容,從而消耗性能
- 數據的預熱,當一些頻繁使用的數據,提早進行加載(相似於惡漢模式)
- 數據庫層面,查詢語句的優化,是否有索引,是否查了全表 so on
- 異步化,線程池的使用
【客戶端層面的優化】:
- 減小請求的數量,合併請求。
- 數據緩存,減小請求的次數
其餘的一些知識:
服務的冪等性:屢次請求和一次請求對於數據的變化保持一致,就是把以前的數據從新發送了一遍,必須保證只有一個數據成功。
- 狀態機:一個數據在整個生命週期中經歷的狀態,好比一個訂單的狀態,發起、支付中、支付結束、so on,咱們能夠經過這個狀態進行判斷
- 數據庫的惟一約束、token
- redis 當一個請求過來判斷存儲key和value下次來redis中進行判斷。
分佈式鎖:咱們知道synchronize和lock是解決同一進程多個線程直接的問題,可是在分佈式中不是同一個進程,那就須要一個第三方的視角去判斷誰能夠訪問某個資源,常見的分佈式鎖:
- zookeeper、數據庫、Redis、etcd
CAP:一致性(在集羣節點中的數據一致性)、可用性(當一個請求發送後,在我能夠接受的時間內,給我一個響應)、分區容錯性(產生網絡故障的時候,集羣中的數據仍是能夠訪問的 )