構建高可靠、高效能的web應用
目標:構建高可靠、高效能的web應用,這是接下來學習的一些重點。
一、可靠性:可擴充套件性、服務降級、負載均衡
垂直擴充套件(scala up):提高機器硬體配置,如加記憶體等
水平擴充套件:加機器,服務須無狀態,可分散式
資料庫擴充套件sharding:
–垂直拆分(一個庫資料量太大,表間將關聯密切的表劃分在一起):
如User Order庫拆成 ->User 、 Order
–水平拆分(一個表的資料量太大,一表拆多表,根據查詢使用過情況確定規則,單表資料不要超過1000萬,做好索引):
如Order表根據 -hash , -代理商拆分
二、效能:快取、併發、池化、非同步
①負載均衡
Ngin反向代理伺服器:http轉發,一個請求對應多臺機器
策略:
Random,隨機打到哪臺機器
RoundRobin,輪詢
LeastActive,如果一個機器A處理請求返回慢,可能就把請求打到另一臺機器B
IPHash, Hash策略 ,如根據hash做hash,特定使用者打到特定機器,
ConsistentHash,如根據內容做hash,有快取的請求打到 同一臺機器
健康檢查:
Healthcheck.html, Nginx定期檢查Healcheck.html,如不能查到說明這機器掛了
②服務降級
對提供的服務進行分級,核心 服務具有更高的優先順序,動態地關閉某個功能等
功能開關:全流程開關, 如去哪兒的qconfig
③併發-Servlet
容易出現的 問題 :
- count++;語句是執行緒不安全的
- 在多執行緒環境下如servlet中的全域性變數定義使用HashMap,可以使用ConcurrentHashMap()或者Collections.unmodifiableMap(new HashMap() )來進行安全的讀(get)操作,在doGet或doPost定義的本地map是執行緒安全的
④併發-鎖
低併發推薦使用 AtomicInteger、AtomicLong
synchronized, 一直等。ReentrantLock:可重入鎖、互斥,它有timeout機制
讀寫鎖:ReadWriteLock 讀鎖是共享鎖,寫鎖是排它鎖互斥的,讀寫鎖有級別,獲取到讀鎖的執行緒不能升級成寫鎖,能降級,寫鎖能獲取到讀鎖,適合讀多寫少
樂觀鎖:分散式鎖 ?
悲觀鎖:
⑤快取-本地
HashMap
ConcurrentHashMap
使用者的搜尋結果進行快取等,可以用Guava Cache,設定過期策略
memcached叢集, 使用key-value 如 username_zhangsan -> {“username:zhangsan”, “nickname”:“二哈”}
LRU: 近期最少使用
分散式 : 一致性Hash, client實現
Client : xmemcached 、spymemcached
⑥快取-redis
豐富的資料結構,可持久化: Hash , List, Set , SortedSet(給set中的每個元素給個score分,如實現分散式 優先順序佇列)
⑦序列化
方式有:
- Json (fastjson或者jackson)
- Java serialization (記得顯示指定serializeVersionID?)
- Hessian (dubbo使用)
dubbo中序列化不要使用列舉類,否則列舉變了服務更新不同步
⑧池化技術,複用資源
- 執行緒池: Executor
- 連線池: tomcat-jdbc、dbcp,c3p0
- 物件池:spring針對物件的管理其實是一個物件池,又比如說A-B, A-C, A-D可以建個A的物件池,節約記憶體
⑨效能-非同步
–前端輪詢、後端非同步,如做一個搜尋系統,搜尋很耗時,不能同步地等待應使用非同步,但非同步要控制好流量,別把別人的服務請求崩了
Futrue/CountDownLatch
訊息佇列,訊息一定要被消費,qmq使用推的方式,kafka只存下訊息,讓客戶端自己來消費
QMQ/Kafka/AMQ/rabbitmq
HTTP
async-http-client
Apache HttpComponents
Dubbo
非同步呼叫、引數回撥