âåè¨ï¼
å¨40å²èæ¶æå¸å°¼æ©ç读è 社åºï¼50+ï¼ä¸ï¼å¾å¤å°ä¼ä¼´æ¿ä¸å°offerï¼æè æ¿ä¸å°å¥½çofferã
å°¼æ©ç»å¸¸ç»å¤§å®¶ ä¼å项ç®ï¼ä¼åç®åï¼ææææ¯äº®ç¹ãå¨æ导ç®åçè¿ç¨ä¸ï¼ Java è°ä¼æ¯ä¸é¡¹å¾éè¦çæ导ã
é®é¢æ¯ï¼å¾å¤å°ä¼ä¼´ï¼è¿ä¸ç¹è°ä¼çåºç¡é½æ²¡æï¼ å½ç¶ï¼è¿é«å¹¶åçåºæ¯ä¹æä¸æ¸ æ¥ã
å®é ä¸ï¼æ 论æ¯è°ä¼ï¼è¿æ¯é«å¹¶åçåºæ¯ï¼æ们é½éè¦è§£å³ä¸äºåºç¡é®é¢ï¼æ¯å¦è¯´ï¼
ä¸äº¿ç¨æ·éï¼å¹³åæ¯äººæ¯å¤©10次çä¸å¡éï¼è¦æ±å¹¶åæ°å¨5000以ä¸ï¼å³°å¼å¨5wå°10wä¹é´ï¼QPSå¨25w以ä¸, å¦ä½è¿è¡åæµï¼å¦ä½è¿è¡è°ä¼ï¼
对äºæ¶æå¸ãé«çº§å¼åæ¥è¯´ï¼ è°ä¼æ¯ æ ¸å¿å å®¹ï¼ é£ä¹åæµæ´æ¯å åä¸çå åã
å°¼æ©å¢éä» é«å¹¶ååæµå®æå¼å§ï¼ç»å¤§å®¶æ¢³çä¸ä¸ªç³»åçãJava è°ä¼å£ç»ãPDF çµå书ï¼å æ¬æ¬æå¨å è§åçäºä¸ªé¨åï¼
(1) è°ä¼å£ç»1ï¼é¶åºç¡ç²¾éJmeteråå¸å¼åæµï¼10Wqps+åæµå®æ
(2) è°ä¼å£ç»2ï¼ä»70så°20msï¼ä¸æ¬¡3500åæ§è½ä¼åå®æï¼æ¹æ¡äººäººå¯ç¨
(3) è°ä¼å£ç»3ï¼é¶åºç¡ç²¾éJVMè°ä¼å®æï¼å®ç°JVMèªç± ï¼åä½ä¸ï¼
(4) è°ä¼å£ç»4ï¼é¶åºç¡ç²¾éMysqlè°ä¼å®æï¼å®ç°Mysqlè°ä¼èªç± ï¼åä½ä¸ï¼
(5) è°ä¼å£ç»5ï¼é¶åºç¡ç²¾éLinuxãTomcatlè°ä¼å®æï¼å®ç°åºç¡è®¾æ½è°ä¼èªç± ï¼åä½ä¸ï¼
以ä¸çå¤ç¯æç« ï¼åç»å°éç»å¨å ¬å·ãææ¯èªç±åãæ¨åºã
ãå°¼æ© æ¶æç¬è®°ããå°¼æ©é«å¹¶åä¸é¨æ²ããå°¼æ©Javaé¢è¯å®å ¸ã çPDFæ件ï¼è¯·å°å ¬å·ãææ¯èªç±åãå
âæ¬æç®å½ï¼
- åè¨
- ç¨æ·ä¸å°çæ§è½é®é¢
- ç¨æ·ä¸å°æ§è½ä¼åç常è§æè·¯
- 第ä¸è½®ä¼åï¼æ°æ®åºå±é¢ä¼åï¼æå60å
- 第äºæ¥ï¼åºç¨å±ä¼åï¼æå70å
- 第ä¸æ¥ï¼åå¸å¼ç¼åä¼åï¼ä½æ¯é«å¹¶ååºæ¯å¤±è´¥çè¿é«
- 使ç¨åå¸å¼ jmeter clusterçæ¹å¼æ¥è¿è¡åæµ
- 第åæ¥ï¼BigKeyé®é¢ä¼åï¼4000并ååºæ¯å°100ms
- 第äºæ¥ï¼æ¬å°ç¼åä¼åï¼ä¼åå°20ms
- ä¼åæ»ç»
- 第å
æ¥ï¼ç½å
³å±é¢çä¼å
- ä»70så°20msè°ä¼å°ç»
- ãJava è°ä¼å£ç»ãè¿ä»£è®¡å
- ææ¯èªç±çå®ç°è·¯å¾ PDF è·å
âç¨æ·ä¸å°çæ§è½é®é¢ï¼
å¨ä¸ä¸ªå¤§åç§æå ¬å¸ç¨æ·ä¸å°ä¸ï¼ç»ç»æºææ®æ¼çè³å ³éè¦çè§è²ï¼æ¶åå°å¤ä¸ªé¨é¨ãå¢éååå·¥çå ³ç³»åå±çº§ã
ç¶èï¼éçå ¬å¸è§æ¨¡çä¸ææ©å¤§åç»ç»ç»æçå¤ææ§å¢å ï¼ç»ç»æºææ çæ°æ®éä¹æ¥çåºå¤§ã
è¿ç»å é¨ç¨æ·å¨å é¨ç³»ç»å¹³å°æ¥è¯¢ç»ç»æºææ æ¶å¸¦æ¥äºä¸ç³»åææåé®é¢ã
å ¶ä¸æçªåºçé®é¢ä¹ä¸æ¯æ¥è¯¢çæçé®é¢ã
ä¼ ç»çæ¥è¯¢æ¹å¼æ æ³ææåºå¯¹ç»ç»æºææ åºå¤§æ°æ®éçææï¼å¯¼è´é¡µé¢å¨æ¥è¯¢æ¶åºç°å¡é¡¿ãååºæ¶é´è¿é¿çè³è¶ æ¶çæ åµã
æå ³é®é¢è¯¦ç»çæ°æ®
å次ç¹å» rtæ¶é´ > 70s
100并å åæµï¼å¹³åRTæ¶é´ > 160
å¨æ个大åç§æå ¬å¸ç¨æ·ä¸å°ä¸ï¼ç»ç»æºææ¥å£çRTæ¶é´ä¸º70sã
éè¿postmanå·¥å ·è°ç¨æ¥å£è·åç»ç»æ ï¼å¯ä»¥çå°è¿ä¸ªæ¶é´ï¼
æ们å¯ä»¥çå°ï¼è¿ä¸æ¬¡ç»ç»æ æ¥è¯¢æ¥å£èæ¶å¤§æ¦å¨70så·¦å³ã è¿ä¸ªæ¯å¤ªé¿äºï¼æ§è½å¤ªå·®äºã
ä¸è¬ç³»ç»RTè¦æ±å¨500mså ï¼å¹¶ä¸è¶çè¶å¥½ã
æ¥ä¸æ¥ï¼æ们å©ç¨jmeter对该æ¥å£è¿è¡åæµï¼
JMeterï¼Apache JMeterï¼æ¯ä¸ä¸ªå¼æºçã纯Javaç¼åçæ§è½æµè¯å·¥å ·ãå®ä¸»è¦ç¨äºå¯¹è½¯ä»¶åæå¡è¿è¡ååæµè¯ãè´è½½æµè¯ãåè½æµè¯ä»¥åæ§è½æµè¯çãJMeteræä¾äºä¸ä¸ªå¾å½¢åçé¢ï¼ä½¿ç¨æ·è½å¤è½»æ¾å建æµè¯è®¡å并é ç½®åç§æµè¯åºæ¯ã
以ä¸æ¯JMeterçä¸äºä¸»è¦ç¹ç¹ååè½ï¼
- å¤åè®®æ¯æï¼JMeteræ¯æå¤ç§åè®®ï¼å æ¬HTTPãHTTPSãFTPãJDBCãSOAPãRESTçï¼ä½¿å ¶éç¨äºæµè¯åç§ç±»åçåºç¨ç¨åºã
- åå¸å¼æµè¯ï¼JMeteræ¯æåå¸å¼æµè¯ï¼å¯ä»¥éè¿å¤ä¸ªJMeterå®ä¾ååå·¥ä½ï¼æ¨¡æ大éç¨æ·åæ¶è®¿é®ç®æ ç³»ç»ï¼ä»¥è¯ä¼°ç³»ç»çæ§è½åæ¿è½½è½åã
- çµæ´»çæµè¯è®¡åï¼ä½¿ç¨JMeterï¼æ¨å¯ä»¥å建çµæ´»çæµè¯è®¡åï¼å®ä¹å¹¶åç¨æ·æ°ã请æ±ç顺åºã延è¿æ¶é´ãæè¨ãçå¬å¨çãæ¨å¯ä»¥æ ¹æ®éè¦å¯¹æµè¯è®¡åè¿è¡èªå®ä¹é ç½®ã
- çæ§ååæï¼JMeteræä¾äºå¤ç§çå¬å¨ï¼å¯ä»¥å®æ¶çæ§ååææµè¯ç»æãæ¨å¯ä»¥æ¥çååºæ¶é´ãååéãé误ççææ ï¼å¸®å©æ¨è¯ä¼°ç³»ç»çæ§è½å稳å®æ§ã
- èæ¬å½å¶ååæ¾ï¼JMeteræ¯æéè¿ä»£çæå¡å¨å½å¶ç¨æ·çæä½ï¼å¹¶çæ对åºçæµè¯èæ¬ãè¿ä½¿å¾å建æµè¯èæ¬åå¾æ´å ç®ååå¿«éã
- å¯æ©å±æ§ï¼JMeterå ·æ丰å¯çæ件åæ©å±æºå¶ï¼å¯ä»¥éè¿æ件æ¥å¢å æ°çåè½ååè®®æ¯æï¼æ»¡è¶³æ´å¤ç¹å®çæµè¯éæ±ã
å¨ã è°ä¼å£ç»ï¼é¶åºç¡ç²¾éJmeteråå¸å¼åæµï¼10Wqps+è¶ é«å¹¶å ãè¿ç¯æç« ä¸ï¼å¯¹jmeterè¿è¡äºè¯¦ç»ä»ç»ï¼
ç±äºæ¥å£æ¥è¯¢èæ¶å¤ªé¿ï¼å½åä» éç¨åæº jmeter è¿è¡åæµï¼æ¨¡æ100QPSçæ§è¡æ åµï¼
å¯å¨åæµï¼çåæµæ§è¡å®åï¼æ¥çèåæ¥åï¼
ä»æ¥åä¸æ们å¯ä»¥çå°ï¼100次æ¥è¯¢è¯·æ±ï¼å¹³åèæ¶æ¥è¿160ç§ã
æ§è½é®é¢æ带æ¥ç严éå½±åï¼
è¿ä¸¥éå½±åäºç¨æ·çå·¥ä½æçåä½éªã æ¯ä¸¥éçç产é®é¢ã
é¢å¯¹è¿ä¸é®é¢ï¼æ们éè¦å¯»æ¾ä¼åç解å³æ¹æ¡ï¼ä»¥æåç»ç»æºææ æ¥è¯¢çæ§è½åååºé度ã
è¿æ¶åå°å¨æ°æ®åºå±é¢ãç¼åå±é¢ä»¥åç½å ³å±é¢è¿è¡é对æ§çä¼åæªæ½ã
éè¿ä¼åæ°æ®åºè¡¨ç»æã使ç¨ç¼åææ¯ãåçé ç½®ç½å ³çæ段ï¼æ们å¯ä»¥æ¾èæ¹åç»ç»æºææ æ¥è¯¢çæçåç¨æ·ä½éªã
æ¥ä¸æ¥ï¼ å°¼æ©å¢é带大家å¼å§ï¼ä¸æ¥ä¸æ¥çè¿è¡ä¼åã
âç¨æ·ä¸å°æ§è½ä¼åç常è§æè·¯ï¼
é¦å ï¼æ¢³çä¸ä¸ç¨æ·ä¸å°æ§è½ä¼åç常è§æè·¯ã
常è§çä¼åæè·¯å¦ä¸ï¼
- ç»ä¸æ°æ®æºï¼å»ºç«ä¸ä¸ªä¸å¿åçç»ç»æºææ°æ®æºï¼å°ææé¨é¨åå¢éçç»ç»æºææ°æ®éä¸åå¨ï¼ç¡®ä¿æ°æ®çä¸è´æ§ååç¡®æ§ã
- æ°æ®åºä¼åï¼è®¾è®¡åéçæ°æ®åºè¡¨ç»æåç´¢å¼ï¼ä»¥æ¯æé«æçç»ç»æºææ¥è¯¢æä½ã使ç¨åéçæ°æ®åºææ¯åä¼åæ¹æ³ï¼å¦åç´æåææ°´å¹³æåçï¼æ¥æé«æ¥è¯¢æ§è½ã
- ç¼åæºå¶ï¼ä½¿ç¨ç¼åæ¥åå¨ç»ç»æºææ°æ®ï¼å¦Redisçãéè¿åççç¼åçç¥ï¼å¦è®¾ç½®éå½çè¿ææ¶é´ã使ç¨LRUç®æ³çï¼åå°å¯¹æ°æ®åºçé¢ç¹æ¥è¯¢ï¼æé«æ¥è¯¢æçã
- åå¸å¼æ¶æï¼éç¨åå¸å¼æ¶æï¼å°æ¥è¯¢è´è½½åæ£å°å¤ä¸ªèç¹ä¸ï¼éè¿æ°´å¹³æ©å±æ¥æé«æ¥è¯¢æ§è½å并åå¤çè½åã
- å¼æ¥å¤çï¼å¯¹äºå¤æçç»ç»æºææ¥è¯¢ï¼å¯ä»¥å°å ¶æ¾å ¥å¼æ¥ä»»å¡éåä¸å¤çï¼åå°å端请æ±ççå¾ æ¶é´ï¼æé«ç³»ç»ç并åå¤çè½åã
- æ°æ®åæ¥æºå¶ï¼ç¡®ä¿ç»ç»æºææ°æ®çåæ¥åæ´æ°çåæ¶æ§ï¼ä½¿ç¨åéçæ°æ®åæ¥ææ¯åæºå¶ï¼å¦å®æ¶ä»»å¡ãäºä»¶é©±å¨çï¼ä¿è¯æ°æ®çä¸è´æ§ã
- å端ä¼åï¼éç¨å端ææ¯åçé¢è®¾è®¡ä¼åï¼å¦æ°æ®å页å è½½ãæå è½½çæ¹å¼ï¼åå°ä¸æ¬¡æ§å 载大éç»ç»æºææ°æ®æ带æ¥çæ§è½ååã
æ¬æå°æ·±å ¥æ¢è®¨é对大åç§æå ¬å¸ä¸ç»ç»æºææ æ°æ®éè¿å¤§æå¼åçé®é¢ï¼å¹¶æä¾ä¸ç³»åä¼åæ¹æ¡ãéè¿è¿äºä¼åæªæ½ï¼æ们å°å¸®å©æ¨å æç»ç»æºææ æ¥è¯¢ä¸çå°é¾ï¼ä½¿æ¨è½å¤æ´å¿«éãé«æå°è·åæéçç»ç»æºæä¿¡æ¯ï¼æåå·¥ä½æçåå³çè½åã
æ¥ä¸æ¥ï¼æ¬æå°å¸¦ç大家ä¸èµ·å®è·µç»ç»æ¶ææ çä¼å!
â第ä¸è½®ä¼åï¼æ°æ®åºå±é¢ä¼åï¼æå60å
æ°æ®åºä¼åæ¯è§£å³å¤§åç§æå ¬å¸ç»ç»æºææ¥è¯¢é®é¢çéè¦ä¸ç¯ãä¸é¢æ¯ä¸äºè¯¦ç»çæ°æ®åºä¼åçç¥åææ¯ï¼
â1. åéç表ç»æ设计ï¼
- æ ¹æ®ç»ç»æºæçç¹ç¹ï¼è®¾è®¡åéç表ç»æï¼ä»¥æ¯æé«æçæ¥è¯¢æä½ãå¯ä»¥éç¨éå½çå ³ç³»åæ°æ®åºæè NoSQLæ°æ®åºï¼æ ¹æ®å ·ä½éæ±éæ©åéçæ°æ®åºå¼æã
- 使ç¨èå¼åæè åèå¼åç设计æ¹å¼ï¼æ ¹æ®æ¥è¯¢éæ±åæ°æ®ä¸è´æ§çè¦æ±æ¥å³å®è¡¨ç»æçè§èåç¨åº¦ã
- 使ç¨åéçæ°æ®ç±»åæ¥åå¨ç»ç»æºææ°æ®ï¼ä»¥èçåå¨ç©ºé´å¹¶æé«æ¥è¯¢æçã
â2. ç´¢å¼ä¼åï¼
- éè¿å建åéçç´¢å¼æ¥å éç»ç»æºææ¥è¯¢ãæ ¹æ®æ¥è¯¢çå段åæ¡ä»¶ï¼ä¸ºç»å¸¸è¢«ç¨äºæ¥è¯¢çåå建索å¼ï¼ä»¥æé«æ¥è¯¢çé度ã
- éæ©éå½çç´¢å¼ç±»åï¼å¦B-treeç´¢å¼ãåå¸ç´¢å¼æè å ¨æç´¢å¼ï¼æ ¹æ®å ·ä½æ¥è¯¢çéæ±åæ°æ®çç¹ç¹ååºéæ©ã
- å®æè¿è¡ç´¢å¼ç»´æ¤åä¼åï¼å æ¬ç´¢å¼é建ãç¢çæ´ççæä½ï¼ä»¥ä¿æç´¢å¼çæ§è½ã
â3. æ¥è¯¢ä¼åï¼
- ç¼åé«æçæ¥è¯¢è¯å¥ï¼ä½¿ç¨åéçSQLè¯æ³åæä½ç¬¦ï¼é¿å ä¸å¿ è¦çæ¥è¯¢æåæ¥è¯¢ï¼æé«æ¥è¯¢çæçã
- 使ç¨åéçæ¥è¯¢ç¼åæºå¶ï¼å¦æ°æ®åºèªå¸¦çæ¥è¯¢ç¼åæè 第ä¸æ¹ç¼åå·¥å ·ï¼ä»¥åå°å¯¹æ°æ®åºçé¢ç¹æ¥è¯¢ã
- é¿å è¿åº¦ä½¿ç¨JOINæä½ï¼å°½éåå°å ³èæ¥è¯¢çå¤ææ§ãèè使ç¨é¢å è½½æ延è¿å è½½çæ¹å¼ï¼æ ¹æ®å®é éæ±æ¥ä¼åæ¥è¯¢æä½ã
- åææ¥è¯¢æ§è¡è®¡åï¼éè¿ç´¢å¼ä¼åã表ç»æè°æ´æè SQLéåçæ段ï¼æ¹åæ¥è¯¢æ§è¡è®¡åçæ§è½ã
â4. æ°æ®ååºååçï¼
- å¦æç»ç»æºææ°æ®éé常大ï¼å¯ä»¥èèå°æ°æ®ååºæè åçåå¨ãéè¿æç §ä¸å®è§åå°æ°æ®æå为å¤ä¸ªååºæè åçï¼æé«æ¥è¯¢ç并è¡åº¦åæ©å±æ§ã
- 使ç¨ååºè¡¨æè åç表çæ¹å¼ï¼å°æ°æ®ååå°åå¸å°å¤ä¸ªç©çåå¨è®¾å¤æè æ°æ®åºå®ä¾ä¸ï¼æé«æ¥è¯¢çæ§è½åååºæ¶é´ã
â5. å®ææ°æ®æ¸ çåç»´æ¤ï¼
- å®ææ¸ çä¸å使ç¨çæ°æ®ï¼å¦è¿æçç»ç»æºæä¿¡æ¯æè åå²æ°æ®ãéè¿å é¤æè å½æ¡£è¿äºæ°æ®ï¼å¯ä»¥åå°æ°æ®åºçåå¨åååæé«æ¥è¯¢æ§è½ã
- å®æè¿è¡æ°æ®åºçç»´æ¤å·¥ä½ï¼å æ¬å¤ä»½ãæ¥å¿æ¸ çãç»è®¡ä¿¡æ¯æ´æ°çæä½ï¼ä»¥ä¿ææ°æ®åºçå¥åº·ç¶æåæ§è½ã
ä¸è¬ç»ç»æºæ对åºç表ç»æå¦ä¸æ示ï¼
CREATE TABLE `department` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`parent_id` int(11) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`remark` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`deleted` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `department_parent_id_IDX` (`parent_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='é¨é¨';
å¨è¿ä¸ªè¡¨ç»æä¸ï¼æ¯ä¸ªç®å½èç¹é½æä¸ä¸ªå¯ä¸çidæ è¯åä¸ä¸ªnameå段表示é¨é¨çå称ã
parent_idå段表示该èç¹çç¶èç¹çidãæ ¹èç¹å¯ä»¥éè¿parent_id为0æ¥è¡¨ç¤ºã
注ææ·»å parent_id为索å¼ï¼å å¿«æ¥è¯¢æçã
éè¿è¿ç§è¡¨ç»æï¼å¯ä»¥ä½¿ç¨éå½æ¥è¯¢æè å¤çº§æ¥è¯¢æ¥æ建æ´ä¸ªæ çç»æã
ä¾å¦ï¼éè¿ä»¥ä¸æ¥è¯¢å¯ä»¥è·å第ä¸å±ç®å½æ ï¼
SELECT * FROM department WHERE parent_id = '0L';
ç¶åï¼éè¿éå½æè å¤çº§æ¥è¯¢ï¼å¯ä»¥æ ¹æ®æ¯ä¸ªèç¹çidå¼ï¼è·åå ¶åèç¹ã
æ们é¢å ç产äºä¸ä¸å¤æ¡çæµè¯æ°æ®ï¼ç»ç»ç»æå±çº§æ大4级ï¼
è·åç»ç»æºææ ç示ä¾ä»£ç å¦ä¸ï¼
public DepartmentDTO findAll() {
DepartmentDTO departmentDTO = new DepartmentDTO();
departmentDTO.setId(0L);
queryChildren(departmentDTO);
return departmentDTO;
}
// éå½æ¥è¯¢
private void queryChildren(DepartmentDTO parent) {
List<DepartmentPO> children = departmentDao.queryByParentId(parent.getId());
if (CollectionUtils.isEmpty(children)) {
return;
}
for (DepartmentPO po : children) {
DepartmentDTO departmentDTO = new DepartmentDTO();
BeanUtil.copyProperties(po, departmentDTO);
parent.getChildren().add(departmentDTO);
queryChildren(departmentDTO);
}
}
åå°ä¼åä¹åï¼æ¥ä¸æ¥è°ç¨æ¥å£è·åç»ç»æ ï¼
ä¼åä¹åï¼è¿è¡å次æ¥å£ç è°ç¨æ¥å£ï¼æ°æ®å¦ä¸ï¼
å¯ä»¥åç°ï¼éè¿éä½SQLè°ç¨æ¬¡æ°ï¼æ¥å£èæ¶ä»70å¤séä½å°äº800mså·¦å³ã
æ¥ä¸æ¥ï¼æ们åæ ·å¯¹æ¥å£è¿è¡ä¸åæµï¼
åæµåï¼èåæ¥åå¦ä¸æ示ï¼
èåæ¥åæ¾ç¤ºï¼100次æ¥è¯¢è¯·æ±å¹³åèæ¶ä» 2ç§å¤ï¼ä¸ååéæåè¿60åã
å½ç¶æ们è¿éè¦è¿ä¸æ¥ä¼åï¼ä»¥åå°æ¥å£èæ¶åæåååéã
â第äºæ¥ï¼åºç¨å±ä¼åï¼æå70å
å¨ç¬¬ä¸æ¥ä¼åè¿ç¨ä¸ï¼æ们éç¨çº§èæ¥è¯¢ï¼ä»æ ¹èç¹æ¥è¯¢ä¸çº§åèç¹å表ï¼åä»ä¸çº§åèç¹æ¥è¯¢ä¸ä¸çº§èç¹ï¼æ¯æ¬¡æ¥è¯¢é½è¦æ交SQLå°MySQLï¼ç¸å½äºä¸æ¬¡æ¥å£è°ç¨ï¼å端éè¦åèµ·ä¸ä¸æ¬¡SQL请æ±ï¼æçé常ä½ä¸ã
å æ¤æ们å¯ä»¥å¨åºç¨æå¡éï¼æ¯æ¬¡æ¥è¯¢ä¸æ¬¡æ§ä»æ°æ®åºä¸è·åæææ°æ®ï¼å¨å åéæåºãæ¼è£ ææ å½¢æ°æ®ï¼
代ç 示ä¾å¦ä¸ï¼
private void queryChildren2(DepartmentDTO root) {
// ä¸æ¬¡æ§ååºæææ°æ®
List<DepartmentPO> list = departmentDao.findAll(Sort.by("parentId", "id").ascending());
Map<Long, DepartmentDTO> departmentMap = new HashMap<>();
departmentMap.put(root.getId(), root);
// éåæ°æ®ï¼ç»ææ å½¢ç»æ
for(DepartmentPO po : list) {
DepartmentDTO departmentDTO = new DepartmentDTO();
BeanUtil.copyProperties(po, departmentDTO);
departmentMap.put(po.getId(), departmentDTO);
DepartmentDTO parent = departmentMap.get(po.getParentId());
parent.getChildren().add(departmentDTO);
}
}
è°ç¨æ¥å£, ç»æå¦ä¸ï¼
å¯ä»¥çå°ï¼åºç¨å±ä¼ååï¼æ¥å£çèæ¶ä»700å¤mséä½å°100mså·¦å³ï¼åºæ¬å·²æ»¡è¶³ç产ç¯å¢è¦æ±çæ¥å£èæ¶ï¼æ¥ä¸æ¥ï¼æ们è¿éè¦å¯¹æ¥å£è¿è¡åæµï¼
â第ä¸æ¥ï¼åå¸å¼ç¼åä¼åï¼ä½æ¯é«å¹¶ååºæ¯å¤±è´¥çè¿é«
ä¼ ç»çæ°æ®åºæ¥è¯¢å¾å¾éè¦è费大éçæ¶é´åèµæºï¼ç¹å«æ¯å¨æ°æ®éåºå¤§çæ åµä¸ã
éè¿å¼å ¥åå¸å¼ç¼åï¼æ们å¯ä»¥å°ç»ç»æºææ°æ®ç¼åå¨å åä¸ï¼ä»¥é¿å é¢ç¹è®¿é®æ°æ®åºçå¼éã
åå¸å¼ç¼åéç¨åå¸å¼æ¶æï¼å°æ°æ®åå¨å¨å¤ä¸ªç¼åèç¹ä¸ï¼æ¯ä¸ªèç¹é½å ·å¤ç¬ç«çå ååå¤çè½åã
å½è¿è¡ç»ç»æºææ¥è¯¢æ¶ï¼é¦å æ£æ¥ç¼åä¸æ¯å¦åå¨ç¸åºçæ°æ®ã
å¦æç¼åä¸åå¨æ°æ®ï¼åç´æ¥è¿åç»æï¼é¿å äºå¯¹æ°æ®åºçæ¥è¯¢æä½ãè¿æ ·å¯ä»¥å¤§å¤§åå°æ¥è¯¢çååºæ¶é´ï¼æé«æ´ä½ç³»ç»çæ§è½ã
å¨å¼å ¥åå¸å¼ç¼åæ¶ï¼éè¦è®¾è®¡åççç¼åçç¥åæ°æ®æ´æ°æºå¶ã
å¯ä»¥éç¨ç¼å失æçç¥ï¼è®¾ç½®åéçç¼åè¿ææ¶é´ï¼ç¡®ä¿ç¼åä¸çæ°æ®ä¸æ°æ®åºçæ°æ®ä¿æä¸è´ãå½ç»ç»æºææ°æ®åçååæ¶ï¼åæ¶æ´æ°ç¼åï¼ä¿è¯æ¥è¯¢ç»æçåç¡®æ§ã
æ¤å¤ï¼è¿å¯ä»¥èè使ç¨åå¸å¼ç¼åææ¯å¦RedisæMemcachedï¼å¹¶è¿è¡åççç¼åæ°æ®åååæ°æ®åçï¼ä»¥å®ç°æ¨ªåæ©å±åè´è½½åè¡¡ãè¿æ ·å¯ä»¥æé«ç³»ç»çå¯ä¼¸ç¼©æ§å容éæ§ï¼åºå¯¹é«å¹¶å访é®å大è§æ¨¡ç»ç»æºææ°æ®çæ¥è¯¢éæ±ã
æ»ä¹ï¼å¼å ¥åå¸å¼ç¼åæ¯ä¸ç§é«æçä¼åçç¥ï¼éè¿åå°å¯¹æ°æ®åºç访é®æ¬¡æ°åå éæ¥è¯¢ååºï¼å¯ä»¥æ大å°æåç»ç»æºææ¥è¯¢çæçåååºæ¶é´ï¼ä»èæé«æ´ä½ç³»ç»çæ§è½åç¨æ·ä½éªã
é¦å ï¼æ们å°è¯å¨æ¥å£è°ç¨æ¶ï¼ä½¿ç¨redisç¼åç»ç»ç»ææ ï¼ä¹åæ¯æ¬¡æ¥å£è¯·æ±æ¶ï¼é½ä¼å æ¥è¯¢ç¼åï¼
代ç 示ä¾å¦ä¸ï¼
public DepartmentDTO findAll() {
// æ¥è¯¢ç¼å
DepartmentDTO departmentDTO = (DepartmentDTO) redisTemplate.opsForValue().get(DEPARTMENT_CACHE_KEY);
// ç¼åä¸åå¨åæ¥è¯¢æ°æ®åº
if (Objects.isNull(departmentDTO)) {
departmentDTO = new DepartmentDTO();
departmentDTO.setId(0L);
queryChildren2(departmentDTO);
}
// æ´æ°ç¼å
redisTemplate.opsForValue().set(DEPARTMENT_CACHE_KEY, departmentDTO, 1, TimeUnit.MINUTES);
return departmentDTO;
}
â使ç¨åå¸å¼ jmeter clusterçæ¹å¼æ¥è¿è¡åæµ
为äºæ¨¡æé«å¹¶ååºæ¯ï¼ä½¿ç¨åå¸å¼ jmeter clusterçæ¹å¼æ¥è¿è¡åæµã
ç±äºåå°jmeteråæµåéäºæ¬å°æºå¨çCPUï¼å åï¼ç½ç»åå ¶ä»åå ï¼éè¦éç¨jmeter clusterçæ¹å¼æ¥è¿è¡åæµã
è¿éæ们å°åè ã è°ä¼å£ç»ï¼é¶åºç¡ç²¾éJmeteråå¸å¼åæµï¼10Wqps+è¶ é«å¹¶å ã è¿ç¯æç« ï¼å©ç¨Jmeter clusteræ¥è¿è¡åæµï¼
Jemter clusteréç¨docker-composeçæ¹å¼æ建ï¼
å¨æ¬æºæ°å»ºjmeteræ件夹ï¼å¨æ件夹ä¸å建jmeter-masteræ件夹ï¼
docker-compose.ymlå 容å¦ä¸ï¼
version: "3.9"
services:
jmeter-master:
image: zhangyx1619/jmeter-master:orcaljdk17-jmeter5.5-graphs-plugins-release
volumes:
- "./jmeter-master:/usr/local/jmeter/apache-jmeter-5.5/work_space/"
networks:
- swarmnet
hostname: jmeter-master
deploy:
labels:
- com.service.name=jmeter-master
mode: global
update_config:
parallelism: 1
delay: 1s
failure_action: rollback
jmeter-slave01:
image: zhangyx1619/jmeter-slave:orcaljdk17-jmeter5.5-graphs-plugins-release
volumes:
- jmeter-slave01:/usr/local/jmeter/apache-jmeter-5.5/
networks:
- swarmnet
hostname: jmeter-slave01
deploy:
mode: global
labels:
- com.service.name=jmeter-slave01
update_config:
parallelism: 1
delay: 1s
failure_action: rollback
jmeter-slave02:
image: zhangyx1619/jmeter-slave:orcaljdk17-jmeter5.5-graphs-plugins-release
volumes:
- jmeter-slave02:/usr/local/jmeter/apache-jmeter-5.5/
networks:
- swarmnet
hostname: jmeter-slave02
deploy:
mode: global
labels:
- com.service.name=jmeter-slave02
update_config:
parallelism: 1
delay: 1s
failure_action: rollback
jmeter-slave03:
image: zhangyx1619/jmeter-slave:orcaljdk17-jmeter5.5-graphs-plugins-release
volumes:
- jmeter-slave03:/usr/local/jmeter/apache-jmeter-5.5/
networks:
- swarmnet
hostname: jmeter-slave03
deploy:
mode: global
labels:
- com.service.name=jmeter-slave03
update_config:
parallelism: 1
delay: 1s
failure_action: rollback
networks:
swarmnet:
driver: bridge
volumes:
jmeter-slave01:
jmeter-slave02:
jmeter-slave03:
å¨å½åjemeterç®å½æå¼ç»ç«¯ï¼è¿è¡dockerå½ä»¤, å¯å¨å®¹å¨ã
docker compose up -d
å¯å¨åï¼å®¹å¨è¯¦æ å¦ä¸ï¼
å ¶ä¸å å«ä¸ä¸ªä¸»èç¹å4个åèç¹ã
æ¥ä¸æ¥ï¼ä¿®æ¹jmxèæ¬ï¼ 线ç¨ç»ç线ç¨æ°æ们è°å¤§å°1000ï¼ è¿æ ·çè¯ï¼4个åèç¹åå«åèµ·1000次请æ±ï¼ç¸å½äºæ¯æ¨¡æ4000 QPS åæµï¼
ç¹å»å·¦ä¸è§æ件 -> ä¿å , å°å½åjmeterèæ¬department.jmx æ件ï¼ä¿åå°jmeter-masteræ件夹ä¸ï¼
okï¼å°è¿éä¸ååå¤å°±ç»ªåï¼å°±å¯ä»¥å¼å§æ§è¡åæµå½ä»¤ï¼
å¨ç»ç«¯è¿è¡å¦ä¸å½ä»¤ï¼
docker exec -it jemeter-jmeter-master-1 jmeter -n -t /usr/local/jmeter/apache-jmeter-5.5/work_space/department.jmx -r -l /usr/local/jmeter/apache-jmeter-5.5/work_space/department.jtl -e -o /usr/local/jmeter/apache-jmeter-5.5/work_space/html/
è¿æ¯ä¸ä¸ªä½¿ç¨Dockeræ§è¡JMeteræ§è½æµè¯çå½ä»¤ï¼å ·ä½å«ä¹å¦ä¸ï¼
- docker exec: è¿è¡ä¸ä¸ªå½ä»¤å¨Docker容å¨ä¸æ§è¡æä½ã
- -it: åé ä¸ä¸ªäº¤äºå¼ç»ç«¯ï¼å¹¶å°å ¶è¿æ¥å°å®¹å¨çè¾å ¥åè¾åºï¼ä»¥ä¾¿ä¸JMeterè¿è¡äº¤äºã
- jemeter-jmeter-master-1: Docker容å¨çå称æIDï¼æå®è¦æ§è¡å½ä»¤çç®æ 容å¨ï¼è¿éæ¯ä¸»èç¹å®¹å¨å称ã
- jmeter: è¦æ§è¡çå½ä»¤ï¼è¿éæ¯æ§è¡JMeteræ§è½æµè¯ã
- -n: å¨éGUI模å¼ä¸è¿è¡JMeterã
- -t /usr/local/jmeter/apache-jmeter-5.5/work_space/department.jmx: æå®è¦è¿è¡çJMXæµè¯è®¡åæ件çè·¯å¾åæ件åã
- -r: è¿è¡ä»¥åå¸å¼æ¹å¼æ§è¡æµè¯ã
- -l /usr/local/jmeter/apache-jmeter-5.5/work_space/department.jtl: æå®æµè¯ç»æçæ¥å¿æ件路å¾åæ件åã
- -e: çæHTMLæ ¼å¼çæµè¯æ¥åã
- -o /usr/local/jmeter/apache-jmeter-5.5/work_space/html/: æå®çæçHTMLæµè¯æ¥åçè¾åºç®å½è·¯å¾ã
éè¿è¿ä¸ªå½ä»¤ï¼æ¨å¯ä»¥å¨æå®çDocker容å¨ä¸æ§è¡JMeteræ§è½æµè¯ï¼å¹¶çæç¸åºçæµè¯ç»ææ¥å¿åHTMLæ¥åã请注æï¼å½ä»¤ä¸çæ件路å¾åå称éè¦æ ¹æ®å®é æ åµè¿è¡ä¿®æ¹ã
æ§è¡è¿ç¨å¦ä¸å¾æ示ï¼
æ¥ççæçæ¥å
æ们å¯ä»¥çå°ï¼4å°jmeterèç¹æ¨¡æ1000个并åï¼ä¸å ±æ¯4000并åï¼Failçå æ¯90%å¤ï¼
æå¡å¨ä¼åºç°å¤§éçå¼å¸¸ï¼
org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: io.lettuce.core.RedisCommandTimeoutException: Command timed out after 3 second(s)
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:70)
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:41)
at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44)
at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:42)
at org.springframework.data.redis.connection.lettuce.LettuceConnection.convertLettuceAccessException(LettuceConnection.java:273)
at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.convertLettuceAccessException(LettuceStringCommands.java:799)
at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.get(LettuceStringCommands.java:68)
at org.springframework.data.redis.connection.DefaultedRedisConnection.get(DefaultedRedisConnection.java:266)
at org.springframework.data.redis.core.DefaultValueOperations$1.inRedis(DefaultValueOperations.java:57)
at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:60)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:228)
æ ¹å åæï¼
å¼å¸¸çåå æ¯redis读åè¶ æ¶ï¼å 为ä¸ä¸ªé®å¼å¯¹çæ°æ®éæ¯è¾å¤§ï¼å¯¼è´redisåºç°äºBigKeyé®é¢ï¼æ们éè¦è¿ä¸æ¥ä¼å
ç¼æ¥äºï¼ BigKeyé®é¢æ¥äº
â第åæ¥ï¼BigKeyé®é¢ä¼åï¼4000并ååºæ¯å°100ms
å¨Redisä¸ï¼BigKeyæçæ¯å ç¨å¤§éå å空é´çé®å¼å¯¹ãå½ä¸ä¸ªé®å¼å¯¹çæ°æ®éè¿å¤§ï¼è¶ è¿Redisçé ç½®éå¶æè å å容éæ¶ï¼å°±ç§°ä¹ä¸ºBigKeyã
BigKeyä¼å¯¼è´ä»¥ä¸é®é¢ï¼
- å åå ç¨è¿é«ï¼BigKeyå ç¨å¤§éå å空é´ï¼å¯è½å¯¼è´Redisæå¡å¨çå åèµæºç´§å¼ ï¼å½±åå ¶ä»æä½åç¼åæ°æ®çåå¨ã
- 延è¿åæ§è½ä¸éï¼ç±äºè¯»å大åBigKeyçæ°æ®éè¦è¾é¿çæ¶é´ï¼ä¼å¯¼è´è¯»åæä½ç延è¿å¢å ï¼å¹¶ä¸æ¶èæ´å¤çCPUèµæºåç½ç»å¸¦å®½ï¼å½±åç³»ç»çæ´ä½æ§è½ã
- Redisæä¹ ååå¤ä»½é®é¢ï¼BigKeyå¨è¿è¡æä¹ åï¼å¦RDBå¿«ç §æAOFæ¥å¿ï¼æå¤ä»½æ¶ï¼ä¼å¢å æä¹ ååå¤ä»½çæ¶é´åèµæºæ¶èã
解å³BigKeyé®é¢çä¸äºä¼åæ¹æ³å æ¬ï¼
- æ°æ®æåï¼å°å¤§åBigKeyæåæå¤ä¸ªè¾å°çé®å¼å¯¹ï¼æ ¹æ®æ°æ®çé»è¾å ³èæ§åæ¥è¯¢æ¨¡å¼è¿è¡åççæåååç»ãè¿æ ·å¯ä»¥éä½å个é®å¼å¯¹ç大å°ï¼åå°å åå ç¨ã
- åçåå¨ï¼å°æ°æ®åæ£åå¨å¨å¤ä¸ªé®ä¸ï¼ä½¿ç¨åéçåå¸å½æ°æè åçç®æ³ï¼å°æ°æ®ååå°åæ£å°ä¸åçé®ä¸ï¼é¿å å个é®å¼å¯¹è¿å¤§ãè¿æ ·å¯ä»¥å¹³è¡¡æ°æ®çåå¨å访é®ååã
- æ°æ®å缩ï¼å¯¹äºå¯ä»¥å缩çæ°æ®ç±»åï¼å¦å符串æJSONæ ¼å¼çæ°æ®ï¼ï¼å¯ä»¥ä½¿ç¨å缩ç®æ³ï¼å¦LZFãSnappyãGzipçï¼è¿è¡å缩ï¼åå°BigKeyçå åå ç¨ã
- æ°æ®å页åå¢éå è½½ï¼å¯¹äºæ¥è¯¢ç»æè¿å¤§çBigKeyï¼å¯ä»¥éç¨æ°æ®å页æè å¢éå è½½çæ¹å¼ï¼åªå è½½é¨åæ°æ®æè æéå è½½ï¼ä»¥éä½å次æ¥è¯¢çæ°æ®éåå åæ¶èã
- é¿å æ æä¹çæ°æ®åå¨ï¼é¿å å°æ éæä¹ åæé¢ç¹åæ´çæ°æ®åå¨ä¸ºBigKeyï¼å¯ä»¥ä½¿ç¨ä¸´æ¶ç¼åæè å ¶ä»æ°æ®åå¨æ¹æ¡ã
éè¿åççæ°æ®æåãåçåå¨åå缩çä¼åæ¹æ³ï¼å¯ä»¥ææå°è§£å³BigKeyé®é¢ï¼æé«Redisçæ§è½åèµæºå©ç¨çã
å 为å¨æ ¹èç¹ä¸ç第ä¸çº§ä¼10个ç»ç»ï¼è¿10个ç»ç»åå«æä¸åçååèç¹ï¼æ们å¯ä»¥å°è¯å°å个keyå æåæ10个keyï¼æ¯ä¸ªkeyåå«å¯¹åºè¿10个ç»ç»ååèç¹æ°æ®ã
示ä¾ä»£ç å¦ä¸ï¼
public DepartmentDTO findAll() {
DepartmentDTO root = new DepartmentDTO();
root.setId(0L);
// ä»10个keyéè·åç¼åæ°æ®ï¼æ¾å
¥å°æ ¹èç¹çchildrenéåé
for (int i = 0; i< 10; i++) {
DepartmentDTO child = (DepartmentDTO) redisTemplate.opsForValue().get(DEPARTMENT_CACHE_KEY + i);
// 没æç¼åæ°æ®
if (Objects.isNull(child)) {
root.setChildren(new ArrayList<>());
break;
}
root.getChildren().add(child);
}
if (root.getChildren().size() == 0) {
// æ¥è¯¢æ°æ®åº
queryChildren2(root);
}
// å°æ°æ®æç
§1级é¨é¨åå¨å°10个key
List<DepartmentDTO> children = root.getChildren();
for (int i = 0 ; i < 10; i++) {
redisTemplate.opsForValue().set(DEPARTMENT_CACHE_KEY + i, children.get(i), 1, TimeUnit.HOURS);
}
return root;
}
æ¥ä¸æ¥ï¼ç»§ç»è¿è¡åå¸å¼åæµï¼
æ们åæ¥çä¸çæçæ¥åï¼
è¿æ¶æ们å¯ä»¥çå°éè¿çä»8%æåå°70%å¤ï¼å¦ææ们å°keyçæ°éæåå°100, éè¿çå°è¿ä¸æ¥æåã
æå ´è¶£çåå¦å¯ä»¥æ¥å°è¯ç»§ç»ä¼åç´å°éè¿ç为100%ã
â第äºæ¥ï¼æ¬å°ç¼åä¼åï¼ä¼åå°20ms
å¨åå¸å¼ç¼åçåºç¡ä¸ï¼å¼å ¥æ¬å°ç¼åæ¯è¿ä¸æ¥æåç»ç»æºææ¥è¯¢æçåååºæ¶é´çä¸ç§ä¼åæ¹æ¡ã
æ¬å°ç¼åæ¯æå°æ°æ®ç¼åå¨åºç¨ç¨åºçå åä¸ï¼ä»¥é¿å é¢ç¹å°è®¿é®åå¸å¼ç¼åææ°æ®åºï¼ä»èå¿«éååºæ¥è¯¢è¯·æ±ã
å¼å ¥æ¬å°ç¼åç好å¤æ¯å¯ä»¥åå°å¯¹åå¸å¼ç¼åç访é®æ¬¡æ°ï¼ä»èéä½ç½ç»å»¶è¿åéä¿¡å¼éã
å½åºç¨ç¨åºåèµ·ç»ç»æºææ¥è¯¢æ¶ï¼é¦å æ£æ¥æ¬å°ç¼åä¸æ¯å¦åå¨ç¸åºçæ°æ®ãå¦ææ°æ®å¨æ¬å°ç¼åä¸å½ä¸ï¼åæ éè¿ä¸æ¥è®¿é®åå¸å¼ç¼åææ°æ®åºï¼å¯ä»¥ç´æ¥è¿åç»æï¼æ大å°æåäºæ¥è¯¢çæçåååºæ¶é´ã
æ¬å°ç¼åç使ç¨éè¦èè以ä¸å ä¸ªå ³é®å ç´ ï¼
- ç¼åçç¥ï¼éæ©åéçç¼åçç¥ï¼å¦LRUï¼æè¿æå°ä½¿ç¨ï¼ãLFUï¼æè¿æä¸å¸¸ç¨ï¼çï¼ä»¥å¹³è¡¡å å使ç¨åæ°æ®å½ä¸çã
- ç¼åæ´æ°æºå¶ï¼å¨ç»ç»æºææ°æ®åçååæ¶ï¼åæ¶æ´æ°æ¬å°ç¼åãå¯ä»¥éè¿è®¢é æ°æ®åºæåå¸å¼ç¼åçæ°æ®åæ´äºä»¶ï¼ä¿ææ¬å°ç¼åä¸æ°æ®æºçä¸è´æ§ã
- ç¼å失æå¤çï¼è®¾ç½®åççç¼å失ææ¶é´ï¼ä»¥ç¡®ä¿ç¼åä¸çæ°æ®ä¸è¿æãå¯ä»¥æ ¹æ®æ°æ®æ´æ°çé¢çåéè¦æ§è¿è¡è°æ´ã
- å å管çï¼åç管çæ¬å°ç¼å使ç¨çå åï¼é¿å å ç¼åè¿å¤å¯¼è´å å溢åºæåºç¨ç¨åºæ§è½ä¸éçé®é¢ã
å¼å ¥æ¬å°ç¼åçä¼åæ¹æ¡éè¦ç»¼åèèåºç¨ç¨åºçç¹ç¹ãæ°æ®çæ´æ°é¢çåä¸è´æ§è¦æ±ãåç使ç¨æ¬å°ç¼åå¯ä»¥åå°å¯¹åå¸å¼ç¼ååæ°æ®åºç访é®ï¼æåç»ç»æºææ¥è¯¢çæçåååºæ¶é´ï¼ä»èæé«ç³»ç»çæ´ä½æ§è½åç¨æ·ä½éªã
å¨å½åSpringBootæ¡æ¶ä¸ï¼å¯ä»¥éè¿ä»¥ä¸æ¥éª¤éæCaffeineä½ä¸ºæ¬å°ç¼åï¼
- æ·»å Caffeineä¾èµï¼å¨pom.xmlæ件ä¸æ·»å Caffeineçä¾èµé¡¹ã
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
- å建ç¼åé 置类ï¼å建ä¸ä¸ªJavaç±»ï¼ç¨äºé ç½®Caffeineç¼åã
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.concurrent.TimeUnit;
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public Caffeine<Object, Object> caffeineConfig() {
return Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES) // 设置ç¼å失ææ¶é´ä¸º10åé
.maximumSize(10_000) // 设置ç¼åçæ大容é为10_000
.recordStats(); // å¯ç¨ç»è®¡ä¿¡æ¯ï¼å¯éè¿Cache.stats()è·åç¼åå½ä¸ççç»è®¡æ°æ®
}
@Bean
public CacheManager cacheManager(Caffeine<Object, Object> caffeine) {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
cacheManager.setCaffeine(caffeine);
return cacheManager;
}
}
å¨ä¸é¢ç示ä¾ä¸ï¼æ们é ç½®äºä¸ä¸ªå为"cacheManager"çç¼å管çå¨ï¼ä½¿ç¨äºCaffeineä½ä¸ºåºå±çç¼åå®ç°ï¼å¹¶è®¾ç½®äºç¼åç失ææ¶é´åæ大容éã
- 使ç¨ç¼åï¼å¨éè¦ç¼åçæ¹æ³ä¸æ·»å @Cacheable注解ï¼ä»¥åè¯Springåºè¯¥ç¼å该æ¹æ³çè¿åå¼ã
@Cacheable("department-cache")
public DepartmentDTO findAll() {
// çç¥å
¶å®ä»£ç
}
å¨ä¸è¿°ç¤ºä¾ä¸ï¼findAllæ¹æ³ä¼é¦å æ£æ¥å为"department-cache"çç¼åä¸æ¯å¦åå¨å¯¹åºçæ°æ®ãå¦æåå¨ï¼ç´æ¥ä»ç¼åä¸è¿åæ°æ®ï¼å¦æç¼åä¸ä¸åå¨ï¼åæ§è¡æ¹æ³ä½çé»è¾ï¼å¹¶å°è¿åå¼ç¼åèµ·æ¥ä¾ä¸æ¬¡ä½¿ç¨ã
åæ ·æ们è°ç¨ä¸æ¥å£ï¼çä¸æ§è¡æ¶é´
ç±äºéç¨æ¬å°ç¼åï¼èæ¶å ä¹å¿½ç¥ä¸è®¡ã
æ¥ä¸æ¥ï¼ç»§ç»æ§è¡ä¸jmeter clusteråæµï¼åæµæ¥åå¦ä¸æ示ï¼
âä¼åæ»ç»
å¦ææ¬å°ç¼åå½ä¸ï¼ ç»è¿è¿ä¸è½®ä¼åï¼ æ§è½æåå° 20msï¼æå700å
å¦ææ¬å°ç¼åä½å½ä¸ï¼ ç»è¿ä¸ä¸è½®ä¼åï¼ æ§è½æåå° 100ms ï¼æå3500å
â第å æ¥ï¼ç½å ³å±é¢çä¼å
é¤äºæ°æ®åºãç¼åãbigkeyææ£ãæ¬å°ç¼åä¼åä¹å¤ï¼è¿æå¾å¤å ¶ä»çä¼åï¼
- ç½å ³å±é¢çä¼å
- ç³»ç»å±é¢çä¼åçç
æ¥ä¸æ¥è¯´ä¸ä¸ç½å ³å±é¢çä¼åã
å¨ç½å ³å±é¢è¿è¡ä¼åå¯ä»¥æé«ç»ç»æºææ æ¥å£æ¥è¯¢çæ§è½åå¯æ©å±æ§ã
以ä¸æ¯ä¸äºä¼åæ¹æ¡ï¼
â1ãNginxå缩ï¼
- å¨Nginxé ç½®ä¸å¯ç¨å缩åè½ï¼å°ååºæ°æ®è¿è¡å缩ï¼åå°æ°æ®ä¼ è¾ç大å°ï¼æé«ç½ç»ä¼ è¾æçåååºé度ã
- é ç½®gzipæ令å¼å¯å缩ï¼å¯ä»¥è®¾ç½®åéçå缩级å«åå缩类åã
http {
gzip on;
gzip_types text/plain text/css application/json;
gzip_comp_level 5;
}
â2ãç½å ³ç¼åï¼
å¨Nginxä¸ï¼å¯ä»¥éè¿é 置代çç¼åæ¥ç¼åæ¥å£çååºç»æã以ä¸æ¯è¯¦ç»çæ¥éª¤ï¼
â1. å¯ç¨ä»£çç¼åï¼
å¨Nginxçé ç½®æ件ä¸ï¼å¼å¯ä»£çç¼ååè½å¹¶å®ä¹ä¸ä¸ªç¼ååºåã
http {
proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
}
- /path/to/cacheï¼æå®ç¼ååå¨è·¯å¾ã
- levels=1:2ï¼å®ä¹ç¼åè·¯å¾å±çº§ã
- keys_zone=my_cache:10mï¼ä¸ºç¼ååºåæå®ä¸ä¸ªå称ï¼my_cacheï¼ååé çå å大å°ï¼10MBï¼ã
- max_size=10gï¼è®¾ç½®ç¼ååºåçæ大容é为10GBã
- inactive=60mï¼æå®ç¼å项å¨60åéå 没æ被访é®æ¶è¢«è®¤ä¸ºæ¯è¿æçã
- use_temp_path=offï¼ç¦æ¢ä½¿ç¨ä¸´æ¶è·¯å¾ã
â2. é 置代çç¼åï¼
å¨Nginxçé ç½®æ件ä¸ï¼ä¸ºéè¦ç¼åçæ¥å£æ·»å ç¼åé ç½®ã
server {
location /api/department {
proxy_cache my_cache;
proxy_cache_valid 200 1d;
proxy_pass http://backend_server;
}
}
- proxy_cache my_cacheï¼æå®ä½¿ç¨åé¢å®ä¹çç¼ååºåï¼my_cacheï¼è¿è¡ç¼åã
- proxy_cache_valid 200 1dï¼è®¾ç½®ç¼åæææ为1天ï¼å¯¹äºç¶æç 为200çååºè¿è¡ç¼åã
- proxy_pass http://backend_serverï¼æå®åå代ççç®æ å端æå¡å¨ã
â3. æ¸ é¤ç¼åï¼
å¦æéè¦æå¨æ¸ é¤ç¼åï¼å¯ä»¥ä½¿ç¨Nginxçproxy_cache_purge模åï¼éè¿åéç¹å®è¯·æ±æ¥æ¸ é¤ç¼åã
location /purge-cache {
proxy_cache_purge my_cache "$scheme$request_method$host$request_uri";
}
- proxy_cache_purgeï¼å¯ç¨proxy_cache_purge模åã
- my_cacheï¼æå®è¦æ¸ é¤çç¼ååºåã
- "$scheme$request_method$host$request_uri"ï¼æå®è¦æ¸ é¤çç¼åé®å¼ã
éè¿ä¸è¿°é ç½®ï¼Nginxä¼å¨æ¥æ¶å°è¯·æ±æ¶å æ¥çç¼åï¼å¦æç¼åä¸åå¨å¯¹åºçååºï¼åç´æ¥è¿åç¼åçç»æï¼åå°å¯¹å端æå¡ç请æ±ãå¦æç¼åä¸ä¸åå¨æå·²è¿æï¼åä¼è½¬å请æ±å°å端æå¡ï¼å¹¶å°ååºç»æç¼åèµ·æ¥ï¼ä»¥ä¾åç»ç¸å请æ±ä½¿ç¨ã
请注æï¼ç¼åæ¥å£éè¦æ ¹æ®å ·ä½çä¸å¡éæ±åæ¥å£ç¹æ§è¿è¡é ç½®ãéè¦æ ¹æ®æ¥å£çé¢çãæ°æ®æ´æ°é¢çåç¼åçç¥è¿è¡åççè°æ´ã
对äºå¨æçæçæ å½¢æ°æ®é¡µé¢ï¼ä¹å¯ä»¥éç¨é¡µé¢ç¼åææ¯ï¼å°é¡µé¢å 容ç¼åå°CDNæå ¶ä»ç¼åä¸ï¼å¹¶è®¾ç½®åéçç¼åè¿ææ¶é´ã
âä»70så°20msè°ä¼å°ç»ï¼
é对ç»ç»ç»ææ çä¼å设计ï¼æ们å¯ä»¥å¨æ°æ®åºå±é¢ãç¼åå±é¢åNGINXç½å ³å±é¢è¿è¡ä¼åï¼ä»¥æé«æ¥è¯¢æ§è½åç³»ç»çå¯ä¼¸ç¼©æ§ã
å¨æ°æ®åºå±é¢ï¼æ们å¯ä»¥éå以ä¸ä¼å设计ï¼
- 使ç¨éå½ç表ç»æåç´¢å¼ï¼ä¼åç»ç»ç»ææ çåå¨åæ¥è¯¢æçã
- èèéç¨åéçååºå表çç¥ï¼å°æ°æ®æ°´å¹³æåï¼åå°å表æ°æ®éã
- é对ç»ç»ç»ææ çæ¥è¯¢ï¼ä½¿ç¨éå½çæ¥è¯¢è¯å¥åä¼åæå·§ï¼å¦éå½æ¥è¯¢ãåµå¥é模åçã
å¨ç¼åå±é¢ï¼æ们å¯ä»¥éå以ä¸ä¼å设计ï¼
- 使ç¨Redisçç¼åææ¯ï¼å°ç»ç»ç»ææ çæ°æ®ç¼åå¨å åä¸ï¼åå°å¯¹æ°æ®åºç访é®æ¬¡æ°ã
- é对é¢ç¹è®¿é®çç»ç»ç»ææ æ°æ®ï¼è®¾ç½®åéçç¼åè¿ææ¶é´åç¼åçç¥ã
- 使ç¨åççç¼åå½åè§ååç¼åé®è®¾è®¡ï¼ç¡®ä¿ç¼åçåç¡®æ§åä¸è´æ§ã
å¨NGINXç½å ³å±é¢ï¼æ们å¯ä»¥éå以ä¸ä¼å设计ï¼
- 使ç¨Nginxçå缩åè½ï¼åå°ååºæ°æ®ç大å°ï¼æé«ç½ç»ä¼ è¾æçã
- 使ç¨CDNç¼åéæèµæºï¼åè½»ç½å ³åå端æå¡å¨çè´è½½ï¼å éèµæºä¼ è¾ã
- é 置代çç¼åï¼å°ç»ç»ç»ææ æ¥å£çååºç»æç¼åèµ·æ¥ï¼åå°å¯¹å端æå¡ç请æ±ã
- 设置éå½çè´è½½åè¡¡æºå¶ï¼åå请æ±å°å¤ä¸ªå端æå¡å®ä¾ï¼æé«ç³»ç»çå¯æ©å±æ§å容éæ§ã
综åä¸è¿°ä¼å设计ï¼å¯ä»¥å¤§å¤§æåç»ç»ç»ææ æ¥å£çæ¥è¯¢æ§è½åç³»ç»çå¯ä¼¸ç¼©æ§ãéè¿æ°æ®åºçä¼åï¼å¯ä»¥æé«æ°æ®çåå¨åæ¥è¯¢æçï¼éè¿ç¼åçä¼åï¼å¯ä»¥åå°å¯¹æ°æ®åºç访é®æ¬¡æ°ï¼éè¿ç½å ³å±é¢çä¼åï¼å¯ä»¥éä½ç½ç»ä¼ è¾ææ¬åå端æå¡çè´è½½ååãè¿äºç»¼åçä¼åæªæ½å°æ¾èæ¹åç³»ç»çæ´ä½æ§è½åç¨æ·ä½éªã
âãJava è°ä¼å£ç»ãè¿ä»£è®¡åï¼
å°¼æ©å¢éçæææç« åPDFçµå书ï¼é½æ¯ æç»è¿ä»£ç模å¼ï¼ ææ°çæ¬æ°¸è¿æ¯æå ¨çã
å°¼æ©å¢éä» é«å¹¶ååæµå®æå¼å§ï¼ç»å¤§å®¶æ¢³çä¸ä¸ªç³»åçãJava è°ä¼å£ç»ãPDF çµå书ï¼å æ¬æ¬æå¨å è§åçäºä¸ªé¨åï¼
(1ï¼è°ä¼å£ç»1ï¼é¶åºç¡ç²¾éJmeteråå¸å¼åæµï¼10Wqps+åæµå®æ ï¼å·²ç»å®æï¼
(2) è°ä¼å£ç»2ï¼ä»70så°20msï¼ä¸æ¬¡3500åæ§è½ä¼åå®æï¼æ¹æ¡äººäººå¯ç¨ï¼å·²ç»å®æï¼
(3ï¼è°ä¼å£ç»3ï¼é¶åºç¡ç²¾éJVMè°ä¼å®æï¼å®ç°JVMèªç± ï¼åä½ä¸ï¼
(4) è°ä¼å£ç»4ï¼é¶åºç¡ç²¾éMysqlè°ä¼å®æï¼å®ç°Mysqlè°ä¼èªç± ï¼åä½ä¸ï¼
(5) è°ä¼å£ç»5ï¼é¶åºç¡ç²¾éLinuxãTomcatlè°ä¼å®æï¼å®ç°åºç¡è®¾æ½è°ä¼èªç± ï¼åä½ä¸ï¼
以ä¸çå¤ç¯æç« ï¼åç»å°éç»å¨å ¬å·ãææ¯èªç±åãæ¨åºã å®æ´çãJava è°ä¼å£ç»ãPDF V2ï¼å¯ä»¥æ¾å°¼æ©åã
âææ¯èªç±çå®ç°è·¯å¾ PDF è·åï¼
âå®ç°ä½ çæ¶æèªç±ï¼
- ãåé8å¾1模æ¿ï¼äººäººå¯ä»¥åæ¶æãPDF
- ã10Wqpsè¯è®ºä¸å°ï¼å¦ä½æ¶æï¼Bç«æ¯è¿ä¹åçï¼ï¼ï¼ãPDF
- ãé¿éäºé¢ï¼åä¸çº§ã亿级æ°æ®ï¼å¦ä½æ§è½ä¼åï¼ æç§ä¹¦çº§ çæ¡æ¥äºãPDF
- ãå³°å¼21WQpsã亿级DAUï¼å°æ¸¸æãç¾äºä¸ªç¾ãæ¯æä¹æ¶æçï¼ãPDF
- ã100亿级订åæä¹è°åº¦ï¼æ¥ä¸ä¸ªå¤§åçæåæ¹æ¡ãPDF
- ã2个大å 100亿级 è¶ å¤§æµé 红å æ¶ææ¹æ¡ãPDF
⦠æ´å¤æ¶ææç« ï¼æ£å¨æ·»å ä¸
âå®ç°ä½ ç ååºå¼ èªç±ï¼
- ãååºå¼å£ç»ï¼10Wåï¼å®ç°Springååºå¼ç¼ç¨èªç±ãPDF
- è¿æ¯èçæ¬ ãFluxãMonoãReactor å®æï¼å²ä¸æå ¨ï¼ãPDF
âå®ç°ä½ ç spring cloud èªç±ï¼
- ãSpring cloud Alibaba å¦ä¹ å£ç»ã PDF
- ãååºå表 Sharding-JDBC åºå±åçãæ ¸å¿å®æï¼å²ä¸æå ¨ï¼ãPDF
- ãä¸ææå®ï¼SpringBootãSLF4jãLog4jãLogbackãNettyä¹é´æ··ä¹±å ³ç³»ï¼å²ä¸æå ¨ï¼ãPDF
âå®ç°ä½ ç linux èªç±ï¼
- ãLinuxå½ä»¤å¤§å ¨ï¼2Wå¤åï¼ä¸æ¬¡å®ç°Linuxèªç±ãPDF
âå®ç°ä½ ç ç½ç» èªç±ï¼
- ãTCPå议详解 (å²ä¸æå ¨)ãPDF
- ãç½ç»ä¸å¼ 表ï¼ARP表, MAC表, è·¯ç±è¡¨ï¼å®ç°ä½ çç½ç»èªç±ï¼ï¼ãPDF
âå®ç°ä½ ç åå¸å¼é èªç±ï¼
- ãRedisåå¸å¼éï¼å¾è§£ - ç§æ - å²ä¸æå ¨ï¼ãPDF
- ãZookeeper åå¸å¼é - å¾è§£ - ç§æãPDF
âå®ç°ä½ ç çè ç»ä»¶ èªç±ï¼
- ãéåä¹çï¼ Disruptor åçãæ¶æãæºç ä¸æç©¿éãPDF
- ãç¼åä¹çï¼Caffeine æºç ãæ¶æãåçï¼å²ä¸æå ¨ï¼10Wå è¶ çº§é¿æï¼ãPDF
- ãç¼åä¹çï¼Caffeine ç使ç¨ï¼å²ä¸æå ¨ï¼ãPDF
- ãJava Agent æ¢éãåèç å¢å¼º ByteBuddyï¼å²ä¸æå ¨ï¼ãPDF
âå®ç°ä½ ç é¢è¯é¢ èªç±ï¼
4000页ãå°¼æ©Javaé¢è¯å®å ¸ãPDF 40个ä¸é¢
....
注ï¼ä»¥ä¸å°¼æ© æ¶æç¬è®°ãé¢è¯é¢ çPDFæ件ï¼è¯·å°å ¬å·ãææ¯èªç±åãå
è¿éè¦å¥èªç±ï¼å¯ä»¥åè¯å°¼æ©ã å°¼æ©å¸®ä½ å®ç°.......