Tomcat調(diào)優(yōu)詳解
前言
Tomcat作為一個(gè)Java Servlet容器,用于運(yùn)行Web應(yīng)用程序,其性能和吞吐量對(duì)于確保應(yīng)用程序的快速響應(yīng)和高效運(yùn)行至關(guān)重要。
因此,Tomcat調(diào)優(yōu)是為了最大限度地提高系統(tǒng)的性能和可擴(kuò)展性,以滿足高并發(fā)和大流量的需求。
由于Tomcat的運(yùn)行依賴于JVM,從虛擬機(jī)的角度把Tomcat的調(diào)整分為外部環(huán)境調(diào)優(yōu)JVM和Tomcat自身調(diào)優(yōu)兩部分,當(dāng)然操作系統(tǒng)(內(nèi)核參數(shù))也需要配合調(diào)整優(yōu)化。
Tomcat 在目前的網(wǎng)絡(luò)編程中是舉足輕重的,由于Tomcat的運(yùn)行依賴于JVM,從虛擬機(jī)的角度把Tomcat的調(diào)整分為外部環(huán)境調(diào)優(yōu) JVM 和 Tomcat 自身調(diào)優(yōu)兩部分:
一、JVM
1.JVM 組成
1.1 JVM 組成部分:
- 類加載子系統(tǒng): 使用Java語(yǔ)言編寫.java Source Code文件,通過(guò) javac 編譯成.class Byte Code文件。class loader 類加載器將所需所有類加載到內(nèi)存,必要時(shí)將類實(shí)例化成實(shí)例
- 運(yùn)行時(shí)數(shù)據(jù)區(qū): 最消耗內(nèi)存的空間,需要優(yōu)化
- 執(zhí)行引擎: 包括JIT (JustInTimeCompiler)即時(shí)編譯器, GC垃圾回收器
- 本地方法接口: 將本地方法棧通過(guò)JNI(Java Native Interface)調(diào)用Native Method Libraries, 比如:C,C++庫(kù)等,擴(kuò)展Java功能,融合不同的編程語(yǔ)言為Java所用
1.2jvm運(yùn)行時(shí),數(shù)據(jù)區(qū)的構(gòu)成:
- Method Area (線程共享):方法區(qū)是所有線程共享的內(nèi)存空間,存放已加載的類信息(構(gòu)造方法,接口定義),常量(final),靜態(tài)變量(static), 運(yùn)行時(shí)常量池等。但實(shí)例變量存放在堆內(nèi)存中. 從JDK8開(kāi)始此空間由永久代改名為元空間
- heap (線程共享):堆在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建,存放創(chuàng)建的所有對(duì)象信息。如果對(duì)象無(wú)法申請(qǐng)到可用內(nèi)存將拋出OOM異常.堆是靠GC垃圾回收器管理的,通過(guò)-Xmx -Xms 指定最大堆和最小堆空間大小
- Java stack (線程私有):Java棧是每個(gè)線程會(huì)分配一個(gè)棧,存放java中8大基本數(shù)據(jù)類型,對(duì)象引用,實(shí)例的本地變量,方法參數(shù)和返回值等,基于FILO()(First In Last Out),每個(gè)方法為一個(gè)棧幀 1 50 %
- Program Counter Register (線程私有):PC寄存器就是一個(gè)指針,指向方法區(qū)中的方法字節(jié)碼,每一個(gè)線程用于記錄當(dāng)前線程正在執(zhí)行的字節(jié)碼指令地址。由執(zhí)行引擎讀取下一條指令.因?yàn)榫€程需要切換,當(dāng)一個(gè)線程被切換回來(lái)需要執(zhí)行的時(shí)候,知道執(zhí)行到哪里了
- Native Method stack (線程私有):本地方法棧為本地方法執(zhí)行構(gòu)建的內(nèi)存空間,存放本地方法執(zhí)行時(shí)的局部變量、操作數(shù)等。
1.3垃圾確定方法:
- 引用計(jì)數(shù): 每一個(gè)堆內(nèi)對(duì)象上都與一個(gè)私有引用計(jì)數(shù)器,記錄著被引用的次數(shù),引用計(jì)數(shù)清零,該對(duì)象所占用堆內(nèi)存就可以被回收。循環(huán)引用的對(duì)象都無(wú)法將引用計(jì)數(shù)歸零,就無(wú)法清除。Python中即使用此種方式。 簡(jiǎn)單來(lái)說(shuō)就是有個(gè)筆記本,記錄有沒(méi)有人在用,缺陷,AB 資源互相調(diào)用
- 根搜索(可達(dá))算法 Root Searching
2.垃圾回收基本算法
2.1 標(biāo)記-清除 Mark-Sweep:
分垃圾標(biāo)記階段和內(nèi)存釋放階段。
標(biāo)記階段,找到所有可訪問(wèn)對(duì)象打個(gè)標(biāo)記。
清理階段,遍歷整個(gè)堆,對(duì)未標(biāo)記對(duì)象(即不再使用的對(duì)象)逐一進(jìn)行清理。
2.2 標(biāo)記壓縮(壓實(shí))Mark-Compact:
分垃圾標(biāo)記階段和內(nèi)存整理階段。
標(biāo)記階段,找到所有可訪問(wèn)對(duì)象打個(gè)標(biāo)記。
內(nèi)存清理階段時(shí),整理時(shí)將對(duì)象向內(nèi)存一端移動(dòng),整理后存活對(duì)象連續(xù)的集中在內(nèi)存一端。
標(biāo)記-壓縮算法好處是整理后內(nèi)存空間連續(xù)分配,有大段的連續(xù)內(nèi)存可分配,沒(méi)有內(nèi)存碎片。
缺點(diǎn)是內(nèi)存整理過(guò)程有消耗,效率相對(duì)低下。
2.3 復(fù)制 Copying:
先將可用內(nèi)存分為大小相同兩塊區(qū)域A和B,每次只用其中一塊,比如A。
當(dāng)A用完后,則將A中存活的對(duì)象復(fù)制到B。
復(fù)制到B的時(shí)候連續(xù)的使用內(nèi)存,最后將A一次性清除干凈。
缺點(diǎn)是比較浪費(fèi)內(nèi)存,只能使用原來(lái)一半內(nèi)存,因?yàn)閮?nèi)存對(duì)半劃分了,復(fù)制過(guò)程畢竟也是有代價(jià)。
好處是沒(méi)有碎片,復(fù)制過(guò)程中保證對(duì)象使用連續(xù)空間,且一次性清除所有垃圾,所以效率很高。
過(guò)程:
2.4 多種算法總結(jié):
沒(méi)有最好的算法,在不同場(chǎng)景選擇最合適的算法
- 效率: 復(fù)制算法>標(biāo)記清除算法> 標(biāo)記壓縮算法
- 內(nèi)存整齊度: 復(fù)制算法=標(biāo)記壓縮算法> 標(biāo)記清除算法
- 內(nèi)存利用率: 標(biāo)記壓縮算法=標(biāo)記清除算法>復(fù)制算法
2.5 STW (Stop The World):
對(duì)于大多數(shù)垃圾回收算法而言,GC 線程工作時(shí),停止所有工作的線程,稱為Stop The World。GC 完成時(shí),恢復(fù)其他工作線程運(yùn)行。這也是JVM運(yùn)行中最頭疼的問(wèn)題。
① 什么時(shí)候進(jìn)入STW狀態(tài)?
可達(dá)性分析算法中枚舉根節(jié)點(diǎn)(GC Roots)會(huì)導(dǎo)致所有Java執(zhí)行線程停頓,進(jìn)入STW狀態(tài)
② 為什么一定要STW停頓的原因?
分析工作必須在一個(gè)能確保一致性的快照中進(jìn)行,一致性指整個(gè)分析期間整個(gè)執(zhí)行系統(tǒng)看起來(lái)像被凍結(jié)在某個(gè)時(shí)間點(diǎn)上,如果出現(xiàn)分析過(guò)程中對(duì)象引用關(guān)系還在不斷變化,則分析結(jié)果的準(zhǔn)確性無(wú)法保證。被STW中斷的應(yīng)用程序線程會(huì)在完成GC之后恢復(fù),頻繁的中斷會(huì)讓用戶感覺(jué)卡頓。所以我們要減少STW的發(fā)生,也就相當(dāng)于要想辦法降低GC垃圾回收的頻率,STW狀態(tài)和采用哪款GC收集器無(wú)關(guān),所有的GC收集器都有這個(gè)狀態(tài),因?yàn)橐WC一致性。 但是好的GC收集器可以減少停頓的時(shí)間。
3. 分代堆內(nèi)存GC策略:
3.1 堆內(nèi)存分代
上述垃圾回收算法都有優(yōu)缺點(diǎn),能不能對(duì)不同數(shù)據(jù)進(jìn)行區(qū)分管理,不同分區(qū)對(duì)數(shù)據(jù)實(shí)施不同回收策略,分而治之。
將heap內(nèi)存空間分為三個(gè)不同類別: 年輕代、老年代、持久代
解釋:
Heap 堆內(nèi)存分為:
年輕代Young:Young Generation
- 伊甸園區(qū)eden: 只有一個(gè),剛剛創(chuàng)建的對(duì)象
- 幸存(存活)區(qū)Servivor Space:有2個(gè)幸存區(qū),一個(gè)是from區(qū),一個(gè)是to區(qū)。大小相等、地位相 同、可互換。
老年代Tenured:Old Generation, 長(zhǎng)時(shí)間存活的對(duì)象
默認(rèn)空間大小比例:
規(guī)律: 一般情況*99%的對(duì)象都是臨時(shí)對(duì)象
3.2 年輕代回收Minor GC:
- 起始時(shí),所有新建對(duì)象(特大對(duì)象直接進(jìn)入老年代)都出生在eden,當(dāng)eden滿了,啟動(dòng)**GC。這個(gè)稱為Young GC 或者 Minor GC。
- 先標(biāo)記eden存活對(duì)象,然后將存活對(duì)象復(fù)制到s0(假設(shè)本次是s0,也可以是s1,它們可以調(diào)換),eden剩余所有空間都清空。GC完成。
- 繼續(xù)新建對(duì)象,當(dāng)eden再次滿了,啟動(dòng)GC。
- 先同時(shí)標(biāo)記eden和s0中存活對(duì)象,然后將存活對(duì)象復(fù)制到s1。將eden和s0清空,此次GC完成
- 繼續(xù)新建對(duì)象,當(dāng)eden滿了,啟動(dòng)GC。
- 先標(biāo)記eden和s1中存活對(duì)象,然后將存活對(duì)象復(fù)制到s0。將eden和s1清空,此次GC完成以后就重復(fù)上面的步驟。
通常場(chǎng)景下,大多數(shù)對(duì)象都不會(huì)存活很久,而且創(chuàng)建活動(dòng)非常多,新生代就需要頻繁垃圾回收。但是,如果一個(gè)對(duì)象一直存活,它最后就在from、to來(lái)回復(fù)制,如果from區(qū)中對(duì)象復(fù)制次數(shù)達(dá)到閾值(默認(rèn)15次,CMS為6次,可通過(guò)java的選項(xiàng) -XX:MaxTenuringThreshold=N 指定),就直接復(fù)制到老年代。
3.3 老年代回收 Major GC::
進(jìn)入老年代的數(shù)據(jù)較少,所以老年代區(qū)被占滿的速度較慢,所以垃圾回收也不頻繁。如果老年代也滿了,會(huì)觸發(fā)老年代GC,稱為Old GC或者 Major GC。
由于老年代對(duì)象一般來(lái)說(shuō)存活次數(shù)較長(zhǎng),所以較常采用標(biāo)記-壓縮算法。
當(dāng)老年代滿時(shí),會(huì)觸發(fā) Full GC,即對(duì)所有"代"的內(nèi)存進(jìn)行垃圾回收
Minor GC比較頻繁,Major GC較少。但一般Major GC時(shí),由于老年代對(duì)象也可以引用新生代對(duì)象,所以先進(jìn)行一次Minor GC,然后在Major GC會(huì)提高效率。可以認(rèn)為回收老年代的時(shí)候完成了一次Full GC。所以可以認(rèn)為 MajorGC = FullGC。
4. java 內(nèi)存調(diào)整相關(guān)參數(shù)
4.1 JVM 內(nèi)存常用相關(guān)參數(shù)
選項(xiàng)分類:
- -選項(xiàng)名稱 此為標(biāo)準(zhǔn)選項(xiàng),所有HotSpot都支持
- -X選項(xiàng)名稱 為穩(wěn)定的非標(biāo)準(zhǔn)選項(xiàng)
- -XX:選項(xiàng)名稱 非標(biāo)準(zhǔn)的不穩(wěn)定選項(xiàng),下一個(gè)版本可能會(huì)取消
參數(shù) | 說(shuō)明 | 舉例 |
---|---|---|
-Xms | 設(shè)置應(yīng)用程序初始使用的堆內(nèi)存大?。贻p代+老年代) | -Xms2g |
-Xmx | 設(shè)置應(yīng)用程序能獲得的最大堆內(nèi)存早期JVM不建議超過(guò)32G,內(nèi)存管理效率下降 | -Xms4g |
-XX:NewSize | 設(shè)置初始新生代大小 | -XX:NewSize=128m |
-XX:MaxNewSize | 設(shè)置最大新生代內(nèi)存空間 | -XX:MaxNewSize=256m |
-Xmnsize | 同時(shí)設(shè)置-XX:NewSize 和 -XX:MaxNewSize,代 | -Xmn1g |
-XX:NewRatio | 以比例方式設(shè)置新生代和老年代 | -XX:NewRatio=2new/old=1/2 |
-XX:SurvivorRatio | 以比例方式設(shè)置eden和survivor(S0或S1) | -XX:SurvivorRatio=6eden/survivor=6/1new/survivor=8/1 |
-Xss | 設(shè)置每個(gè)線程私有的??臻g大小,依據(jù)具體線程 | -Xss256k |
-Xms 和 -Xmx 建議兩個(gè)值調(diào)一樣大小
標(biāo)準(zhǔn)選項(xiàng):
[root@localhost ~]#java 用法: java [-options] class [args...] (執(zhí)行類) 或 java [-options] -jar jarfile [args...] (執(zhí)行 jar 文件) 其中選項(xiàng)包括: -d32 使用 32 位數(shù)據(jù)模型 (如果可用) -d64 使用 64 位數(shù)據(jù)模型 (如果可用) -server 選擇 "server" VM 默認(rèn) VM 是 server, 因?yàn)槟窃诜?wù)器類計(jì)算機(jī)上運(yùn)行。 -cp <目錄和 zip/jar 文件的類搜索路徑> -classpath <目錄和 zip/jar 文件的類搜索路徑> 用 : 分隔的目錄, JAR 檔案 和 ZIP 檔案列表, 用于搜索類文件。 -D<名稱>=<值> 設(shè)置系統(tǒng)屬性 -verbose:[class|gc|jni] 啟用詳細(xì)輸出 -version 輸出產(chǎn)品版本并退出 -version:<值> 警告: 此功能已過(guò)時(shí), 將在 未來(lái)發(fā)行版中刪除。 需要指定的版本才能運(yùn)行 -showversion 輸出產(chǎn)品版本并繼續(xù) -jre-restrict-search | -no-jre-restrict-search 警告: 此功能已過(guò)時(shí), 將在 未來(lái)發(fā)行版中刪除。 在版本搜索中包括/排除用戶專用 JRE -? -help 輸出此幫助消息 -X 輸出非標(biāo)準(zhǔn)選項(xiàng)的幫助 -ea[:<packagename>...|:<classname>] -enableassertions[:<packagename>...|:<classname>] 按指定的粒度啟用斷言 -da[:<packagename>...|:<classname>] -disableassertions[:<packagename>...|:<classname>] 禁用具有指定粒度的斷言 -esa | -enablesystemassertions 啟用系統(tǒng)斷言 -dsa | -disablesystemassertions 禁用系統(tǒng)斷言 -agentlib:<libname>[=<選項(xiàng)>] 加載本機(jī)代理庫(kù) <libname>, 例如 -agentlib:hprof 另請(qǐng)參閱 -agentlib:jdwp=help 和 -agentlib:hprof=help -agentpath:<pathname>[=<選項(xiàng)>] 按完整路徑名加載本機(jī)代理庫(kù) -javaagent:<jarpath>[=<選項(xiàng)>] 加載 Java 編程語(yǔ)言代理, 請(qǐng)參閱 java.lang.instrument -splash:<imagepath> 使用指定的圖像顯示啟動(dòng)屏幕
非標(biāo)準(zhǔn)的穩(wěn)定選項(xiàng):
[root@localhost ~]#java -X -Xmixed 混合模式執(zhí)行 (默認(rèn)) -Xint 僅解釋模式執(zhí)行 -Xbootclasspath:<用 : 分隔的目錄和 zip/jar 文件> 設(shè)置搜索路徑以引導(dǎo)類和資源 -Xbootclasspath/a:<用 : 分隔的目錄和 zip/jar 文件> 附加在引導(dǎo)類路徑末尾 -Xbootclasspath/p:<用 : 分隔的目錄和 zip/jar 文件> 置于引導(dǎo)類路徑之前 -Xdiag 顯示附加診斷消息 -Xnoclassgc 禁用類垃圾收集 -Xincgc 啟用增量垃圾收集 -Xloggc:<file> 將 GC 狀態(tài)記錄在文件中 (帶時(shí)間戳) -Xbatch 禁用后臺(tái)編譯 -Xms<size> 設(shè)置初始 Java 堆大小 -Xmx<size> 設(shè)置最大 Java 堆大小 -Xss<size> 設(shè)置 Java 線程堆棧大小 -Xprof 輸出 cpu 配置文件數(shù)據(jù) -Xfuture 啟用最嚴(yán)格的檢查, 預(yù)期將來(lái)的默認(rèn)值 -Xrs 減少 Java/VM 對(duì)操作系統(tǒng)信號(hào)的使用 (請(qǐng)參閱文檔) -Xcheck:jni 對(duì) JNI 函數(shù)執(zhí)行其他檢查 -Xshare:off 不嘗試使用共享類數(shù)據(jù) -Xshare:auto 在可能的情況下使用共享類數(shù)據(jù) (默認(rèn)) -Xshare:on 要求使用共享類數(shù)據(jù), 否則將失敗。 -XshowSettings 顯示所有設(shè)置并繼續(xù) -XshowSettings:all 顯示所有設(shè)置并繼續(xù) -XshowSettings:vm 顯示所有與 vm 相關(guān)的設(shè)置并繼續(xù) -XshowSettings:properties 顯示所有屬性設(shè)置并繼續(xù) -XshowSettings:locale 顯示所有與區(qū)域設(shè)置相關(guān)的設(shè)置并繼續(xù) -X 選項(xiàng)是非標(biāo)準(zhǔn)選項(xiàng), 如有更改, 恕不另行通知。
有不穩(wěn)定選項(xiàng)的當(dāng)前生效值:
[root@centos7 ~]#java -XX:+PrintFlagsFinal
查看所有不穩(wěn)定選項(xiàng)的默認(rèn)值:
[root@centos7 ~]#java -XX:+PrintFlagsInitial
示例:
指定內(nèi)存空間:
#指定內(nèi)存空間 [root@centos7 ~]#java -Xms1024m -Xmx1024m -XX:+PrintGCDetails -cp . Heap #Heap 是一個(gè)腳本文件
二、Tomcat 配置文件參數(shù)優(yōu)化
1. 常用的優(yōu)化相關(guān)參數(shù)
- 【redirectPort】如果某連接器支持的協(xié)議是HTTP,當(dāng)接收客戶端發(fā)來(lái)的HTTPS 443 請(qǐng)求時(shí),則轉(zhuǎn)發(fā)至此屬性定義的 8443 端口。
- 【maxThreads】Tomcat使用線程來(lái)處理接收的每個(gè)請(qǐng)求,這個(gè)值表示Tomcat可創(chuàng)建的最大的線程數(shù),即支持的最大并發(fā)連接數(shù),默認(rèn)值是 200。
- 【minSpareThreads】最小空閑線程數(shù),Tomcat 啟動(dòng)時(shí)的初始化的線程數(shù),表示即使沒(méi)有人使用也開(kāi)這么多空線程等待,默認(rèn)值是 10。
- 【maxSpareThreads】最大備用線程數(shù),一旦創(chuàng)建的線程超過(guò)這個(gè)值,Tomcat就會(huì)關(guān)閉不再需要的socket線程。默認(rèn)值是-1(無(wú)限制)。一般不需要指定。
- 【processorCache】進(jìn)程緩沖器,可以提升并發(fā)請(qǐng)求。默認(rèn)值是200,如果不做限制的話可以設(shè)置為-1,一般采用maxThreads的值或者-1。
- 【URIEncoding】指定 Tomcat 容器的 URL 編碼格式,網(wǎng)站一般采用UTF-8作為默認(rèn)編碼。
- 【connnectionTimeout】網(wǎng)絡(luò)連接超時(shí),單位:毫秒,設(shè)置為 0 表示永不超時(shí),這樣設(shè)置有隱患的。通常默認(rèn) 20000 毫秒就可以。
- 【enableLookups】是否反查域名,以返回遠(yuǎn)程主機(jī)的主機(jī)名,取值為:true 或 false,如果設(shè)置為 false,則直接返回 IP 地址,為了提高處理能力,應(yīng)設(shè)置為 false。
- 【disableUploadTimeout】上傳時(shí)是否使用超時(shí)機(jī)制。應(yīng)設(shè)置為 true。
- 【connectionUploadTimeout】上傳超時(shí)時(shí)間,畢竟文件上傳可能需要消耗更多的時(shí)間,這個(gè)根據(jù)你自己的業(yè)務(wù)需要自己調(diào),以使Servlet有較長(zhǎng)的時(shí)間來(lái)完成它的執(zhí)行,需要與上一個(gè)參數(shù)一起配合使用才會(huì)生效。
- 【acceptCount】指定當(dāng)所有可以使用的處理請(qǐng)求的線程數(shù)都被使用時(shí),可傳入連接請(qǐng)求的最大隊(duì)列長(zhǎng)度,超過(guò)這個(gè)數(shù)的請(qǐng)求將不予處理,默認(rèn)為 100 個(gè)。
- 【maxKeepAliveRequests】指定一個(gè)長(zhǎng)連接的最大請(qǐng)求數(shù)。默認(rèn)長(zhǎng)連接是打開(kāi)的,設(shè)置為1時(shí),代表關(guān)閉長(zhǎng)連接;為-1時(shí),代表請(qǐng)求數(shù)無(wú)限制
- 【compression】是否對(duì)響應(yīng)的數(shù)據(jù)進(jìn)行GZIP壓縮,off:表示禁止壓縮;on:表示允許壓縮(文本將被壓縮)、force:表示所有情況下都進(jìn)行壓縮,默認(rèn)值為 off,壓縮數(shù)據(jù)后可以有效的減少頁(yè)面的大小,一般可以減小 1/3 左右,節(jié)省帶寬。
- 【compressionMinSize】表示壓縮響應(yīng)的最小值,只有當(dāng)響應(yīng)報(bào)文大小大于這個(gè)值的時(shí)候才會(huì)對(duì)報(bào)文進(jìn)行壓縮,如果開(kāi)啟了壓縮功能,默認(rèn)值就是 2048。
- 【compressableMimeType】壓縮類型,指定對(duì)哪些類型的文件進(jìn)行數(shù)據(jù)壓縮。
- 【noCompressionUserAgents="gozilla, traviata"】對(duì)于以下的瀏覽器,不啟用壓縮 #如果已經(jīng)進(jìn)行了動(dòng)靜分離處理,靜態(tài)頁(yè)面和圖片等數(shù)據(jù)就不需做 Tomcat 處理,也就不要在 Tomcat 中配置壓縮了。
2. 編輯全局配置
vim /usr/local/tomcat/conf/server.xml ...... <Connector port="8080" protocol="HTTP/11.1" connectionTimeout="20000" redirectPort="8443" --71行--插入 minSpareThreads="50" enableLookups="false" disableUploadTimeout="true" acceptCount="300" maxThreads="500" processorCache="500" URIEncoding="UTF-8" maxKeepAliveRequests="100" compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image /jpg,image/png"/>
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot初始教程之Servlet、Filter、Listener配置詳解
本篇文章主要介紹了SpringBoot初始教程之Servlet、Filter、Listener配置詳解,具有一定的參考價(jià)值,有興趣的可以了解一下2017-09-09Spring Boot 中的自動(dòng)配置autoconfigure詳解
這篇文章主要介紹了Spring Boot 中的自動(dòng)配置autoconfigure詳解,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01Spring常用注解及自定義Filter的實(shí)現(xiàn)
這篇文章主要介紹了Spring常用注解及自定義Filter的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08Java并發(fā)Lock接口實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了Java并發(fā)Lock接口,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06Spring?Boot?3.3?實(shí)現(xiàn)職責(zé)鏈模式輕松應(yīng)對(duì)電商訂單流程分析
在電商系統(tǒng)中,訂單處理流程包括庫(kù)存校驗(yàn)、優(yōu)惠券驗(yàn)證、運(yùn)費(fèi)計(jì)算等多個(gè)步驟,這些步驟具有順序依賴性,為了管理這些業(yè)務(wù)邏輯,職責(zé)鏈模式提供了解決方案,通過(guò)鏈?zhǔn)疥P(guān)系將處理邏輯模塊化,實(shí)現(xiàn)解耦和靈活擴(kuò)展,本文將探討如何結(jié)合SpringBoot實(shí)現(xiàn)職責(zé)鏈模式,優(yōu)化電商訂單處理流程2024-10-10Mybatis查詢時(shí)數(shù)據(jù)丟失的問(wèn)題及解決
Mybatis查詢時(shí)數(shù)據(jù)丟失的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01關(guān)于idea引入spring boot <parent></parent>父依賴標(biāo)紅問(wèn)題
這篇文章主要介紹了idea引入spring boot <parent></parent>父依賴標(biāo)紅問(wèn)題,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10對(duì)SpringMVC的@RequestParam的解釋
下面小編就為大家?guī)?lái)一篇對(duì)SpringMVC的@RequestParam的解釋。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09