業務設計html
冪等:就是用戶對於同一操做發起的一次請求或者屢次請求的結果是一致的,不會由於屢次點擊而產生了反作用,就像數學裏的數字1,多少次冪的結果都是1。舉個最簡單的例子,那就是支付,用戶購買商品後支付,支付扣款成功,可是返回結果的時候網絡異常,此時錢已經扣了,用戶再次點擊按鈕,此時會進行第二次扣款,返回結果成功,用戶查詢餘額發現多扣錢了,流水記錄也變成了兩條...nginx
詳細內容參考 《分佈式中的冪等性》https://www.cnblogs.com/vveiliang/p/6643874.html算法
防重:防止一樣的數據同時提交數據庫
除了在業務方向判斷和按鈕點擊以後不能繼續點擊的限制之外,在服務器端也能夠作到防重:後端
在服務器端生成一個惟一的隨機標識號(Token<令牌>)同事在當前用戶的Session域中保存這個令牌,而後將令牌發送到客戶端的form表單中,在form表單中使用隱藏域來存儲這個Token,表單提交的時候聯通這個Token一塊兒提交到服務器,而後在服務器端判斷客戶提交上來的Token與服務器端生成的Token是否一致,若是不一致,那就重複提交了,此時服務器端就能夠不處理重複提交的表單,若是相同則處理表單,處理完後清楚當前用戶的Session域中存儲的標識號。 緩存
在下列狀況中,服務器程序將拒絕處理用戶提交的表單請求: tomcat
1)存儲Session域中的Token與表單提交的Token不一致
2)當前用戶的Session中不存在Token
3)用戶提交的表單數據中沒有Token。 服務器
限流方式:網絡
1. 限制瞬時併發數 : 好比在入口層(nginx添加nginx_http_limit_conn_module)來限制同一個ip來源的鏈接數,防止惡意攻擊訪問的狀況。併發
2. 限制總併發數:經過配置數據庫鏈接池、線程池大小來約束總併發數
3. 限制時間窗口內的平均速率:在接口層面,經過限制訪問速率來控制接口的併發請求。
4. 其餘方式:限制遠程接口的調用速率、限制MQ的消費速率。
經常使用限流算法
1. 滑動窗口協議:一種常見的流量控制技術,用來改善吞吐量的技術。
滑動窗口協議的由來:
滑動窗口(sliding window)是一種流量控制技術。早期的網絡通信中,通訊雙方不會考慮網絡的擁擠狀況直接發送數據。因爲你們不知道網絡擁塞情況,同時發送數據,致使中間節點阻塞掉包,誰也發送不了數據,因此就有了滑動窗口機制來解決此問題。 發送和接收方都會維護一個數據幀的序列,這個序列被稱爲窗口。
定義:滑動窗口協議(Sliding Window Protocol),屬於TCP協議的一種應用,用於網絡數據傳輸時的流量控制,以免擁塞的發生。該協議容許發送方在中止並等待確認前發送多個數據分組。因爲發送方沒必要每發一個分組就停下來等待確認,所以該協議能夠加速數據的傳輸,提升網絡吞吐量。
發送窗口:就是發送端容許連續發送的幀的序號表。發送端能夠不等待應答而連續發送數據(能夠經過設置窗口的尺寸來控制)
接收窗口:接收方容許接收的幀的序列表,凡是落在接收窗口內的幀,接收方都必須處理,落在接收窗口外的幀將被丟棄。接收方每次容許接收的幀數稱爲接收窗口的尺寸
2. 漏桶:漏桶算法能強行限制數據的傳輸速率。
3. 令牌桶:屬於控制速率類型的限流算法。
4. 計數器:最簡單的一種。經過控制時間段內的請求次數。
https://mp.weixin.qq.com/s/qeDFklNlvlP9o2uqVtTmdg
通常開發高併發系統場景的限流有:
限制總併發數(好比數據庫鏈接池、線程池)、
限制瞬時併發數(如Nginx的limit_conn模塊,用來限制瞬間併發鏈接數)、
限制時間窗口內的平均速率(如Guava的RateLimiter、Nginx的limit_req模塊,用來限制每秒的平均速率),
以及限制遠程接口調用速率、限制MQ的消費速率等。
另外還能夠根據網絡鏈接數、網絡流量、CPU或內存負載等來限流。
https://my.oschina.net/u/3705388/blog/1631547
分佈式限流實踐
https://my.oschina.net/u/3705388/blog/1806229
頁面降級。
頁面片斷降級。
頁面異步請求降級。
服務功能降級。
讀降級。好比多級緩存模式,若是後端服務有問題,則能夠降級爲只讀緩存,這種方式是用於對讀一致性要求不高的場景。
寫降級。好比秒殺搶購咱們能夠只進行Cache的更新,而後異步扣減庫存到DB,保證最終一致性便可,此時能夠將DB降級爲Cache。
爬蟲降級。
風控降級。
http://blog.csdn.net/foreverling/article/details/78011726
在Tomcat容器中,咱們能夠經過自定義線程池,配置最大鏈接數,請求處理隊列等參數來達到限流的目的。
Tomcat默認使用自帶的鏈接池,這裏咱們也能夠自定義實現,打開/conf/server.xml文件,在Connector以前配置一個線程池:
<Executor name="tomcatThreadPool"
namePrefix="tomcatThreadPool-"
maxThreads="1000"
maxIdleTime="300000"
minSpareThreads="200"/>
name:共享線程池的名字。這是Connector爲了共享線程池要引用的名字,該名字必須惟一。默認值:None;
namePrefix:在JVM上,每一個運行線程均可以有一個name 字符串。這一屬性爲線程池中每一個線程的name字符串設置了一個前綴,Tomcat將把線程號追加到這一前綴的後面。默認值:tomcat-exec-;
maxThreads:該線程池能夠容納的最大線程數。默認值:200;
maxIdleTime:在Tomcat關閉一個空閒線程以前,容許空閒線程持續的時間(以毫秒爲單位)。只有當前活躍的線程數大於minSpareThread的值,纔會關閉空閒線程。默認值:60000(一分鐘)。
minSpareThreads:Tomcat應該始終打開的最小不活躍線程數。默認值:25。
配置Connector
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
minProcessors="5"
maxProcessors="75"
acceptCount="1000"/>
executor:表示使用該參數值對應的線程池;
minProcessors:服務器啓動時建立的處理請求的線程數;
maxProcessors:最大能夠建立的處理請求的線程數;
acceptCount:指定當全部可使用的處理請求的線程數都被使用時,能夠放處處理隊列中的請求數,超過這個數的請求將不予處理。
https://mp.weixin.qq.com/s/smuUEAhZAHtPCz5vbDqhFQ