01. 聊 啥面試
世人都說路不齊、別人騎馬我騎驢、回頭看看推車漢、比上不足下有餘!
數據庫
你騎馬來我騎驢,看看眼前我不如;回頭一看推車漢,比上不足比下餘。apache
回頭總結一下以往填過的坑,感受本身還真挺牛掰。緩存
今天不閒聊,主題不跑偏,就想送大家一籮筐經驗,預防大家再入坑。
安全
吃個核桃,坐穩,扶好,咱們開始。bash
02. 聊 開服務器
經驗一:CPU 長期利用率爲 100%多線程
問題現象:併發
多用戶併發狀況下,CPU 利用率長期爲100%,DUMP 線程信息,發現 CPU 利用率高的線程都與 HashMap 操做相關。異步
緣由分析:
在併發狀況下選擇非線程安全的容器是沒有保障的,HashMap是非線程安全的;
HashMap 在多線程狀況下,進行擴容很容易致使死循環,最終致使 CPU 利用率 100%。
解決方法:
在併發場景下,避免使用 hashMap;
在併發場景下,若必定要使用 HashMap,使用同步鎖或者使用 ConcurrentHashMap 替代 HashMap。
經驗二:數據庫訪問至關的慢
問題現象:
數據庫請求次數多,響應慢。
緣由分析:
在索引具有的前提下,數據庫分配鏈接數少,且缺乏緩存。
解決方法:
對於須要鏈接到數據庫的應用,要考慮查詢的結果是否能夠複用;
對於查詢結果時效性不高並且須要屢次調用的請求,作緩存每每能夠節省數據庫的資源,也使應用自己效率大大提升。
經驗三:系統鏈接數巨多
問題現象:
系統鏈接數巨多
緣由分析:
Tomcat 容器默認的通信方式爲 TCP/IP + BIO,這種模式每每不適合大併發的狀況,BIO 模式生成 Socket 會消耗過多的本地資源,Socket 鏈接的創建通常比較慢,能支持的鏈接數有限。
通常都採起 accept 獲取 Socket 之後採用一個 thread 來處理,one connection one thread,不管鏈接是否有真正數據請求,都須要獨佔一個 thread。
若是咱們 server 端須要支持大量鏈接,但這些鏈接同時發送請求的峯值不會不少,通常建議替換成 NIO 模式。
解決方法:
替換成 TCP/IP+NIO,NIO 模型是內置的,調用很方便,只須要修改配置文件conf/server.xml文件,將配置文件中 protocol 修改爲 org.apache.coyote.http11.Http11NioProtocol,重啓便可生效。
下面的配置是已經改過了的,默認 protocol 是HTTP/1.1
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443" maxThreads="500" minSpareThreads="20" acceptCount="100" disableUploadTimeout="true" enableLookups="false" URIEncoding="UTF-8" />複製代碼
經驗四:使用HttpClient的版本問題
問題現象:
不是每一個請求都能正確返回,可能遇到 The remote server returned an error.(417) Unkown
緣由分析:
系統使用的是 4.0.3 版本,該版本發佈時 Expect:100-continue 默認爲開啓狀態,即客戶端每次與服務器通信過程,每次先向服務器發送一個請求,看服務器是否能處理這個請求,通常應用在上傳一些特殊的文件或者比較大數據量的交互上,有時候會造 time_wait 不少。
該問題在 HttpClient 4.1 版本中解決,默認爲關閉該功能。
解決方法:
升級到 4.1 以上版本,默認爲關閉該功能。
經驗五:使用 log4j 日誌性能的問題
問題現象:
日誌 IO 佔用大量的系統資源,CPU 利用率高,TPS 偏低,熱點方法在
org.apache.log4j.Category.callAppenders
ch.qos.logback.core.OutputStreamAppender.subAppend() 複製代碼
等與日誌相關的方法。
緣由分析:
日誌量過大,IO 頻繁。日誌對系統性能的影響程度主要體如今如下幾方面
日誌輸出的選項設置,有些選項極慢, 例如 C/class、 F/file 、L/line 、l 、M/method速度極慢,儘可能避免使用;
日誌輸出雙份,某些應用一般將業務日誌同時輸出到控制檯和另一個文件或者日誌信息在同一份文件中輸出兩次;
日誌輸出的目的地,輸出到控制檯的速度比輸出到文件系統的速度要慢;
日誌輸出格式不同對性能也會有影響,如簡單輸出佈局(SimpleLayout)比格式化輸出佈局(PatternLayout)輸出速度要快。能夠根據須要儘可能採用簡單輸出佈局格式輸出日誌信息;
日誌級別越低輸出的日誌內容就越多,對系統系能影響很大;
日誌輸出方式的不一樣,對系統系能也是有必定影響的,採用異步輸出方式比同步輸出方式性能要高;
每次接收到日誌輸出事件就打印一條日誌內容比當日志內容達到必定大小時打印性能要低。
解決方法:
精簡日誌輸出內容,合理設置日誌輸出格式,避免使用那些極慢的選項;
設置日誌緩存,以及緩存大小;
將業務日誌僅輸出到文件系統,且僅輸出一份(以log4j爲例,對於日誌輸出多份的狀況舉例以下):
同一份日誌輸出到兩個文件的狀況
log4j.rootLogger=DEBUG, stdout, system
表示將等級爲 DEBUG 的日誌信息輸出到 stdout 和 system 這兩個目的地,
此配置將使得日誌輸出兩份,將此行改爲
log4j.rootLogger=DEBUG, system;
表示將日誌只輸出到 system 這一個目的地;複製代碼
經驗六:logback 比 log4j 擁有更好的性能
使用 logback 和 log4j 日誌組件進行日誌打印。
當日志級別爲 debug 時,系統平均 tps 比爲 logback:log4j=1.31:1
當日志級別爲 info 時,系統平均 tps 比爲 logback:log4j=1.03:1
日誌輸出量越大時,使用 logback 日誌組件進行日誌打印比 log4j 方式在處理速度方面的優點越爲明顯,實驗過程當中 logback 比之 log4j 系統處理能力提高幅度爲 3%~30%。
經驗七:已經分享一籮筐了,再分享籮筐也裝不下,惟恐聰明的大家也消化不動了。(有緣再續)
03. 聊 畢
過往從事研發中的點滴經驗,送給大家,預防大家再入坑,另外大家也能夠在面試的時候吹吹牛啦(哈哈)。
若是大家感受稍微有點意思,不用讚揚,就點擊右下角的「在看」,或者多多分享轉發給大家的朋友就很感激。