æ¥å¿ç³»ç»ïŒELKæå»ºäžäœ¿çš
ç³»åäžïŒåºç¡è®Ÿæœç¯ · 第4ç¯
åæšäžç¹ïŒçº¿äžæå¡çªç¶æ¥èŠãäœ è¢«å«èµ·æ¥ææ¥é®é¢ïŒåŽåç°å ³é®çéè¯¯ä¿¡æ¯æ ¹æ¬æ²¡è®°åœãæè ïŒæ¥å¿è®°äºïŒäœèŠåšå å GB çæ¥å¿æä»¶é倧海æéâŠâŠ
æ¥å¿ç³»ç»å°±åæ¯ç³»ç»ç"é»å£å"ïŒè®°åœçæ¯äžå»åççäºæ ãåœé®é¢åºç°æ¶ïŒå®èœåžŠäœ ç©¿è¶åäºæ ç°åºïŒè¿åäºæ ççžã
ä»å€©æä»¬æ¥èèæ¥å¿ç³»ç»ç讟计åçïŒçç宿¯åŠäœæäžºé®é¢ç"æ¶å æº"çã
äžãæ¥å¿çä»·åŒ
åšæ·±å ¥ææ¯ç»èä¹åïŒæä»¬å çè§£æ¥å¿å°åºæå€éèŠã
1.1 æ¥å¿çå倧çšé
è¿æ¯æ¥å¿æçŽæ¥ççšéãåœç³»ç»åºç°åŒåžžæ¶ïŒæ¥å¿æ¯ç¬¬äžæçè¯æèµæïŒ
- é误åçæ¶ç³»ç»çç¶ææ¯ä»ä¹ïŒ
- 请æ±ç»è¿äºåªäºæå¡åç»ä»¶ïŒ
- åªäžæ¥åºäºé®é¢ïŒéè¯¯ä¿¡æ¯æ¯ä»ä¹ïŒ
æ²¡ææ¥å¿ïŒææ¥é®é¢å°±ååšé»æäžæžçŽ¢ã
æ¥å¿äžä» æ¯äºååæçå·¥å ·ïŒä¹æ¯å®æ¶çæ§çæ°æ®æºïŒ
- é误ççªç¶é£å â è§ŠååèŠ
- æ ¢è¯·æ±æ¥å¿å¢å€ â æ§èœé®é¢é¢èŠ
- å ³é®äžå¡æ¥å¿åŒåžž â äžå¡é£é©æç€º
æ¥å¿äžä» è®°åœææ¯ä¿¡æ¯ïŒä¹è®°åœäžå¡ä¿¡æ¯ïŒ
- çšæ·è¡äžºåæïŒåªäºåèœæåæ¬¢è¿
- äžå¡ææ ç»è®¡ïŒæ¥æŽ»ã蜬åçãçå
- è¿è¥ææè¯äŒ°ïŒæŽ»åšåžŠæ¥çæµéåæ¶å ¥
å®å šçžå ³çäºä»¶å¿ 须记åœåšæ¡ïŒ
- ç»åœç»åºè®°åœ
- æææäœæ¥å¿
- æéåæŽåå²
- åŒåžžè®¿é®è¡äžº
è¿äºæ¥å¿æ¯å®å šäºä»¶è¿œæº¯ååè§å®¡è®¡çéèŠäŸæ®ã
1.2 奜æ¥å¿ vs 忥å¿
2024-01-15 03:14:22 ERROR - Error occurred
2024-01-15 03:14:23 INFO - Processing...
2024-01-15 03:14:24 ERROR - Something went wrong
è¿äºæ¥å¿å 乿²¡æä»»äœä»·åŒïŒäžç¥éä»ä¹é误ãåçåšåªäžªæš¡åã圱åçæ¯ä»ä¹è¯·æ±ã
2024-01-15 03:14:22.123 ERROR [order-service] [traceId:abc123]
[userId:10086] Order creation failed: inventory check timeout,
productId=789, retryCount=3
- æ¶éŽæ³ç²Ÿç¡®å°æ¯«ç§
- æ¥å¿çº§å«æž æ°
- å 嫿å¡/æš¡åæ è¯
- æéŸè·¯è¿œèžª ID
- æå ³èçäžå¡æ è¯
- é误åå å ·äœ
- å ³é®åæ°å®æŽ
äºãæ¥å¿çå级äžè§è
äžæ¯æææ¥å¿éœçèå¹³çãæä»¬éèŠå¯¹æ¥å¿è¿è¡å级ïŒåš"ä¿¡æ¯å®æŽæ§"å"ååšææ¬"ä¹éŽæŸå°å¹³è¡¡ã
2.1 æ¥å¿çº§å«
äžçéçšçæ¥å¿çº§å«ä»äœå°é«ïŒ
æè¯Šç»çæ¥å¿çº§å«ïŒçšäºåŒåè°è¯ïŒ
- 诊ç»çäžéŽç¶æ
- åéåŒçåå
- ç®æ³æ§è¡æ¥éª€
ç产ç¯å¢éåžžå ³é DEBUG æ¥å¿ïŒåªå𿿥é®é¢æ¶äžŽæ¶åŒå¯ã
è®°åœç³»ç»æ£åžžè¿è¡çå ³é®äºä»¶ïŒ
- æå¡å¯åš/å ³é
- 请æ±å€ççåŒå§åç»æ
- éèŠäžå¡äºä»¶ïŒè®¢ååå»ºãæ¯ä»å®æïŒ
- 宿¶ä»»å¡çæ§è¡
INFO æ¥å¿æ¯äºè§£ç³»ç»è¿è¡ç¶æçäž»èŠæ¥æºã
è®°åœæœåšçé®é¢ïŒäœäžåœ±åç³»ç»æ£åžžè¿è¡ïŒ
- é 眮䜿çšäºé»è®€åŒ
- 请æ±å€çæ¥è¿è¶ æ¶éåŒ
- çŒååœäžçè¿äœ
- éè¯äºäžæ¬¡äœæç»æå
WARN æ¯"éèŠå ³æ³šäœäžéèŠç«å³å€ç"çä¿¡å·ã
è®°åœé误äºä»¶ïŒåœ±åäžå¡äœäžåœ±åç³»ç»æŽäœå¯çšæ§ïŒ
- 请æ±å€ç倱莥
- å€éšæå¡è°çšå€±èŽ¥
- æ°æ®æ ¡éªäžéè¿
- äžå¡è§åæ ¡éªå€±èŽ¥
ERROR éåžžéèŠäººå·¥å ³æ³šåå€çã
æäž¥éç级å«ïŒç³»ç»æ æ³ç»§ç»è¿è¡ïŒ
- æ æ³è¿æ¥æ°æ®åº
- å åæº¢åº
- å ³é®é 眮猺倱
- æå¡æ æ³å¯åš
FATAL åŸåŸæå³çéèŠç«å³éå¯æçŽ§æ¥ä¿®å€ã
2.2 æ¥å¿çº§å«ç䜿çšåå
INFO æ¯ç产ç¯å¢çæäœ³é»è®€çº§å«ïŒ
- DEBUG 倪诊ç»ïŒæ¥å¿é倪倧ïŒåœ±åæ§èœ
- WARN å以äžå€ªç²ç³ïŒäž¢å€±å ³é®ä¿¡æ¯
æ¥å¿çº§å«åºè¯¥æ¯æåšæè°æŽïŒ
- ææ¥é®é¢æ¶ïŒäžŽæ¶è°é«å° DEBUG
- æ¥å¿éè¿å€§æ¶ïŒäžŽæ¶è°äœå° WARN
- è°æŽæ éé坿å¡
åžžè§è¯¯åºïŒ
- çš ERROR è®°åœé¢æå çäžå¡åŒåžžïŒåºè¯¥çš WARN æ INFOïŒ
- çš INFO è®°åœå€§éè°è¯ä¿¡æ¯ïŒåºè¯¥çš DEBUGïŒ
- æ»¥çš WARNïŒå¯ŒèŽçæ£çé®é¢è¢«æ·¹æ²¡
2.3 ç»æåæ¥å¿
äŒ ç»çææ¬æ¥å¿äžäŸ¿äºæºåšè§£æïŒç»æåæ¥å¿åºè¿èçïŒ
2024-01-15 03:14:22 ERROR Order 12345 creation failed for user 10086
{
"timestamp": "2024-01-15T03:14:22.123Z",
"level": "ERROR",
"service": "order-service",
"traceId": "abc123",
"spanId": "def456",
"userId": 10086,
"orderId": 12345,
"message": "Order creation failed",
"error": {
"type": "InventoryCheckTimeout",
"retryCount": 3
}
}
ç»æåæ¥å¿çäŒå¿ïŒ
- æºåšå奜ïŒäŸ¿äºæ¥å¿å¹³å°è§£æå玢åŒ
- åæ®µå¯æ£çŽ¢ïŒæä»»æå段æ¥è¯¢åèå
- ç±»åæç¡®ïŒæ°åæ¯æ°åïŒæ¶éŽæ¯æ¶éŽ
- æ©å±çµæŽ»ïŒæ°å¢å段äžåœ±åç°æé»èŸ
äžãæ¥å¿ç³»ç»ç讟计åç
èŠè®Ÿè®¡äžäžªå¥œçæ¥å¿ç³»ç»ïŒéèŠçè§£å ¶æ žå¿åçåæ¶ææš¡åŒãæ¥å¿ç³»ç»æ¬èŽšäžæ¯äžäžªæ°æ®ç®¡éïŒä»äº§çå°æç»äœ¿çšïŒç»åééãäŒ èŸãå€çãååšãæ£çŽ¢äºäžªé¶æ®µã
3.1 æŽäœæ¶æè®Ÿè®¡
äžäžªå®æŽçæ¥å¿ç³»ç»æ¶æå¯ä»¥çäœäžæ¡"æ°æ®æµæ°Žçº¿"ïŒ
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â æ¥å¿æ°æ®æµæ°Žçº¿ â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ€
â â
â ââââââââââââ ââââââââââââ ââââââââââââ ââââââââââââ âââââââââââ
â â 产ç â â â éé â â â äŒ èŸ â â â å€ç â â â ååš ââ
â â (åºçš) â â (Agent) â â (éå) â â (ETL) â â (ES) ââ
â ââââââââââââ ââââââââââââ ââââââââââââ ââââââââââââ âââââââââââ
â â â â â â â
â æ¥å¿èŸåº æä»¶/çœç» æ¶æ¯çŒå² æ ŒåŒèœ¬æ¢ æä¹
å â
â SDKå°è£
äœçœ®è¿œèžª åå³°å¡«è°· åæ®µæå 建ç«çŽ¢åŒ â
â åŒæ¥åå
¥ å€è¡åå¹¶ å¯é äŒ èŸ è±ææž
æŽ å·çå犻 â
â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â æ£çŽ¢äžåæå± â â
â â ââââââââââââ ââââââââââââ ââââââââââââ ââââââââââââ â â
â â â æ¥è¯¢ â â èå â â åèŠ â â å¯è§å â â â
â â â (DSL) â â (ç»è®¡) â â (è§å) â â (仪衚ç) â â â
â â ââââââââââââ ââââââââââââ ââââââââââââ ââââââââââââ â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
è¿äžªæ¶æçæ žå¿è®Ÿè®¡ååæ¯è§£èŠïŒæ¯äžªé¶æ®µç¬ç«æŒè¿ïŒäºäžåœ±åã
3.2 æ¥å¿ééåç
æ¥å¿é鿝æŽäžªç³»ç»ç"å ¥å£"ïŒéèŠè§£å³äžäžªæ žå¿é®é¢ïŒ
æ¥å¿æä»¶æ¯æç»å¢é¿çïŒééåšéèŠå"å°Ÿå·Ž"äžæ ·è·éæä»¶æ«å°ŸïŒæä»¥å« tailïŒãè¿ç䌌ç®åïŒå®é æå äžªææ¯éŸç¹ïŒ
- äœçœ®è®°åœïŒééåšéå¯åèŠç¥éä»åªéç»§ç»è¯»ãéåžžå°è¯»åäœçœ®ïŒæä»¶ inode + offsetïŒè®°åœå°ç¬ç«çäœçœ®æä»¶äžïŒ
# position.db
/var/log/app.log::inode=123456::offset=9876543
- æä»¶æ»åšïŒLog RotationïŒïŒæ¥å¿æä»¶äŒå®ææ»åšïŒapp.log â app.log.1ïŒïŒééåšéèŠè¯å«æ°æä»¶å¹¶åæ¢ãè¿éè¿æ¯èŸæä»¶ inode å®ç°ïŒåäžäžªæä»¶åïŒinode åäºå°±æ¯æ°æä»¶ã
- å€è¡æ¥å¿åå¹¶ïŒJava å æ æ¯å žåçå€è¡æ¥å¿ïŒ
2024-01-15 03:14:22 ERROR Exception occurred
java.lang.NullPointerException
at com.example.OrderService.create(OrderService.java:123)
at com.example.OrderController.createOrder(OrderController.java:45)
ééåšéèŠçšæ£åå¹é æ¥å¿éŠè¡ïŒé垞以æ¶éŽæ³åŒå€ŽïŒïŒå°åç»è¡åå¹¶å°åäžæ¡æ¥å¿äžã
ééåšéèŠåšäž€äžªæç«¯ä¹éŽæŸå¹³è¡¡ïŒ
- 宿¶æšéïŒæ¯æ¡æ¥å¿ç«å³åéïŒå»¶è¿äœäœçœç»åŒé倧
- æ¹éæšéïŒæå€ N æ¡æçåŸ T ç§ååéïŒæçé«äœå»¶è¿å¢å
ç产ç¯å¢çåæ³æ¯æ¹é + è¶ æ¶ïŒæå€ 1000 æ¡æçåŸ 5 ç§ïŒåªäžªå å°è§Šååéãè¿æ ·åšæ£åžžæ åµäžæ¹é髿ïŒäœæµéæ¶ä¹äžäŒå€ªæ ¢ã
çœç»æ éãäžæžžæå¡äžå¯çšæ¯åžžæãééåšéèŠïŒ
- æ¬å°çŒå²ïŒåéå€±èŽ¥çæ¥å¿æåæ¬å°éå
- ææ°éé¿éè¯ïŒå€±èŽ¥å 1sã2sã4s... 鿥å¢å éè¯éŽé
- é级çç¥ïŒéåæ»¡æ¶å¯äž¢åŒäœçº§å«æ¥å¿ïŒå 䞢 DEBUGïŒå䞢 INFOïŒ
3.3 æ¥å¿äŒ èŸåç
æ¥å¿äŒ èŸå±æ¯æŽäžªç³»ç»ç"çŒå²åº"ïŒæ žå¿æ¯æ¶æ¯éåã
åè®Ÿäœ æäžäžªçµåç³»ç»ïŒå€§ä¿æ¶æ¥å¿éæŽå¢ 10 åïŒ
- 没æéåïŒæ¥å¿çŽæ¥åå ¥ ESïŒES æäžäœåå ¥ååïŒçŽæ¥ææ
- æéåïŒæ¥å¿å è¿ KafkaïŒKafka æäœå³°åŒïŒES æ ¢æ ¢æ¶è޹
æ¶æ¯éåå®ç°äºåå³°å¡«è°·ïŒäžæžžæµéçªå¢æ¶éå积åïŒäžæžžæèªå·±çè奿¶è޹ã
| ç¹æ§ | Kafka | NSQ | RabbitMQ |
|---|---|---|---|
| ååé | æé«ïŒ10äž+/ç§ïŒ | é«ïŒäžçº§/ç§ïŒ | äžçïŒäžçº§/ç§ïŒ |
| å»¶è¿ | 毫ç§çº§ | 毫ç§çº§ | 埮ç§çº§ |
| æä¹ å | ç£ç顺åºå | ç£ç | å å/ç£ç |
| æ¶èŽ¹æš¡åŒ | æå | æšæç»å | æšé |
| è¿ç»Žå€æåºŠ | é« | äœ | äž |
| éçšåºæ¯ | å€§è§æš¡æ¥å¿ | äžå°è§æš¡ | äºå¡æ§æ¶æ¯ |
æ¥å¿åºæ¯çç¹ç¹æ¯åå€è¯»å°ãååäŒå ïŒKafka æ¯æåžžè§çéæ©ã
Kafka éè¿ Topic ååºå®ç°å¹¶è¡å€çïŒ
Topic: app-logs
âââ Partition 0 â Consumer 1 (å€ç order-service æ¥å¿)
âââ Partition 1 â Consumer 2 (å€ç payment-service æ¥å¿)
âââ Partition 2 â Consumer 3 (å€ç user-service æ¥å¿)
æ service åæ®µååºïŒåäžæå¡çæ¥å¿è¿å ¥åäžååºïŒä¿è¯æ¶åºæ§ã
3.4 æ¥å¿å€çåç
æ¥å¿è¿å ¥ååšåïŒéåžžéèŠ"æž æŽ"å"å å·¥"ãè¿äžªé¶æ®µå« ETLïŒExtract-Transform-LoadïŒã
- åæ®µæåïŒä»æ¥å¿å å®¹äžæåç»æååæ®µ
åå§æ¥å¿: 2024-01-15 03:14:22 ERROR [order-service] Order failed
æåå: {time: "...", level: "ERROR", service: "order-service", message: "..."}
- æ°æ®è±æïŒéèææä¿¡æ¯
åå§: ææºå· 13812345678 ç»åœæå
è±æ: ææºå· 138****5678 ç»åœæå
- åæ®µå¯åïŒè¡¥å äžäžæä¿¡æ¯
åå§: IP=192.168.1.100
å¯å: IP=192.168.1.100, region=å京, isp=çµä¿¡
- æ ŒåŒç»äžïŒå°äžåæ ŒåŒèœ¬äžºç»äžæ ŒåŒ
Nginx æ¥å¿ â JSON
Java æ¥å¿ â JSON
Go æ¥å¿ â JSON
- LogstashïŒåèœåŒºå€§ïŒæä»¶äž°å¯ïŒäœèµæºæ¶è倧ïŒJVMïŒ
- FluentdïŒèœ»é级ïŒRuby å®ç°ïŒèµæºå çšå°
- VectorïŒRust å®ç°ïŒé«æ§èœïŒé 眮ç®å
- FlinkïŒæµåŒå€çïŒéå倿ç宿¶åæ
å°è§æš¡çš Fluentd/VectorïŒå€§è§æš¡å€æå€ççš Flinkã
3.5 æ¥å¿ååšåç
ååšæ¯æ¥å¿ç³»ç»ç"å¿è"ïŒå³å®äºæ£çŽ¢èœååææ¬ã
Elasticsearch çæ žå¿æ¯åæçŽ¢åŒãæäžªæ¯æ¹ïŒ
æ³è±¡äžæ¬æç§ä¹ŠïŒäœ æ³æŸ"æ¥å¿"è¿äžªè¯åºç°çäœçœ®ïŒ
- æ£æçŽ¢åŒïŒäŒ ç»ç®åœïŒïŒæç« è顺åºïŒåè¯äœ æ¯ç« 讲ä»ä¹ãèŠæŸ"æ¥å¿"ïŒäœ åŸç¿»éæŽæ¬ä¹Šã
- åæçŽ¢åŒïŒä¹Šå玢åŒïŒïŒåè¯äœ "æ¥å¿"åºç°åšç¬¬ 12ã45ã78 页ãçŽæ¥å®äœã
ææ¯å®ç°ïŒ
ææ¡£ 1: "æ¥å¿ç³»ç»åŸéèŠ"
ææ¡£ 2: "ç³»ç»è®Ÿè®¡èŠåç"
åæçŽ¢åŒ:
"æ¥å¿" â [ææ¡£1]
"ç³»ç»" â [ææ¡£1, ææ¡£2]
"åŸéèŠ" â [ææ¡£1]
"讟计" â [ææ¡£2]
"èŠ" â [ææ¡£2]
"åç" â [ææ¡£2]
æçŽ¢"æ¥å¿ç³»ç»"æ¶ïŒæŸå°"æ¥å¿"å"ç³»ç»"çææ¡£å衚ïŒå亀éïŒåŸå°ææ¡£ 1ã
- ååŒååšïŒClickHouseïŒïŒåäžåæ°æ®ç±»åçžåïŒå猩æ¯é«
- æ¶éŽååºïŒæå€©/å°æ¶ååºïŒå 逿§æ°æ®çŽæ¥å ååº
- å·çå犻ïŒçæ°æ® SSDïŒå·æ°æ® HDD æå¯¹è±¡ååš
- æ°æ®å¯æ¬ïŒå€å¯æ¬ä¿è¯å¯é æ§ïŒäœä¹å¢å ææ¬
åãæ¥å¿ééæ¶æå®è·µ
çè§£äºåçïŒæä»¬æ¥çå ·äœçæ¶æå®è·µã
4.1 æ¶ææŒè¿è·¯åŸ
æç®åçæ¶æïŒéåååå¢éïŒ
ââââââââââââââââ
â åºçšæå¡ â
ââââââââ¬ââââââââ
â çŽæ¥åå
¥
âŒ
ââââââââââââââââ
â Elasticsearch â
ââââââââ¬ââââââââ
â
âŒ
ââââââââââââââââ
â Kibana â
ââââââââââââââââ
åºçšéè¿ Elasticsearch 客æ·ç«¯çŽæ¥åå ¥ ESã
äŒç¹ïŒç®åïŒç»ä»¶å° 猺ç¹ïŒåºçšå ES èŠåïŒES æ é圱ååºçš
åŒå ¥æä»¶å AgentïŒè§£èŠåºçšåæ¥å¿ç³»ç»ïŒ
ââââââââââââââââ
â åºçšæå¡ â
ââââââââ¬ââââââââ
â åæä»¶
âŒ
ââââââââââââââââ
â æ¥å¿æä»¶ â
ââââââââ¬ââââââââ
â Filebeat
âŒ
ââââââââââââââââ
â Logstash â
ââââââââ¬ââââââââ
â
âŒ
ââââââââââââââââ
â Elasticsearch â
ââââââââ¬ââââââââ
â
âŒ
ââââââââââââââââ
â Kibana â
ââââââââââââââââ
è¿æ¯ç»å žç ELK æ¶æã
å å ¥æ¶æ¯éåïŒææµéå³°åŒïŒ
åºçš â æä»¶ â Filebeat â Kafka â Logstash â ES â Kibana
Kafka äœäžºçŒå²ïŒå³äœ¿ ES çæäžå¯çšïŒæ¥å¿ä¹äžäŒäž¢å€±ã
è¶ å€§è§æš¡éèŠå€é矀ïŒ
ââââ Kafka Cluster 1 â ES Cluster 1
åºçš â Filebeat âââââŒâââ Kafka Cluster 2 â ES Cluster 2
ââââ Kafka Cluster 3 â ES Cluster 3
æäžå¡æç§æ·ååºïŒé¿å åç¹ç¶é¢ã
4.2 Kubernetes ç¯å¢éé
容åšåç¯å¢åžŠæ¥æ°ææïŒå®¹åšæ¯äžŽæ¶çïŒPod 鿝忥å¿ä¹æ²¡äºã
æ¯äžªèç¹è¿è¡äžäžª Agent PodïŒéé该èç¹ææå®¹åšçæ¥å¿ïŒ
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat
spec:
template:
spec:
containers:
- name: filebeat
image: docker.elastic.co/beats/filebeat:8.0.0
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
äŒç¹ïŒèµæºåŒéå°ïŒé 眮éäž çŒºç¹ïŒææå®¹åšå ±çšé 眮ïŒçµæŽ»æ§å·®
æ¯äžªåºçš Pod 䌎éäžäžªæ¥å¿éé容åšïŒ
apiVersion: v1
kind: Pod
metadata:
name: app-with-logging
spec:
containers:
- name: app
image: my-app:latest
volumeMounts:
- name: logs
mountPath: /var/log/app
- name: log-agent
image: fluent/fluent-bit:latest
volumeMounts:
- name: logs
mountPath: /var/log/app
volumes:
- name: logs
emptyDir: {}
äŒç¹ïŒæ¯äžªåºçšç¬ç«é 眮 猺ç¹ïŒèµæºåŒéå€§ïŒæ¯äžª Pod éœæéé容åšïŒ
åºçšçŽæ¥éè¿ SDK åå ¥æ¥å¿ç³»ç»ïŒäžèœæ¬å°æä»¶ïŒ
// äœ¿çš Logstash æäŸç Log4j Appender
log4j.appender.LOGSTASH=net.logstash.log4j.JSONEventAwareLogstashAppender
log4j.appender.LOGSTASH.host=kafka.logging.svc.cluster.local
log4j.appender.LOGSTASH.port=9092
äŒç¹ïŒæ æ¬å°äŸèµïŒå®¹åšéæ¯äžåœ±å 猺ç¹ïŒçœç»æ éå¯èœäž¢æ¥å¿ïŒéèŠå奜çŒå²
4.3 ééæ¹æ¡éæ©å»ºè®®
| åºæ¯ | æšèæ¹æ¡ | çç± |
|---|---|---|
| äŒ ç» VM éšçœ² | Filebeat + Kafka | æççš³å®ïŒèµæºåŒéå° |
| Kubernetes | DaemonSet Fluent Bit | éäžç®¡çïŒè¿ç»Žç®å |
| èµæºææ | VectorïŒæ¿ä»£ LogstashïŒ | å åå çšäœïŒæ§èœå¥œ |
| å€äºç¯å¢ | åºçšçŽå + æ¬å°çŒå² | é¿å è·šäºæä»¶è®¿é® |
äºãELK/EFK 宿æ¡äŸ
ç论讲äºåŸå€ïŒæ¥çäžäžªå®æŽç宿æ¡äŸã
5.1 ELK æ¶æéšçœ²
å讟æä»¬æäžäžªäžçè§æš¡çç³»ç»ïŒ
- 20 䞪æå¡å®äŸ
- æ¥åæ¥å¿é 100GB
- ä¿ç 7 å€©çæ°æ®ïŒ30 å€©æž©æ°æ®
- ElasticsearchïŒ3 èç¹é矀ïŒ3 master + 3 dataïŒ
- KibanaïŒ1 èç¹
- LogstashïŒ2 èç¹ïŒåèŽèœœåè¡¡ïŒ
- KafkaïŒ3 èç¹é矀
- FilebeatïŒéšçœ²åšæ¯äžªåºçšæå¡åš
# elasticsearch.yml
cluster.name: logging-cluster
node.name: node-1
node.roles: [master, data]
# 玢åŒè®Ÿçœ®
index.number_of_shards: 3
index.number_of_replicas: 1
# å å
å讟眮ïŒäžè¶
è¿ 32GBïŒ
-Xms16g
-Xmx16g
# å·çå犻
node.attr.data_type: hot # çèç¹
# node.attr.data_type: warm # æž©èç¹
# logstash.conf
input {
kafka {
bootstrap_servers => "kafka1:9092,kafka2:9092,kafka3:9092"
topics => ["app-logs"]
consumer_threads => 4
}
}
filter {
json {
source => "message"
}
# è§£ææ¶éŽæ³
date {
match => ["timestamp", "ISO8601"]
target => "@timestamp"
}
# ææºå·è±æ
gsub => [
"message", "(1[3-9]\d)\d{4}(\d{4})", "\1****\2"
]
# æ·»å å°çäœçœ®
geoip {
source => "client_ip"
target => "geoip"
}
}
output {
elasticsearch {
hosts => ["es1:9200", "es2:9200", "es3:9200"]
index => "app-logs-%{+YYYY.MM.dd}"
}
}
# filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/app/*.log
multiline:
pattern: '^\d{4}-\d{2}-\d{2}'
negate: true
match: after
fields:
service: ${SERVICE_NAME}
env: production
fields_under_root: true
output.kafka:
hosts: ["kafka1:9092", "kafka2:9092", "kafka3:9092"]
topic: "app-logs"
partition.round_robin:
reachable_only: true
required_acks: 1
5.2 EFK æ¶æïŒFluentd æ¿ä»£ LogstashïŒ
EFK = Elasticsearch + Fluentd + KibanaïŒæŽéå容åšåç¯å¢ã
# fluent.conf
<source>
@type tail
path /var/log/containers/*.log
pos_file /var/log/fluentd-containers.log.pos
tag kubernetes.*
format json
read_from_head true
</source>
<filter kubernetes.**>
@type kubernetes_metadata
@id filter_kube_metadata
kubernetes_url "#{ENV['KUBERNETES_SERVICE_HOST']}:#{ENV['KUBERNETES_SERVICE_PORT']}"
</filter>
<match kubernetes.**>
@type elasticsearch
host "#{ENV['ELASTICSEARCH_HOST']}"
port "#{ENV['ELASTICSEARCH_PORT']}"
logstash_format true
logstash_prefix app-logs
include_tag_key true
</match>
# fluent-bit.conf
[INPUT]
Name tail
Path /var/log/containers/*.log
Parser docker
Tag kube.*
[FILTER]
Name kubernetes
Match kube.*
Kube_URL https://kubernetes.default.svc:443
Merge_Log On
[OUTPUT]
Name es
Match *
Host elasticsearch
Port 9200
Logstash_Format On
Logstash_Prefix app-logs
5.3 玢åŒçåœåšæç®¡ç
æ¥å¿æ°æ®äŒæ éå¢é¿ïŒéèŠèªåšç®¡ççåœåšæã
PUT _ilm/policy/logs-policy
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_size": "50gb",
"max_age": "1d"
},
"set_priority": {
"priority": 100
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"shrink": {
"number_of_shards": 1
},
"forcemerge": {
"max_num_segments": 1
},
"allocate": {
"require": {
"data_type": "warm"
}
},
"set_priority": {
"priority": 50
}
}
},
"cold": {
"min_age": "30d",
"actions": {
"allocate": {
"require": {
"data_type": "cold"
}
},
"set_priority": {
"priority": 0
}
}
},
"delete": {
"min_age": "90d",
"actions": {
"delete": {}
}
}
}
}
}
è¿äžªé 眮å®ç°ïŒ
- Hot é¶æ®µïŒ0-7倩ïŒïŒé«æ§èœ SSDïŒæ¯æé¢ç¹æ¥è¯¢
- Warm é¶æ®µïŒ7-30倩ïŒïŒè¿ç§»å°æ®éç£çïŒå猩äŒå
- Cold é¶æ®µïŒ30-90倩ïŒïŒåŸå°æ¥è¯¢ïŒäœäŒå 级
- Delete é¶æ®µïŒ90倩åïŒïŒèªåšå é€
å ãæ¥å¿åææ¹æ¡
æ¥å¿åè¿å»äºïŒæä¹çšå¥œå®æ¯å ³é®ã
6.1 åžžçšæ¥è¯¢æš¡åŒ
traceId: "abc123"
æ¥çäžäžªè¯·æ±ç宿ŽéŸè·¯ã
level: ERROR
AND @timestamp: [now-1h TO now]
<table>
<thead><tr>
</tr></thead><tbody>
</tbody></table>
è¿å» 1 å°æ¶åæå¡çé误æ°éã
duration_ms: >1000
AND service: "order-service"
<table>
<thead><tr>
</tr></thead><tbody>
</tbody></table>
订åæå¡äžå API çå¹³å/æå€§èæ¶ã
userId: 10086
AND level: INFO
AND message: ("ç»åœ" OR "äžå" OR "æ¯ä»")
è¿œèžªçšæ· 10086 çå ³é®æäœã
6.2 èååæå®æ
éæ±ïŒåæè®¢åæ¥å£ç P50ãP95ãP99 å»¶è¿è¶å¿ã
ES æ¥è¯¢ïŒ
GET app-logs-*/_search
{
"size": 0,
"query": {
"bool": {
"filter": [
{"term": {"service": "order-service"}},
{"range": {"@timestamp": {"gte": "now-7d"}}}
]
}
},
"aggs": {
"over_time": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "1h"
},
"aggs": {
"p50": {"percentiles": {"field": "duration_ms", "percents": [50]}},
"p95": {"percentiles": {"field": "duration_ms", "percents": [95]}},
"p99": {"percentiles": {"field": "duration_ms", "percents": [99]}}
}
}
}
}
éæ±ïŒæŸåºè¿å» 1 å°æ¶åºç°æé¢ç¹çé误ã
GET app-logs-*/_search
{
"size": 0,
"query": {
"bool": {
"filter": [
{"term": {"level": "ERROR"}},
{"range": {"@timestamp": {"gte": "now-1h"}}}
]
}
},
"aggs": {
"error_types": {
"terms": {
"field": "error.type.keyword",
"size": 10
}
}
}
}
6.3 Kibana å¯è§å
- ç³»ç»å¥åº·æ»è§
- åæå¡æ¥å¿éïŒé¥ŒåŸïŒ - 宿¶é误æµïŒæ°æ®è¡šïŒ
- æ§èœçæ§
- æ ¢è¯·æ± TOP 10ïŒæ¡åœ¢åŸïŒ - æ¥å£ååºååžïŒçŽæ¹åŸïŒ
- äžå¡åæ
- çšæ·æŽ»è·åºŠïŒææ åŸïŒ - åŒåžžäº€æïŒæ°æ®è¡šïŒ
- å®å šçæ§
- åŒåžž IP 访é®ïŒå°åŸïŒ - æææäœè®°åœïŒæ°æ®è¡šïŒ
äžãåèŠæºå¶è®Ÿè®¡
æ¥å¿äžä» èŠååšåæ¥è¯¢ïŒè¿èŠäž»åšåç°é®é¢ã
7.1 åèŠç³»ç»æ¶æ
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â åèŠç³»ç»æ¶æ â
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ€
â â
â âââââââââââââââ âââââââââââââââ âââââââââââââââ â
â â æ¥å¿æº â â ææ æº â â äºä»¶æº â â
â â (ES/Loki) â â (Prometheus)â â (Webhook) â â
â ââââââââ¬âââââââ ââââââââ¬âââââââ ââââââââ¬âââââââ â
â â â â â
â âââââââââââââââââââŒââââââââââââââââââ â
â ⌠â
â âââââââââââââââââ â
â â è§ååŒæ â â
â â (Alertè§å) â â
â âââââââââ¬ââââââââ â
â â â
â ââââââââââââââââââŒâââââââââââââââââ â
â ⌠⌠⌠â
â âââââââââââââââ âââââââââââââââ âââââââââââââââ â
â â éåŒå€æ â â è¶å¿åæ â â åŒåžžæ£æµ â â
â â (æ°é>N) â â (ç¯æ¯/忝) â â (ML/AI) â â
â âââââââââââââââ âââââââââââââââ âââââââââââââââ â
â â â â â
â ââââââââââââââââââŒâââââââââââââââââ â
â ⌠â
â âââââââââââââââââ â
â â åèŠè·¯ç± â â
â â (åç»/æ¶æ) â â
â âââââââââ¬ââââââââ â
â â â
â ââââââââââââââââââŒâââââââââââââââââ â
â ⌠⌠⌠â
â âââââââââââââââ âââââââââââââââ âââââââââââââââ â
â â é®ä»¶ â â éé/é£ä¹Š â â SMS â â
â âââââââââââââââ âââââââââââââââ âââââââââââââââ â
â â
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
7.2 åèŠè§å讟计
æç®åçŽæ¥ïŒè¶ è¿éåŒå°±åèŠã
# é误çåèŠ
name: error_rate_high
condition:
query: "level:ERROR"
time_window: 5m
threshold: 100
operator: ">"
actions:
- type: feishu
webhook: "https://open.feishu.cn/..."
message: "â ïž é误çè¿é«ïŒ5åéå
é误æ°è¶
è¿100"
äžå岿°æ®å¯¹æ¯ïŒè¯å«åŒåžžæ³¢åšã
# ç¯æ¯åèŠ
name: error_spike
condition:
query: "level:ERROR"
compare_with: "1h_ago"
increase_threshold: 50%
actions:
- type: feishu
message: "â ïž é误æ°ç¯æ¯å¢é¿è¶
è¿50%"
倿¡ä»¶ç»åïŒåå°è¯¯æ¥ã
# æå¡å¯çšæ§åèŠ
name: service_availability
condition:
- query: "level:ERROR AND service:order-service"
threshold: 10
time_window: 1m
- query: "level:INFO AND service:order-service"
threshold: 5
time_window: 1m
operator: "<"
logic: "AND"
actions:
- type: sms
recipients: ["13812345678"]
message: "ðš 订åæå¡å¯çšæ§äžé"
7.3 åèŠæ¶æäžéåª
åèŠé£æŽæ¯æå€ŽçŒçé®é¢ïŒäžäžªé®é¢è§Šå 100 æ¡åèŠïŒè°ä¹å€çäžäºã
çžåç±»åçåèŠåå¹¶ïŒ
åå§åèŠïŒ
- 10:00 order-service ERROR: timeout
- 10:01 order-service ERROR: timeout
- 10:02 order-service ERROR: timeout
- ...
æ¶æåïŒ
- 10:10 order-service ERROR: timeout (åºç° 15 次)
äœçº§å«åèŠè¢«é«çº§å«åèŠæå¶ïŒ
åŠæ FATAL åèŠè§Šå â æå¶åäžæå¡ç ERROR åèŠ
åŠæ ERROR åèŠè§Šå â æå¶åäžæå¡ç WARN åèŠ
åèŠè§ŠååïŒäžæ®µæ¶éŽå äžåéå€åèŠïŒ
silence:
duration: 30m
comment: "å·²å€çïŒçåŸ
æ¢å€"
7.4 ElastAlert 宿
ElastAlert æ¯ Yelp åŒæºç ES åèŠå·¥å ·ïŒé 眮ç®åã
pip install elastalert
# config.yaml
rules_folder: rules
run_every:
minutes: 1
buffer_time:
minutes: 5
es_host: elasticsearch
es_port: 9200
# rules/error_frequency.yaml
name: Error Frequency Alert
type: frequency
index: app-logs-*
num_events: 50
timeframe:
minutes: 5
filter:
- term:
level: "ERROR"
alert:
- "feishu"
feishu_webhook_url: "https://open.feishu.cn/open-apis/bot/v2/hook/xxx"
# rules/blacklist.yaml
name: Blacklist Alert
type: blacklist
index: app-logs-*
compare_key: user.ip
blacklist:
- "192.168.1.100" # å·²ç¥æ¶æIP
- "10.0.0.50"
include:
- user.ip
- user.name
- action
alert:
- "email"
email: "security@example.com"
7.5 åèŠæäœ³å®è·µ
äžå级å«çåèŠèµ°äžåæž éïŒ
| çº§å« | æ¡ä»¶ | éç¥æž é | ååºæ¶éŽ |
|---|---|---|---|
| P0 | æå¡äžå¯çš | çµè¯ + SMS + é£ä¹Š | 5åé |
| P1 | é误çè¶ è¿éåŒ | é£ä¹Š + é®ä»¶ | 15åé |
| P2 | æ§èœäžé | é£ä¹Š | 1å°æ¶ |
| P3 | æœåšé£é© | é®ä»¶ | 1倩 |
- é 眮åèŠæ¶è®Ÿçœ®åŒç人å
- 蜮æ¢åŒçïŒé¿å ç²å³
- é玧æ¥åèŠåªéç¥åŒç人å
æ¯åšå顟åèŠæ°æ®ïŒ
- åªäºåèŠæ¯ææçïŒçæ£åç°äºé®é¢ïŒ
- åªäºæ¯è¯¯æ¥ïŒéèŠè°æŽéåŒïŒ
- åªäºé®é¢æ²¡æåèŠïŒéèŠæ°å¢è§åïŒ
对äºå·²ç¥é®é¢ïŒè®Ÿè®¡èªææµçšïŒ
# èªåšé坿å¡
name: auto_restart
condition:
query: "level:FATAL AND service:payment-service"
threshold: 3
time_window: 2m
actions:
- type: webhook
url: "http://k8s-api/restart?service=payment-service"
- type: feishu
message: "payment-service å·²èªåšéå¯"
å «ãæ§èœäŒåäžææ¬æ§å¶
æ¥å¿ç³»ç»æ¯"ç§é±å€§æ·"ïŒéèŠå奜äŒåã
8.1 åå ¥äŒå
åæ¡åå ¥ vs æ¹éåå ¥æ§èœå·® 10 å以äžïŒ
// å·®ïŒæ¯æ¡æ¥å¿åç¬å
for (Log log : logs) {
esClient.index(log);
}
// å¥œïŒæ¹éåå
¥
BulkRequest bulk = new BulkRequest();
for (Log log : logs) {
bulk.add(new IndexRequest("app-logs").source(log));
}
esClient.bulk(bulk);
æ¥å¿åå ¥äžåºè¯¥é»å¡äžå¡çº¿çšïŒ
// 䜿çšå
åéååŒæ¥å
ExecutorService executor = Executors.newFixedThreadPool(4);
BlockingQueue<Log> queue = new LinkedBlockingQueue<>(10000);
// äžå¡çº¿çšåªå
¥é
queue.offer(log);
// åå°çº¿çšæ¹éæ¶è޹
executor.submit(() -> {
List<Log> batch = new ArrayList<>();
while (true) {
queue.drainTo(batch, 1000);
if (!batch.isEmpty()) {
esClient.bulk(batch);
batch.clear();
}
}
});
8.2 ååšäŒå
äžåé¶æ®µçæ°æ®äœ¿çšäžåååšïŒ
HotïŒ0-3倩ïŒïŒNVMe SSDïŒ3坿¬
WarmïŒ3-30倩ïŒïŒSATA SSDïŒ2坿¬
ColdïŒ30-90倩ïŒïŒHDDïŒ1坿¬
FrozenïŒ>90倩ïŒïŒå¯¹è±¡ååš S3ïŒæ 坿¬
ES é»è®€äœ¿çš LZ4 å猩ïŒå¯ä»¥åæ¢å° DEFLATE è·åŸæŽé«å猩æ¯ïŒ
PUT app-logs-*
{
"settings": {
"index": {
"codec": "best_compression"
}
}
}
åçŒ©æ¯æå 15-20%ïŒäœ CPU æ¶èå¢å ã
- åå°äžå¿ èŠçåæ®µçŽ¢åŒ
- å ³éäžéèŠç text åæ®µç fielddata
- äœ¿çš keyword ç±»åæ¿ä»£ textïŒç²Ÿç¡®å¹é åºæ¯ïŒ
8.3 æ¥è¯¢äŒå
ES ææ¶éŽååºïŒæ¥è¯¢æ¶å°œéæå®æ¶éŽèåŽïŒ
// å¥œïŒæå®æ¶éŽèåŽ
{
"query": {
"bool": {
"filter": [
{"range": {"@timestamp": {"gte": "now-1h"}}}
]
}
}
}
// å·®ïŒå
šéæ«æ
{
"query": {
"match_all": {}
}
}
filter äžè®¡ç®åŸåïŒå¯ä»¥å©çšçŒåïŒ
// 奜ïŒäœ¿çš filter
{
"query": {
"bool": {
"filter": [
{"term": {"level": "ERROR"}},
{"term": {"service": "order-service"}}
]
}
}
}
// å·®ïŒäœ¿çš queryïŒäŒè®¡ç®çžå
³æ§åŸåïŒ
{
"query": {
"bool": {
"must": [
{"term": {"level": "ERROR"}},
{"term": {"service": "order-service"}}
]
}
}
}
ES é»è®€åªå 讞æ¥è¯¢å 10000 æ¡ç»æã深床åé¡µäœ¿çš search_afterïŒ
// 第äžé¡µ
GET app-logs/_search
{
"size": 100,
"sort": [{"@timestamp": "desc"}]
}
// äžäžé¡µïŒäœ¿çšäžäžé¡µæåäžæ¡çæåºåŒïŒ
GET app-logs/_search
{
"size": 100,
"sort": [{"@timestamp": "desc"}],
"search_after": ["2024-01-15T03:14:22.123Z"]
}
8.4 ææ¬äŒ°ç®
以æ¥å 100GB æ¥å¿ãä¿ç 30 倩䞺äŸïŒ
- åå§æ°æ®ïŒ100GB à 30 = 3TB
- å猩åïŒçºŠ 40%ïŒïŒ1.2TB
- 2 坿¬ïŒ2.4TB
- äºååšè޹çšïŒçºŠ Â¥0.35/GB/æïŒïŒ2.4TB à 0.35 à 1024 â Â¥860/æ
- ES é矀ïŒ3èç¹ïŒ8æ ž16GïŒïŒçºŠ Â¥2000/æ
- Kafka é矀ïŒ3èç¹ïŒ4æ ž8GïŒïŒçºŠ Â¥1000/æ
- åå°ä¿ç倩æ°ïŒ30倩 â 7倩ïŒ
- éäœå¯æ¬æ°ïŒ2坿¬ â 1坿¬ïŒ
- å·æ°æ®å对象ååš
- è¿æ»€æ çšæ¥å¿ïŒå¥åº·æ£æ¥ãéæèµæºïŒ
ä¹ãæ¥å¿ç³»ç»éå对æ¯
åžé¢äžçæ¥å¿ç³»ç»è¶æ¥è¶å€ïŒæä¹éïŒ
9.1 äž»æµæ¹æ¡å¯¹æ¯
| æ¹æ¡ | äŒç¹ | çŒºç¹ | éçšåºæ¯ |
|---|---|---|---|
| ELK | åèœå šé¢ãçææçãç€ŸåºæŽ»è· | èµæºæ¶è倧ãè¿ç»Žå€æ | äžå€§è§æš¡äŒäž |
| EFK | 容åšå奜ãFluentd 蜻é | åèœäžåŠ Logstash äž°å¯ | Kubernetes ç¯å¢ |
| Loki | æ¶æç®åãææ¬äœãäž Grafana éæ | å šææ£çŽ¢åŒ±ãäžéåå€æåæ | äºåçãå°å¢é |
| ClickHouse | 髿§èœãäœææ¬ãèå区 | å šææ£çŽ¢åŒ±ãåŠä¹ æ²çº¿é¡ | æ¥å¿åæãæ¥è¡š |
| Graylog | åŒç®±å³çšãåèŠåèœåŒº | 瀟åºçåèœæé | äžå°å¢é |
9.2 éå建议
æšèïŒLoki + Grafana
çç±ïŒ
- éšçœ²ç®åïŒåæºå°±èœè·
- èµæºæ¶èäœ
- äž Grafana æ çŒéæ
- å 莹
æšèïŒELK æ
çç±ïŒ
- åèœå šé¢ïŒèŠçåç§åºæ¯
- çææçïŒèµæäž°å¯
- 坿©å±æ§å¥œ
æšèïŒELK + ClickHouse
çç±ïŒ
- ELK çšäºå®æ¶æ¥è¯¢ååèŠ
- ClickHouse çšäºå岿°æ®åæ
- ååæé¿
æšèïŒEFK æ Loki
çç±ïŒ
- äž K8s çææ·±åºŠéæ
- DaemonSet éšçœ²æ¹äŸ¿
- åšææ©çŒ©å®¹å奜
åãæ»ç»
æ¥å¿ç³»ç»æ¯åºç¡è®Ÿæœäž"ååšææäœäœä»·åŒæé«"çç»ä»¶ä¹äžãå¹³æ¶äœ å¯èœæè§äžå°å®çååšïŒäœåœé®é¢åçæ¶ïŒå®å°±æ¯äœ çæåœçš»èã
- é®é¢ææ¥ïŒå¿«éå®äœåè§£å³é®é¢
- çæ§åèŠïŒå®æ¶æç¥ç³»ç»å¥åº·ç¶æ
- äžå¡åæïŒä»æ¥å¿äžææäžå¡ä»·åŒ
- å®å šå®¡è®¡ïŒè¿œæº¯ååè¯çéèŠäŸæ®
- æ¥å¿è§èïŒç»äžæ ŒåŒãåçå级ãç»æåèŸåº
- ééæ¶æïŒå¯é ééãè§£èŠåºçšãçµæŽ»æ©å±
- ååšéæ©ïŒæ ¹æ®åºæ¯éæ©åéçååšåŒæ
- æ£çŽ¢èœåïŒå¹³è¡¡çŽ¢åŒææ¬åæ¥è¯¢æ§èœ
- çåœåšæç®¡çïŒå·çå犻ãèªåšåœæ¡£
- æ°æ®æµæ°Žçº¿ïŒéé â äŒ èŸ â å€ç â ååš â æ£çŽ¢
- è§£èŠååïŒæ¯äžªé¶æ®µç¬ç«æŒè¿ïŒéè¿éåè§£èŠ
- åå³°å¡«è°·ïŒKafka æäœå³°åŒïŒäžæžžæè奿¶è޹
- å·çå犻ïŒçæ°æ®é«æ§èœïŒå·æ°æ®äœææ¬
- è®°åœæä»·åŒçä¿¡æ¯ïŒäžèŠè®°æµæ°ŽèŽŠ
- ç»æåæ¥å¿ïŒäŸ¿äºæºåšå€ç
- éŸè·¯è¿œèžªïŒäž²è宿Žè¯·æ±
- åçå级ïŒåšæè°æŽ
- å®å šè±æïŒä¿æ€éç§
- åèŠæ¶æïŒé¿å åèŠé£æŽ
- æ¹éåå ¥ïŒæååå
- åŒæ¥åå ¥ïŒé¿å é»å¡äžå¡
- å·çå犻ïŒéäœååšææ¬
- æ¥è¯¢äŒåïŒåå°èµæºæ¶è
å¥œçæ¥å¿ç³»ç»å°±åæ¯ç³»ç»ç"é»å£å"ââåžææ°žè¿çšäžå°å®ïŒäœåœéèŠæ¶ïŒå®èœæäœ çåœã
- ç³»åäž Â· 第1ç¯ïŒæå¡æ³šåäžåç°
- ç³»åäž Â· 第2ç¯ïŒèŽèœœåè¡¡
- ç³»åäž Â· 第3ç¯ïŒé 眮äžå¿
- ç³»åäž Â· 第4ç¯ïŒæ¥å¿ç³»ç»ïŒæ¬æïŒ
- ç³»åäž Â· 第5ç¯ïŒæå¡çœå ³ïŒåŸ ç»ïŒ
ð¬ è¯è®º (0)