自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

關(guān)于Java程序服務(wù)預(yù)熱那些事

開發(fā) 前端
所謂服務(wù)預(yù)熱,就是在服務(wù)啟動完成到對外提供服務(wù)之前,針對特定場景提供一些初始化準(zhǔn)備操作。比如線程池預(yù)熱、緩存預(yù)熱、數(shù)據(jù)庫預(yù)熱、web預(yù)熱和JVM預(yù)熱等。

一、背景

1.1 什么是服務(wù)預(yù)熱

所謂服務(wù)預(yù)熱,就是在服務(wù)啟動完成到對外提供服務(wù)之前,針對特定場景提供一些初始化準(zhǔn)備操作。

比如線程池預(yù)熱、緩存預(yù)熱、數(shù)據(jù)庫預(yù)熱、web預(yù)熱和JVM預(yù)熱等。

1.2 為什么要預(yù)熱

因為服務(wù)剛啟動的時候需要一段磨合期,這段期間,服務(wù)運行狀態(tài)沒有達(dá)到最佳。因此,如果這時候一下子將服務(wù)流量提升到正常水平,就有可能導(dǎo)致大量請求超時或者瞬間將系統(tǒng)壓垮。

針對 Web 應(yīng)用的場景,將Java程序啟動分為兩個過程:

1、啟動過程:是指從JVM 啟動到程序初始化完成能響應(yīng)第一個請求的階段。由于啟動時需要動態(tài)類加載和程序啟動時的初始化,導(dǎo)致啟動會比較慢。啟動慢會影響程序的響應(yīng)度,減慢 Web 應(yīng)用擴容。

2、預(yù)熱過程:是指從JVM 啟動到程序優(yōu)化完成、達(dá)到性能峰值的階段。預(yù)熱慢會導(dǎo)致 Web 應(yīng)用無法及時的處理完用戶請求,造成大量請求超時。

圖片圖片

二、如何預(yù)熱

2.1 預(yù)熱緩存

a.連接池預(yù)熱

和數(shù)據(jù)庫連接池一樣,我們可以在應(yīng)用啟動時,根據(jù)需要初始化若干連接放入連接池,從而避免請求過來的時候再創(chuàng)建而影響性能。

系統(tǒng)啟動時,嘗試獲取若干連接(這里取最小閑置),此時連接池為空,生成連接后會放入連接池,等請求進來的時候就不會再去創(chuàng)建連接了。

圖片圖片

b.熱點數(shù)據(jù)預(yù)熱

  • 數(shù)據(jù)存到redis中

處理方案:

1、配置一個定時任務(wù),刷新緩存數(shù)據(jù)。

2、直接寫個緩存刷新頁面,上線后手動刷新。

  • 數(shù)據(jù)存到本地

對于一些訪問度特別高的熱點數(shù)據(jù),在極端情況下,考慮到服務(wù)到redis有網(wǎng)絡(luò)延遲以及序列化和反序列化消耗,所以放入redis緩存是不太理想的。

那么對于這些數(shù)據(jù)我們可以考慮放入本地緩存,當(dāng)然這些數(shù)據(jù)量不能太大。對于極端的熱點數(shù)據(jù)放入本地緩存后,請求獲取數(shù)據(jù)在應(yīng)用維度基本沒有任何消耗,沒有網(wǎng)絡(luò)延遲也沒有序列化和反序列化消耗。

可以使用guava 的cache

2.2 預(yù)熱線程池

1)請求接收線程池

以tomcat為例,我們可以配置初始化創(chuàng)建線程的數(shù)量來做線程池預(yù)熱。

圖片

2)自定義線程池

對于自定義線程池,初始化時候調(diào)用prestartAllCoreThreads方法即可。

圖片

3)預(yù)熱DB連接池

服務(wù)啟動時根據(jù)需要創(chuàng)建若干數(shù)據(jù)庫連接,放到連接池中,然后應(yīng)用啟動處理數(shù)據(jù)庫讀寫請求時,可以直接從連接池中拿連接來用,避免了讀寫請求創(chuàng)建連接并放入連接池的流程耗時。

我們常用的連接池Druid提供了比較方便的連接池預(yù)熱能力。常見的配置方式:

圖片

4)JVM預(yù)熱

大家都知道,Java語言是解釋執(zhí)行和編譯執(zhí)行共同存在的。即Java源代碼文件(.java)首先由Javac編譯為字節(jié)碼(.class),然后字節(jié)碼由各操作系統(tǒng)對應(yīng)的虛擬機解釋或編譯執(zhí)行。

為了提高執(zhí)行速度,引入了JIT(Just-in-time compilation)。在運行時,JIT會把編譯過來的機器碼保存起來,以便下次使用。JIT只會對經(jīng)常執(zhí)行的熱點代碼進行編譯,如循環(huán),高頻度使用的方法等。

JVM默認(rèn)開啟JIT編譯,可以檢查啟動參數(shù)-Xint和-Djava.compiler=NONE,如果有說明關(guān)閉了JIT,根據(jù)需要可以移除重新開啟JIT。

此外,JDK1.8引入了Lambda表達(dá)式,給開發(fā)人員帶來了很多方便,但是過度的使用Lambda表達(dá)式也會帶來負(fù)面效果。lambda表達(dá)式的原理是在執(zhí)行時生成匿名內(nèi)部類,并且需要加載和編譯。

所以對于一些熱點代碼可以選擇不使用Lambda表達(dá)式,或者在服務(wù)啟動時進行預(yù)調(diào)用,經(jīng)過充分的調(diào)用之后使其成為熱點代碼,后續(xù)的調(diào)用就會走JIT編譯,就會跳過生成匿名內(nèi)部類、加載的步驟,也就提升了執(zhí)行效率。

三、預(yù)熱的問題及解決

3.1 時長

既然在服務(wù)啟動階段加入了預(yù)熱邏輯,就會產(chǎn)生損耗,最直接的體現(xiàn)就是服務(wù)啟動時間變長,可能幾分鐘到十幾分鐘不等。

但啟動慢不一定就是壞事,相當(dāng)于是在對外提供服務(wù)之前做了充足的初始化以及預(yù)熱準(zhǔn)備。

當(dāng)然事情都有兩面性,關(guān)鍵的是要在啟動快與慢之間找到一個平衡點,在保證服務(wù)能夠在可接受的時間內(nèi)啟動,并且上線之后短時間內(nèi)就能提供高質(zhì)量的服務(wù)。

3.2 CPU升高

在實際應(yīng)用過程中,遇到了CPU突增的情況。如下圖,服務(wù)在啟動時會收到CPU報警,查看監(jiān)控發(fā)現(xiàn)CPU使用率是平時的2倍以上。

圖片圖片

查看啟動時的預(yù)熱代碼,發(fā)現(xiàn)會觸發(fā)下面的請求,如圖,請求量是平時正常水平的幾百倍。因此定位應(yīng)該是預(yù)熱代碼的問題。

圖片圖片

預(yù)熱代碼如下:

圖片圖片

圖片圖片

上述代碼使用CountDownLatch作為計數(shù)器,在服務(wù)啟動時,觸發(fā)三個熱點接口,以達(dá)到預(yù)熱的目的。但是由于參數(shù)過多導(dǎo)致服務(wù)的請求激增,引發(fā)報警。

問題定位之后,我們降低了入?yún)?shù)量,減少了循環(huán)次數(shù),從而減少了服務(wù)自請求次數(shù),問題得以修復(fù)。

四、總結(jié)

以上是服務(wù)預(yù)熱的一些常見方式,服務(wù)預(yù)熱是把雙刃劍,在使用之前,需要搞清楚哪些服務(wù)需要預(yù)熱。對于需要預(yù)熱的服務(wù),需要搞清楚具體需要預(yù)熱哪些內(nèi)容,不能盲目預(yù)熱,容易適得其反。

責(zé)任編輯:武曉燕 來源: 架構(gòu)精進之路
相關(guān)推薦

2012-05-01 08:06:49

手機

2015-08-19 09:10:37

程序員面試

2012-01-02 19:30:22

iPad

2011-08-22 16:42:43

SqliteiPad

2015-07-23 13:10:38

服務(wù)器虛擬化

2022-05-06 07:52:06

Nacos服務(wù)注冊

2021-05-17 08:18:35

Java內(nèi)存模型JMM

2012-07-13 00:03:08

WEB前端開發(fā)WEB開發(fā)

2011-07-04 13:51:02

QT 對象 模型

2011-08-01 17:31:25

Xcode開發(fā) Cocoa

2019-12-10 08:00:46

Kata容器Linux

2021-03-18 16:05:20

SSD存儲故障

2011-06-30 10:59:43

2009-02-19 10:21:00

路由多WAN口

2011-07-19 15:33:57

iPhone

2015-08-13 10:54:46

2015-09-14 09:28:47

2022-09-09 08:08:28

開源項目服務(wù)

2019-01-04 10:53:59

CPUCache緩存

2012-05-01 21:27:55

圖標(biāo)
點贊
收藏

51CTO技術(shù)棧公眾號