diff --git a/ReadMe.md b/ReadMe.md index 6aabce3..84572da 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -30,6 +30,8 @@

+

+ # Java基础 ## 基础知识 @@ -394,6 +396,25 @@ todo # 消æ�¯é˜Ÿåˆ— ## Kafka +* [消æ�¯é˜Ÿåˆ—kafka详解:Kafka快速上手(Java版)](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafka快速上手(Java版).md) +* [消æ�¯é˜Ÿåˆ—kafka详解:Kafka一æ�¡æ¶ˆæ�¯å­˜åˆ°broker的过程](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafka一æ�¡æ¶ˆæ�¯å­˜åˆ°broker的过程.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:消æ�¯é˜Ÿåˆ—kafka详解:Kafka介ç»�](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafka介ç»�.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:Kafka原ç�†åˆ†æž�总结篇](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafka原ç�†åˆ†æž�总结篇.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:Kafka常è§�命令å�Šé…�置总结](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafka常è§�命令å�Šé…�置总结.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:Kafka架构介ç»�](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafka架构介ç»�.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:Kafka的集群工作原ç�†](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafka的集群工作原ç�†.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:Kafkaé‡�è¦�知识点+é�¢è¯•题大全](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafkaé‡�è¦�知识点+é�¢è¯•题大全.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:如何实现延迟队列](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:如何实现延迟队列.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:如何实现死信队列](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:如何实现死信队列.md) + +## RocketMQ +* [RocketMQ系列:事务消æ�¯ï¼ˆæœ€ç»ˆä¸€è‡´æ€§ï¼‰](docs/mq/RocketMQ/RocketMQ系列:事务消æ�¯ï¼ˆæœ€ç»ˆä¸€è‡´æ€§ï¼‰.md) +* [RocketMQ系列:基本概念](docs/mq/RocketMQ/RocketMQ系列:基本概念.md) +* [RocketMQ系列:广播与延迟消æ�¯](docs/mq/RocketMQ/RocketMQ系列:广播与延迟消æ�¯.md) +* [RocketMQ系列:批é‡�å�‘é€�与过滤](docs/mq/RocketMQ/RocketMQ系列:批é‡�å�‘é€�与过滤.md) +* [RocketMQ系列:消æ�¯çš„生产与消费](docs/mq/RocketMQ/RocketMQ系列:消æ�¯çš„生产与消费.md) +* [RocketMQ系列:环境æ�­å»º](docs/mq/RocketMQ/RocketMQ系列:环境æ�­å»º.md) +* [RocketMQ系列:顺åº�消费](docs/mq/RocketMQ/RocketMQ系列:顺åº�消费.md) # 大å�Žç«¯ * [å�Žç«¯æŠ€æœ¯æ�‚谈开篇:云计算,大数æ�®ä¸ŽAI的故事](docs/backend/å�Žç«¯æŠ€æœ¯æ�‚谈开篇:云计算,大数æ�®ä¸ŽAI的故事.md) diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudConfig.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudConfig.md" index 67c9c5a..cb6a94c 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudConfig.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudConfig.md" @@ -821,4 +821,13 @@ config: 4\. ʹÓÃä¯ÀÀÆ÷ÔٴηÃÎÊ¡°http://localhost:3366/getConfig¡±£¬½á¹ûÈçÏÂͼ¡£ ![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/10194222Y-15.png) -ͼ17£ºSpring Cloud Bus ¶¨µã֪ͨ \ No newline at end of file +ͼ17£ºSpring Cloud Bus ¶¨µã֪ͨ + + +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudConsul.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudConsul.md" index 730cda5..85fcf19 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudConsul.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudConsul.md" @@ -239,3 +239,10 @@ Spring Cloud Consul # ÏîĿԴÂëµØÖ· https://github.com/macrozheng/springcloud-learning +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudEureka.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudEureka.md" index b1a2d68..960e5c7 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudEureka.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudEureka.md" @@ -1041,4 +1041,12 @@ enable-self-preservation: false # false ÔÚͼ 11 ÖÐ £¬Äú¿ÉÒÔ¿´µ½ÒÔÏÂÄÚÈÝ£º * ÔÚ DS Replicas Ñ¡ÏîÉÏÃæ³öÏÖÁ˺ìÉ«¾¯¸æÐÅÏ¢¡°EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.¡±£¬³öÏÖ¸ÃÐÅÏ¢±íÃ÷ Eureka µÄ×ÔÎÒ±£»¤»úÖÆ´¦ÓÚ¿ªÆô״̬£¬ÇÒÒѾ­±»´¥·¢¡£ -* micro-service-cloud-provider-dept-8001 µÄ·þÎñÐÅÏ¢ÒÀÈ»±£´æ Eureka Server ·þÎñ×¢²á±íÖУ¬²¢Î´±»ÒƳý¡£ \ No newline at end of file +* micro-service-cloud-provider-dept-8001 µÄ·þÎñÐÅÏ¢ÒÀÈ»±£´æ Eureka Server ·þÎñ×¢²á±íÖУ¬²¢Î´±»ÒƳý¡£ + +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudGateway.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudGateway.md" index 8b7ad04..e99968d 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudGateway.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudGateway.md" @@ -496,9 +496,18 @@ eureka: 2\. ÖØÆô```micro-service-cloud-gateway-9527£¬Ê¹ÓÃä¯ÀÀÆ÷·ÃÎÊ¡°http://eureka7001.com:9527/dept/list¡±£¬ÎÒÃǻᷢÏÖ·ÃÎʱ¨ 406 ´íÎ󣬿ØÖÆÌ¨Êä³öÈçÏ¡£ ```2021-10-21 16:25:39.450 INFO 19116 --- [ctor-http-nio-4] net.biancheng.c.filter.MyGlobalFilter : Thu Oct 21 16:25:39 CST 2021½øÈë×Ô¶¨ÒåµÄÈ«¾Ö¹ýÂËÆ÷ MyGlobalFilter -2021-10-21 16:25:39.451 INFO 19116 --- [ctor-http-nio-4] net.biancheng.c.filter.MyGlobalFilter : ²ÎÊý uname ²»ÄÜΪ null£¡``` +2021-10-21 16:25:39.451 INFO 19116 --- [ctor-http-nio-4] net.biancheng.c.filter.MyGlobalFilter : ²ÎÊý uname ²»ÄÜΪ null£¡ +``` 3\. ʹÓÃä¯ÀÀÆ÷·ÃÎÊ¡°http://eureka7001.com:9527/dept/list?uname=123¡±,½á¹ûÈçÏÂͼ¡£ ![×Ô¶¨ÒåÈ«¾ÖÍø¹Ø¹ýÂËÆ÷](http://c.biancheng.net/uploads/allimg/211210/101P43096-6.png) -ͼ7£º×Ô¶¨ÒåÈ«¾ÖÍø¹Ø¹ýÂËÆ÷ \ No newline at end of file +ͼ7£º×Ô¶¨ÒåÈ«¾ÖÍø¹Ø¹ýÂËÆ÷ + +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudHystrix.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudHystrix.md" index adddc7d..1a26d68 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudHystrix.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudHystrix.md" @@ -1109,4 +1109,12 @@ public class HystrixDashboardConfig { 8\. ʹÓÃä¯ÀÀÆ÷¶à´Î·ÃÎÊ¡°http://eureka7001.com:8004/dept/hystrix/circuit/1¡±ºÍ ¡°http://eureka7001.com:8004/dept/hystrix/circuit/-1¡±£¬²é¿´ Hystrix ¼à¿ØÒ³Ã棬ÈçÏÂͼ¡£ ![Hystrix ¼à¿Ø 8004 ÔËÐÐÇé¿ö](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/10162345J-15.png) -ͼ16£ºHystrix ¼à¿Ø·þÎñÔËÐÐÇé¿ö \ No newline at end of file +ͼ16£ºHystrix ¼à¿Ø·þÎñÔËÐÐÇé¿ö + +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudLoadBalancer.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudLoadBalancer.md" index 9289412..1a35579 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudLoadBalancer.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudLoadBalancer.md" @@ -336,3 +336,11 @@ LoadBalancerΪ # ÏîĿԴÂëµØÖ· https://github.com/macrozheng/springcloud-learning/tree/master/nacos-loadbalancer-service + +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudOpenFeign.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudOpenFeign.md" index d2e6a26..50c14d5 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudOpenFeign.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudOpenFeign.md" @@ -479,4 +479,11 @@ Logger.Level 2021-10-12 14:33:07.983 DEBUG 13388 --- [p-nio-80-exec-2] n.biancheng.c.service.DeptFeignService : [DeptFeignService#list] 2021-10-12 14:33:07.991 DEBUG 13388 --- [p-nio-80-exec-2] n.biancheng.c.service.DeptFeignService : [DeptFeignService#list] [{"deptNo":1,"deptName":"¿ª·¢²¿","dbSource":"bianchengbang_jdbc"},{"deptNo":2,"deptName":"ÈËʲ¿","dbSource":"bianchengbang_jdbc"},{"deptNo":3,"deptName":"²ÆÎñ²¿","dbSource":"bianchengbang_jdbc"},{"deptNo":4,"deptName":"Êг¡²¿","dbSource":"bianchengbang_jdbc"},{"deptNo":5,"deptName":"ÔËά²¿","dbSource":"bianchengbang_jdbc"}] 2021-10-12 14:33:07.991 DEBUG 13388 --- [p-nio-80-exec-2] n.biancheng.c.service.DeptFeignService : [DeptFeignService#list] <--- END HTTP (341-byte body)``` -``` \ No newline at end of file +``` +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudRibbon.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudRibbon.md" index 7d3f979..74eff0a 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudRibbon.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudRibbon.md" @@ -654,4 +654,12 @@ public class MicroServiceCloudConsumerDept80Application { ![¶¨ÖƸºÔؾùºâ²ßÂÔ](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/10122152E-5.gif) ͼ6£º¶¨ÖƸºÔؾùºâ²ßÂÔ -ͨ¹ýͼ 6 ÖÐ dbSource ×Ö¶ÎȡֵµÄ±ä»¯¿ÉÒÔ¿´³ö£¬ÎÒÃǶ¨ÖƵĸºÔؾùºâ²ßÂÔÒѾ­ÉúЧ¡£ \ No newline at end of file +ͨ¹ýͼ 6 ÖÐ dbSource ×Ö¶ÎȡֵµÄ±ä»¯¿ÉÒÔ¿´³ö£¬ÎÒÃǶ¨ÖƵĸºÔؾùºâ²ßÂÔÒѾ­ÉúЧ¡£ + +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudSleuth.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudSleuth.md" index e3f2000..45bc82f 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudSleuth.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudSleuth.md" @@ -131,4 +131,12 @@ springcloud-learning ## [#](https://www.macrozheng.com/cloud/sleuth.html#%E9%A1%B9%E7%9B%AE%E6%BA%90%E7%A0%81%E5%9C%B0%E5%9D%80)ÏîĿԴÂëµØÖ· -[https://github.com/macrozheng/springcloud-learning](https://github.com/macrozheng/springcloud-learning) \ No newline at end of file +[https://github.com/macrozheng/springcloud-learning](https://github.com/macrozheng/springcloud-learning) + +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudZuul.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudZuul.md" index 7bca86e..9040110 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudZuul.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloudZuul.md" @@ -384,3 +384,9 @@ Zuul #ÏîĿԴÂëµØÖ· https://github.com/macrozheng/springcloud-learning +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloud\346\246\202\350\277\260.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloud\346\246\202\350\277\260.md" index fb27ab5..a525595 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloud\346\246\202\350\277\260.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud/SpringCloud\346\246\202\350\277\260.md" @@ -134,4 +134,10 @@ Spring Boot ¡­¡­ } -```` \ No newline at end of file +```` +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudAlibabaNacos\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\234\215\345\212\241\346\263\250\345\206\214.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudAlibabaNacos\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\234\215\345\212\241\346\263\250\345\206\214.md" index 3569058..1a59865 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudAlibabaNacos\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\234\215\345\212\241\346\263\250\345\206\214.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudAlibabaNacos\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\234\215\345\212\241\346\263\250\345\206\214.md" @@ -346,4 +346,12 @@ task Ò²¾ÍÊÇÔÚ¶ÔÏó³õʼ»¯µÄʱºò¾Í½øÐÐÆô¶¯Ò»¸öÏ̳߳أ¬È¥ÔËÐÐnotifier¶ÔÓ¦µÄ·½·¨¡£Õâ¸örun·½·¨¾ÍÊÇÕâÑùrunµÄ¡£Æô¶¯ºó¾Í»áʵʱ¼àÌýÒì²½¶ÓÁС£ÕâÑùдµÄºÃ´¦£¬¾ÍÊǽ«Ð´ºÍ´¦ÀíÍêÈ«¸ôÀëÁË¡£Í¨¹ý¼àÌý¸ßÐÔÄܵÄÄÚ´æ¶ÓÁУ¬À´´¦ÀíÕâ¸öÊÂÇ飬ËûÕâÑùµÄºÃ´¦£¬1¡¢Ìá¸ßÐÔÄÜ -![image.png](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/e27c8e72b30845c3ab9346b89932fb42.png "image.png") \ No newline at end of file +![image.png](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/e27c8e72b30845c3ab9346b89932fb42.png "image.png") + +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudAlibabaNacos\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\246\202\350\247\210.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudAlibabaNacos\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\246\202\350\247\210.md" index 0bc283c..dc517a0 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudAlibabaNacos\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\246\202\350\247\210.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudAlibabaNacos\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\246\202\350\247\210.md" @@ -491,4 +491,11 @@ NACOS µ±È»£¬Ò²»á´æÔÚһЩ²»¿ÉºöÊÓµÄȱµã£¬±ÈÈ磬עÊ͹ýÉÙ£¬´úÂ뻹ÓкܴóµÄÖØ¹¹¿Õ¼ä£¬tenantºÍnamespaceÁ½¸ö¸ÅÄî»ìÏýʹÓᣠ-¹ØÓÚSpring Cloud Alibaba NacosµÄ½éÉܵ½´Ë¾Í½áÊøÁË£¬Ï£Íû¶ÔÄãÓÐËù°ïÖú¡£ \ No newline at end of file +¹ØÓÚSpring Cloud Alibaba NacosµÄ½éÉܵ½´Ë¾Í½áÊøÁË£¬Ï£Íû¶ÔÄãÓÐËù°ïÖú¡£ +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudAlibabaNacos\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\351\205\215\347\275\256\344\270\255\345\277\203.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudAlibabaNacos\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\351\205\215\347\275\256\344\270\255\345\277\203.md" index 2ed31c8..7515d8b 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudAlibabaNacos\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\351\205\215\347\275\256\344\270\255\345\277\203.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudAlibabaNacos\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\351\205\215\347\275\256\344\270\255\345\277\203.md" @@ -256,4 +256,11 @@ public class ConfigServerDemo { ×÷ÕߣºÕþ²ÉÔÆµç×ÓÂô³¡ÍÅ¶Ó Á´½Ó£ºhttps://juejin.cn/post/6999814668390760484 À´Ô´£ºÏ¡ÍÁ¾ò½ð -Öø×÷Ȩ¹é×÷ÕßËùÓС£ÉÌÒµ×ªÔØÇëÁªÏµ×÷Õß»ñµÃÊÚȨ£¬·ÇÉÌÒµ×ªÔØÇë×¢Ã÷³ö´¦¡£ \ No newline at end of file +Öø×÷Ȩ¹é×÷ÕßËùÓС£ÉÌÒµ×ªÔØÇëÁªÏµ×÷Õß»ñµÃÊÚȨ£¬·ÇÉÌÒµ×ªÔØÇë×¢Ã÷³ö´¦¡£ +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudRocketMQ\346\272\220\347\240\201\345\210\206\346\236\220.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudRocketMQ\346\272\220\347\240\201\345\210\206\346\236\220.md" index 35fcfef..9be0e22 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudRocketMQ\346\272\220\347\240\201\345\210\206\346\236\220.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudRocketMQ\346\272\220\347\240\201\345\210\206\346\236\220.md" @@ -524,4 +524,11 @@ public synchronized void start() throws MQClientException { ×÷Õߣº·ãÒ¶ºì»¨ Á´½Ó£ºhttps://www.jianshu.com/p/8dd4cfeae39d À´Ô´£º¼òÊé -Öø×÷Ȩ¹é×÷ÕßËùÓС£ÉÌÒµ×ªÔØÇëÁªÏµ×÷Õß»ñµÃÊÚȨ£¬·ÇÉÌÒµ×ªÔØÇë×¢Ã÷³ö´¦¡£ \ No newline at end of file +Öø×÷Ȩ¹é×÷ÕßËùÓС£ÉÌÒµ×ªÔØÇëÁªÏµ×÷Õß»ñµÃÊÚȨ£¬·ÇÉÌÒµ×ªÔØÇë×¢Ã÷³ö´¦¡£ +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudSeata\346\272\220\347\240\201\345\210\206\346\236\220.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudSeata\346\272\220\347\240\201\345\210\206\346\236\220.md" index 1287eef..19ce963 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudSeata\346\272\220\347\240\201\345\210\206\346\236\220.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudSeata\346\272\220\347\240\201\345\210\206\346\236\220.md" @@ -994,4 +994,12 @@ public BranchStatus branchRollback(BranchType branchType, String xid, long branc -×îÖջعö·½·¨µ÷ÓõÄÊÇUndoLogManager.undo(dataSourceProxy, xid, branchId);![SpringCloud AlibabaϵÁСª¡ª17Seata ATģʽԴÂë·ÖÎö£¨Ï£©-¿ªÔ´»ù´¡Èí¼þÉçÇø](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/4842a0701546824cf2720855d8310a1274c576.jpg "SpringCloud AlibabaϵÁСª¡ª17Seata ATģʽԴÂë·ÖÎö£¨Ï£©-¿ªÔ´»ù´¡Èí¼þÉçÇø")ÅжÏundologÊÇ·ñ´æÔÚ£¬´æÔÚÔòɾ³ý¶ÔÓ¦undolog£¬²¢Ò»ÆðÌá½»£¬µ½´ËseataµÄATģʽԴÂë½âÎöÍê±Ï¡£ \ No newline at end of file +×îÖջعö·½·¨µ÷ÓõÄÊÇUndoLogManager.undo(dataSourceProxy, xid, branchId);![SpringCloud AlibabaϵÁСª¡ª17Seata ATģʽԴÂë·ÖÎö£¨Ï£©-¿ªÔ´»ù´¡Èí¼þÉçÇø](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/4842a0701546824cf2720855d8310a1274c576.jpg "SpringCloud AlibabaϵÁСª¡ª17Seata ATģʽԴÂë·ÖÎö£¨Ï£©-¿ªÔ´»ù´¡Èí¼þÉçÇø")ÅжÏundologÊÇ·ñ´æÔÚ£¬´æÔÚÔòɾ³ý¶ÔÓ¦undolog£¬²¢Ò»ÆðÌá½»£¬µ½´ËseataµÄATģʽԴÂë½âÎöÍê±Ï¡£ + +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudSentinel\346\272\220\347\240\201\345\210\206\346\236\220.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudSentinel\346\272\220\347\240\201\345\210\206\346\236\220.md" index 0d6c22c..9fc4976 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudSentinel\346\272\220\347\240\201\345\210\206\346\236\220.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloudAlibaba\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudSentinel\346\272\220\347\240\201\345\210\206\346\236\220.md" @@ -650,3 +650,10 @@ public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudConfig\346\272\220\347\240\201\345\210\206\346\236\220.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudConfig\346\272\220\347\240\201\345\210\206\346\236\220.md" index 60d1f61..4ae8cc8 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudConfig\346\272\220\347\240\201\345\210\206\346\236\220.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudConfig\346\272\220\347\240\201\345\210\206\346\236\220.md" @@ -1038,4 +1038,12 @@ if (!remoteProperties.isAllowOverride() || (!remoteProperties.isOverrideNone() ×÷ÕߣºÓµ±§¹Â¶À_to Á´½Ó£ºhttps://www.jianshu.com/p/60c6ab0e79d5 À´Ô´£º¼òÊé -Öø×÷Ȩ¹é×÷ÕßËùÓС£ÉÌÒµ×ªÔØÇëÁªÏµ×÷Õß»ñµÃÊÚȨ£¬·ÇÉÌÒµ×ªÔØÇë×¢Ã÷³ö´¦¡£ \ No newline at end of file +Öø×÷Ȩ¹é×÷ÕßËùÓС£ÉÌÒµ×ªÔØÇëÁªÏµ×÷Õß»ñµÃÊÚȨ£¬·ÇÉÌÒµ×ªÔØÇë×¢Ã÷³ö´¦¡£ + +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudEureka\346\272\220\347\240\201\345\210\206\346\236\220.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudEureka\346\272\220\347\240\201\345\210\206\346\236\220.md" index 8ad8c31..0236a13 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudEureka\346\272\220\347\240\201\345\210\206\346\236\220.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudEureka\346\272\220\347\240\201\345\210\206\346\236\220.md" @@ -1773,4 +1773,12 @@ Value getValue(final Key key, boolean useReadOnlyCache) { } return payload; } -``` \ No newline at end of file +``` + +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudGateway\346\272\220\347\240\201\345\210\206\346\236\220.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudGateway\346\272\220\347\240\201\345\210\206\346\236\220.md" index 9a6c22c..80db850 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudGateway\346\272\220\347\240\201\345\210\206\346\236\220.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudGateway\346\272\220\347\240\201\345\210\206\346\236\220.md" @@ -404,4 +404,12 @@ public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 6\. Ö´ÐйýÂËÆ÷Á´ÖÐµÄÆäËû¹ýÂËÇëÇó return chain.filter(exchange); } -``` \ No newline at end of file +``` + +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudHystrix\346\272\220\347\240\201\345\210\206\346\236\220.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudHystrix\346\272\220\347\240\201\345\210\206\346\236\220.md" index c9323b5..87b59fb 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudHystrix\346\272\220\347\240\201\345\210\206\346\236\220.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudHystrix\346\272\220\347\240\201\345\210\206\346\236\220.md" @@ -1183,5 +1183,10 @@ circuitBreaker.allowRequest() ×îÖÕµ÷Óõ½ÎÒÃÇ×Ô¼ºµÄÒµÎñÂß¼­¡£ - -ÏÂÃæ×ܽáÒ»ÏÂÎÒÃÇÕûÌåµÄÒµÎñÂß¼­Í¼£º +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudLoadBalancer\346\272\220\347\240\201\345\210\206\346\236\220.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudLoadBalancer\346\272\220\347\240\201\345\210\206\346\236\220.md" index 9704860..f66f6ba 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudLoadBalancer\346\272\220\347\240\201\345\210\206\346\236\220.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudLoadBalancer\346\272\220\347\240\201\345\210\206\346\236\220.md" @@ -659,4 +659,12 @@ public class CustomLoadBalancerConfiguration { ![image-20220509003807968](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/c72e3f02f7e0d5d3343f8ae9c464b69c.png) -![image-20220509003927550](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/59796bbbd6b3524e32759d42b622f1bc.png) \ No newline at end of file +![image-20220509003927550](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/59796bbbd6b3524e32759d42b622f1bc.png) + +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudOpenFeign\346\272\220\347\240\201\345\210\206\346\236\220.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudOpenFeign\346\272\220\347\240\201\345\210\206\346\236\220.md" index 7a54f90..17db744 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudOpenFeign\346\272\220\347\240\201\345\210\206\346\236\220.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudOpenFeign\346\272\220\347\240\201\345\210\206\346\236\220.md" @@ -893,3 +893,10 @@ Response convertResponse(HttpURLConnection connection, Request request) throws I +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudRibbon\346\272\220\347\240\201\345\210\206\346\236\220.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudRibbon\346\272\220\347\240\201\345\210\206\346\236\220.md" index 57606b3..d06f945 100644 --- "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudRibbon\346\272\220\347\240\201\345\210\206\346\236\220.md" +++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringCloud\346\272\220\347\240\201\345\210\206\346\236\220/SpringCloudRibbon\346\272\220\347\240\201\345\210\206\346\236\220.md" @@ -944,4 +944,12 @@ public interface ServerList { getInitialListOfServersÊÇ»ñÈ¡³õʼ»¯µÄ·þÎñÁÐ±í¡£ getUpdatedListOfServersÊÇ»ñÈ¡¸üеķþÎñÁÐ±í¡£ ServerListÓжà¸öʵÏÖÀ࣬¾ßÌåÓõÄÄĸöÄØ£¬¿ÉÒÔÔÚ -EurekaRibbonClientConfigurationÀàÖÐÕÒµ½£¬ÕâÊÇRibbonºÍEureka½áºÏµÄ×Ô¶¯ÅäÖÃÀ࣬µ«ÊÇĿǰÎÒÃÇûÓÐÕûºÏEureka£¬ÊÇͨ¹ýÅäÖÃÎļþÅäÖã¬ËùÒÔ»á×ßConfigurationBasedServerListÀà¡£ \ No newline at end of file +EurekaRibbonClientConfigurationÀàÖÐÕÒµ½£¬ÕâÊÇRibbonºÍEureka½áºÏµÄ×Ô¶¯ÅäÖÃÀ࣬µ«ÊÇĿǰÎÒÃÇûÓÐÕûºÏEureka£¬ÊÇͨ¹ýÅäÖÃÎļþÅäÖã¬ËùÒÔ»á×ßConfigurationBasedServerListÀà¡£ + +# ²Î¿¼ÎÄÕ +https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF +https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA +https://juejin.cn/post/6931922457741770760 +https://github.com/D2C-Cai/herring +http://c.biancheng.net/springcloud +https://github.com/macrozheng/springcloud-learning \ No newline at end of file diff --git a/docs/monitor/Spring Actuator.md b/docs/monitor/Spring Actuator.md new file mode 100644 index 0000000..a1ee5ef --- /dev/null +++ b/docs/monitor/Spring Actuator.md @@ -0,0 +1,578 @@ +## ǰÑÔ + +ÔÚ΢·þÎñϵͳ¼Ü¹¹ÖУ¬·þÎñµÄ¼à¿ØÊDZز»¿ÉÉٵġ£Ä¿Ç°´ó¶àÊý΢·þÎñÓ¦ÓÃÓÖÊÇ»ùÓÚSpring CloudϵÁУ¬Ò²¿ÉÒÔ˵ÊÇ»ùÓÚSpring BootϵÁеġ£´ËʱʹÓÃSpring Boot ActuatorÀ´½øÐÐ΢·þÎñµÄ¼à¿Ø£¬²»½ö¹¦ÄÜÈ«Ãæ£¬¶øÇҷdz£·½±ã¡£ + +ÔÚÉÏÆªÎÄÕ¡¶[Spring Boot Actuator¼¯³É£¬ÄѵÄÊÇÁé»îÔËÓã¡](https://link.juejin.cn?target=https%3A%2F%2Fmp.weixin.qq.com%2Fs%2FBaNQWygQb8UXxktrXetOcw "https://mp.weixin.qq.com/s/BaNQWygQb8UXxktrXetOcw")¡·ÖÐÎÒÃÇÒѾ­½éÉÜÁËÈçºÎ½«Actuator¼¯³Éµ½Spring BootÏîÄ¿ÖУ¬²¢ÇÒ½éÉÜÁËÈçºÎ×Ô¶¨ÒåEndpoint£¨¶Ëµã£©¡£ÓÐÅóÓÑÁôÑÔ˵²»¹»ÉîÈ룬ÄÇô£¬±¾ÆªÎÄÕÂÄØ£¬ÎÒÃǽ«½éÉÜActuatorÔ­Éú¶ËµãµÄ¹¦Äܼ°»ù±¾Ê¹Óó¡¾°¡£ + +## Endpoints ½éÉÜ + +ActuatorÖÐËùνµÄ Endpoints £¨·­ÒëΪ¶Ëµã£©ÌṩÁËÍⲿÀ´ÓëÓ¦ÓóÌÐò½øÐзÃÎʺͽ»»¥µÄ¹¦ÄÜ¡£ ±ÈÈç˵/health¶ËµãÌṩÁËÓ¦Óý¡¿µÇé¿öµÄÐÅÏ¢£¬metrics ¶ËµãÌṩÁËÓ¦ÓóÌÐòµÄÖ¸±ê£¨JVM ÄÚ´æÊ¹Óá¢ÏµÍ³CPUʹÓõȣ©ÐÅÏ¢¡£ + +ActuatorÔ­ÉúµÄ¶Ëµã¿É·ÖΪÈý´óÀࣺ + +* Ó¦ÓÃÅäÖÃÀࣺ»ñȡӦÓóÌÐòÖмÓÔØµÄÓ¦ÓÃÅäÖᢻ·¾³±äÁ¿¡¢×Ô¶¯»¯ÅäÖñ¨¸æµÈÓëSpring BootÓ¦ÓÃÃÜÇÐÏà¹ØµÄÅäÖÃÀàÐÅÏ¢¡£ +* ¶ÈÁ¿Ö¸±êÀࣺ»ñȡӦÓóÌÐòÔËÐйý³ÌÖÐÓÃÓÚ¼à¿ØµÄ¶ÈÁ¿Ö¸±ê£¬±ÈÈ磺ÄÚ´æÐÅÏ¢¡¢Ï̳߳ØÐÅÏ¢¡¢HTTPÇëÇóͳ¼ÆµÈ¡£ +* ²Ù×÷¿ØÖÆÀࣺÌṩÁ˶ÔÓ¦ÓõĹرյȲÙ×÷À๦ÄÜ¡£ + +²»Í¬°æ±¾µÄActuatorÌṩµÄÔ­Éú¶ËµãÓÐËù³öÈ룬ÔÚʹÓõĹý³ÌÖÐ×îºÃÒÔËùʹÓð汾µÄ¹Ù·½ÎĵµÎª×¼¡£Í¬Ê±£¬Ã¿¸öÔ­ÉúµÄ¶Ëµã¶¼¿ÉÒÔͨ¹ýÅäÖÃÀ´µ¥¶ÀµÄ½ûÓûòÆôÓᣠ+ +¶øÔÚActuator 2.x ÖÐĬÈ϶˵ãÔö¼ÓÁË/actuatorǰ׺£¬Í¬Ê±Ä¬ÈÏÖ»±©Â¶µÄÁ½¸ö¶ËµãΪ/actuator/healthºÍ /actuator/info¡£¹ØÓڶ˵㱩¶µÄÅäÖ㬿ɲο¼Ç°Ò»ÆªÎÄÕ¡£ÏÂÃæ»ùÓÚSpring Boot 2.2.2.RELEASE°æ±¾À´Öص㽲½âÿ¸ö¶ËµãµÄ¹¦ÄܺÍÓ¦Óó¡¾°¡£ + +## actuator¶Ëµã + +Actuator 2.xÐÂÔöµÄĬÈ϶˵㣬ÓÃÓÚչʾĿǰӦÓÃÖб©Â¶³öÀ´µÄ¶Ëµã»ã×Ü£¬Äã¿ÉÒÔÀí½âΪ¿ÉÓö˵ãµÄĿ¼¡£ + +·ÃÎÊURL£º[http://localhost:8080/actuator](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator "http://localhost:8080/actuator") £¬¶ÔӦչʾ½á¹ûÈçÏÂͼ£º + +![image-20230530233537559](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530233537559.png) + +ÉÏÊöֻչʾÁËÒ»²¿·ÖµÄ¶Ëµã£¬·µ»Ø½á¹ûΪ£¬ÕâÀï²ÉÓÃÁËä¯ÀÀÆ÷µÄ²å¼þ-Handler½øÐÐÁ˸ñʽÃÀ»¯¡£Í¨¹ýactuator¿ÉÒÔÖ±¹ÛµÄ¿´³öĿǰ¿ª·ÅÁËÄÄЩ¶Ëµã£¬ÒÔ¼°ÕâЩ¶ËµãµÄÃû³ÆºÍÇëÇó·¾¶¡£ + +ÏÂÃæÎÒÃǾͰ´ÕÕÏÔʾactuator¶ËµãչʾµÄÁбíÖðÒ»½éÉÜ¡£ + +## auditevents¶Ëµã + +auditevents¶ËµãÓÃÓÚÏÔʾӦÓñ©Â¶µÄÉó¼ÆÊ¼þ (±ÈÈçÈÏÖ¤½øÈë¡¢¶©µ¥Ê§°Ü)£¬¼´Ê¹ÎÒÃÇ´ò¿ªÁËËùÓж˵㣬ĬÈÏÇé¿öÏÂÒ²ÊÇ¿´²»µ½Õâ¸ö¶ËµãµÄ¡£ÒòΪʹÓÃËüµÄǰÌáÊÇÐèÒªÔÚSpringÈÝÆ÷ÖдæÔÚÒ»¸öÀàÐÍΪAuditEventRepositoryµÄBeanµÄ¡£ + +²é¿´ÁËÍøÂçÉÏ´ó¶àÊý½Ì³Ì£¬»ù±¾É϶¼ÊǽéÉÜÁËauditevents¶Ëµã¹¦ÄÜ£¬¶øÎ´Õ¹Ê¾¾ßÌåʵÀý¡£±ÊÕß¾­¹ý¶à·½³¢ÊÔ£¬ÖÕÓÚ¸ø´ó¼ÒдÁËÒ»¸ö°¸Àý³öÀ´¡£ + +Ê×ÏÈÉæ¼°µ½È¨ÏÞÈÏÖ¤£¬ÐèÒªÏÈÒýÈëspring-boot-starter-securityÒÀÀµ£º + +```` + + org.springframework.boot + spring-boot-starter-security +` +```` + +µ¥´¿Ìí¼ÓÕâ¸öÒÀÀµ»¹ÊDz»¹»µÄ£¬»¹ÐèÒª¼ÓÈësecurityµÄÅäÖ㬲»È»AuthorizationAuditListener,AuthenticationAuditListener ¼àÌýʲôʼþÄØ? Òò´Ë,ÎÒÃǼÓÈëÈçÏ´úÂ룺 + + +```` +@Configuration +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + + auth.inMemoryAuthentication() + .withUser("admin") + .password(bcryptPasswordEncoder().encode("admin")) + .roles("admin"); + } +```` + +```` + @Bean + public PasswordEncoder bcryptPasswordEncoder() { + return new BCryptPasswordEncoder(); + } +} +```` + +ÕâÀï²ÉÓÃÁËsecurityĬÈϵĵǼ½çÃæºÍȨÏÞ¿ØÖÆ£¬Ò²¾ÍÊÇ˵ËùÓеķÃÎʶ¼ÐèÒª½øÐеǼ¡£¶øµÇ¼µÄÓû§ÃûºÍÃÜÂë¾ùΪadmin¡£ + +ÁíÍâ£¬Ç°ÃæÌáµ½ÐèÒªÓõ½AuditEventRepositoryµÄBean£¬ÕâÀï³õʼ»¯Ò»¸ö¶ÔÓ¦µÄBean£º + + + + +```` +@Configuration +public class AuditEventConfig { + + @Bean + public InMemoryAuditEventRepository repository(){ + return new InMemoryAuditEventRepository(); + } +} +```` + +InMemoryAuditEventRepositoryÊÇAuditEventRepository½Ó¿ÚµÄΨһʵÏÖÀà¡£ + +ÖØÆôÏîÄ¿£¬auditevents¶Ëµã±ã¿ÉÓÃÁË¡£·ÃÎÊ[http://localhost:8080/actuator](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator "http://localhost:8080/actuator") ,´Ëʱ»áÌø×ªµ½SecurityÌṩµÄµÇÂ¼Ò³Ãæ£º + +![image-20230530233604253](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530233604253.png) + +ÊäÈë´úÂëÖÐÖ¸¶¨µÄÓû§ÃûºÍÃÜÂ룬µÇ¼³É¹¦£¬Ìø×ªµ½/actuatorÒ³Ãæ£º + +![image-20230530233625068](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530233625068.png) + +¿ÉÒÔ¿´µ½auditevents¶ËµãÒѾ­³É¹¦ÏÔʾ³öÀ´ÁË¡£Ð¿ªÒ³Ãæ·ÃÎÊ[http://localhost:8080/actuator/auditevents](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fauditevents "http://localhost:8080/actuator/auditevents") £¬Õ¹Ê¾ÄÚÈÝÈçÏ£º + +![image-20230530233716752](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530233716752.png) + +¿ÉÒÔ¿´µ½ÒѾ­¼Ç¼ÏÂÁËȨÏÞÏà¹ØµÄʼþ£¬ÆäÖеÚÒ»´ÎʼþÊÇÎÒÃÇÖ±½Ó·ÃÎÊactuator¶Ëµãʱ£¬ÓÉÓÚ֮ǰΪ×öȨÏÞÈÏÕæ£¬ËùÒÔʼþÀàÐÍΪ"AUTHORIZATION_FAILURE"£¬Ò²¾ÍÊÇÈÏ֤ʧ°Ü¡£´ËÊ±Ìø×ªµ½µÇÂ¼Ò³Ãæ£¬È»ºóÔÚµÇÂ¼Ò³ÃæÊäÈëÓû§ÃûºÍÃÜÂ룬µÇ¼³É¹¦£¬¶ÔÓ¦µÄʼþΪ"AUTHENTICATION_SUCCESS"¡£ + +Ò²¾ÍÊÇ˵auditevents¼Ç¼ÁËÓû§ÈÏÖ¤µÇ¼ϵͳÏà¹ØµÄʼþÐÅÏ¢£¬°üÀ¨Ê±¼ä´Á¡¢ÈÏÖ¤Óû§¡¢Ê¼þÀàÐÍ¡¢·ÃÎʵØÖ·¡¢sessionIdµÈ¡£ + +ʾÀýÔ´ÂëµØÖ·£º[github.com/secbr/sprin¡­](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fsecbr%2Fspringboot-all%2Ftree%2Fmaster%2Fspringboot-actuator-auditevents "https://github.com/secbr/springboot-all/tree/master/springboot-actuator-auditevents") ¡£ + +## beans¶Ëµã + +/beans¶Ëµã»á·µ»ØSpringÈÝÆ÷ÖÐËùÓÐbeanµÄ±ðÃû¡¢ÀàÐÍ¡¢ÊÇ·ñµ¥Àý¡¢ÒÀÀµµÈÐÅÏ¢¡£ + +·ÃÎÊ·¾¶Îª[http://localhost:8080/actuator/beans](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fbeans "http://localhost:8080/actuator/beans") £¬·¶Î§½á¹ûÈçÏ£º + +![image-20230530233748286](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530233748286.png) + +Õâ¸ö¶Ëµã»áչʾĿǰSpringÈÝÆ÷Öгõʼ»¯µÄËùÓÐBean£¬ÊÔÏëһϣ¬Èç¹ûÄãÅäÖÃÁËÒ»¸öBean£¬µ«²»È·¶¨ÊÇ·ñ³É¹¦ÊµÀý»¯£¬ÊDz»ÊǾͿÉÒÔͨ¹ýÕâ¸ö¶Ë¿Ú²éѯһÏÂÄØ£¿ + +ÎÒÃÇÔÚÏîÄ¿Öж¨ÒåÒ»¸öTestController£¬²¢×¢ÈëÒ»¸öUserService£º + + +```` +@Controller +public class TestController { + + @Resource + private UserService userService; +} +```` + +ÖØÐÂÆô¶¯²¢·ÃÎʸö˵㣬»á¿´µ½ÈçÏÂÐÅÏ¢£º + +![image-20230530233805161](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530233805161.png) + +¿ÉÒÔ¿´µ½TestController±»ÊµÀý»¯ÁË£¬¶øÇÒÒÀÀµÓÚUserService¡£ + +## caches¶Ëµã + +caches¶ËµãÖ÷ÒªÓÃÓÚ±©Â¶Ó¦ÓóÌÐòÖеĻº³å¡£ÕâÀïÒÔSpring BootÌṩµÄCache×é¼þÀ´Õ¹Ê¾Ò»ÏÂʵÀý¡£ + +ÔÚÏîÄ¿Öм¯³Éspring-boot-starter-cache£¬ÒýÈëÒÀÀµ£º + + +```` + + org.springframework.boot + spring-boot-starter-cache + +```` + +È»ºóÔÚÆô¶¯ÀàÉÏÌí¼Ó@EnableCaching£¬¿ªÆô»º´æ¹¦ÄÜ¡£ + +¶¨ÒåÒ»¸öCacheController£¬¶ÔÆä·½·¨queryAllʹÓûº´æ»úÖÆ£º + + +```` +@RestController +public class CacheController { + + @RequestMapping("/queryAll") + @Cacheable(value = "queryAll") + public Map queryAll() { + Map map = new HashMap<>(); + map.put("1", "Tom"); + map.put("2", "Steven"); + return map; + } +} +```` + +ÕâÀïʹÓÃ@Cacheable×¢½âÀ´ÊµÏÖ»º´æ¹¦ÄÜ£¬»º´æµÄkeyΪqueryAll¡£´Ëʱ£¬·ÃÎÊ[http://localhost:8080/actuator/caches](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fcaches "http://localhost:8080/actuator/caches") £¬»áչʾ»º´æµÄ¸ùÄÚÈÝ£¬µ«ÀïÃæ²¢Ã»Óлº´æ¡£ + +·ÃÎÊÒ»ÏÂ[http://localhost:8080/queryAll](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2FqueryAll "http://localhost:8080/queryAll") £¬Ò²¾ÍÊÇ´¥·¢Ò»Ï»º´æÄÚÈݵÄÉú³É¡£´ËʱÔÙ·ÃÎÊÉÏÃæµÄÁ´½Ó£¬±ã¿ÉÒÔ¿´µ½Ó¦ÓóÌÐòÖеĻº´æÐÅÏ¢ÁË£º + +![image-20230530233852486](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530233852486.png) + +¿ÉÒÔ¿´µ½£¬·µ»ØµÄÄÚÈݲ»½öչʾÁËÓ¦ÓóÌÐòµÄ»º´æ¹ÜÀíÆ÷£¬Í¬Ê±Ò²Õ¹Ê¾ÁË»º´æµÄKeyºÍ»º´æÊý¾Ý´æ´¢ÀàÐÍÐÅÏ¢¡£ + +## caches-cache¶Ëµã + +caches-cache¶ËµãÊǶÔÉÏÃæcaches¶ËµãµÄÀ©Õ¹£¬caches¶ËµãչʾµÄËùÓеĻº´æÐÅÏ¢¡£Èç¹ûÏëÖ±½Ó¿´³ö¾ßÌåµÄÒ»¸ö»º´æÐÅÏ¢£¬Ôò¿ÉÒÔʹÓÃcaches-cache¶Ëµã¡£ + +·ÃÎʵÄURLΪ£º[http://localhost:8080/actuator/caches/{cache}](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fcaches%2F%257Bcache%257D "http://localhost:8080/actuator/caches/%7Bcache%7D") £¬ÆäÖдóÀ¨ºÅÄÚµÄÖµ¿ÉÒÔÌæ»»Îª»º´æµÄkey¡£ + + + + +`http://localhost:8080/actuator/caches/queryAll` + +½«ÉÏÃæµÄռλ·û»»³ÉqueryAll£¨»º´æµÄkey£©£¬Ö´Ðнá¹ûÈçÏ£º + +![image-20230530233906164](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530233906164.png) + +¿ÉÒÔ¿´³ö£¬Ö»²éѯ³ýÁËÖ¸¶¨µÄ»º´æÐÅÏ¢£¬°üÀ¨»º´æ¹ÜÀíÆ÷¡¢»º´æÃû³Æ£¨key£©£¬»º´æµÄ´æ´¢ÀàÐÍ¡£ + +## health¶Ëµã + +health¶ËµãÓÃÀ´¼ì²éÓ¦ÓõÄÔËÐÐ״̬£¬×î¸ßƵʹÓõÄÒ»¸ö¶Ëµã¡£¼ì²éÓ¦ÓÃʵÀýµÄÔËÐÐ״̬ÒÔ¼°Ó¦Óò»¡±½¡¿µ¡°µÄÔ­Òò£¬±ÈÈçÊý¾Ý¿âÁ¬½Ó¡¢´ÅÅ̿ռ䲻¹»µÈ¡£ + +·ÃÎʵØÖ·£º[http://localhost:8080/actuator/health](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fhealth "http://localhost:8080/actuator/health") + +չʾ½á¹û£º + +`{ +"status": "UP" +}` + +ÉÏÃæµÄʵÀý¹ýÓÚ¼òµ¥£¬ÔÚÏîÄ¿ÖаÑÊý¾Ý¿â¸ø¼¯³É½øÈ¥£º + +` + +```` + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java +` +```` + +È»ºóÔÚapplicationÅäÖÃÎļþÖнøÐÐÅäÖ㺠+ + + +``` +spring: + datasource: + url: jdbc:mysql://xxx:3333/xxx?characterEncoding=utf8&serverTimezone=Asia/Shanghai + username: root + password: root + driver-class-name: com.mysql.cj.jdbc.Driver +``` + +ͬʱ£¬ÎÒÃÇÒªÔÚapplicationÅäÖÃÎļþÖÐÅäÖÃÒ»ÏÂmanagement.endpoint.health.show-detailsµÄÖµ¡£¸ÃÊôÐÔÓÐÈý¸ö¿ÉÑ¡Ï + +* never £º²»Õ¹Ê¾ÏêϸÐÅÏ¢£¬up »òÕß down µÄ״̬£¬Ä¬ÈÏÅäÖã» +* when-authorized£ºÏêϸÐÅÏ¢½«»áչʾ¸øÍ¨¹ýÈÏÖ¤µÄÓû§¡£ÊÚȨµÄ½ÇÉ«¿ÉÒÔͨ¹ýmanagement.endpoint.health.roles ÅäÖã» +* always£º¶ÔËùÓÐÓû§±©Â¶ÏêϸÐÅÏ¢¡£ + +ĬÈÏÖµÊÇnever£¬ËùÒÔÎÒÃÇÖ±½Ó·ÃÎÊ¿´µ½µÄÖ»ÓÐUP»òDOWN¡£ÏÖÔÚ¼¯³ÉÁËÊý¾Ý¿â£¬Í¬Ê±°Ñ¸ÃÏîÖµÅäÖÃΪalways£¬¿´Ò»ÏÂÏêÇ飺 + +![image-20230530233934501](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530233934501.png) + +¿ÉÒÔ¿´µ½ÕûÌå״̬ΪUP£¬ÆäÖÐÏÂÃæµÄÈý¸ö×é¼þ¾ùΪUP£¬¶øÊý¾Ý¿âÊÇMYSQL£¬¼ì²éÊý¾Ý¿âµÄÓï¾äΪ¡°SELECT 1¡±¡£Í¬Ê±£¬»¹Õ¹Ê¾ÁË´ÅÅÌÐÅÏ¢ºÍpingµÄ״̬¡£ + +ÏÖÔÚÎÒÃǰÑÊý¾Ý¿âµÄÓû§ÃûºÍÃÜÂë¹ÊÒâ¸Ä´í£¬ÖØÆô·ÃÎʿɵ㺠+ +![image-20230530233951145](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530233951145.png) + +״̬ΪDOWN£¬×é¼þÖÐdb³öÏÖÁËÎÊÌ⣬״̬ΪDOWN¡£ÎÊÌâµÄÏêÇéÔÚerrorÖÐչʾ£¬¿ÉÒÔ¿´³öÊǽ¨Á¢Á¬½Óʱ³ö´íÁË¡£ÔÚʵ¼ùÖУ¬ÎÒÃÇ¿ÉÒÔͨ¹ýhealth¶Ë¿Ú¼à¿ØÊý¾Ý¿â¡¢Redis¡¢MongoDB¡¢´ÅÅ̵Ƚ¡¿µÇé¿ö¡£ActuatorÔ¤¶¨ÒåµÄ´¦ÀíÀàΪ£ºDataSourceHealthIndicator, DiskSpaceHealthIndicator, MongoHealthIndicator, RedisHealthIndicatorµÈ¡£ + +¶øÇÒÿ¸öÖ¸±ê¶¼¿ÉÒÔµ¥¶ÀµÄ½øÐпªÆôºÍ¹Ø±Õ£¬ÒÔÊý¾Ý¿âµÄΪÀý£º + + +```` +management: + health: + db: + enabled: true` +```` + +## info¶Ëµã + +/info ¶ËµãÓÃÀ´²é¿´ÅäÖÃÎļþ applicationÖÐÒÔinfo¿ªÍ·µÄÅäÖÃÐÅÏ¢£¬Ä¬ÈÏÇé¿öÏ applicationÖв¢Ã»ÓÐ info ½ÚµãÅäÖã¬ËùÒÔĬÈÏΪ¿Õ¡£ + +applicationÖÐÌí¼ÓÈçÏÂÅäÖ㺠+ + + +```` +info: + user: + type: ¹«ÖںŠ+ name: ³ÌÐòÐÂÊÓ½ç + wechat: zhuan2quan +```` + +·ÃÎÊ[http://localhost:8080/actuator/info](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Finfo "http://localhost:8080/actuator/info") £¬Õ¹Ê¾½á¹ûÈçÏ£º + +![image-20230530234019487](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530234019487.png) + +## conditions¶Ëµã + +Spring BootÌṩÁË×Ô¶¯ÅäÖù¦ÄÜ£¬Ê¹ÓÃÆðÀ´·Ç³£·½±ã¡£µ«ÕâЩ×Ô¶¯ÅäÖÃÀàÊÇʲôÇé¿öÏÂÉúЧµÄ£¬ÊÇ·ñÉúЧÊDZȽÏÄÑÅŲéµÄ¡£´Ëʱ£¬¿ÉÒÔʹÓà conditions ÔÚÓ¦ÓÃÔËÐÐʱ²é¿´Ä³¸öÅäÖÃÀàÔÚʲôÌõ¼þÏÂÉúЧ£¬»òΪʲôûÓÐÉúЧ¡£ + +·ÃÎÊURL£º[http://localhost:8080/actuator/conditions](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fconditions "http://localhost:8080/actuator/conditions") £¬²¿·Ö·µ»ØÐÅÏ¢ÈçÏ£º + +![image-20230530234053134](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530234053134.png) + +¿ÉÒÔ¿´µ½Ä³¸ö×Ô¶¯ÅäÖÃÀà¶ÔÓ¦µÄÉúЧÌõ¼þºÍÌáʾÐÅÏ¢¡£ + +## shutdown¶Ëµã + +shutdown¶ËµãÊôÓÚ²Ù×÷¿ØÖÆÀà¶Ëµã£¬¿ÉÒÔÓÅÑÅ¹Ø±Õ Spring Boot Ó¦Óá£ÐèÒªÔÚÅäÖÃÎļþÖпªÆô£º + + +```` +management: + endpoint: + shutdown: + enabled: true +```` + +¸Ã¶ËµãÖ»Ö§³ÖPOSTÇëÇó£¬Ö´ÐÐÃüÁî¼°·µ»Ø½á¹ûÈçÏ£º + + +``` +curl -X POST "http://localhost:8080/actuator/shutdown" +{ + "message": "Shutting down, bye..." +} +``` + +Ö´ÐÐÖ®ºó£¬»á·¢ÏÖÓ¦ÓóÌÐòÒѾ­±»¹Ø±ÕÁË¡£ÓÉÓڸö˵ã»á¹Ø±ÕÓ¦ÓóÌÐò£¬Òò´ËʹÓÃÊÇÐèҪСÐÄ¡£ + +## configprops¶Ëµã + +ÔÚSpring BootÏîÄ¿ÖУ¬ÎÒÃǾ­³£»áÓõ½@ConfigurationProperties×¢½âÀ´ÅúÁ¿×¢ÈëһЩÊôÐÔ£¬¶øconfigprops¶Ëµã¾ÍÊÇÓÃÀ´ÏÔʾÕâЩ±»¸Ã×¢½â±ê×¢µÄÅäÖÃÀà¡£ + +±ÈÈçÇ°ÃæµÄinfoÅäÖã¬ÎÒÃǾͿÉÒÔ¶¨ÒåÒ»¸öÀàInfoProperties£º + + +```` +@Component +@ConfigurationProperties(prefix = "info") +public class InfoProperties { + + private String type; + + private String name; + + private String wechat; + + // Ê¡ÂÔgetter/setter +} +```` + +·ÃÎÊURL£º[http://localhost:8080/actuator/configprops](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fconfigprops "http://localhost:8080/actuator/configprops") £¬²¿·ÖÐÅÏ¢ÈçÏ£º + +![image-20230530234110515](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530234110515.png) + +²»½ö¿ÉÒÔ¿´µ½ÏµÍ³ÖÐĬÈϼ¯³ÉµÄÅäÖÃÀàÐÅÏ¢£¬»¹¿ÉÒÔ¿´µ½ÎÒÃÇ×Ô¶¨ÒåµÄÅäÖÃÀàÐÅÏ¢¡£ÕâÀïÐèҪעÒâµÄÊǶÔÓ¦µÄÀàÐèÒª½øÐÐʵÀý»¯£¨@Component£©ÕâÀï²ÅÄܹ»¿´µ½¡£ + +ÎÒÃÇ×Ô¶¨ÒåµÄÀàÖзµ»ØÁËBeanµÄÃû³Æ¡¢ÅäÖÃǰ׺¡£ÉÏÃæµÄProjectInfoProperties»¹·µ»ØÁËÊôÐÔÐÅÏ¢¡£ + +## env¶Ëµã + +env¶ËµãÓÃÓÚ»ñȡȫ²¿»·¾³ÊôÐÔ£¬°üÀ¨applicationÅäÖÃÎļþÖеÄÄÚÈÝ¡¢ÏµÍ³±äÁ¿µÈ¡£ + +·ÃÎÊURL£º[http://localhost:8080/actuator/env£¬·µ»Ø²¿·ÖÐÅÏ¢£º](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fenv%25EF%25BC%258C%25E8%25BF%2594%25E5%259B%259E%25E9%2583%25A8%25E5%2588%2586%25E4%25BF%25A1%25E6%2581%25AF%25EF%25BC%259A "http://localhost:8080/actuator/env%EF%BC%8C%E8%BF%94%E5%9B%9E%E9%83%A8%E5%88%86%E4%BF%A1%E6%81%AF%EF%BC%9A") + +![image-20230530234200949](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530234200949.png) + +## env-toMatch¶Ëµã + +env-toMatch¶ËµãÓëcachesºÍcaches-cacheÀàËÆ£¬Ò»¸öÊÇ»ñÈ¡ËùÓеģ¬Ò»¸öÊÇ»ñȡָ¶¨µÄ¡£ÕâÀïµÄenv-toMatch¶ËµãÊÇ»ñȡָ¶¨keyµÄ»·¾³±äÁ¿ÊôÐÔ¡£ + +»ù±¾¸ñʽΪ£º[http://localhost:8080/actuator/env/{toMatch}¡£](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fenv%2F%257BtoMatch%257D%25E3%2580%2582 "http://localhost:8080/actuator/env/%7BtoMatch%7D%E3%80%82") ʵÀýURL£º[http://localhost:8080/actuator/env/info.user.name](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fenv%2Finfo.user.name "http://localhost:8080/actuator/env/info.user.name") £¬·µ»Ø½á¹ûÈçÏÂͼ£º + +![image-20230530234238073](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530234238073.png) + +·µ»ØÊý¾ÝÐÅÏ¢°üÀ¨¸ÃÊôÐÔµÄÀ´Ô´¡¢valueÖµµÈÐÅÏ¢¡£ + +## loggers¶Ëµã + +/loggers ¶Ëµã±©Â¶Á˳ÌÐòÄÚ²¿ÅäÖõÄËùÓÐ logger µÄÐÅÏ¢£¬°üÀ¨²»Í¬µÄpackage¡¢²»Í¬µÄÀàµÄÈÕÖ¾¼¶±ðÐÅÏ¢¡£ + +·ÃÎÊURL£º[http://localhost:8080/actuator/loggers](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Floggers "http://localhost:8080/actuator/loggers") £¬²¿·Ö·µ»Ø½á¹û£º + +![image-20230530234301625](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530234301625.png) + +## loggers-name¶Ëµã + +loggers-name¶ËµãÒ²ÊÇlogger¶ËµãµÄϸ·Ö£¬¿ÉÒÔͨ¹ýname·ÃÎÊijһ¸ölogger¡£ + +»ù±¾ÇëÇó¸ñʽ£º[http://localhost:8080/actuator/loggers/{name}](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Floggers%2F%257Bname%257D "http://localhost:8080/actuator/loggers/%7Bname%7D") ʾÀýÇëÇóURL£º[http://localhost:8080/actuator/loggers/com.secbro2.SpringbootActuatorApplication](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Floggers%2Fcom.secbro2.SpringbootActuatorApplication "http://localhost:8080/actuator/loggers/com.secbro2.SpringbootActuatorApplication") £¬·µ»Ø½á¹ûÈçÏ£º + + + +`{ +"configuredLevel": null, +"effectiveLevel": "INFO" +}` + +¿ÉÒÔ¿´³ö£¬Æô¶¯ÀàµÄÈÕÖ¾¼¶±ðΪINFO¡£ + +## heapdump¶Ëµã + +heapdump¶Ëµã»á·µ»ØÒ»¸öJVM ¶Ñdump£¬Í¨¹ýJVM×Ô´øµÄ¼à¿Ø¹¤¾ßVisualVM¿É´ò¿ª´ËÎļþ²é¿´ÄÚ´æ¿ìÕÕ¡£ÕâÊÇÄÚ´æÓÅ»¯£¬»ùÓÚ¶ÑÕ»²ãÃæ½øÐÐÅŲéµÄÀûÆ÷¡£ + +·ÃÎÊURL£º[http://localhost:8080/actuator/heapdump](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fheapdump "http://localhost:8080/actuator/heapdump") ¡£Mac²Ù×÷ϵͳÏÂä¯ÀÀÆ÷·ÃÎÊ»áÏÂÔØÒ»¸öÃû×ÖΪheapdumpµÄÎļþ£¬ÎÞºó׺£¬30M¡£ + +ÃüÁîÐÐÖ´ÐÐjvisualvmÃüÁ´ò¿ªVisualVM£¬ÒÀ´Îµã»÷¡°Îļþ¡±¡¢¡°×°È롱£¬¼ÇµÃÎļþÀàÐÍҪѡÔñ¡°¶ÑDump(_.hprof,_.*)¡±£¬È»ºóÑ¡Ôñheapdump¡£ + +![image-20230530234346098](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530234346098.png) + +´Ëʱ±ã¿ÉÒÔͨ¹ý¹¤¾ßÀ´½øÐжÑÕ»ÐÅÏ¢µÄ·ÖÎöÁË¡£¶ÔÓÚÏßÉÏÎÊÌâµÄ·ÖÎöÌṩÁ˼«Îª±ãÀûµÄ·½Ê½¡£ + +## threaddump¶Ëµã + +/threaddump ¶Ëµã»áÉú³Éµ±Ç°Ï̻߳µÄ¿ìÕÕ¡£ÔÚÈÕ³£¶¨Î»ÎÊÌâµÄʱºò²é¿´Ï̵߳ÄÇé¿ö·Ç³£ÓÐÓã¬Ö÷ҪչʾÁËÏß³ÌÃû¡¢Ïß³ÌID¡¢Ï̵߳Ä״̬¡¢ÊÇ·ñµÈ´ýËø×ÊÔ´µÈÐÅÏ¢¡£ + +·ÃÎÊURL£º[http://localhost:8080/actuator/threaddump](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fthreaddump "http://localhost:8080/actuator/threaddump") £¬²¿·Ö·µ»Ø½á¹û£º + +![image-20230530234405331](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530234405331.png) + +ÎÒÃÇ¿Éͨ¹ýÏ߳̿ìÕÕÀ´ÅŲéÉú²ú»·¾³µÄÎÊÌâ¡£ + +## metrics¶Ëµã + +/metrics ¶ËµãÓÃÀ´±©Â¶µ±Ç°Ó¦Óõĸ÷ÀàÖØÒª¶ÈÁ¿Ö¸±ê£¬±ÈÈ磺ÄÚ´æÐÅÏ¢¡¢Ïß³ÌÐÅÏ¢¡¢À¬»ø»ØÊÕÐÅÏ¢¡¢tomcat¡¢Êý¾Ý¿âÁ¬½Ó³ØµÈ¡£2.x°æ±¾ÕâÀïÖ»ÏÔʾÁËÒ»¸öÖ¸±êµÄÁÐ±í¡£ + +·ÃÎÊURL£º[http://localhost:8080/actuator/metrics](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fmetrics "http://localhost:8080/actuator/metrics") ¡£ + +```` +{ + "names": [ + "jvm.memory.max", + "jvm.threads.states", + "jvm.gc.pause", + "http.server.requests", + "process.files.max", + "jvm.gc.memory.promoted", + "system.load.average.1m", + "jvm.memory.used", + "jvm.gc.max.data.size", + "jvm.memory.committed", + "system.cpu.count", + "logback.events", + "jvm.buffer.memory.used", + "tomcat.sessions.created", + "jvm.threads.daemon", + "system.cpu.usage", + "jvm.gc.memory.allocated", + "tomcat.sessions.expired", + "jvm.threads.live", + "jvm.threads.peak", + "process.uptime", + "tomcat.sessions.rejected", + "process.cpu.usage", + "jvm.classes.loaded", + "jvm.classes.unloaded", + "tomcat.sessions.active.current", + "tomcat.sessions.alive.max", + "jvm.gc.live.data.size", + "process.files.open", + "jvm.buffer.count", + "jvm.buffer.total.capacity", + "tomcat.sessions.active.max", + "process.start.time" + ] +} +```` + +/metrics¶Ëµã¿ÉÒÔÌṩӦÓÃÔËÐÐ״̬µÄÍêÕû¶ÈÁ¿Ö¸±ê±¨¸æ£¬ÕâÏÄܷdz£µÄʵÓ㬵«ÊǶÔÓÚ¼à¿ØÏµÍ³Öеĸ÷Ïî¼à¿Ø¹¦ÄÜ£¬ËüÃÇµÄ¼à¿ØÄÚÈÝ¡¢Êý¾ÝÊÕ¼¯ÆµÂʶ¼ÓÐËù²»Í¬£¬Èç¹ûÎÒÃÇÿ´Î¶¼Í¨¹ýÈ«Á¿»ñÈ¡±¨¸æµÄ·½Ê½À´ÊÕ¼¯£¬ÂÔÏÔ´Ö±©¡£¹Ù·½Ò²ÊÇ¿ÉÄÜÊÇ´¦ÓÚ´Ë·½ÃæµÄ¿¼ÂÇ£¬ÔÚSpring Boot 2.xÖ®ºó£¬/metrics¶ËµãÖ»ÏÔʾÁËÖ¸±êµÄÁÐ±í¡£ + +Èç¹ûÐèÒª²é¿´¾ßÌåµÄijÏîÖ¸±ê£¬Ôò¿Éͨ¹ý/metrics-requiredMetricName¶ËµãÀ´ÊµÏÖ¡£ + +## metrics-requiredMetricName¶Ëµã + +metrics-requiredMetricName¶Ëµã£¬ÓÃÓÚ·ÃÎÊÖ¸¶¨Ö¸±êµÄ±¨¸æ£¬Ò»°ã»áÅäºÏ/metrics¶ËµãÏȲé³öÖ¸±êÁÐ±í£¬È»ºóÔÙ²éѯ¾ßÌåµÄij¸öÖ¸±ê¡£ + +»ù±¾¸ñʽ£º[http://localhost:8080/actuator/metrics/{requiredMetricName}¡£](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fmetrics%2F%257BrequiredMetricName%257D%25E3%2580%2582 "http://localhost:8080/actuator/metrics/%7BrequiredMetricName%7D%E3%80%82") ʵÀýURL£º[http://localhost:8080/actuator/metrics/jvm.memory.max](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fmetrics%2Fjvm.memory.max "http://localhost:8080/actuator/metrics/jvm.memory.max") £¬·µ»Ø½á¹ûÈçÏ£º + + +```` +{ + "name": "jvm.memory.max", + "description": "The maximum amount of memory in bytes that can be used for memory management", + "baseUnit": "bytes", + "measurements": [ + { + "statistic": "VALUE", + "value": 5606211583 + } + ], + "availableTags": [ + { + "tag": "area", + "values": [ + "heap", + "nonheap" + ] + }, + { + "tag": "id", + "values": [ + "Compressed Class Space", + "PS Survivor Space", + "PS Old Gen", + "Metaspace", + "PS Eden Space", + "Code Cache" + ] + } + ] +} +```` + +ÉÏÊö½á¹ûչʾÁË×î´ó¿ÉÓÃÄÚ´æµÄÇé¿ö¡£ÆäËûÏà¹ØÖ¸±êµÄÕ¹Ê¾Ìæ»»¶ÔÓ¦µÄÃû×Ö½øÐв鿴¼´¿É¡£ + +## scheduledtasks¶Ëµã + +/scheduledtasks¶ËµãÓÃÓÚչʾӦÓÃÖеĶ¨Ê±ÈÎÎñÐÅÏ¢¡£ + +ÏÈÔÚÏîÄ¿Öй¹½¨Á½¸ö¶¨Ê±ÈÎÎñ£¬Ê×ÏÈÔÚÆô¶¯ÀàÉÏÌí¼Ó@EnableScheduling¿ªÆô¶¨Ê±ÈÎÎñ¹¦ÄÜ¡£È»ºó´´½¨¶¨Ê±ÈÎÎñÀࣺ + +```` +@Component +public class MyTask { + + @Scheduled(cron = "0/10 * * * * *") + public void work() { + System.out.println("I am a cron job."); + } + + @Scheduled(fixedDelay = 10000) + public void work1() { + System.out.println("I am a fixedDelay job."); + } +} +```` + +ÆäÖж¨ÒåÁËÁ½ÖÖÀàÐ͵Ķ¨Ê±ÈÎÎñ£¬workÊÇ»ùÓÚcronʵÏֵĶ¨Ê±ÈÎÎñ£¬work1ÊÇ»ùÓÚfixedDelayʵÏֵĶ¨Ê±ÈÎÎñ¡£ + +·ÃÎÊURL£º[http://localhost:8080/actuator/scheduledtasks](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fscheduledtasks "http://localhost:8080/actuator/scheduledtasks") £¬·µ»Ø½á¹ûÐÅÏ¢ÈçÏ£º + +``` +{ + "cron": [ + { + "runnable": { + "target": "com.secbro2.job.MyTask.work" + }, + "expression": "0/10 * * * * *" + } + ], + "fixedDelay": [ + { + "runnable": { + "target": "com.secbro2.job.MyTask.work1" + }, + "initialDelay": 0, + "interval": 10000 + } + ], + "fixedRate": [], + "custom": [] +} +``` + +¿ÉÒÔ¿´µ½£¬Í¨¹ý¸Ã¶Ëµã¿ÉÒÔÃ÷È·µÄÖªµÀµ±Ç°Ó¦ÓÃÖж¨ÒåµÄ¶¨Ê±ÈÎÎñ£¬ÒÔ¼°Ö´ÐÐģʽºÍƵ´Î¡£ + +## mappings¶Ëµã + +/mappings¶ËµãÓÃÓÚÃèÊöÈ«²¿µÄ URI ·¾¶£¬ÒÔ¼°ºÍ¿ØÖÆÆ÷µÄÓ³Éä¹ØÏµ¡£Õâ¸ö¹¦ÄÜËãÊDZȽϳ£ÓõÄÁË£¬Èç¹ûÏëϵͳµÄ²é¿´URL¶ÔÓ¦µÄController¼°·½·¨£¬¿ÉÒÔʹÓô˶˵㡣 + +·ÃÎÊURL£º[http://localhost:8080/actuator/mappings](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8080%2Factuator%2Fmappings "http://localhost:8080/actuator/mappings") £¬²¿·Ö·µ»Ø½á¹ûÈçÏ£º + +![image-20230530234501440](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230530234501440.png) + +ÖÁ´Ë¹ØÓÚSpring Boot ActuatorÌṩµÄËùÓж˵ã½éÉÜÍê±Ï¡£ + +## С½á + +±¾ÎÄͨ¹ý¶ÔSpring Boot ActuatorÌṩËùÓж˵㹹½¨ÊµÀý²¢ÑÝʾ½á¹û£¬±¾ÎÄ´ó¶àÊýÄÚÈݺÍʵÀý¶¼ÊÇÈ«ÍøµÚÒ»ÊÖ×ÊÁÏ¡£¸Ã¿ò¼Ü¶ÔÅŲéÏßÉÏÎÊÌ⣬ÐÔÄÜÓÅ»¯µÈ¶¼Óм«´óµÄ°ïÖú¡£¶øÔÚд±¾ÎĵĹý³ÌÖÐÒ²Ô½À´Ô½¾ªÌ¾ActuatorµÄ¹¦ÄÜ֮ǿ´ó£¬Ç¿ÁÒÍÆ¼öÓÃÆðÀ´¡£ + +## ²Î¿¼Á´½Ó + +×÷Õߣº³ÌÐòÐÂÊÓ½ç +Á´½Ó£ºhttps://juejin.cn/post/6984550846876876814 +À´Ô´£ºÏ¡ÍÁ¾ò½ð +Öø×÷Ȩ¹é×÷ÕßËùÓС£ÉÌÒµ×ªÔØÇëÁªÏµ×÷Õß»ñµÃÊÚȨ£¬·ÇÉÌÒµ×ªÔØÇë×¢Ã÷³ö´¦¡£ + diff --git a/docs/monitor/SpringBoot Admin.md b/docs/monitor/SpringBoot Admin.md new file mode 100644 index 0000000..7b0c8ab --- /dev/null +++ b/docs/monitor/SpringBoot Admin.md @@ -0,0 +1,495 @@ +## ÕªÒª + +Spring Boot Admin ¿ÉÒÔ¶ÔSpringBootÓ¦Óõĸ÷ÏîÖ¸±ê½øÐÐ¼à¿Ø£¬¿ÉÒÔ×÷Ϊ΢·þÎñ¼Ü¹¹ÖÐµÄ¼à¿ØÖÐÐÄÀ´Ê¹Ó㬱¾ÎĽ«¶ÔÆäÓ÷¨½øÐÐÏêϸ½éÉÜ¡£ + +## Spring Boot Admin ¼ò½é + +SpringBootÓ¦ÓÿÉÒÔͨ¹ýActuatorÀ´±©Â¶Ó¦ÓÃÔËÐйý³ÌÖеĸ÷ÏîÖ¸±ê£¬Spring Boot Adminͨ¹ýÕâЩָ±êÀ´¼à¿ØSpringBootÓ¦Óã¬È»ºóͨ¹ýͼÐλ¯½çÃæ³ÊÏÖ³öÀ´¡£Spring Boot Admin²»½ö¿ÉÒÔ¼à¿Øµ¥ÌåÓ¦Ó㬻¹¿ÉÒÔºÍSpring CloudµÄ×¢²áÖÐÐÄÏà½áºÏÀ´¼à¿ØÎ¢·þÎñÓ¦Óᣠ+ +Spring Boot Admin ¿ÉÒÔÌṩӦÓõÄÒÔÏÂ¼à¿ØÐÅÏ¢£º + +* ¼à¿ØÓ¦ÓÃÔËÐйý³ÌÖеĸÅÀÀÐÅÏ¢£» +* ¶ÈÁ¿Ö¸±êÐÅÏ¢£¬±ÈÈçJVM¡¢Tomcat¼°½ø³ÌÐÅÏ¢£» +* »·¾³±äÁ¿ÐÅÏ¢£¬±ÈÈçϵͳÊôÐÔ¡¢ÏµÍ³»·¾³±äÁ¿ÒÔ¼°Ó¦ÓÃÅäÖÃÐÅÏ¢£» +* ²é¿´ËùÓд´½¨µÄBeanÐÅÏ¢£» +* ²é¿´Ó¦ÓÃÖеÄËùÓÐÅäÖÃÐÅÏ¢£» +* ²é¿´Ó¦ÓÃÔËÐÐÈÕÖ¾ÐÅÏ¢£» +* ²é¿´JVMÐÅÏ¢£» +* ²é¿´¿ÉÒÔ·ÃÎʵÄWeb¶Ëµã£» +* ²é¿´HTTP¸ú×ÙÐÅÏ¢¡£ + +## ´´½¨admin-serverÄ£¿é + +> ÕâÀïÎÒÃÇ´´½¨Ò»¸öadmin-serverÄ£¿éÀ´×÷Ϊ¼à¿ØÖÐÐÄÑÝʾÆä¹¦ÄÜ¡£ + +* ÔÚpom.xmlÖÐÌí¼ÓÏà¹ØÒÀÀµ£º + + + + + +```` + + org.springframework.boot + spring-boot-starter-web + + + de.codecentric + spring-boot-admin-starter-server + + +```` + +* ÔÚapplication.ymlÖнøÐÐÅäÖ㺠+ + + + + +````spring: + application: + name: admin-server +server: + port: 9301 +```` + +* ÔÚÆô¶¯ÀàÉÏÌí¼Ó@EnableAdminServerÀ´ÆôÓÃadmin-server¹¦ÄÜ£º + + + + +```` +@EnableAdminServer +@SpringBootApplication +public class AdminServerApplication { + + public static void main(String[] args) { + SpringApplication.run(AdminServerApplication.class, args); + } + +} +```` + +## ´´½¨admin-clientÄ£¿é + +> ÕâÀïÎÒÃÇ´´½¨Ò»¸öadmin-clientÄ£¿é×÷Ϊ¿Í»§¶Ë×¢²áµ½admin-server¡£ + +* ÔÚpom.xmlÖÐÌí¼ÓÏà¹ØÒÀÀµ£º + + + +```` + + org.springframework.boot + spring-boot-starter-web + + + de.codecentric + spring-boot-admin-starter-client + +```` + +* ÔÚapplication.ymlÖнøÐÐÅäÖ㺠+ + + + + + + + +``` +spring: + application: + name: admin-client + boot: + admin: + client: + url: http://localhost:9301 #ÅäÖÃadmin-serverµØÖ· +server: + port: 9305 +management: + endpoints: + web: + exposure: + include: '*' + endpoint: + health: + show-details: always +logging: + file: admin-client.log #Ìí¼Ó¿ªÆôadminµÄÈÕÖ¾¼à¿Ø +``` + +* Æô¶¯admin-serverºÍadmin-client·þÎñ¡£ + +## ¼à¿ØÐÅÏ¢ÑÝʾ + +* ·ÃÎÊÈçϵØÖ·´ò¿ªSpring Boot AdminµÄÖ÷Ò³£º[http://localhost:9301](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A9301 "http://localhost:9301") + +![image-20230531001002163](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230531001002163.png) + + + + + +* µã»÷wallboard°´Å¥£¬Ñ¡Ôñadmin-client²é¿´¼à¿ØÐÅÏ¢£» + +* ¼à¿ØÐÅÏ¢¸ÅÀÀ£» + +![image-20230531001023644](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230531001023644.png) + + + + + +* ¶ÈÁ¿Ö¸±êÐÅÏ¢£¬±ÈÈçJVM¡¢Tomcat¼°½ø³ÌÐÅÏ¢£» + +![image-20230531001053279](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230531001053279.png) + + + + + +* »·¾³±äÁ¿ÐÅÏ¢£¬±ÈÈçϵͳÊôÐÔ¡¢ÏµÍ³»·¾³±äÁ¿ÒÔ¼°Ó¦ÓÃÅäÖÃÐÅÏ¢£» + +![image-20230531001103093](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230531001103093.png) + + + + + +* ²é¿´ËùÓд´½¨µÄBeanÐÅÏ¢£» + +![image-20230531001111221](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230531001111221.png) + + + + + +* ²é¿´Ó¦ÓÃÖеÄËùÓÐÅäÖÃÐÅÏ¢£» + +![image-20230531001124678](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230531001124678.png) + + + + + +* ²é¿´ÈÕÖ¾ÐÅÏ¢£¬ÐèÒªÌí¼ÓÒÔÏÂÅäÖòÅÄÜ¿ªÆô£» + + + +`logging: +file: admin-client.log #Ìí¼Ó¿ªÆôadminµÄÈÕÖ¾¼à¿Ø` + +![image-20230531001136184](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230531001136184.png) + + + + +* ²é¿´JVMÐÅÏ¢£» + +![image-20230531001144614](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230531001144614.png) + + + + + +* ²é¿´¿ÉÒÔ·ÃÎʵÄWeb¶Ëµã£» + +![image-20230531001156191](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230531001156191.png) + + + + + +* ²é¿´HTTP¸ú×ÙÐÅÏ¢£» + +![image-20230531001206364](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230531001206364.png) + + + + + +## ½áºÏ×¢²áÖÐÐÄʹÓà + +> Spring Boot Admin½áºÏSpring Cloud ×¢²áÖÐÐÄʹÓã¬Ö»Ð轫admin-serverºÍ×¢²áÖÐÐÄÕûºÏ¼´¿É£¬admin-server »á×Ô¶¯´Ó×¢²áÖÐÐÄ»ñÈ¡·þÎñÁÐ±í£¬È»ºó°¤¸ö»ñÈ¡¼à¿ØÐÅÏ¢¡£ÕâÀïÒÔEureka×¢²áÖÐÐÄΪÀýÀ´½éÉÜϸù¦ÄÜ¡£ + +### ÐÞ¸Äadmin-server + +* ÔÚpom.xmlÖÐÌí¼ÓÏà¹ØÒÀÀµ£º + + + + +```` + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + +```` + +* ÔÚapplication-eureka.ymlÖнøÐÐÅäÖã¬Ö»ÐèÌí¼Ó×¢²áÖÐÐÄÅäÖü´¿É£º + + + + +```` +spring: + application: + name: admin-server +server: + port: 9301 +eureka: + client: + register-with-eureka: true + fetch-registry: true + service-url: + defaultZone: http://localhost:8001/eureka/ +```` + +* ÔÚÆô¶¯ÀàÉÏÌí¼Ó@EnableDiscoveryClientÀ´ÆôÓ÷þÎñ×¢²á¹¦ÄÜ£º + + + + + +```` +`@EnableDiscoveryClient +@EnableAdminServer +@SpringBootApplication +public class AdminServerApplication { + + public static void main(String[] args) { + SpringApplication.run(AdminServerApplication.class, args); + } + +} +```` + +### ÐÞ¸Äadmin-client + +* ÔÚpom.xmlÖÐÌí¼ÓÏà¹ØÒÀÀµ£º + + + +```` + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + +```` + +* ÔÚapplication-eureka.ymlÖнøÐÐÅäÖã¬É¾³ýÔ­À´µÄadmin-serverµØÖ·ÅäÖã¬Ìí¼Ó×¢²áÖÐÐÄÅäÖü´¿É£º + + + + + +``` +spring: + application: + name: admin-client +server: + port: 9305 +management: + endpoints: + web: + exposure: + include: '*' + endpoint: + health: + show-details: always +logging: + file: admin-client.log #Ìí¼Ó¿ªÆôadminµÄÈÕÖ¾¼à¿Ø +eureka: + client: + register-with-eureka: true + fetch-registry: true + service-url: + defaultZone: http://localhost:8001/eureka/ +``` + +* ÔÚÆô¶¯ÀàÉÏÌí¼Ó@EnableDiscoveryClientÀ´ÆôÓ÷þÎñ×¢²á¹¦ÄÜ£º + + + + + +``` +@EnableDiscoveryClient +@SpringBootApplication +public class AdminClientApplication { + + public static void main(String[] args) { + SpringApplication.run(AdminClientApplication.class, args); + } + +} +``` + +### ¹¦ÄÜÑÝʾ + +* Æô¶¯eureka-server£¬Ê¹ÓÃapplication-eureka.ymlÅäÖÃÆô¶¯admin-server£¬admin-client£» + +* ²é¿´×¢²áÖÐÐÄ·¢ÏÖ·þÎñ¾ùÒÑ×¢²á£º[http://localhost:8001/](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A8001%2F "http://localhost:8001/") + +![image-20230531001221519](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230531001221519.png) + + +* ²é¿´Spring Boot Admin Ö÷Ò³·¢ÏÖ¿ÉÒÔ¿´µ½·þÎñÐÅÏ¢£º[http://localhost:9301](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A9301 "http://localhost:9301") + +![image-20230531001232048](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230531001232048.png) + + +## Ìí¼ÓµÇ¼ÈÏÖ¤ + +> ÎÒÃÇ¿ÉÒÔͨ¹ý¸øadmin-serverÌí¼ÓSpring SecurityÖ§³ÖÀ´»ñµÃµÇ¼ÈÏÖ¤¹¦ÄÜ¡£ + +### ´´½¨admin-security-serverÄ£¿é + +* ÔÚpom.xmlÖÐÌí¼ÓÏà¹ØÒÀÀµ£º + + + +``` + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + de.codecentric + spring-boot-admin-starter-server + 2.1.5 + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-web + +``` + +* ÔÚapplication.ymlÖнøÐÐÅäÖã¬ÅäÖõǼÓû§ÃûºÍÃÜÂ룬ºöÂÔadmin-security-serverµÄ¼à¿ØÐÅÏ¢£º + + + + + +``` +spring: + application: + name: admin-security-server + security: # ÅäÖõǼÓû§ÃûºÍÃÜÂë + user: + name: macro + password: 123456 + boot: # ²»ÏÔʾadmin-security-serverµÄ¼à¿ØÐÅÏ¢ + admin: + discovery: + ignored-services: ${spring.application.name} +server: + port: 9301 +eureka: + client: + register-with-eureka: true + fetch-registry: true + service-url: + defaultZone: http://localhost:8001/eureka/ +``` + +* ¶ÔSpringSecurity½øÐÐÅäÖã¬ÒÔ±ãadmin-client¿ÉÒÔ×¢²á£º + + + + + +scss + +¸´ÖÆ´úÂë + + + + + +``` +/** + * Created by macro on 2019/9/30. + */ +@Configuration +public class SecuritySecureConfig extends WebSecurityConfigurerAdapter { + private final String adminContextPath; + + public SecuritySecureConfig(AdminServerProperties adminServerProperties) { + this.adminContextPath = adminServerProperties.getContextPath(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler(); + successHandler.setTargetUrlParameter("redirectTo"); + successHandler.setDefaultTargetUrl(adminContextPath + "/"); + + http.authorizeRequests() + //1.ÅäÖÃËùÓо²Ì¬×ÊÔ´ºÍµÇ¼ҳ¿ÉÒÔ¹«¿ª·ÃÎÊ + .antMatchers(adminContextPath + "/assets/**").permitAll() + .antMatchers(adminContextPath + "/login").permitAll() + .anyRequest().authenticated() + .and() + //2.ÅäÖõǼºÍµÇ³ö·¾¶ + .formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and() + .logout().logoutUrl(adminContextPath + "/logout").and() + //3.¿ªÆôhttp basicÖ§³Ö£¬admin-client×¢²áʱÐèҪʹÓà + .httpBasic().and() + .csrf() + //4.¿ªÆô»ùÓÚcookieµÄcsrf±£»¤ + .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) + //5.ºöÂÔÕâЩ·¾¶µÄcsrf±£»¤ÒÔ±ãadmin-client×¢²á + .ignoringAntMatchers( + adminContextPath + "/instances", + adminContextPath + "/actuator/**" + ); + } +} +``` + +* ÐÞ¸ÄÆô¶¯À࣬¿ªÆôAdminServer¼°×¢²á·¢ÏÖ¹¦ÄÜ£º + + + + + +``` +@EnableDiscoveryClient +@EnableAdminServer +@SpringBootApplication +public class AdminSecurityServerApplication { + + public static void main(String[] args) { + SpringApplication.run(AdminSecurityServerApplication.class, args); + } +} +``` + +* Æô¶¯eureka-server£¬admin-security-server£¬·ÃÎÊSpring Boot Admin Ö÷Ò³·¢ÏÖÐèÒªµÇ¼²ÅÄÜ·ÃÎÊ£º[http://localhost:9301](https://link.juejin.cn?target=http%3A%2F%2Flocalhost%3A9301 "http://localhost:9301") + +![image-20230531001242361](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230531001242361.png) + + + + + +## ʹÓõ½µÄÄ£¿é + + + + + +``` +springcloud-learning +©À©¤©¤ eureka-server -- eureka×¢²áÖÐÐÄ +©À©¤©¤ admin-server -- admin¼à¿ØÖÐÐÄ·þÎñ +©À©¤©¤ admin-client -- admin¼à¿ØÖÐÐÄ¼à¿ØµÄÓ¦Ó÷þÎñ +©¸©¤©¤ admin-security-server -- ´øµÇ¼ÈÏÖ¤µÄadmin¼à¿ØÖÐÐÄ·þÎñ` +``` \ No newline at end of file diff --git "a/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\344\272\213\345\212\241\346\266\210\346\201\257\357\274\210\346\234\200\347\273\210\344\270\200\350\207\264\346\200\247\357\274\211.md" "b/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\344\272\213\345\212\241\346\266\210\346\201\257\357\274\210\346\234\200\347\273\210\344\270\200\350\207\264\346\200\247\357\274\211.md" new file mode 100644 index 0000000..7b22bce --- /dev/null +++ "b/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\344\272\213\345\212\241\346\266\210\346\201\257\357\274\210\346\234\200\347\273\210\344\270\200\350\207\264\346\200\247\357\274\211.md" @@ -0,0 +1,62 @@ +# [RocketMQϵÁУ¨Ò»£©»ù±¾¸ÅÄî](https://www.cnblogs.com/boboooo/p/13038950.html) + + + + + +RocketMQÊǰ¢Àï³öÆ·µÄÒ»¿î¿ªÔ´µÄÏûÏ¢Öмä¼þ£¬ÈÃÆäÉùÃû´óÔëµÄ¾ÍÊÇËüµÄÊÂÎñÏûÏ¢µÄ¹¦ÄÜ¡£ÔÚÆóÒµÖУ¬ÏûÏ¢Öмä¼þÑ¡ÔñʹÓÃRocketMQµÄ»¹ÊÇͦ¶àµÄ£¬ÕâһϵÁеÄÎÄÕ¶¼ÊÇÕë¶ÔRocketMQµÄ£¬ÔÛÃÇÏÈ´ÓRocketMQµÄһЩ»ù±¾¸ÅÄîºÍ»·¾³µÄ´î½¨¿ªÊ¼ÁÄÆð¡£ + +RocketMQÓÉ4²¿·Ö×é³É£¬·Ö±ðÊÇ£ºÃû³Æ·þÎñ£¨Name Server£©¡¢ÏûÏ¢¶ÓÁУ¨Brokers£©¡¢Éú²úÕߣ¨producer£©ºÍÏû·ÑÕߣ¨consumer£©¡£Õâ4²¿·Ö¶¼¿ÉÒÔ½øÐÐˮƽÀ©Õ¹£¬´Ó¶ø±ÜÃâµ¥µã¹ÊÕÏ£¬ÈçÏÂͼ£¬ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/1191201-20200603173058174-1551688390.png) + +ÕâÊÇRocketMQ¹ÙÍøÉϵÄÒ»ÕÅͼ£¬·Ç³£ÇåÎúµÄÁгöÁË4¸ö²¿·Ö£¬²¢ÇÒ¶¼ÊǼ¯ÈºÄ£Ê½¡£ÏÂÃæÎÒÃǾͷֱð˵һ˵Õâ4²¿·Ö¡£ + +## Ãû³Æ·þÎñ£¨NameServer£© + +Name Server°çÑݵĽÇÉ«ÊÇÒ»¸ö×¢²áÖÐÐÄ£¬ºÍZookeeperµÄ×÷Óò¶à¡£ËüµÄÖ÷Òª¹¦ÄÜÓÐÁ½¸ö£¬ÈçÏ£º + +* brokerµÄ¹ÜÀí£ºbroker¼¯Èº½«×Ô¼ºµÄÐÅÏ¢×¢²áµ½NameServer£¬NameServerÌṩÐÄÌø»úÖÆ¼ì²âÿһ¸öbrokerÊÇ·ñÕý³£¡£ +* ·ÓɹÜÀí£ºÃ¿Ò»¸öNameServer¶¼ÓÐÕû¸öbroker¼¯ÈººÍ¶ÓÁеÄÐÅÏ¢£¬ÒÔ±ã¿Í»§¶Ë£¨Éú²úÕߺÍÏû·ÑÕߣ©²éѯ¡£ + +NameServerЭµ÷×Å·Ö²¼Ê½ÏµÍ³ÖеÄÿһ¸ö×é¼þ£¬²¢ÇÒ¹ÜÀí×Åÿһ¸öTopicµÄ·ÓÉÐÅÏ¢¡£ + +## Broker + +BrokerÖ÷ÒªÊÇ´æ´¢ÏûÏ¢£¬²¢ÇÒÌṩTopicµÄ»úÖÆ¡£ËüÌá¹©ÍÆºÍÀ­Á½ÖÖģʽ£¬»¹ÓÐһЩÈÝÔֵĴëÊ©£¬±ÈÈç¿ÉÒÔÅäÖÃÏûÏ¢¸±±¾¡£ÏÂÃæÎÒÃÇ¿´Ò»¿´BrokcerµÄÖ÷´Ó»úÖÆ¡£ + +BrokerµÄ½ÇÉ«·ÖΪ¡°Òì²½Ö÷¡±¡¢¡°Í¬²½Ö÷¡±ºÍ¡°´Ó¡±Èý¸ö½ÇÉ«¡£Èç¹ûÄã²»ÄÜÈÝÈÌÏûÏ¢µÄ¶ªÊ§£¬Äã¿ÉÒÔÅäÖÃÒ»¸ö¡°Í¬²½Ö÷¡±ºÍ¡°´Ó¡±Á½¸öBroker£¬Èç¹ûÄã¾õµÃÏûÏ¢¶ªÊ§Ò²ÎÞËùν£¬Ö»Òª¶ÓÁпÉÓþÍokµÄ»°£¬Äã¿ÉÒÔÅäÖá°Òì²½Ö÷¡±ºÍ¡°´Ó¡±Á½¸öbroker¡£Èç¹ûÄãÖ»ÊÇÏë¼òµ¥µÄ´î½¨£¬Ö»ÅäÖÃÒ»¸ö¡°Òì²½Ö÷¡±£¬²»ÅäÖá°´Ó¡±Ò²ÊÇ¿ÉÒԵġ£ + +ÉÏÃæÌáµ½µÄÊÇbrokerÖ®¼äµÄ±¸·Ý£¬brokerÀïµÄÐÅÏ¢Ò²ÊÇ¿ÉÒÔ±£´æµ½´ÅÅ̵쬱£´æµ½´ÅÅ̵ķ½Ê½Ò²ÓÐÁ½ÖÖ£¬ÍƼöµÄ·½Ê½ÊÇÒì²½±£´æ´ÅÅÌ£¬Í¬²½±£´æ´ÅÅÌÊǷdz£ËðºÄÐÔÄܵġ£ + +## Éú²úÕß + +Éú²úÕßÖ§³Ö¼¯Èº²¿Êð£¬ËüÃÇÏòbroker¼¯Èº·¢ËÍÏûÏ¢£¬¶øÇÒÖ§³Ö¶àÖÖ¸ºÔؾùºâµÄ·½Ê½¡£ + +µ±Éú²úÕßÏòbroker·¢ËÍÏûϢʱ£¬»áµÃµ½·¢Ëͽá¹û£¬·¢Ëͽá¹ûÖÐÓÐÒ»¸ö·¢ËÍ״̬¡£¼ÙÉèÎÒÃǵÄÅäÖÃÖУ¬ÏûÏ¢µÄÅäÖÃ`isWaitStoreMsgOK = true`£¬Õâ¸öÅäÖÃĬÈÏÒ²ÊÇ`true`£¬Èç¹ûÄãÅäÖÃΪ`false`£¬ÔÚ·¢ËÍÏûÏ¢µÄ¹ý³ÌÖУ¬Ö»Òª²»·¢ÉúÒì³££¬·¢Ëͽá¹û¶¼ÊÇ`SEND_OK`¡£µ±`isWaitStoreMsgOK = true`£¬·¢Ëͽá¹ûÓÐÒÔϼ¸ÖÖ£¬ + +* `FLUSH_DISK_TIMEOUT`£º±£´æ´ÅÅ̳¬Ê±£¬µ±±£´æ´ÅÅ̵ķ½Ê½ÉèÖÃΪSYNC_FLUSH£¨Í¬²½£©£¬²¢ÇÒÔÚsyncFlushTimeoutÅäÖõÄʱ¼äÄÚ£¨Ä¬ÈÏ5s£©£¬Ã»ÓÐÍê³É±£´æ´ÅÅ̵͝×÷£¬½«»áµÃµ½Õâ¸ö״̬¡£ +* `FLUSH_SLAVE_TIMEOUT`£ºÍ¬²½¡°´Ó¡±³¬Ê±£¬µ±brokerµÄ½ÇÉ«ÉèÖÃΪ¡°Í¬²½Ö÷¡±Ê±£¬µ«ÊÇÔÚÉèÖõÄͬ²½Ê±¼äÄÚ£¬Ä¬ÈÏΪ5s£¬Ã»ÓÐÍê³ÉÖ÷´ÓÖ®¼äµÄͬ²½£¬¾Í»áµÃµ½Õâ¸ö״̬¡£ +* `SLAVE_NOT_AVAILABLE`£º¡°´Ó¡±²»¿ÉÓ㬵±ÎÒÃÇÉèÖá°Í¬²½Ö÷¡±£¬µ«ÊÇûÓÐÅäÖá°´Ó¡±brokerʱ£¬»á·µ»ØÕâ¸ö״̬¡£ +* `SEND_OK`£ºÏûÏ¢·¢Ëͳɹ¦¡£ + +ÔÙÀ´¿´¿´ÏûÏ¢ÖØ¸´ÓëÏûÏ¢¶ªÊ§£¬µ±Äã·¢ÏÖÄãµÄÏûÏ¢¶ªÊ§Ê±£¬Í¨³£ÓÐÁ½¸öÑ¡Ôñ£¬Ò»¸öÊǶª¾Í¶ª°É£¬ÕâÑùÏûÏ¢¾ÍÕæµÄ¶ªÁË£»ÁíÒ»¸öÑ¡ÔñÊÇÏûÏ¢ÖØÐ·¢ËÍ£¬ÕâÑùÓпÉÄÜÒýÆðÏûÏ¢ÖØ¸´¡£Í¨³£Çé¿öÏ£¬»¹ÊÇÍÆ¼öÖØÐ·¢Ë͵ģ¬ÎÒÃÇÔÚÏû·ÑÏûÏ¢µÄʱºòҪȥ³ýµôÖØ¸´µÄÏûÏ¢¡£ + +·¢ËÍmessageµÄ´óСһ°ã²»³¬¹ý512k£¬Ä¬Èϵķ¢ËÍÏûÏ¢µÄ·½Ê½ÊÇͬ²½µÄ£¬·¢ËÍ·½·¨»áÒ»Ö±×èÈû£¬Ö±µ½µÈµ½·µ»ØµÄÏìÓ¦¡£Èç¹ûÄã±È½ÏÔÚÒâÐÔÄÜ£¬Ò²¿ÉÒÔÓÃ`send(msg, callback)`Òì²½µÄ·½Ê½·¢ËÍÏûÏ¢¡£ + +## Ïû·ÑÕß + +¶à¸öÏû·ÑÕß¿ÉÒÔ×é³É**Ïû·ÑÕß×飨consumer group£©**£¬²»Í¬µÄ**Ïû·ÑÕß×é**¿ÉÒÔ¶©ÔÄÏàͬµÄTopic£¬Ò²¿ÉÒÔ¶ÀÁ¢µÄÏû·ÑTopic£¬Ã¿Ò»¸öÏû·ÑÕß×é¶¼ÓÐ×Ô¼ºµÄÏû·ÑÆ«ÒÆÁ¿¡£ + +ÏûÏ¢µÄÏû·Ñ·½Ê½Ò»°ãÓÐÁ½ÖÖ£¬Ë³ÐòÏû·ÑºÍ²¢·¢Ïû·Ñ¡£ + +* ˳ÐòÏû·Ñ£ºÏû·ÑÕß½«Ëø×¡ÏûÏ¢¶ÓÁУ¬È·±£ÏûÏ¢°´ÕÕ˳ÐòÒ»¸öÒ»¸öµÄ±»Ïû·Ñµô£¬Ë³ÐòÏû·Ñ»áÒýÆðÒ»²¿·ÖÐÔÄÜËðʧ¡£ÔÚÏû·ÑÏûÏ¢µÄʱºò£¬Èç¹û³öÏÖÒì³££¬²»½¨ÒéÖ±½ÓÅ׳ö£¬¶øÊÇÓ¦¸Ã·µ»Ø`SUSPEND_CURRENT_QUEUE_A_MOMENT`Õâ¸ö״̬£¬Ëü½«¸æËßÏû·ÑÕß¹ýÒ»¶Îʱ¼äºó£¬»áÖØÐÂÏû·ÑÕâ¸öÏûÏ¢¡£ +* ²¢·¢Ïû·Ñ£ºÏû·ÑÕß½«²¢·¢µÄÏû·ÑÏûÏ¢£¬ÕâÖÖ·½Ê½µÄÐÔÄܷdz£ºÃ£¬Ò²ÊÇÍÆ¼öµÄÏû·Ñ·½Ê½¡£ÔÚÏû·ÑµÄ¹ý³ÌÖУ¬Èç¹û³öÏÖÒì³££¬²»½¨ÒéÖ±½ÓÅ׳ö£¬¶øÊÇ·µ»Ø`RECONSUME_LATER`״̬£¬Ëü¸æËßÏû·ÑÕßÏÖÔÚ²»ÄÜÕýÈ·µÄÏû·ÑËü£¬¹ýÒ»¶Îʱ¼äºó£¬»áÔÙ´ÎÏû·ÑËü¡£ + +ÔÚÏû·ÑÕßÄÚ²¿£¬ÊÇʹÓÃ`ThreadPoolExecutor`×÷ΪÏ̳߳صģ¬ÎÒÃÇ¿ÉÒÔͨ¹ý`setConsumeThreadMin`ºÍ`setConsumeThreadMax`ÉèÖÃ×îСÏû·ÑÏ̺߳Í×î´óÏû·ÑÏ̡߳£ + +µ±Ò»¸öеÄÏû·ÑÕß×齨Á¢ÒÔºó£¬ËüÒª¾ö¶¨ÊÇ·ñÏû·Ñ֮ǰµÄÀúÊ·ÏûÏ¢£¬`CONSUME_FROM_LAST_OFFSET`½«ºöÂÔÀúÊ·ÏûÏ¢£¬Ïû·ÑеÄÏûÏ¢¡£`CONSUME_FROM_FIRST_OFFSET`½«Ïû·Ñ¶ÓÁÐÖеÄÿһ¸öÏûÏ¢£¬Ö®Ç°µÄÀúÊ·ÏûÏ¢Ò²»áÔÙÏû·ÑÒ»±é¡£`CONSUME_FROM_TIMESTAMP`¿ÉÒÔÖ¸¶¨Ïû·ÑÏûÏ¢µÄʱ¼ä£¬Ö¸¶¨Ê±¼äÒÔºóµÄÏûÏ¢»á±»Ïû·Ñ¡£ + +Èç¹ûÄãµÄÓ¦Óò»ÄÜÈÝÈÌÖØ¸´Ïû·Ñ£¬ÄÇôÔÚÏû·ÑÏûÏ¢µÄ¹ý³ÌÖУ¬Òª×öºÃÏûÏ¢µÄУÑé¡£ + +ºÃÁË£¬½ñÌì¾Íµ½ÕâÀï°É£¬ÏÂһƪÎÒÃǽ«½éÉÜRocketMQµÄ»·¾³´î½¨¡£ \ No newline at end of file diff --git "a/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\345\237\272\346\234\254\346\246\202\345\277\265.md" "b/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\345\237\272\346\234\254\346\246\202\345\277\265.md" new file mode 100644 index 0000000..7b22bce --- /dev/null +++ "b/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\345\237\272\346\234\254\346\246\202\345\277\265.md" @@ -0,0 +1,62 @@ +# [RocketMQϵÁУ¨Ò»£©»ù±¾¸ÅÄî](https://www.cnblogs.com/boboooo/p/13038950.html) + + + + + +RocketMQÊǰ¢Àï³öÆ·µÄÒ»¿î¿ªÔ´µÄÏûÏ¢Öмä¼þ£¬ÈÃÆäÉùÃû´óÔëµÄ¾ÍÊÇËüµÄÊÂÎñÏûÏ¢µÄ¹¦ÄÜ¡£ÔÚÆóÒµÖУ¬ÏûÏ¢Öмä¼þÑ¡ÔñʹÓÃRocketMQµÄ»¹ÊÇͦ¶àµÄ£¬ÕâһϵÁеÄÎÄÕ¶¼ÊÇÕë¶ÔRocketMQµÄ£¬ÔÛÃÇÏÈ´ÓRocketMQµÄһЩ»ù±¾¸ÅÄîºÍ»·¾³µÄ´î½¨¿ªÊ¼ÁÄÆð¡£ + +RocketMQÓÉ4²¿·Ö×é³É£¬·Ö±ðÊÇ£ºÃû³Æ·þÎñ£¨Name Server£©¡¢ÏûÏ¢¶ÓÁУ¨Brokers£©¡¢Éú²úÕߣ¨producer£©ºÍÏû·ÑÕߣ¨consumer£©¡£Õâ4²¿·Ö¶¼¿ÉÒÔ½øÐÐˮƽÀ©Õ¹£¬´Ó¶ø±ÜÃâµ¥µã¹ÊÕÏ£¬ÈçÏÂͼ£¬ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/1191201-20200603173058174-1551688390.png) + +ÕâÊÇRocketMQ¹ÙÍøÉϵÄÒ»ÕÅͼ£¬·Ç³£ÇåÎúµÄÁгöÁË4¸ö²¿·Ö£¬²¢ÇÒ¶¼ÊǼ¯ÈºÄ£Ê½¡£ÏÂÃæÎÒÃǾͷֱð˵һ˵Õâ4²¿·Ö¡£ + +## Ãû³Æ·þÎñ£¨NameServer£© + +Name Server°çÑݵĽÇÉ«ÊÇÒ»¸ö×¢²áÖÐÐÄ£¬ºÍZookeeperµÄ×÷Óò¶à¡£ËüµÄÖ÷Òª¹¦ÄÜÓÐÁ½¸ö£¬ÈçÏ£º + +* brokerµÄ¹ÜÀí£ºbroker¼¯Èº½«×Ô¼ºµÄÐÅÏ¢×¢²áµ½NameServer£¬NameServerÌṩÐÄÌø»úÖÆ¼ì²âÿһ¸öbrokerÊÇ·ñÕý³£¡£ +* ·ÓɹÜÀí£ºÃ¿Ò»¸öNameServer¶¼ÓÐÕû¸öbroker¼¯ÈººÍ¶ÓÁеÄÐÅÏ¢£¬ÒÔ±ã¿Í»§¶Ë£¨Éú²úÕߺÍÏû·ÑÕߣ©²éѯ¡£ + +NameServerЭµ÷×Å·Ö²¼Ê½ÏµÍ³ÖеÄÿһ¸ö×é¼þ£¬²¢ÇÒ¹ÜÀí×Åÿһ¸öTopicµÄ·ÓÉÐÅÏ¢¡£ + +## Broker + +BrokerÖ÷ÒªÊÇ´æ´¢ÏûÏ¢£¬²¢ÇÒÌṩTopicµÄ»úÖÆ¡£ËüÌá¹©ÍÆºÍÀ­Á½ÖÖģʽ£¬»¹ÓÐһЩÈÝÔֵĴëÊ©£¬±ÈÈç¿ÉÒÔÅäÖÃÏûÏ¢¸±±¾¡£ÏÂÃæÎÒÃÇ¿´Ò»¿´BrokcerµÄÖ÷´Ó»úÖÆ¡£ + +BrokerµÄ½ÇÉ«·ÖΪ¡°Òì²½Ö÷¡±¡¢¡°Í¬²½Ö÷¡±ºÍ¡°´Ó¡±Èý¸ö½ÇÉ«¡£Èç¹ûÄã²»ÄÜÈÝÈÌÏûÏ¢µÄ¶ªÊ§£¬Äã¿ÉÒÔÅäÖÃÒ»¸ö¡°Í¬²½Ö÷¡±ºÍ¡°´Ó¡±Á½¸öBroker£¬Èç¹ûÄã¾õµÃÏûÏ¢¶ªÊ§Ò²ÎÞËùν£¬Ö»Òª¶ÓÁпÉÓþÍokµÄ»°£¬Äã¿ÉÒÔÅäÖá°Òì²½Ö÷¡±ºÍ¡°´Ó¡±Á½¸öbroker¡£Èç¹ûÄãÖ»ÊÇÏë¼òµ¥µÄ´î½¨£¬Ö»ÅäÖÃÒ»¸ö¡°Òì²½Ö÷¡±£¬²»ÅäÖá°´Ó¡±Ò²ÊÇ¿ÉÒԵġ£ + +ÉÏÃæÌáµ½µÄÊÇbrokerÖ®¼äµÄ±¸·Ý£¬brokerÀïµÄÐÅÏ¢Ò²ÊÇ¿ÉÒÔ±£´æµ½´ÅÅ̵쬱£´æµ½´ÅÅ̵ķ½Ê½Ò²ÓÐÁ½ÖÖ£¬ÍƼöµÄ·½Ê½ÊÇÒì²½±£´æ´ÅÅÌ£¬Í¬²½±£´æ´ÅÅÌÊǷdz£ËðºÄÐÔÄܵġ£ + +## Éú²úÕß + +Éú²úÕßÖ§³Ö¼¯Èº²¿Êð£¬ËüÃÇÏòbroker¼¯Èº·¢ËÍÏûÏ¢£¬¶øÇÒÖ§³Ö¶àÖÖ¸ºÔؾùºâµÄ·½Ê½¡£ + +µ±Éú²úÕßÏòbroker·¢ËÍÏûϢʱ£¬»áµÃµ½·¢Ëͽá¹û£¬·¢Ëͽá¹ûÖÐÓÐÒ»¸ö·¢ËÍ״̬¡£¼ÙÉèÎÒÃǵÄÅäÖÃÖУ¬ÏûÏ¢µÄÅäÖÃ`isWaitStoreMsgOK = true`£¬Õâ¸öÅäÖÃĬÈÏÒ²ÊÇ`true`£¬Èç¹ûÄãÅäÖÃΪ`false`£¬ÔÚ·¢ËÍÏûÏ¢µÄ¹ý³ÌÖУ¬Ö»Òª²»·¢ÉúÒì³££¬·¢Ëͽá¹û¶¼ÊÇ`SEND_OK`¡£µ±`isWaitStoreMsgOK = true`£¬·¢Ëͽá¹ûÓÐÒÔϼ¸ÖÖ£¬ + +* `FLUSH_DISK_TIMEOUT`£º±£´æ´ÅÅ̳¬Ê±£¬µ±±£´æ´ÅÅ̵ķ½Ê½ÉèÖÃΪSYNC_FLUSH£¨Í¬²½£©£¬²¢ÇÒÔÚsyncFlushTimeoutÅäÖõÄʱ¼äÄÚ£¨Ä¬ÈÏ5s£©£¬Ã»ÓÐÍê³É±£´æ´ÅÅ̵͝×÷£¬½«»áµÃµ½Õâ¸ö״̬¡£ +* `FLUSH_SLAVE_TIMEOUT`£ºÍ¬²½¡°´Ó¡±³¬Ê±£¬µ±brokerµÄ½ÇÉ«ÉèÖÃΪ¡°Í¬²½Ö÷¡±Ê±£¬µ«ÊÇÔÚÉèÖõÄͬ²½Ê±¼äÄÚ£¬Ä¬ÈÏΪ5s£¬Ã»ÓÐÍê³ÉÖ÷´ÓÖ®¼äµÄͬ²½£¬¾Í»áµÃµ½Õâ¸ö״̬¡£ +* `SLAVE_NOT_AVAILABLE`£º¡°´Ó¡±²»¿ÉÓ㬵±ÎÒÃÇÉèÖá°Í¬²½Ö÷¡±£¬µ«ÊÇûÓÐÅäÖá°´Ó¡±brokerʱ£¬»á·µ»ØÕâ¸ö״̬¡£ +* `SEND_OK`£ºÏûÏ¢·¢Ëͳɹ¦¡£ + +ÔÙÀ´¿´¿´ÏûÏ¢ÖØ¸´ÓëÏûÏ¢¶ªÊ§£¬µ±Äã·¢ÏÖÄãµÄÏûÏ¢¶ªÊ§Ê±£¬Í¨³£ÓÐÁ½¸öÑ¡Ôñ£¬Ò»¸öÊǶª¾Í¶ª°É£¬ÕâÑùÏûÏ¢¾ÍÕæµÄ¶ªÁË£»ÁíÒ»¸öÑ¡ÔñÊÇÏûÏ¢ÖØÐ·¢ËÍ£¬ÕâÑùÓпÉÄÜÒýÆðÏûÏ¢ÖØ¸´¡£Í¨³£Çé¿öÏ£¬»¹ÊÇÍÆ¼öÖØÐ·¢Ë͵ģ¬ÎÒÃÇÔÚÏû·ÑÏûÏ¢µÄʱºòҪȥ³ýµôÖØ¸´µÄÏûÏ¢¡£ + +·¢ËÍmessageµÄ´óСһ°ã²»³¬¹ý512k£¬Ä¬Èϵķ¢ËÍÏûÏ¢µÄ·½Ê½ÊÇͬ²½µÄ£¬·¢ËÍ·½·¨»áÒ»Ö±×èÈû£¬Ö±µ½µÈµ½·µ»ØµÄÏìÓ¦¡£Èç¹ûÄã±È½ÏÔÚÒâÐÔÄÜ£¬Ò²¿ÉÒÔÓÃ`send(msg, callback)`Òì²½µÄ·½Ê½·¢ËÍÏûÏ¢¡£ + +## Ïû·ÑÕß + +¶à¸öÏû·ÑÕß¿ÉÒÔ×é³É**Ïû·ÑÕß×飨consumer group£©**£¬²»Í¬µÄ**Ïû·ÑÕß×é**¿ÉÒÔ¶©ÔÄÏàͬµÄTopic£¬Ò²¿ÉÒÔ¶ÀÁ¢µÄÏû·ÑTopic£¬Ã¿Ò»¸öÏû·ÑÕß×é¶¼ÓÐ×Ô¼ºµÄÏû·ÑÆ«ÒÆÁ¿¡£ + +ÏûÏ¢µÄÏû·Ñ·½Ê½Ò»°ãÓÐÁ½ÖÖ£¬Ë³ÐòÏû·ÑºÍ²¢·¢Ïû·Ñ¡£ + +* ˳ÐòÏû·Ñ£ºÏû·ÑÕß½«Ëø×¡ÏûÏ¢¶ÓÁУ¬È·±£ÏûÏ¢°´ÕÕ˳ÐòÒ»¸öÒ»¸öµÄ±»Ïû·Ñµô£¬Ë³ÐòÏû·Ñ»áÒýÆðÒ»²¿·ÖÐÔÄÜËðʧ¡£ÔÚÏû·ÑÏûÏ¢µÄʱºò£¬Èç¹û³öÏÖÒì³££¬²»½¨ÒéÖ±½ÓÅ׳ö£¬¶øÊÇÓ¦¸Ã·µ»Ø`SUSPEND_CURRENT_QUEUE_A_MOMENT`Õâ¸ö״̬£¬Ëü½«¸æËßÏû·ÑÕß¹ýÒ»¶Îʱ¼äºó£¬»áÖØÐÂÏû·ÑÕâ¸öÏûÏ¢¡£ +* ²¢·¢Ïû·Ñ£ºÏû·ÑÕß½«²¢·¢µÄÏû·ÑÏûÏ¢£¬ÕâÖÖ·½Ê½µÄÐÔÄܷdz£ºÃ£¬Ò²ÊÇÍÆ¼öµÄÏû·Ñ·½Ê½¡£ÔÚÏû·ÑµÄ¹ý³ÌÖУ¬Èç¹û³öÏÖÒì³££¬²»½¨ÒéÖ±½ÓÅ׳ö£¬¶øÊÇ·µ»Ø`RECONSUME_LATER`״̬£¬Ëü¸æËßÏû·ÑÕßÏÖÔÚ²»ÄÜÕýÈ·µÄÏû·ÑËü£¬¹ýÒ»¶Îʱ¼äºó£¬»áÔÙ´ÎÏû·ÑËü¡£ + +ÔÚÏû·ÑÕßÄÚ²¿£¬ÊÇʹÓÃ`ThreadPoolExecutor`×÷ΪÏ̳߳صģ¬ÎÒÃÇ¿ÉÒÔͨ¹ý`setConsumeThreadMin`ºÍ`setConsumeThreadMax`ÉèÖÃ×îСÏû·ÑÏ̺߳Í×î´óÏû·ÑÏ̡߳£ + +µ±Ò»¸öеÄÏû·ÑÕß×齨Á¢ÒÔºó£¬ËüÒª¾ö¶¨ÊÇ·ñÏû·Ñ֮ǰµÄÀúÊ·ÏûÏ¢£¬`CONSUME_FROM_LAST_OFFSET`½«ºöÂÔÀúÊ·ÏûÏ¢£¬Ïû·ÑеÄÏûÏ¢¡£`CONSUME_FROM_FIRST_OFFSET`½«Ïû·Ñ¶ÓÁÐÖеÄÿһ¸öÏûÏ¢£¬Ö®Ç°µÄÀúÊ·ÏûÏ¢Ò²»áÔÙÏû·ÑÒ»±é¡£`CONSUME_FROM_TIMESTAMP`¿ÉÒÔÖ¸¶¨Ïû·ÑÏûÏ¢µÄʱ¼ä£¬Ö¸¶¨Ê±¼äÒÔºóµÄÏûÏ¢»á±»Ïû·Ñ¡£ + +Èç¹ûÄãµÄÓ¦Óò»ÄÜÈÝÈÌÖØ¸´Ïû·Ñ£¬ÄÇôÔÚÏû·ÑÏûÏ¢µÄ¹ý³ÌÖУ¬Òª×öºÃÏûÏ¢µÄУÑé¡£ + +ºÃÁË£¬½ñÌì¾Íµ½ÕâÀï°É£¬ÏÂһƪÎÒÃǽ«½éÉÜRocketMQµÄ»·¾³´î½¨¡£ \ No newline at end of file diff --git "a/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\345\271\277\346\222\255\344\270\216\345\273\266\350\277\237\346\266\210\346\201\257.md" "b/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\345\271\277\346\222\255\344\270\216\345\273\266\350\277\237\346\266\210\346\201\257.md" new file mode 100644 index 0000000..7b22bce --- /dev/null +++ "b/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\345\271\277\346\222\255\344\270\216\345\273\266\350\277\237\346\266\210\346\201\257.md" @@ -0,0 +1,62 @@ +# [RocketMQϵÁУ¨Ò»£©»ù±¾¸ÅÄî](https://www.cnblogs.com/boboooo/p/13038950.html) + + + + + +RocketMQÊǰ¢Àï³öÆ·µÄÒ»¿î¿ªÔ´µÄÏûÏ¢Öмä¼þ£¬ÈÃÆäÉùÃû´óÔëµÄ¾ÍÊÇËüµÄÊÂÎñÏûÏ¢µÄ¹¦ÄÜ¡£ÔÚÆóÒµÖУ¬ÏûÏ¢Öмä¼þÑ¡ÔñʹÓÃRocketMQµÄ»¹ÊÇͦ¶àµÄ£¬ÕâһϵÁеÄÎÄÕ¶¼ÊÇÕë¶ÔRocketMQµÄ£¬ÔÛÃÇÏÈ´ÓRocketMQµÄһЩ»ù±¾¸ÅÄîºÍ»·¾³µÄ´î½¨¿ªÊ¼ÁÄÆð¡£ + +RocketMQÓÉ4²¿·Ö×é³É£¬·Ö±ðÊÇ£ºÃû³Æ·þÎñ£¨Name Server£©¡¢ÏûÏ¢¶ÓÁУ¨Brokers£©¡¢Éú²úÕߣ¨producer£©ºÍÏû·ÑÕߣ¨consumer£©¡£Õâ4²¿·Ö¶¼¿ÉÒÔ½øÐÐˮƽÀ©Õ¹£¬´Ó¶ø±ÜÃâµ¥µã¹ÊÕÏ£¬ÈçÏÂͼ£¬ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/1191201-20200603173058174-1551688390.png) + +ÕâÊÇRocketMQ¹ÙÍøÉϵÄÒ»ÕÅͼ£¬·Ç³£ÇåÎúµÄÁгöÁË4¸ö²¿·Ö£¬²¢ÇÒ¶¼ÊǼ¯ÈºÄ£Ê½¡£ÏÂÃæÎÒÃǾͷֱð˵һ˵Õâ4²¿·Ö¡£ + +## Ãû³Æ·þÎñ£¨NameServer£© + +Name Server°çÑݵĽÇÉ«ÊÇÒ»¸ö×¢²áÖÐÐÄ£¬ºÍZookeeperµÄ×÷Óò¶à¡£ËüµÄÖ÷Òª¹¦ÄÜÓÐÁ½¸ö£¬ÈçÏ£º + +* brokerµÄ¹ÜÀí£ºbroker¼¯Èº½«×Ô¼ºµÄÐÅÏ¢×¢²áµ½NameServer£¬NameServerÌṩÐÄÌø»úÖÆ¼ì²âÿһ¸öbrokerÊÇ·ñÕý³£¡£ +* ·ÓɹÜÀí£ºÃ¿Ò»¸öNameServer¶¼ÓÐÕû¸öbroker¼¯ÈººÍ¶ÓÁеÄÐÅÏ¢£¬ÒÔ±ã¿Í»§¶Ë£¨Éú²úÕߺÍÏû·ÑÕߣ©²éѯ¡£ + +NameServerЭµ÷×Å·Ö²¼Ê½ÏµÍ³ÖеÄÿһ¸ö×é¼þ£¬²¢ÇÒ¹ÜÀí×Åÿһ¸öTopicµÄ·ÓÉÐÅÏ¢¡£ + +## Broker + +BrokerÖ÷ÒªÊÇ´æ´¢ÏûÏ¢£¬²¢ÇÒÌṩTopicµÄ»úÖÆ¡£ËüÌá¹©ÍÆºÍÀ­Á½ÖÖģʽ£¬»¹ÓÐһЩÈÝÔֵĴëÊ©£¬±ÈÈç¿ÉÒÔÅäÖÃÏûÏ¢¸±±¾¡£ÏÂÃæÎÒÃÇ¿´Ò»¿´BrokcerµÄÖ÷´Ó»úÖÆ¡£ + +BrokerµÄ½ÇÉ«·ÖΪ¡°Òì²½Ö÷¡±¡¢¡°Í¬²½Ö÷¡±ºÍ¡°´Ó¡±Èý¸ö½ÇÉ«¡£Èç¹ûÄã²»ÄÜÈÝÈÌÏûÏ¢µÄ¶ªÊ§£¬Äã¿ÉÒÔÅäÖÃÒ»¸ö¡°Í¬²½Ö÷¡±ºÍ¡°´Ó¡±Á½¸öBroker£¬Èç¹ûÄã¾õµÃÏûÏ¢¶ªÊ§Ò²ÎÞËùν£¬Ö»Òª¶ÓÁпÉÓþÍokµÄ»°£¬Äã¿ÉÒÔÅäÖá°Òì²½Ö÷¡±ºÍ¡°´Ó¡±Á½¸öbroker¡£Èç¹ûÄãÖ»ÊÇÏë¼òµ¥µÄ´î½¨£¬Ö»ÅäÖÃÒ»¸ö¡°Òì²½Ö÷¡±£¬²»ÅäÖá°´Ó¡±Ò²ÊÇ¿ÉÒԵġ£ + +ÉÏÃæÌáµ½µÄÊÇbrokerÖ®¼äµÄ±¸·Ý£¬brokerÀïµÄÐÅÏ¢Ò²ÊÇ¿ÉÒÔ±£´æµ½´ÅÅ̵쬱£´æµ½´ÅÅ̵ķ½Ê½Ò²ÓÐÁ½ÖÖ£¬ÍƼöµÄ·½Ê½ÊÇÒì²½±£´æ´ÅÅÌ£¬Í¬²½±£´æ´ÅÅÌÊǷdz£ËðºÄÐÔÄܵġ£ + +## Éú²úÕß + +Éú²úÕßÖ§³Ö¼¯Èº²¿Êð£¬ËüÃÇÏòbroker¼¯Èº·¢ËÍÏûÏ¢£¬¶øÇÒÖ§³Ö¶àÖÖ¸ºÔؾùºâµÄ·½Ê½¡£ + +µ±Éú²úÕßÏòbroker·¢ËÍÏûϢʱ£¬»áµÃµ½·¢Ëͽá¹û£¬·¢Ëͽá¹ûÖÐÓÐÒ»¸ö·¢ËÍ״̬¡£¼ÙÉèÎÒÃǵÄÅäÖÃÖУ¬ÏûÏ¢µÄÅäÖÃ`isWaitStoreMsgOK = true`£¬Õâ¸öÅäÖÃĬÈÏÒ²ÊÇ`true`£¬Èç¹ûÄãÅäÖÃΪ`false`£¬ÔÚ·¢ËÍÏûÏ¢µÄ¹ý³ÌÖУ¬Ö»Òª²»·¢ÉúÒì³££¬·¢Ëͽá¹û¶¼ÊÇ`SEND_OK`¡£µ±`isWaitStoreMsgOK = true`£¬·¢Ëͽá¹ûÓÐÒÔϼ¸ÖÖ£¬ + +* `FLUSH_DISK_TIMEOUT`£º±£´æ´ÅÅ̳¬Ê±£¬µ±±£´æ´ÅÅ̵ķ½Ê½ÉèÖÃΪSYNC_FLUSH£¨Í¬²½£©£¬²¢ÇÒÔÚsyncFlushTimeoutÅäÖõÄʱ¼äÄÚ£¨Ä¬ÈÏ5s£©£¬Ã»ÓÐÍê³É±£´æ´ÅÅ̵͝×÷£¬½«»áµÃµ½Õâ¸ö״̬¡£ +* `FLUSH_SLAVE_TIMEOUT`£ºÍ¬²½¡°´Ó¡±³¬Ê±£¬µ±brokerµÄ½ÇÉ«ÉèÖÃΪ¡°Í¬²½Ö÷¡±Ê±£¬µ«ÊÇÔÚÉèÖõÄͬ²½Ê±¼äÄÚ£¬Ä¬ÈÏΪ5s£¬Ã»ÓÐÍê³ÉÖ÷´ÓÖ®¼äµÄͬ²½£¬¾Í»áµÃµ½Õâ¸ö״̬¡£ +* `SLAVE_NOT_AVAILABLE`£º¡°´Ó¡±²»¿ÉÓ㬵±ÎÒÃÇÉèÖá°Í¬²½Ö÷¡±£¬µ«ÊÇûÓÐÅäÖá°´Ó¡±brokerʱ£¬»á·µ»ØÕâ¸ö״̬¡£ +* `SEND_OK`£ºÏûÏ¢·¢Ëͳɹ¦¡£ + +ÔÙÀ´¿´¿´ÏûÏ¢ÖØ¸´ÓëÏûÏ¢¶ªÊ§£¬µ±Äã·¢ÏÖÄãµÄÏûÏ¢¶ªÊ§Ê±£¬Í¨³£ÓÐÁ½¸öÑ¡Ôñ£¬Ò»¸öÊǶª¾Í¶ª°É£¬ÕâÑùÏûÏ¢¾ÍÕæµÄ¶ªÁË£»ÁíÒ»¸öÑ¡ÔñÊÇÏûÏ¢ÖØÐ·¢ËÍ£¬ÕâÑùÓпÉÄÜÒýÆðÏûÏ¢ÖØ¸´¡£Í¨³£Çé¿öÏ£¬»¹ÊÇÍÆ¼öÖØÐ·¢Ë͵ģ¬ÎÒÃÇÔÚÏû·ÑÏûÏ¢µÄʱºòҪȥ³ýµôÖØ¸´µÄÏûÏ¢¡£ + +·¢ËÍmessageµÄ´óСһ°ã²»³¬¹ý512k£¬Ä¬Èϵķ¢ËÍÏûÏ¢µÄ·½Ê½ÊÇͬ²½µÄ£¬·¢ËÍ·½·¨»áÒ»Ö±×èÈû£¬Ö±µ½µÈµ½·µ»ØµÄÏìÓ¦¡£Èç¹ûÄã±È½ÏÔÚÒâÐÔÄÜ£¬Ò²¿ÉÒÔÓÃ`send(msg, callback)`Òì²½µÄ·½Ê½·¢ËÍÏûÏ¢¡£ + +## Ïû·ÑÕß + +¶à¸öÏû·ÑÕß¿ÉÒÔ×é³É**Ïû·ÑÕß×飨consumer group£©**£¬²»Í¬µÄ**Ïû·ÑÕß×é**¿ÉÒÔ¶©ÔÄÏàͬµÄTopic£¬Ò²¿ÉÒÔ¶ÀÁ¢µÄÏû·ÑTopic£¬Ã¿Ò»¸öÏû·ÑÕß×é¶¼ÓÐ×Ô¼ºµÄÏû·ÑÆ«ÒÆÁ¿¡£ + +ÏûÏ¢µÄÏû·Ñ·½Ê½Ò»°ãÓÐÁ½ÖÖ£¬Ë³ÐòÏû·ÑºÍ²¢·¢Ïû·Ñ¡£ + +* ˳ÐòÏû·Ñ£ºÏû·ÑÕß½«Ëø×¡ÏûÏ¢¶ÓÁУ¬È·±£ÏûÏ¢°´ÕÕ˳ÐòÒ»¸öÒ»¸öµÄ±»Ïû·Ñµô£¬Ë³ÐòÏû·Ñ»áÒýÆðÒ»²¿·ÖÐÔÄÜËðʧ¡£ÔÚÏû·ÑÏûÏ¢µÄʱºò£¬Èç¹û³öÏÖÒì³££¬²»½¨ÒéÖ±½ÓÅ׳ö£¬¶øÊÇÓ¦¸Ã·µ»Ø`SUSPEND_CURRENT_QUEUE_A_MOMENT`Õâ¸ö״̬£¬Ëü½«¸æËßÏû·ÑÕß¹ýÒ»¶Îʱ¼äºó£¬»áÖØÐÂÏû·ÑÕâ¸öÏûÏ¢¡£ +* ²¢·¢Ïû·Ñ£ºÏû·ÑÕß½«²¢·¢µÄÏû·ÑÏûÏ¢£¬ÕâÖÖ·½Ê½µÄÐÔÄܷdz£ºÃ£¬Ò²ÊÇÍÆ¼öµÄÏû·Ñ·½Ê½¡£ÔÚÏû·ÑµÄ¹ý³ÌÖУ¬Èç¹û³öÏÖÒì³££¬²»½¨ÒéÖ±½ÓÅ׳ö£¬¶øÊÇ·µ»Ø`RECONSUME_LATER`״̬£¬Ëü¸æËßÏû·ÑÕßÏÖÔÚ²»ÄÜÕýÈ·µÄÏû·ÑËü£¬¹ýÒ»¶Îʱ¼äºó£¬»áÔÙ´ÎÏû·ÑËü¡£ + +ÔÚÏû·ÑÕßÄÚ²¿£¬ÊÇʹÓÃ`ThreadPoolExecutor`×÷ΪÏ̳߳صģ¬ÎÒÃÇ¿ÉÒÔͨ¹ý`setConsumeThreadMin`ºÍ`setConsumeThreadMax`ÉèÖÃ×îСÏû·ÑÏ̺߳Í×î´óÏû·ÑÏ̡߳£ + +µ±Ò»¸öеÄÏû·ÑÕß×齨Á¢ÒÔºó£¬ËüÒª¾ö¶¨ÊÇ·ñÏû·Ñ֮ǰµÄÀúÊ·ÏûÏ¢£¬`CONSUME_FROM_LAST_OFFSET`½«ºöÂÔÀúÊ·ÏûÏ¢£¬Ïû·ÑеÄÏûÏ¢¡£`CONSUME_FROM_FIRST_OFFSET`½«Ïû·Ñ¶ÓÁÐÖеÄÿһ¸öÏûÏ¢£¬Ö®Ç°µÄÀúÊ·ÏûÏ¢Ò²»áÔÙÏû·ÑÒ»±é¡£`CONSUME_FROM_TIMESTAMP`¿ÉÒÔÖ¸¶¨Ïû·ÑÏûÏ¢µÄʱ¼ä£¬Ö¸¶¨Ê±¼äÒÔºóµÄÏûÏ¢»á±»Ïû·Ñ¡£ + +Èç¹ûÄãµÄÓ¦Óò»ÄÜÈÝÈÌÖØ¸´Ïû·Ñ£¬ÄÇôÔÚÏû·ÑÏûÏ¢µÄ¹ý³ÌÖУ¬Òª×öºÃÏûÏ¢µÄУÑé¡£ + +ºÃÁË£¬½ñÌì¾Íµ½ÕâÀï°É£¬ÏÂһƪÎÒÃǽ«½éÉÜRocketMQµÄ»·¾³´î½¨¡£ \ No newline at end of file diff --git "a/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\346\211\271\351\207\217\345\217\221\351\200\201\344\270\216\350\277\207\346\273\244.md" "b/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\346\211\271\351\207\217\345\217\221\351\200\201\344\270\216\350\277\207\346\273\244.md" new file mode 100644 index 0000000..7b22bce --- /dev/null +++ "b/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\346\211\271\351\207\217\345\217\221\351\200\201\344\270\216\350\277\207\346\273\244.md" @@ -0,0 +1,62 @@ +# [RocketMQϵÁУ¨Ò»£©»ù±¾¸ÅÄî](https://www.cnblogs.com/boboooo/p/13038950.html) + + + + + +RocketMQÊǰ¢Àï³öÆ·µÄÒ»¿î¿ªÔ´µÄÏûÏ¢Öмä¼þ£¬ÈÃÆäÉùÃû´óÔëµÄ¾ÍÊÇËüµÄÊÂÎñÏûÏ¢µÄ¹¦ÄÜ¡£ÔÚÆóÒµÖУ¬ÏûÏ¢Öмä¼þÑ¡ÔñʹÓÃRocketMQµÄ»¹ÊÇͦ¶àµÄ£¬ÕâһϵÁеÄÎÄÕ¶¼ÊÇÕë¶ÔRocketMQµÄ£¬ÔÛÃÇÏÈ´ÓRocketMQµÄһЩ»ù±¾¸ÅÄîºÍ»·¾³µÄ´î½¨¿ªÊ¼ÁÄÆð¡£ + +RocketMQÓÉ4²¿·Ö×é³É£¬·Ö±ðÊÇ£ºÃû³Æ·þÎñ£¨Name Server£©¡¢ÏûÏ¢¶ÓÁУ¨Brokers£©¡¢Éú²úÕߣ¨producer£©ºÍÏû·ÑÕߣ¨consumer£©¡£Õâ4²¿·Ö¶¼¿ÉÒÔ½øÐÐˮƽÀ©Õ¹£¬´Ó¶ø±ÜÃâµ¥µã¹ÊÕÏ£¬ÈçÏÂͼ£¬ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/1191201-20200603173058174-1551688390.png) + +ÕâÊÇRocketMQ¹ÙÍøÉϵÄÒ»ÕÅͼ£¬·Ç³£ÇåÎúµÄÁгöÁË4¸ö²¿·Ö£¬²¢ÇÒ¶¼ÊǼ¯ÈºÄ£Ê½¡£ÏÂÃæÎÒÃǾͷֱð˵һ˵Õâ4²¿·Ö¡£ + +## Ãû³Æ·þÎñ£¨NameServer£© + +Name Server°çÑݵĽÇÉ«ÊÇÒ»¸ö×¢²áÖÐÐÄ£¬ºÍZookeeperµÄ×÷Óò¶à¡£ËüµÄÖ÷Òª¹¦ÄÜÓÐÁ½¸ö£¬ÈçÏ£º + +* brokerµÄ¹ÜÀí£ºbroker¼¯Èº½«×Ô¼ºµÄÐÅÏ¢×¢²áµ½NameServer£¬NameServerÌṩÐÄÌø»úÖÆ¼ì²âÿһ¸öbrokerÊÇ·ñÕý³£¡£ +* ·ÓɹÜÀí£ºÃ¿Ò»¸öNameServer¶¼ÓÐÕû¸öbroker¼¯ÈººÍ¶ÓÁеÄÐÅÏ¢£¬ÒÔ±ã¿Í»§¶Ë£¨Éú²úÕߺÍÏû·ÑÕߣ©²éѯ¡£ + +NameServerЭµ÷×Å·Ö²¼Ê½ÏµÍ³ÖеÄÿһ¸ö×é¼þ£¬²¢ÇÒ¹ÜÀí×Åÿһ¸öTopicµÄ·ÓÉÐÅÏ¢¡£ + +## Broker + +BrokerÖ÷ÒªÊÇ´æ´¢ÏûÏ¢£¬²¢ÇÒÌṩTopicµÄ»úÖÆ¡£ËüÌá¹©ÍÆºÍÀ­Á½ÖÖģʽ£¬»¹ÓÐһЩÈÝÔֵĴëÊ©£¬±ÈÈç¿ÉÒÔÅäÖÃÏûÏ¢¸±±¾¡£ÏÂÃæÎÒÃÇ¿´Ò»¿´BrokcerµÄÖ÷´Ó»úÖÆ¡£ + +BrokerµÄ½ÇÉ«·ÖΪ¡°Òì²½Ö÷¡±¡¢¡°Í¬²½Ö÷¡±ºÍ¡°´Ó¡±Èý¸ö½ÇÉ«¡£Èç¹ûÄã²»ÄÜÈÝÈÌÏûÏ¢µÄ¶ªÊ§£¬Äã¿ÉÒÔÅäÖÃÒ»¸ö¡°Í¬²½Ö÷¡±ºÍ¡°´Ó¡±Á½¸öBroker£¬Èç¹ûÄã¾õµÃÏûÏ¢¶ªÊ§Ò²ÎÞËùν£¬Ö»Òª¶ÓÁпÉÓþÍokµÄ»°£¬Äã¿ÉÒÔÅäÖá°Òì²½Ö÷¡±ºÍ¡°´Ó¡±Á½¸öbroker¡£Èç¹ûÄãÖ»ÊÇÏë¼òµ¥µÄ´î½¨£¬Ö»ÅäÖÃÒ»¸ö¡°Òì²½Ö÷¡±£¬²»ÅäÖá°´Ó¡±Ò²ÊÇ¿ÉÒԵġ£ + +ÉÏÃæÌáµ½µÄÊÇbrokerÖ®¼äµÄ±¸·Ý£¬brokerÀïµÄÐÅÏ¢Ò²ÊÇ¿ÉÒÔ±£´æµ½´ÅÅ̵쬱£´æµ½´ÅÅ̵ķ½Ê½Ò²ÓÐÁ½ÖÖ£¬ÍƼöµÄ·½Ê½ÊÇÒì²½±£´æ´ÅÅÌ£¬Í¬²½±£´æ´ÅÅÌÊǷdz£ËðºÄÐÔÄܵġ£ + +## Éú²úÕß + +Éú²úÕßÖ§³Ö¼¯Èº²¿Êð£¬ËüÃÇÏòbroker¼¯Èº·¢ËÍÏûÏ¢£¬¶øÇÒÖ§³Ö¶àÖÖ¸ºÔؾùºâµÄ·½Ê½¡£ + +µ±Éú²úÕßÏòbroker·¢ËÍÏûϢʱ£¬»áµÃµ½·¢Ëͽá¹û£¬·¢Ëͽá¹ûÖÐÓÐÒ»¸ö·¢ËÍ״̬¡£¼ÙÉèÎÒÃǵÄÅäÖÃÖУ¬ÏûÏ¢µÄÅäÖÃ`isWaitStoreMsgOK = true`£¬Õâ¸öÅäÖÃĬÈÏÒ²ÊÇ`true`£¬Èç¹ûÄãÅäÖÃΪ`false`£¬ÔÚ·¢ËÍÏûÏ¢µÄ¹ý³ÌÖУ¬Ö»Òª²»·¢ÉúÒì³££¬·¢Ëͽá¹û¶¼ÊÇ`SEND_OK`¡£µ±`isWaitStoreMsgOK = true`£¬·¢Ëͽá¹ûÓÐÒÔϼ¸ÖÖ£¬ + +* `FLUSH_DISK_TIMEOUT`£º±£´æ´ÅÅ̳¬Ê±£¬µ±±£´æ´ÅÅ̵ķ½Ê½ÉèÖÃΪSYNC_FLUSH£¨Í¬²½£©£¬²¢ÇÒÔÚsyncFlushTimeoutÅäÖõÄʱ¼äÄÚ£¨Ä¬ÈÏ5s£©£¬Ã»ÓÐÍê³É±£´æ´ÅÅ̵͝×÷£¬½«»áµÃµ½Õâ¸ö״̬¡£ +* `FLUSH_SLAVE_TIMEOUT`£ºÍ¬²½¡°´Ó¡±³¬Ê±£¬µ±brokerµÄ½ÇÉ«ÉèÖÃΪ¡°Í¬²½Ö÷¡±Ê±£¬µ«ÊÇÔÚÉèÖõÄͬ²½Ê±¼äÄÚ£¬Ä¬ÈÏΪ5s£¬Ã»ÓÐÍê³ÉÖ÷´ÓÖ®¼äµÄͬ²½£¬¾Í»áµÃµ½Õâ¸ö״̬¡£ +* `SLAVE_NOT_AVAILABLE`£º¡°´Ó¡±²»¿ÉÓ㬵±ÎÒÃÇÉèÖá°Í¬²½Ö÷¡±£¬µ«ÊÇûÓÐÅäÖá°´Ó¡±brokerʱ£¬»á·µ»ØÕâ¸ö״̬¡£ +* `SEND_OK`£ºÏûÏ¢·¢Ëͳɹ¦¡£ + +ÔÙÀ´¿´¿´ÏûÏ¢ÖØ¸´ÓëÏûÏ¢¶ªÊ§£¬µ±Äã·¢ÏÖÄãµÄÏûÏ¢¶ªÊ§Ê±£¬Í¨³£ÓÐÁ½¸öÑ¡Ôñ£¬Ò»¸öÊǶª¾Í¶ª°É£¬ÕâÑùÏûÏ¢¾ÍÕæµÄ¶ªÁË£»ÁíÒ»¸öÑ¡ÔñÊÇÏûÏ¢ÖØÐ·¢ËÍ£¬ÕâÑùÓпÉÄÜÒýÆðÏûÏ¢ÖØ¸´¡£Í¨³£Çé¿öÏ£¬»¹ÊÇÍÆ¼öÖØÐ·¢Ë͵ģ¬ÎÒÃÇÔÚÏû·ÑÏûÏ¢µÄʱºòҪȥ³ýµôÖØ¸´µÄÏûÏ¢¡£ + +·¢ËÍmessageµÄ´óСһ°ã²»³¬¹ý512k£¬Ä¬Èϵķ¢ËÍÏûÏ¢µÄ·½Ê½ÊÇͬ²½µÄ£¬·¢ËÍ·½·¨»áÒ»Ö±×èÈû£¬Ö±µ½µÈµ½·µ»ØµÄÏìÓ¦¡£Èç¹ûÄã±È½ÏÔÚÒâÐÔÄÜ£¬Ò²¿ÉÒÔÓÃ`send(msg, callback)`Òì²½µÄ·½Ê½·¢ËÍÏûÏ¢¡£ + +## Ïû·ÑÕß + +¶à¸öÏû·ÑÕß¿ÉÒÔ×é³É**Ïû·ÑÕß×飨consumer group£©**£¬²»Í¬µÄ**Ïû·ÑÕß×é**¿ÉÒÔ¶©ÔÄÏàͬµÄTopic£¬Ò²¿ÉÒÔ¶ÀÁ¢µÄÏû·ÑTopic£¬Ã¿Ò»¸öÏû·ÑÕß×é¶¼ÓÐ×Ô¼ºµÄÏû·ÑÆ«ÒÆÁ¿¡£ + +ÏûÏ¢µÄÏû·Ñ·½Ê½Ò»°ãÓÐÁ½ÖÖ£¬Ë³ÐòÏû·ÑºÍ²¢·¢Ïû·Ñ¡£ + +* ˳ÐòÏû·Ñ£ºÏû·ÑÕß½«Ëø×¡ÏûÏ¢¶ÓÁУ¬È·±£ÏûÏ¢°´ÕÕ˳ÐòÒ»¸öÒ»¸öµÄ±»Ïû·Ñµô£¬Ë³ÐòÏû·Ñ»áÒýÆðÒ»²¿·ÖÐÔÄÜËðʧ¡£ÔÚÏû·ÑÏûÏ¢µÄʱºò£¬Èç¹û³öÏÖÒì³££¬²»½¨ÒéÖ±½ÓÅ׳ö£¬¶øÊÇÓ¦¸Ã·µ»Ø`SUSPEND_CURRENT_QUEUE_A_MOMENT`Õâ¸ö״̬£¬Ëü½«¸æËßÏû·ÑÕß¹ýÒ»¶Îʱ¼äºó£¬»áÖØÐÂÏû·ÑÕâ¸öÏûÏ¢¡£ +* ²¢·¢Ïû·Ñ£ºÏû·ÑÕß½«²¢·¢µÄÏû·ÑÏûÏ¢£¬ÕâÖÖ·½Ê½µÄÐÔÄܷdz£ºÃ£¬Ò²ÊÇÍÆ¼öµÄÏû·Ñ·½Ê½¡£ÔÚÏû·ÑµÄ¹ý³ÌÖУ¬Èç¹û³öÏÖÒì³££¬²»½¨ÒéÖ±½ÓÅ׳ö£¬¶øÊÇ·µ»Ø`RECONSUME_LATER`״̬£¬Ëü¸æËßÏû·ÑÕßÏÖÔÚ²»ÄÜÕýÈ·µÄÏû·ÑËü£¬¹ýÒ»¶Îʱ¼äºó£¬»áÔÙ´ÎÏû·ÑËü¡£ + +ÔÚÏû·ÑÕßÄÚ²¿£¬ÊÇʹÓÃ`ThreadPoolExecutor`×÷ΪÏ̳߳صģ¬ÎÒÃÇ¿ÉÒÔͨ¹ý`setConsumeThreadMin`ºÍ`setConsumeThreadMax`ÉèÖÃ×îСÏû·ÑÏ̺߳Í×î´óÏû·ÑÏ̡߳£ + +µ±Ò»¸öеÄÏû·ÑÕß×齨Á¢ÒÔºó£¬ËüÒª¾ö¶¨ÊÇ·ñÏû·Ñ֮ǰµÄÀúÊ·ÏûÏ¢£¬`CONSUME_FROM_LAST_OFFSET`½«ºöÂÔÀúÊ·ÏûÏ¢£¬Ïû·ÑеÄÏûÏ¢¡£`CONSUME_FROM_FIRST_OFFSET`½«Ïû·Ñ¶ÓÁÐÖеÄÿһ¸öÏûÏ¢£¬Ö®Ç°µÄÀúÊ·ÏûÏ¢Ò²»áÔÙÏû·ÑÒ»±é¡£`CONSUME_FROM_TIMESTAMP`¿ÉÒÔÖ¸¶¨Ïû·ÑÏûÏ¢µÄʱ¼ä£¬Ö¸¶¨Ê±¼äÒÔºóµÄÏûÏ¢»á±»Ïû·Ñ¡£ + +Èç¹ûÄãµÄÓ¦Óò»ÄÜÈÝÈÌÖØ¸´Ïû·Ñ£¬ÄÇôÔÚÏû·ÑÏûÏ¢µÄ¹ý³ÌÖУ¬Òª×öºÃÏûÏ¢µÄУÑé¡£ + +ºÃÁË£¬½ñÌì¾Íµ½ÕâÀï°É£¬ÏÂһƪÎÒÃǽ«½éÉÜRocketMQµÄ»·¾³´î½¨¡£ \ No newline at end of file diff --git "a/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\346\266\210\346\201\257\347\232\204\347\224\237\344\272\247\344\270\216\346\266\210\350\264\271.md" "b/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\346\266\210\346\201\257\347\232\204\347\224\237\344\272\247\344\270\216\346\266\210\350\264\271.md" new file mode 100644 index 0000000..7b22bce --- /dev/null +++ "b/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\346\266\210\346\201\257\347\232\204\347\224\237\344\272\247\344\270\216\346\266\210\350\264\271.md" @@ -0,0 +1,62 @@ +# [RocketMQϵÁУ¨Ò»£©»ù±¾¸ÅÄî](https://www.cnblogs.com/boboooo/p/13038950.html) + + + + + +RocketMQÊǰ¢Àï³öÆ·µÄÒ»¿î¿ªÔ´µÄÏûÏ¢Öмä¼þ£¬ÈÃÆäÉùÃû´óÔëµÄ¾ÍÊÇËüµÄÊÂÎñÏûÏ¢µÄ¹¦ÄÜ¡£ÔÚÆóÒµÖУ¬ÏûÏ¢Öмä¼þÑ¡ÔñʹÓÃRocketMQµÄ»¹ÊÇͦ¶àµÄ£¬ÕâһϵÁеÄÎÄÕ¶¼ÊÇÕë¶ÔRocketMQµÄ£¬ÔÛÃÇÏÈ´ÓRocketMQµÄһЩ»ù±¾¸ÅÄîºÍ»·¾³µÄ´î½¨¿ªÊ¼ÁÄÆð¡£ + +RocketMQÓÉ4²¿·Ö×é³É£¬·Ö±ðÊÇ£ºÃû³Æ·þÎñ£¨Name Server£©¡¢ÏûÏ¢¶ÓÁУ¨Brokers£©¡¢Éú²úÕߣ¨producer£©ºÍÏû·ÑÕߣ¨consumer£©¡£Õâ4²¿·Ö¶¼¿ÉÒÔ½øÐÐˮƽÀ©Õ¹£¬´Ó¶ø±ÜÃâµ¥µã¹ÊÕÏ£¬ÈçÏÂͼ£¬ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/1191201-20200603173058174-1551688390.png) + +ÕâÊÇRocketMQ¹ÙÍøÉϵÄÒ»ÕÅͼ£¬·Ç³£ÇåÎúµÄÁгöÁË4¸ö²¿·Ö£¬²¢ÇÒ¶¼ÊǼ¯ÈºÄ£Ê½¡£ÏÂÃæÎÒÃǾͷֱð˵һ˵Õâ4²¿·Ö¡£ + +## Ãû³Æ·þÎñ£¨NameServer£© + +Name Server°çÑݵĽÇÉ«ÊÇÒ»¸ö×¢²áÖÐÐÄ£¬ºÍZookeeperµÄ×÷Óò¶à¡£ËüµÄÖ÷Òª¹¦ÄÜÓÐÁ½¸ö£¬ÈçÏ£º + +* brokerµÄ¹ÜÀí£ºbroker¼¯Èº½«×Ô¼ºµÄÐÅÏ¢×¢²áµ½NameServer£¬NameServerÌṩÐÄÌø»úÖÆ¼ì²âÿһ¸öbrokerÊÇ·ñÕý³£¡£ +* ·ÓɹÜÀí£ºÃ¿Ò»¸öNameServer¶¼ÓÐÕû¸öbroker¼¯ÈººÍ¶ÓÁеÄÐÅÏ¢£¬ÒÔ±ã¿Í»§¶Ë£¨Éú²úÕߺÍÏû·ÑÕߣ©²éѯ¡£ + +NameServerЭµ÷×Å·Ö²¼Ê½ÏµÍ³ÖеÄÿһ¸ö×é¼þ£¬²¢ÇÒ¹ÜÀí×Åÿһ¸öTopicµÄ·ÓÉÐÅÏ¢¡£ + +## Broker + +BrokerÖ÷ÒªÊÇ´æ´¢ÏûÏ¢£¬²¢ÇÒÌṩTopicµÄ»úÖÆ¡£ËüÌá¹©ÍÆºÍÀ­Á½ÖÖģʽ£¬»¹ÓÐһЩÈÝÔֵĴëÊ©£¬±ÈÈç¿ÉÒÔÅäÖÃÏûÏ¢¸±±¾¡£ÏÂÃæÎÒÃÇ¿´Ò»¿´BrokcerµÄÖ÷´Ó»úÖÆ¡£ + +BrokerµÄ½ÇÉ«·ÖΪ¡°Òì²½Ö÷¡±¡¢¡°Í¬²½Ö÷¡±ºÍ¡°´Ó¡±Èý¸ö½ÇÉ«¡£Èç¹ûÄã²»ÄÜÈÝÈÌÏûÏ¢µÄ¶ªÊ§£¬Äã¿ÉÒÔÅäÖÃÒ»¸ö¡°Í¬²½Ö÷¡±ºÍ¡°´Ó¡±Á½¸öBroker£¬Èç¹ûÄã¾õµÃÏûÏ¢¶ªÊ§Ò²ÎÞËùν£¬Ö»Òª¶ÓÁпÉÓþÍokµÄ»°£¬Äã¿ÉÒÔÅäÖá°Òì²½Ö÷¡±ºÍ¡°´Ó¡±Á½¸öbroker¡£Èç¹ûÄãÖ»ÊÇÏë¼òµ¥µÄ´î½¨£¬Ö»ÅäÖÃÒ»¸ö¡°Òì²½Ö÷¡±£¬²»ÅäÖá°´Ó¡±Ò²ÊÇ¿ÉÒԵġ£ + +ÉÏÃæÌáµ½µÄÊÇbrokerÖ®¼äµÄ±¸·Ý£¬brokerÀïµÄÐÅÏ¢Ò²ÊÇ¿ÉÒÔ±£´æµ½´ÅÅ̵쬱£´æµ½´ÅÅ̵ķ½Ê½Ò²ÓÐÁ½ÖÖ£¬ÍƼöµÄ·½Ê½ÊÇÒì²½±£´æ´ÅÅÌ£¬Í¬²½±£´æ´ÅÅÌÊǷdz£ËðºÄÐÔÄܵġ£ + +## Éú²úÕß + +Éú²úÕßÖ§³Ö¼¯Èº²¿Êð£¬ËüÃÇÏòbroker¼¯Èº·¢ËÍÏûÏ¢£¬¶øÇÒÖ§³Ö¶àÖÖ¸ºÔؾùºâµÄ·½Ê½¡£ + +µ±Éú²úÕßÏòbroker·¢ËÍÏûϢʱ£¬»áµÃµ½·¢Ëͽá¹û£¬·¢Ëͽá¹ûÖÐÓÐÒ»¸ö·¢ËÍ״̬¡£¼ÙÉèÎÒÃǵÄÅäÖÃÖУ¬ÏûÏ¢µÄÅäÖÃ`isWaitStoreMsgOK = true`£¬Õâ¸öÅäÖÃĬÈÏÒ²ÊÇ`true`£¬Èç¹ûÄãÅäÖÃΪ`false`£¬ÔÚ·¢ËÍÏûÏ¢µÄ¹ý³ÌÖУ¬Ö»Òª²»·¢ÉúÒì³££¬·¢Ëͽá¹û¶¼ÊÇ`SEND_OK`¡£µ±`isWaitStoreMsgOK = true`£¬·¢Ëͽá¹ûÓÐÒÔϼ¸ÖÖ£¬ + +* `FLUSH_DISK_TIMEOUT`£º±£´æ´ÅÅ̳¬Ê±£¬µ±±£´æ´ÅÅ̵ķ½Ê½ÉèÖÃΪSYNC_FLUSH£¨Í¬²½£©£¬²¢ÇÒÔÚsyncFlushTimeoutÅäÖõÄʱ¼äÄÚ£¨Ä¬ÈÏ5s£©£¬Ã»ÓÐÍê³É±£´æ´ÅÅ̵͝×÷£¬½«»áµÃµ½Õâ¸ö״̬¡£ +* `FLUSH_SLAVE_TIMEOUT`£ºÍ¬²½¡°´Ó¡±³¬Ê±£¬µ±brokerµÄ½ÇÉ«ÉèÖÃΪ¡°Í¬²½Ö÷¡±Ê±£¬µ«ÊÇÔÚÉèÖõÄͬ²½Ê±¼äÄÚ£¬Ä¬ÈÏΪ5s£¬Ã»ÓÐÍê³ÉÖ÷´ÓÖ®¼äµÄͬ²½£¬¾Í»áµÃµ½Õâ¸ö״̬¡£ +* `SLAVE_NOT_AVAILABLE`£º¡°´Ó¡±²»¿ÉÓ㬵±ÎÒÃÇÉèÖá°Í¬²½Ö÷¡±£¬µ«ÊÇûÓÐÅäÖá°´Ó¡±brokerʱ£¬»á·µ»ØÕâ¸ö״̬¡£ +* `SEND_OK`£ºÏûÏ¢·¢Ëͳɹ¦¡£ + +ÔÙÀ´¿´¿´ÏûÏ¢ÖØ¸´ÓëÏûÏ¢¶ªÊ§£¬µ±Äã·¢ÏÖÄãµÄÏûÏ¢¶ªÊ§Ê±£¬Í¨³£ÓÐÁ½¸öÑ¡Ôñ£¬Ò»¸öÊǶª¾Í¶ª°É£¬ÕâÑùÏûÏ¢¾ÍÕæµÄ¶ªÁË£»ÁíÒ»¸öÑ¡ÔñÊÇÏûÏ¢ÖØÐ·¢ËÍ£¬ÕâÑùÓпÉÄÜÒýÆðÏûÏ¢ÖØ¸´¡£Í¨³£Çé¿öÏ£¬»¹ÊÇÍÆ¼öÖØÐ·¢Ë͵ģ¬ÎÒÃÇÔÚÏû·ÑÏûÏ¢µÄʱºòҪȥ³ýµôÖØ¸´µÄÏûÏ¢¡£ + +·¢ËÍmessageµÄ´óСһ°ã²»³¬¹ý512k£¬Ä¬Èϵķ¢ËÍÏûÏ¢µÄ·½Ê½ÊÇͬ²½µÄ£¬·¢ËÍ·½·¨»áÒ»Ö±×èÈû£¬Ö±µ½µÈµ½·µ»ØµÄÏìÓ¦¡£Èç¹ûÄã±È½ÏÔÚÒâÐÔÄÜ£¬Ò²¿ÉÒÔÓÃ`send(msg, callback)`Òì²½µÄ·½Ê½·¢ËÍÏûÏ¢¡£ + +## Ïû·ÑÕß + +¶à¸öÏû·ÑÕß¿ÉÒÔ×é³É**Ïû·ÑÕß×飨consumer group£©**£¬²»Í¬µÄ**Ïû·ÑÕß×é**¿ÉÒÔ¶©ÔÄÏàͬµÄTopic£¬Ò²¿ÉÒÔ¶ÀÁ¢µÄÏû·ÑTopic£¬Ã¿Ò»¸öÏû·ÑÕß×é¶¼ÓÐ×Ô¼ºµÄÏû·ÑÆ«ÒÆÁ¿¡£ + +ÏûÏ¢µÄÏû·Ñ·½Ê½Ò»°ãÓÐÁ½ÖÖ£¬Ë³ÐòÏû·ÑºÍ²¢·¢Ïû·Ñ¡£ + +* ˳ÐòÏû·Ñ£ºÏû·ÑÕß½«Ëø×¡ÏûÏ¢¶ÓÁУ¬È·±£ÏûÏ¢°´ÕÕ˳ÐòÒ»¸öÒ»¸öµÄ±»Ïû·Ñµô£¬Ë³ÐòÏû·Ñ»áÒýÆðÒ»²¿·ÖÐÔÄÜËðʧ¡£ÔÚÏû·ÑÏûÏ¢µÄʱºò£¬Èç¹û³öÏÖÒì³££¬²»½¨ÒéÖ±½ÓÅ׳ö£¬¶øÊÇÓ¦¸Ã·µ»Ø`SUSPEND_CURRENT_QUEUE_A_MOMENT`Õâ¸ö״̬£¬Ëü½«¸æËßÏû·ÑÕß¹ýÒ»¶Îʱ¼äºó£¬»áÖØÐÂÏû·ÑÕâ¸öÏûÏ¢¡£ +* ²¢·¢Ïû·Ñ£ºÏû·ÑÕß½«²¢·¢µÄÏû·ÑÏûÏ¢£¬ÕâÖÖ·½Ê½µÄÐÔÄܷdz£ºÃ£¬Ò²ÊÇÍÆ¼öµÄÏû·Ñ·½Ê½¡£ÔÚÏû·ÑµÄ¹ý³ÌÖУ¬Èç¹û³öÏÖÒì³££¬²»½¨ÒéÖ±½ÓÅ׳ö£¬¶øÊÇ·µ»Ø`RECONSUME_LATER`״̬£¬Ëü¸æËßÏû·ÑÕßÏÖÔÚ²»ÄÜÕýÈ·µÄÏû·ÑËü£¬¹ýÒ»¶Îʱ¼äºó£¬»áÔÙ´ÎÏû·ÑËü¡£ + +ÔÚÏû·ÑÕßÄÚ²¿£¬ÊÇʹÓÃ`ThreadPoolExecutor`×÷ΪÏ̳߳صģ¬ÎÒÃÇ¿ÉÒÔͨ¹ý`setConsumeThreadMin`ºÍ`setConsumeThreadMax`ÉèÖÃ×îСÏû·ÑÏ̺߳Í×î´óÏû·ÑÏ̡߳£ + +µ±Ò»¸öеÄÏû·ÑÕß×齨Á¢ÒÔºó£¬ËüÒª¾ö¶¨ÊÇ·ñÏû·Ñ֮ǰµÄÀúÊ·ÏûÏ¢£¬`CONSUME_FROM_LAST_OFFSET`½«ºöÂÔÀúÊ·ÏûÏ¢£¬Ïû·ÑеÄÏûÏ¢¡£`CONSUME_FROM_FIRST_OFFSET`½«Ïû·Ñ¶ÓÁÐÖеÄÿһ¸öÏûÏ¢£¬Ö®Ç°µÄÀúÊ·ÏûÏ¢Ò²»áÔÙÏû·ÑÒ»±é¡£`CONSUME_FROM_TIMESTAMP`¿ÉÒÔÖ¸¶¨Ïû·ÑÏûÏ¢µÄʱ¼ä£¬Ö¸¶¨Ê±¼äÒÔºóµÄÏûÏ¢»á±»Ïû·Ñ¡£ + +Èç¹ûÄãµÄÓ¦Óò»ÄÜÈÝÈÌÖØ¸´Ïû·Ñ£¬ÄÇôÔÚÏû·ÑÏûÏ¢µÄ¹ý³ÌÖУ¬Òª×öºÃÏûÏ¢µÄУÑé¡£ + +ºÃÁË£¬½ñÌì¾Íµ½ÕâÀï°É£¬ÏÂһƪÎÒÃǽ«½éÉÜRocketMQµÄ»·¾³´î½¨¡£ \ No newline at end of file diff --git "a/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\347\216\257\345\242\203\346\220\255\345\273\272.md" "b/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\347\216\257\345\242\203\346\220\255\345\273\272.md" new file mode 100644 index 0000000..7b22bce --- /dev/null +++ "b/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\347\216\257\345\242\203\346\220\255\345\273\272.md" @@ -0,0 +1,62 @@ +# [RocketMQϵÁУ¨Ò»£©»ù±¾¸ÅÄî](https://www.cnblogs.com/boboooo/p/13038950.html) + + + + + +RocketMQÊǰ¢Àï³öÆ·µÄÒ»¿î¿ªÔ´µÄÏûÏ¢Öмä¼þ£¬ÈÃÆäÉùÃû´óÔëµÄ¾ÍÊÇËüµÄÊÂÎñÏûÏ¢µÄ¹¦ÄÜ¡£ÔÚÆóÒµÖУ¬ÏûÏ¢Öмä¼þÑ¡ÔñʹÓÃRocketMQµÄ»¹ÊÇͦ¶àµÄ£¬ÕâһϵÁеÄÎÄÕ¶¼ÊÇÕë¶ÔRocketMQµÄ£¬ÔÛÃÇÏÈ´ÓRocketMQµÄһЩ»ù±¾¸ÅÄîºÍ»·¾³µÄ´î½¨¿ªÊ¼ÁÄÆð¡£ + +RocketMQÓÉ4²¿·Ö×é³É£¬·Ö±ðÊÇ£ºÃû³Æ·þÎñ£¨Name Server£©¡¢ÏûÏ¢¶ÓÁУ¨Brokers£©¡¢Éú²úÕߣ¨producer£©ºÍÏû·ÑÕߣ¨consumer£©¡£Õâ4²¿·Ö¶¼¿ÉÒÔ½øÐÐˮƽÀ©Õ¹£¬´Ó¶ø±ÜÃâµ¥µã¹ÊÕÏ£¬ÈçÏÂͼ£¬ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/1191201-20200603173058174-1551688390.png) + +ÕâÊÇRocketMQ¹ÙÍøÉϵÄÒ»ÕÅͼ£¬·Ç³£ÇåÎúµÄÁгöÁË4¸ö²¿·Ö£¬²¢ÇÒ¶¼ÊǼ¯ÈºÄ£Ê½¡£ÏÂÃæÎÒÃǾͷֱð˵һ˵Õâ4²¿·Ö¡£ + +## Ãû³Æ·þÎñ£¨NameServer£© + +Name Server°çÑݵĽÇÉ«ÊÇÒ»¸ö×¢²áÖÐÐÄ£¬ºÍZookeeperµÄ×÷Óò¶à¡£ËüµÄÖ÷Òª¹¦ÄÜÓÐÁ½¸ö£¬ÈçÏ£º + +* brokerµÄ¹ÜÀí£ºbroker¼¯Èº½«×Ô¼ºµÄÐÅÏ¢×¢²áµ½NameServer£¬NameServerÌṩÐÄÌø»úÖÆ¼ì²âÿһ¸öbrokerÊÇ·ñÕý³£¡£ +* ·ÓɹÜÀí£ºÃ¿Ò»¸öNameServer¶¼ÓÐÕû¸öbroker¼¯ÈººÍ¶ÓÁеÄÐÅÏ¢£¬ÒÔ±ã¿Í»§¶Ë£¨Éú²úÕߺÍÏû·ÑÕߣ©²éѯ¡£ + +NameServerЭµ÷×Å·Ö²¼Ê½ÏµÍ³ÖеÄÿһ¸ö×é¼þ£¬²¢ÇÒ¹ÜÀí×Åÿһ¸öTopicµÄ·ÓÉÐÅÏ¢¡£ + +## Broker + +BrokerÖ÷ÒªÊÇ´æ´¢ÏûÏ¢£¬²¢ÇÒÌṩTopicµÄ»úÖÆ¡£ËüÌá¹©ÍÆºÍÀ­Á½ÖÖģʽ£¬»¹ÓÐһЩÈÝÔֵĴëÊ©£¬±ÈÈç¿ÉÒÔÅäÖÃÏûÏ¢¸±±¾¡£ÏÂÃæÎÒÃÇ¿´Ò»¿´BrokcerµÄÖ÷´Ó»úÖÆ¡£ + +BrokerµÄ½ÇÉ«·ÖΪ¡°Òì²½Ö÷¡±¡¢¡°Í¬²½Ö÷¡±ºÍ¡°´Ó¡±Èý¸ö½ÇÉ«¡£Èç¹ûÄã²»ÄÜÈÝÈÌÏûÏ¢µÄ¶ªÊ§£¬Äã¿ÉÒÔÅäÖÃÒ»¸ö¡°Í¬²½Ö÷¡±ºÍ¡°´Ó¡±Á½¸öBroker£¬Èç¹ûÄã¾õµÃÏûÏ¢¶ªÊ§Ò²ÎÞËùν£¬Ö»Òª¶ÓÁпÉÓþÍokµÄ»°£¬Äã¿ÉÒÔÅäÖá°Òì²½Ö÷¡±ºÍ¡°´Ó¡±Á½¸öbroker¡£Èç¹ûÄãÖ»ÊÇÏë¼òµ¥µÄ´î½¨£¬Ö»ÅäÖÃÒ»¸ö¡°Òì²½Ö÷¡±£¬²»ÅäÖá°´Ó¡±Ò²ÊÇ¿ÉÒԵġ£ + +ÉÏÃæÌáµ½µÄÊÇbrokerÖ®¼äµÄ±¸·Ý£¬brokerÀïµÄÐÅÏ¢Ò²ÊÇ¿ÉÒÔ±£´æµ½´ÅÅ̵쬱£´æµ½´ÅÅ̵ķ½Ê½Ò²ÓÐÁ½ÖÖ£¬ÍƼöµÄ·½Ê½ÊÇÒì²½±£´æ´ÅÅÌ£¬Í¬²½±£´æ´ÅÅÌÊǷdz£ËðºÄÐÔÄܵġ£ + +## Éú²úÕß + +Éú²úÕßÖ§³Ö¼¯Èº²¿Êð£¬ËüÃÇÏòbroker¼¯Èº·¢ËÍÏûÏ¢£¬¶øÇÒÖ§³Ö¶àÖÖ¸ºÔؾùºâµÄ·½Ê½¡£ + +µ±Éú²úÕßÏòbroker·¢ËÍÏûϢʱ£¬»áµÃµ½·¢Ëͽá¹û£¬·¢Ëͽá¹ûÖÐÓÐÒ»¸ö·¢ËÍ״̬¡£¼ÙÉèÎÒÃǵÄÅäÖÃÖУ¬ÏûÏ¢µÄÅäÖÃ`isWaitStoreMsgOK = true`£¬Õâ¸öÅäÖÃĬÈÏÒ²ÊÇ`true`£¬Èç¹ûÄãÅäÖÃΪ`false`£¬ÔÚ·¢ËÍÏûÏ¢µÄ¹ý³ÌÖУ¬Ö»Òª²»·¢ÉúÒì³££¬·¢Ëͽá¹û¶¼ÊÇ`SEND_OK`¡£µ±`isWaitStoreMsgOK = true`£¬·¢Ëͽá¹ûÓÐÒÔϼ¸ÖÖ£¬ + +* `FLUSH_DISK_TIMEOUT`£º±£´æ´ÅÅ̳¬Ê±£¬µ±±£´æ´ÅÅ̵ķ½Ê½ÉèÖÃΪSYNC_FLUSH£¨Í¬²½£©£¬²¢ÇÒÔÚsyncFlushTimeoutÅäÖõÄʱ¼äÄÚ£¨Ä¬ÈÏ5s£©£¬Ã»ÓÐÍê³É±£´æ´ÅÅ̵͝×÷£¬½«»áµÃµ½Õâ¸ö״̬¡£ +* `FLUSH_SLAVE_TIMEOUT`£ºÍ¬²½¡°´Ó¡±³¬Ê±£¬µ±brokerµÄ½ÇÉ«ÉèÖÃΪ¡°Í¬²½Ö÷¡±Ê±£¬µ«ÊÇÔÚÉèÖõÄͬ²½Ê±¼äÄÚ£¬Ä¬ÈÏΪ5s£¬Ã»ÓÐÍê³ÉÖ÷´ÓÖ®¼äµÄͬ²½£¬¾Í»áµÃµ½Õâ¸ö״̬¡£ +* `SLAVE_NOT_AVAILABLE`£º¡°´Ó¡±²»¿ÉÓ㬵±ÎÒÃÇÉèÖá°Í¬²½Ö÷¡±£¬µ«ÊÇûÓÐÅäÖá°´Ó¡±brokerʱ£¬»á·µ»ØÕâ¸ö״̬¡£ +* `SEND_OK`£ºÏûÏ¢·¢Ëͳɹ¦¡£ + +ÔÙÀ´¿´¿´ÏûÏ¢ÖØ¸´ÓëÏûÏ¢¶ªÊ§£¬µ±Äã·¢ÏÖÄãµÄÏûÏ¢¶ªÊ§Ê±£¬Í¨³£ÓÐÁ½¸öÑ¡Ôñ£¬Ò»¸öÊǶª¾Í¶ª°É£¬ÕâÑùÏûÏ¢¾ÍÕæµÄ¶ªÁË£»ÁíÒ»¸öÑ¡ÔñÊÇÏûÏ¢ÖØÐ·¢ËÍ£¬ÕâÑùÓпÉÄÜÒýÆðÏûÏ¢ÖØ¸´¡£Í¨³£Çé¿öÏ£¬»¹ÊÇÍÆ¼öÖØÐ·¢Ë͵ģ¬ÎÒÃÇÔÚÏû·ÑÏûÏ¢µÄʱºòҪȥ³ýµôÖØ¸´µÄÏûÏ¢¡£ + +·¢ËÍmessageµÄ´óСһ°ã²»³¬¹ý512k£¬Ä¬Èϵķ¢ËÍÏûÏ¢µÄ·½Ê½ÊÇͬ²½µÄ£¬·¢ËÍ·½·¨»áÒ»Ö±×èÈû£¬Ö±µ½µÈµ½·µ»ØµÄÏìÓ¦¡£Èç¹ûÄã±È½ÏÔÚÒâÐÔÄÜ£¬Ò²¿ÉÒÔÓÃ`send(msg, callback)`Òì²½µÄ·½Ê½·¢ËÍÏûÏ¢¡£ + +## Ïû·ÑÕß + +¶à¸öÏû·ÑÕß¿ÉÒÔ×é³É**Ïû·ÑÕß×飨consumer group£©**£¬²»Í¬µÄ**Ïû·ÑÕß×é**¿ÉÒÔ¶©ÔÄÏàͬµÄTopic£¬Ò²¿ÉÒÔ¶ÀÁ¢µÄÏû·ÑTopic£¬Ã¿Ò»¸öÏû·ÑÕß×é¶¼ÓÐ×Ô¼ºµÄÏû·ÑÆ«ÒÆÁ¿¡£ + +ÏûÏ¢µÄÏû·Ñ·½Ê½Ò»°ãÓÐÁ½ÖÖ£¬Ë³ÐòÏû·ÑºÍ²¢·¢Ïû·Ñ¡£ + +* ˳ÐòÏû·Ñ£ºÏû·ÑÕß½«Ëø×¡ÏûÏ¢¶ÓÁУ¬È·±£ÏûÏ¢°´ÕÕ˳ÐòÒ»¸öÒ»¸öµÄ±»Ïû·Ñµô£¬Ë³ÐòÏû·Ñ»áÒýÆðÒ»²¿·ÖÐÔÄÜËðʧ¡£ÔÚÏû·ÑÏûÏ¢µÄʱºò£¬Èç¹û³öÏÖÒì³££¬²»½¨ÒéÖ±½ÓÅ׳ö£¬¶øÊÇÓ¦¸Ã·µ»Ø`SUSPEND_CURRENT_QUEUE_A_MOMENT`Õâ¸ö״̬£¬Ëü½«¸æËßÏû·ÑÕß¹ýÒ»¶Îʱ¼äºó£¬»áÖØÐÂÏû·ÑÕâ¸öÏûÏ¢¡£ +* ²¢·¢Ïû·Ñ£ºÏû·ÑÕß½«²¢·¢µÄÏû·ÑÏûÏ¢£¬ÕâÖÖ·½Ê½µÄÐÔÄܷdz£ºÃ£¬Ò²ÊÇÍÆ¼öµÄÏû·Ñ·½Ê½¡£ÔÚÏû·ÑµÄ¹ý³ÌÖУ¬Èç¹û³öÏÖÒì³££¬²»½¨ÒéÖ±½ÓÅ׳ö£¬¶øÊÇ·µ»Ø`RECONSUME_LATER`״̬£¬Ëü¸æËßÏû·ÑÕßÏÖÔÚ²»ÄÜÕýÈ·µÄÏû·ÑËü£¬¹ýÒ»¶Îʱ¼äºó£¬»áÔÙ´ÎÏû·ÑËü¡£ + +ÔÚÏû·ÑÕßÄÚ²¿£¬ÊÇʹÓÃ`ThreadPoolExecutor`×÷ΪÏ̳߳صģ¬ÎÒÃÇ¿ÉÒÔͨ¹ý`setConsumeThreadMin`ºÍ`setConsumeThreadMax`ÉèÖÃ×îСÏû·ÑÏ̺߳Í×î´óÏû·ÑÏ̡߳£ + +µ±Ò»¸öеÄÏû·ÑÕß×齨Á¢ÒÔºó£¬ËüÒª¾ö¶¨ÊÇ·ñÏû·Ñ֮ǰµÄÀúÊ·ÏûÏ¢£¬`CONSUME_FROM_LAST_OFFSET`½«ºöÂÔÀúÊ·ÏûÏ¢£¬Ïû·ÑеÄÏûÏ¢¡£`CONSUME_FROM_FIRST_OFFSET`½«Ïû·Ñ¶ÓÁÐÖеÄÿһ¸öÏûÏ¢£¬Ö®Ç°µÄÀúÊ·ÏûÏ¢Ò²»áÔÙÏû·ÑÒ»±é¡£`CONSUME_FROM_TIMESTAMP`¿ÉÒÔÖ¸¶¨Ïû·ÑÏûÏ¢µÄʱ¼ä£¬Ö¸¶¨Ê±¼äÒÔºóµÄÏûÏ¢»á±»Ïû·Ñ¡£ + +Èç¹ûÄãµÄÓ¦Óò»ÄÜÈÝÈÌÖØ¸´Ïû·Ñ£¬ÄÇôÔÚÏû·ÑÏûÏ¢µÄ¹ý³ÌÖУ¬Òª×öºÃÏûÏ¢µÄУÑé¡£ + +ºÃÁË£¬½ñÌì¾Íµ½ÕâÀï°É£¬ÏÂһƪÎÒÃǽ«½éÉÜRocketMQµÄ»·¾³´î½¨¡£ \ No newline at end of file diff --git "a/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\351\241\272\345\272\217\346\266\210\350\264\271.md" "b/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\351\241\272\345\272\217\346\266\210\350\264\271.md" new file mode 100644 index 0000000..7b22bce --- /dev/null +++ "b/docs/mq/RocketMQ/RocketMQ\347\263\273\345\210\227\357\274\232\351\241\272\345\272\217\346\266\210\350\264\271.md" @@ -0,0 +1,62 @@ +# [RocketMQϵÁУ¨Ò»£©»ù±¾¸ÅÄî](https://www.cnblogs.com/boboooo/p/13038950.html) + + + + + +RocketMQÊǰ¢Àï³öÆ·µÄÒ»¿î¿ªÔ´µÄÏûÏ¢Öмä¼þ£¬ÈÃÆäÉùÃû´óÔëµÄ¾ÍÊÇËüµÄÊÂÎñÏûÏ¢µÄ¹¦ÄÜ¡£ÔÚÆóÒµÖУ¬ÏûÏ¢Öмä¼þÑ¡ÔñʹÓÃRocketMQµÄ»¹ÊÇͦ¶àµÄ£¬ÕâһϵÁеÄÎÄÕ¶¼ÊÇÕë¶ÔRocketMQµÄ£¬ÔÛÃÇÏÈ´ÓRocketMQµÄһЩ»ù±¾¸ÅÄîºÍ»·¾³µÄ´î½¨¿ªÊ¼ÁÄÆð¡£ + +RocketMQÓÉ4²¿·Ö×é³É£¬·Ö±ðÊÇ£ºÃû³Æ·þÎñ£¨Name Server£©¡¢ÏûÏ¢¶ÓÁУ¨Brokers£©¡¢Éú²úÕߣ¨producer£©ºÍÏû·ÑÕߣ¨consumer£©¡£Õâ4²¿·Ö¶¼¿ÉÒÔ½øÐÐˮƽÀ©Õ¹£¬´Ó¶ø±ÜÃâµ¥µã¹ÊÕÏ£¬ÈçÏÂͼ£¬ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/1191201-20200603173058174-1551688390.png) + +ÕâÊÇRocketMQ¹ÙÍøÉϵÄÒ»ÕÅͼ£¬·Ç³£ÇåÎúµÄÁгöÁË4¸ö²¿·Ö£¬²¢ÇÒ¶¼ÊǼ¯ÈºÄ£Ê½¡£ÏÂÃæÎÒÃǾͷֱð˵һ˵Õâ4²¿·Ö¡£ + +## Ãû³Æ·þÎñ£¨NameServer£© + +Name Server°çÑݵĽÇÉ«ÊÇÒ»¸ö×¢²áÖÐÐÄ£¬ºÍZookeeperµÄ×÷Óò¶à¡£ËüµÄÖ÷Òª¹¦ÄÜÓÐÁ½¸ö£¬ÈçÏ£º + +* brokerµÄ¹ÜÀí£ºbroker¼¯Èº½«×Ô¼ºµÄÐÅÏ¢×¢²áµ½NameServer£¬NameServerÌṩÐÄÌø»úÖÆ¼ì²âÿһ¸öbrokerÊÇ·ñÕý³£¡£ +* ·ÓɹÜÀí£ºÃ¿Ò»¸öNameServer¶¼ÓÐÕû¸öbroker¼¯ÈººÍ¶ÓÁеÄÐÅÏ¢£¬ÒÔ±ã¿Í»§¶Ë£¨Éú²úÕߺÍÏû·ÑÕߣ©²éѯ¡£ + +NameServerЭµ÷×Å·Ö²¼Ê½ÏµÍ³ÖеÄÿһ¸ö×é¼þ£¬²¢ÇÒ¹ÜÀí×Åÿһ¸öTopicµÄ·ÓÉÐÅÏ¢¡£ + +## Broker + +BrokerÖ÷ÒªÊÇ´æ´¢ÏûÏ¢£¬²¢ÇÒÌṩTopicµÄ»úÖÆ¡£ËüÌá¹©ÍÆºÍÀ­Á½ÖÖģʽ£¬»¹ÓÐһЩÈÝÔֵĴëÊ©£¬±ÈÈç¿ÉÒÔÅäÖÃÏûÏ¢¸±±¾¡£ÏÂÃæÎÒÃÇ¿´Ò»¿´BrokcerµÄÖ÷´Ó»úÖÆ¡£ + +BrokerµÄ½ÇÉ«·ÖΪ¡°Òì²½Ö÷¡±¡¢¡°Í¬²½Ö÷¡±ºÍ¡°´Ó¡±Èý¸ö½ÇÉ«¡£Èç¹ûÄã²»ÄÜÈÝÈÌÏûÏ¢µÄ¶ªÊ§£¬Äã¿ÉÒÔÅäÖÃÒ»¸ö¡°Í¬²½Ö÷¡±ºÍ¡°´Ó¡±Á½¸öBroker£¬Èç¹ûÄã¾õµÃÏûÏ¢¶ªÊ§Ò²ÎÞËùν£¬Ö»Òª¶ÓÁпÉÓþÍokµÄ»°£¬Äã¿ÉÒÔÅäÖá°Òì²½Ö÷¡±ºÍ¡°´Ó¡±Á½¸öbroker¡£Èç¹ûÄãÖ»ÊÇÏë¼òµ¥µÄ´î½¨£¬Ö»ÅäÖÃÒ»¸ö¡°Òì²½Ö÷¡±£¬²»ÅäÖá°´Ó¡±Ò²ÊÇ¿ÉÒԵġ£ + +ÉÏÃæÌáµ½µÄÊÇbrokerÖ®¼äµÄ±¸·Ý£¬brokerÀïµÄÐÅÏ¢Ò²ÊÇ¿ÉÒÔ±£´æµ½´ÅÅ̵쬱£´æµ½´ÅÅ̵ķ½Ê½Ò²ÓÐÁ½ÖÖ£¬ÍƼöµÄ·½Ê½ÊÇÒì²½±£´æ´ÅÅÌ£¬Í¬²½±£´æ´ÅÅÌÊǷdz£ËðºÄÐÔÄܵġ£ + +## Éú²úÕß + +Éú²úÕßÖ§³Ö¼¯Èº²¿Êð£¬ËüÃÇÏòbroker¼¯Èº·¢ËÍÏûÏ¢£¬¶øÇÒÖ§³Ö¶àÖÖ¸ºÔؾùºâµÄ·½Ê½¡£ + +µ±Éú²úÕßÏòbroker·¢ËÍÏûϢʱ£¬»áµÃµ½·¢Ëͽá¹û£¬·¢Ëͽá¹ûÖÐÓÐÒ»¸ö·¢ËÍ״̬¡£¼ÙÉèÎÒÃǵÄÅäÖÃÖУ¬ÏûÏ¢µÄÅäÖÃ`isWaitStoreMsgOK = true`£¬Õâ¸öÅäÖÃĬÈÏÒ²ÊÇ`true`£¬Èç¹ûÄãÅäÖÃΪ`false`£¬ÔÚ·¢ËÍÏûÏ¢µÄ¹ý³ÌÖУ¬Ö»Òª²»·¢ÉúÒì³££¬·¢Ëͽá¹û¶¼ÊÇ`SEND_OK`¡£µ±`isWaitStoreMsgOK = true`£¬·¢Ëͽá¹ûÓÐÒÔϼ¸ÖÖ£¬ + +* `FLUSH_DISK_TIMEOUT`£º±£´æ´ÅÅ̳¬Ê±£¬µ±±£´æ´ÅÅ̵ķ½Ê½ÉèÖÃΪSYNC_FLUSH£¨Í¬²½£©£¬²¢ÇÒÔÚsyncFlushTimeoutÅäÖõÄʱ¼äÄÚ£¨Ä¬ÈÏ5s£©£¬Ã»ÓÐÍê³É±£´æ´ÅÅ̵͝×÷£¬½«»áµÃµ½Õâ¸ö״̬¡£ +* `FLUSH_SLAVE_TIMEOUT`£ºÍ¬²½¡°´Ó¡±³¬Ê±£¬µ±brokerµÄ½ÇÉ«ÉèÖÃΪ¡°Í¬²½Ö÷¡±Ê±£¬µ«ÊÇÔÚÉèÖõÄͬ²½Ê±¼äÄÚ£¬Ä¬ÈÏΪ5s£¬Ã»ÓÐÍê³ÉÖ÷´ÓÖ®¼äµÄͬ²½£¬¾Í»áµÃµ½Õâ¸ö״̬¡£ +* `SLAVE_NOT_AVAILABLE`£º¡°´Ó¡±²»¿ÉÓ㬵±ÎÒÃÇÉèÖá°Í¬²½Ö÷¡±£¬µ«ÊÇûÓÐÅäÖá°´Ó¡±brokerʱ£¬»á·µ»ØÕâ¸ö״̬¡£ +* `SEND_OK`£ºÏûÏ¢·¢Ëͳɹ¦¡£ + +ÔÙÀ´¿´¿´ÏûÏ¢ÖØ¸´ÓëÏûÏ¢¶ªÊ§£¬µ±Äã·¢ÏÖÄãµÄÏûÏ¢¶ªÊ§Ê±£¬Í¨³£ÓÐÁ½¸öÑ¡Ôñ£¬Ò»¸öÊǶª¾Í¶ª°É£¬ÕâÑùÏûÏ¢¾ÍÕæµÄ¶ªÁË£»ÁíÒ»¸öÑ¡ÔñÊÇÏûÏ¢ÖØÐ·¢ËÍ£¬ÕâÑùÓпÉÄÜÒýÆðÏûÏ¢ÖØ¸´¡£Í¨³£Çé¿öÏ£¬»¹ÊÇÍÆ¼öÖØÐ·¢Ë͵ģ¬ÎÒÃÇÔÚÏû·ÑÏûÏ¢µÄʱºòҪȥ³ýµôÖØ¸´µÄÏûÏ¢¡£ + +·¢ËÍmessageµÄ´óСһ°ã²»³¬¹ý512k£¬Ä¬Èϵķ¢ËÍÏûÏ¢µÄ·½Ê½ÊÇͬ²½µÄ£¬·¢ËÍ·½·¨»áÒ»Ö±×èÈû£¬Ö±µ½µÈµ½·µ»ØµÄÏìÓ¦¡£Èç¹ûÄã±È½ÏÔÚÒâÐÔÄÜ£¬Ò²¿ÉÒÔÓÃ`send(msg, callback)`Òì²½µÄ·½Ê½·¢ËÍÏûÏ¢¡£ + +## Ïû·ÑÕß + +¶à¸öÏû·ÑÕß¿ÉÒÔ×é³É**Ïû·ÑÕß×飨consumer group£©**£¬²»Í¬µÄ**Ïû·ÑÕß×é**¿ÉÒÔ¶©ÔÄÏàͬµÄTopic£¬Ò²¿ÉÒÔ¶ÀÁ¢µÄÏû·ÑTopic£¬Ã¿Ò»¸öÏû·ÑÕß×é¶¼ÓÐ×Ô¼ºµÄÏû·ÑÆ«ÒÆÁ¿¡£ + +ÏûÏ¢µÄÏû·Ñ·½Ê½Ò»°ãÓÐÁ½ÖÖ£¬Ë³ÐòÏû·ÑºÍ²¢·¢Ïû·Ñ¡£ + +* ˳ÐòÏû·Ñ£ºÏû·ÑÕß½«Ëø×¡ÏûÏ¢¶ÓÁУ¬È·±£ÏûÏ¢°´ÕÕ˳ÐòÒ»¸öÒ»¸öµÄ±»Ïû·Ñµô£¬Ë³ÐòÏû·Ñ»áÒýÆðÒ»²¿·ÖÐÔÄÜËðʧ¡£ÔÚÏû·ÑÏûÏ¢µÄʱºò£¬Èç¹û³öÏÖÒì³££¬²»½¨ÒéÖ±½ÓÅ׳ö£¬¶øÊÇÓ¦¸Ã·µ»Ø`SUSPEND_CURRENT_QUEUE_A_MOMENT`Õâ¸ö״̬£¬Ëü½«¸æËßÏû·ÑÕß¹ýÒ»¶Îʱ¼äºó£¬»áÖØÐÂÏû·ÑÕâ¸öÏûÏ¢¡£ +* ²¢·¢Ïû·Ñ£ºÏû·ÑÕß½«²¢·¢µÄÏû·ÑÏûÏ¢£¬ÕâÖÖ·½Ê½µÄÐÔÄܷdz£ºÃ£¬Ò²ÊÇÍÆ¼öµÄÏû·Ñ·½Ê½¡£ÔÚÏû·ÑµÄ¹ý³ÌÖУ¬Èç¹û³öÏÖÒì³££¬²»½¨ÒéÖ±½ÓÅ׳ö£¬¶øÊÇ·µ»Ø`RECONSUME_LATER`״̬£¬Ëü¸æËßÏû·ÑÕßÏÖÔÚ²»ÄÜÕýÈ·µÄÏû·ÑËü£¬¹ýÒ»¶Îʱ¼äºó£¬»áÔÙ´ÎÏû·ÑËü¡£ + +ÔÚÏû·ÑÕßÄÚ²¿£¬ÊÇʹÓÃ`ThreadPoolExecutor`×÷ΪÏ̳߳صģ¬ÎÒÃÇ¿ÉÒÔͨ¹ý`setConsumeThreadMin`ºÍ`setConsumeThreadMax`ÉèÖÃ×îСÏû·ÑÏ̺߳Í×î´óÏû·ÑÏ̡߳£ + +µ±Ò»¸öеÄÏû·ÑÕß×齨Á¢ÒÔºó£¬ËüÒª¾ö¶¨ÊÇ·ñÏû·Ñ֮ǰµÄÀúÊ·ÏûÏ¢£¬`CONSUME_FROM_LAST_OFFSET`½«ºöÂÔÀúÊ·ÏûÏ¢£¬Ïû·ÑеÄÏûÏ¢¡£`CONSUME_FROM_FIRST_OFFSET`½«Ïû·Ñ¶ÓÁÐÖеÄÿһ¸öÏûÏ¢£¬Ö®Ç°µÄÀúÊ·ÏûÏ¢Ò²»áÔÙÏû·ÑÒ»±é¡£`CONSUME_FROM_TIMESTAMP`¿ÉÒÔÖ¸¶¨Ïû·ÑÏûÏ¢µÄʱ¼ä£¬Ö¸¶¨Ê±¼äÒÔºóµÄÏûÏ¢»á±»Ïû·Ñ¡£ + +Èç¹ûÄãµÄÓ¦Óò»ÄÜÈÝÈÌÖØ¸´Ïû·Ñ£¬ÄÇôÔÚÏû·ÑÏûÏ¢µÄ¹ý³ÌÖУ¬Òª×öºÃÏûÏ¢µÄУÑé¡£ + +ºÃÁË£¬½ñÌì¾Íµ½ÕâÀï°É£¬ÏÂһƪÎÒÃǽ«½éÉÜRocketMQµÄ»·¾³´î½¨¡£ \ No newline at end of file diff --git "a/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka \345\277\253\351\200\237\344\270\212\346\211\213\357\274\210Java\347\211\210\357\274\211.md" "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka \345\277\253\351\200\237\344\270\212\346\211\213\357\274\210Java\347\211\210\357\274\211.md" new file mode 100644 index 0000000..b4bc0a9 --- /dev/null +++ "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka \345\277\253\351\200\237\344\270\212\346\211\213\357\274\210Java\347\211\210\357\274\211.md" @@ -0,0 +1,173 @@ +**å‰�言** + +上篇文章讲解了 Kafka 的基础概念和架构,了解了基本概念之å�Žï¼Œå¿…须得实践一波了,所谓“实践æ‰�是检验真ç�†çš„唯一办法â€�,å�Žç»­ç³»åˆ—关于 Kafka 的文章都以 kafka_2.11-0.9.0.0 为例;å�¦å¤–为了让大家快速入门,本文å�ªæ��ä¾›å�•机版的安装实战教程,如果有想å°�试集群方案的,å�Žé�¢åœ¨å‡ºä¸€ç¯‡é›†ç¾¤å®‰è£…的教程,废è¯�ä¸�多说了,直接开干。 + +## **安装** + +### **1\. 下载** + +版本å�·ï¼škafka_2.11-0.9.0.0 + +下载地å�€ï¼š[http://kafka.apache.org/downloads](https://link.zhihu.com/?target=http%3A//kafka.apache.org/downloads) + +### **2\. 安装** + + + +``` +# 安装目录 +$ pwd +/Users/my/software/study + +# å‡�压 +$ sudo tar -zxvf kafka_2.11-0.9.0.0.tgz + +# é‡�命å�� +$ sudo mv kafka_2.11-0.9.0.0.tgz kafka-0.9 + +# 查看目录结构 +$ cd kafka-0.9 && ls +LICENSE NOTICE bin config libs site-docs + +# 目录结构介ç»�: +# bin: 存放kafka 客户端和æœ�务端的执行脚本 +# config: 存放kafka的一些é…�置文件 +# libs: 存放kafkaè¿�行的的jar包 +# site-docs: 存放kafkaçš„é…�置文档说明 + +# é…�置环境å�˜é‡�,方便在任æ„�目录下è¿�行kafka命令 +# å�šä¸»ä½¿ç”¨çš„Mac,所以é…�置在了 ~/.bash_profile文件中, +# Linux中则é…�置在 ~/.bashrc 或者 ~/.zshrc文件中 +$ vim ~/.bash_profile + +export KAFKA_HOME=/Users/haikuan1/software/study/kafka-0.9 +export PATH=$PATH:$JAVA_HOME:$KAFKA_HOME/bin + +# 使得环境å�˜é‡�生效 +$ source ~/.bash_profile + +``` + + + +### **3.è¿�行** + +### **3.1 å�¯åЍ zookeeper** + + + +``` +# å�¯åЍzookeeper,因为kafka的元数æ�®éœ€è¦�ä¿�存到zookeeper中 +$ bin/zookeeper-server-start.sh config/zookeeper.properties + +# 若出现如下信æ�¯ï¼Œåˆ™è¯�明zookeeperå�¯åЍæˆ�功了 +[2020-04-25 16:23:44,493] INFO Server environment:user.dir=/Users/haikuan1/software/study/kafka-0.10 (org.apache.zookeeper.server.ZooKeeperServer) +[2020-04-25 16:23:44,505] INFO tickTime set to 3000 (org.apache.zookeeper.server.ZooKeeperServer) +[2020-04-25 16:23:44,505] INFO minSessionTimeout set to -1 (org.apache.zookeeper.server.ZooKeeperServer) +[2020-04-25 16:23:44,505] INFO maxSessionTimeout set to -1 (org.apache.zookeeper.server.ZooKeeperServer) +[2020-04-25 16:23:44,548] INFO binding to port 0.0.0.0/0.0.0.0:2181 (org.apache.zookeeper.server.NIOServerCnxnFactory) + +``` + + + +### **3.2 å�¯åЍ Kafka server** + + + +``` +# 以守护进程的方å¼�å�¯åЍkafkaæœ�务端,去掉 -daemon å�‚数则关闭当å‰�窗å�£æœ�务端自动退出 +$ bin/kafka-server-start.sh -daemon config/server.properties + +``` + + + +### **3.3 kafka 基础命令使用** + + + +``` +# 1\. 创建一个topic +# --replication-factor:指定副本个数 +# --partition:指定partition个数 +# --topic:指定topicçš„å��å­— +$ bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partition 1 --topic mytopic + +# 2\. 查看创建æˆ�功的topic +$ kafka-topics.sh --list --zookeeper localhost:2181 + +# 3\. 创建生产者和消费者 + +# 3.1 å�¯åЍkafka消费端 +# --from-beginning:从头开始消费,该特性也表明kafka消æ�¯å…·æœ‰æŒ�久性 +$ bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic mytopic --from-beginning + +# 3.2 å�¯åЍkafka生产端 +# --broker-list:当å‰�çš„Broker列表,å�³æ��ä¾›æœ�务的列表 +$ bin/kafka-console-producer.sh --broker-list localhost:9092 --topic mytopic + +``` + + + +

+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-a1e0c6db02c2822b2ad88db1c3b0b8a7_720w.webp) + +
+ +### **4.使用 Java 连接 kafka 进行测试** + +### **4.1 创建一个 maven 工程,引入如下 pom �赖** + + + +``` + + org.apache.kafka + kafka-clients + 0.9.0.0 + + + + org.apache.kafka + kafka_2.11 + 0.9.0.0 + + +``` + + + +### **4.2 消费者端代�** + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-5e9876ca0dc733fe8c2df51d2e42d1ce_720w.webp) + +
+ +### **4.3 生产者端代�** + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-d1e6bfdf23c2b42e23f30d4430c587e2_720w.webp) + +
+ +### **4.4 消费者端效果图** + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-1912f5b2b12ac766d746d88a04b9bd28_720w.webp) + +
+ +### **5.总结** + +本文介�了 kafka �机版安装�简�命令使用,然�使用 Java 实现了生产者和消费者的简�功能,虽然内容�能比较简�,但还是**强烈建议大家手动去实践一下**,从而对 kafka 的架构有一个更深入的�解。 \ No newline at end of file diff --git "a/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\344\270\200\346\235\241\346\266\210\346\201\257\345\255\230\345\210\260broker\347\232\204\350\277\207\347\250\213.md" "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\344\270\200\346\235\241\346\266\210\346\201\257\345\255\230\345\210\260broker\347\232\204\350\277\207\347\250\213.md" new file mode 100644 index 0000000..6af0292 --- /dev/null +++ "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\344\270\200\346\235\241\346\266\210\346\201\257\345\255\230\345\210\260broker\347\232\204\350\277\207\347\250\213.md" @@ -0,0 +1,112 @@ +**�言** + +�过上篇文章的简�实战之�,**今天���生产者将消�从客户端��到 Broker 上背��生了哪些故事**,看�看由你,但是我���以本篇文章你一定�以学到应用背�的一些实质东西。 + +本文我们从以下 4 个方��探讨下一�消�如何被准确的��到 Broker 的 partition 上。 + +**1\. 客户端组件** + +**2\. 客户端缓存存储模型** + +**3\. 确定消�的 partition �置** + +**4\. ��线程的工作原�** + +* * * + +## **客户端组件** + +* **KafkaProducer:** + +KafkaProducer 是一个生产者客户端的进程,通过该对象�动生产者���消�。 + +* **RecordAccumulator:** + +RecordAccumulator 是一个记录收集器,用于收集客户端��的消�,并将收集到的消�暂存到客户端缓存中。 + +* **Sender:** + +Sender 是一个��线程,负责读�记录收集器中缓存的批�消�,�过一些中间转��作,将���的数�准备好,然�交由 Selector 进行网络传输。 + +* **Selector:** + +Selector 是一个选择器,用于处�网络连接和读写处�,使用网络连接处�客户端上的网络请求。 + +通过使用以上四大组件��完�客户端消�的��工作。消�在网络中传输的方��能通过二级制的方�,所以首先需�将消��列化为二进制形�缓存在客户端,kafka 使用了�端队列的方�将消�缓存起�,然�使用��线程(Sender)读�队列中的消�交给 Selector 进行网络传输��给�务端(Broker) + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-7d57acd1d7dc5942e999e6ffebb28679_720w.webp) + +
+ +以上为��消�的主�程,附上部分��供大家�考,接下�分�下几个�常���程的具体实现原�。 + +* * * + +## **客户端缓存存储模型** + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-5da65c5f9f8c0c9082e07c6431e78cd2_720w.webp) + +
+ +从上图�以看出,一�消�首先需�确定�被存储到那个 partition 对应的�端队列上;其次,存储消�的�端队列是以批的维度存储的,� N �消�组�一批,一批消�最多存储 N �,超过�则新建一个组�存储新消�;其次,新�的消�总是从左侧写入,�越�左侧的消�产生的时间越晚;最�,�有当一批消�凑够 N ���会��给 Broker,�则�会��到 Broker 上。 + +了解了客户端存储模型�,�探讨下确定消�的 partition(分区)�置? + +* * * + +## **确定消�的 partition �置** + +消��分为两�,一�是指定了 key 的消�,一�是没有指定 key 的消�。 + +对于指定了 key 的消�,partition �置的计算方�为:**`Utils.murmur2(key) % numPartitions`**,�先对 key 进行哈希计算,然�在于 partition 个数求余,从而得到该�消�应该被存储在哪个 partition 上。 + +对于没有指定 key 的消�,partition �置的计算方�为:**采用 round-robin 方�确定 partition �置**,�采用轮询的方�,平�的将消�分布到��的 partition 上,从而���些 partition 数��过大影� Broker 和消费端性能。 + +### **注�** + +由于 partition 有主副的区分,此处�与计算的 partition 数�是当�有主 partition 的数�,�如果�个 partition 无主的时候,则此 partition 是�能够进行数�写入的。 + +�微解释一下,主副 partition 的机制是为了�高 kafka 系统的容错性的,�当�个 Broker �外宕机时,在此 Broker 上的主 partition 状�为��读写时(�有主 partition �对外�供读写�务,副 partition �有数�备份的功能),kafka 会从主 partition 对应的 N 个副 partition 中挑选一个,并将其状�改为主 partition,从而继续对外�供读写�作。 + +消�被确定分�到�个 partition 对应记录收集器(��端队列)�,接下�,��线程(Sender)从记录收集器中收集满足�件的批数���给 Broker,那么��线程是如何收集满足�件的批数�的?批数�是按照 partition 维度��的还是按照 Broker 维度��数�的? + +* * * + +## **��线程的工作原�** + +Sender 线程的主�工作是收集满足�件的批数�,何为满足�件的批数�?缓存数�是以批维度存储的,当一批数��达到指定的 N �时,就满足��给 Broker 的�件了。 + +partition 维度和 Broker 维度��消�模型对比。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-36b7c2761f17fb2d6481747523999011_720w.webp) + +
+ +从图中�以看出,左侧按照 partition 维度��消�,�个 partition 都需�和 Broker 建连,总共�生了四次网络连接。而�侧将分布在�一个 Broker 的 partition 按组���在与 Broker 建连,�需�两次网络连接��。所以 Kafka 选择�侧的方�。 + +### **Sender 的主�工作** + +第一步:扫�记录收集器中满足�件的批数�,然�将 partition -> 批数�映射转�� BrokerId -> N 批数�的映射。第二步:Sender 线程会为�个 BrokerId 创建一个客户端请求,然�将请求交给 NetWorkClient,由 NetWrokClient 去真正��网络请求到 Broker。 + +### **NetWorkClient 的工作内容** + +Sender 线程准备好���的数��,交由 NetWorkClient �进行网络相关�作。主�包括客户端与�务端的建连���客户端请求�接��务端�应。完�如上一系列的工作主�由如下方法完�。 + +1. reday()方法。从记录收集器获�准备完毕的节点,并连接所有准备好的节点。 +2. send()方法。为�个节点创建一个客户端请求,然�将请求暂时存到节点对应的 Channel(通�)中。 +3. poll()方法。该方法会真正轮询网络请求,��请求给�务端节点和接��务端的�应。 + +* * * + +## **总结** + +以上,�为生产者客户端的一�消�从生产到��到 Broker 上的全过程。现在是�是就很清晰了呢?也许有些朋�会比较疑惑它的**网络请求模型是什么样的**,作者就猜你会你会问,下一篇我们就�扒开它的神秘�纱看看其究竟是怎么实现的,敬请期待。 \ No newline at end of file diff --git "a/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\344\273\213\347\273\215.md" "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\344\273\213\347\273\215.md" new file mode 100644 index 0000000..bb4fd3b --- /dev/null +++ "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\344\273\213\347\273\215.md" @@ -0,0 +1,122 @@ +## 一.官网Kafka介� + +## 1.1 什么是事件�? + +事件�是相当于人体中枢神�系统的数字系统。它是“永远在线�世界的技术基础,在这个世界里,�业越�越多地由软件定义和自动化,软件的用户也更多地是软件。 + +从技术上讲,事件�是指以事件�的形�从数�库�传感器�移动设备�云�务和软件应用等事件�实时�获数�的实践;�久地存储这些事件�以备以�检索;实时和回顾性地�作�处�和�应事件�;并根�需�将事件�路由到��的目的地技术。因此,事件�确�了数�的连续�动和解释,从而使正确的信�在正确的地点�正确的时间出现。 + +## 1.2 我�以使用事件��什么? + +事件�应用于众多行业和组织的��用例。它的许多例�包括: 1. 实时处�支付和金�交易,如股票交易所�银行和�险。 2. 实时跟踪和监控汽车��车�车队和�输,如物�和汽车行业。 3. �续�获和分��自物�网设备或其他设备的传感器数�,如工厂和风电场。 4. 收集并立��应客户的互动和订�,如零售�酒店和旅游行业,以�移动应用程�。 5. 监测�院病人,预测病情�化,确�在紧急情况下�时治疗。 6. 连接�存储公���部门产生的数�并使其�用。 7. 作为数�平��事件驱动架构和微�务的基础。 + +## 1.3 Apache Kafka®是一个事件�平�。这是什么��? + +Kafka结�了三个关键的功能,所以你�以用一个�一的战斗测试解决方案�实现端到端事件�的用例: 1. �布(写)和订阅(读)事件�,包括从其他系统连续导入/导出数�。 2. �久性和��地存储事件�,��你想。 3. 在事件�生或回顾时处�事件�。 + +所有这些功能都是以分布��高度�伸缩�弹性�容错和安全的方��供的。Kafka�以部署在裸金属硬件�虚拟机和容器上,也�以部署在云上。您�以选择自管�您的Kafka环境和使用由��供应商�供的完全管�的�务。 + +## 1.4 简而言之,Kafka是如何工作的? + +Kafka是一个分布�系统,由�务器和客户端组�,通过高性能的TCP网络�议进行通信。它�以部署在裸金属硬件�虚拟机和内部环境中的容器上,也�以部署在云环境中。 + +**�务器:**Kafka作为一个集群�行一个或多个�务器,�以跨越多个数�中心或云区域。其中一些�务器构�存储层,称为代�。其他�务器�行Kafka Connect��续导入和导出数�作为事件�,将Kafka与您现有的系统集�,如关系数�库以�其他Kafka集群。为了让你实现关键任务的用例,Kafka集群具有高度的�扩展性和容错性:如果它的任何一个�务器�生故障,其他�务器将接管它们的工作,以确��续的�作而�丢失任何数�。 + +**客户机:**它们�许您编写分布�应用程�和微�务,这些应用程�和微�务�以并行地�大规模地读��写入和处�事件�,甚至在出现网络问题或机器故障的情况下也�以容错。Kafka附带了一些这样的客户端,这些客户端被Kafka社区�供的几�个客户端增强了:客户端�以用于Java和Scala,包括更高级别的Kafka Streams库,用于Go�Python�C/ c++和许多其他编程语言以�REST api。 + +## 1.5 主�概念和术语 + +事件记录了在世界上或你的�业中“�生了�事�的事实。在文档中也称为记录或消�。当你读或写数�到Kafka时,你以事件的形��这件事。从概念上讲,事件具有键�值�时间戳和�选的元数�头。下�是一个例�: 1. 活动�点:“爱丽�� 2. 事件值:“�Bob支付200美元� 3. 事件时间戳:“2020年6月25日下�2:06。� + +生产者是那些�Kafka�布(写)事件的客户端应用程�,而消费者是那些订阅(读和处�)这些事件的应用程�。在Kafka中,生产者和消费者是完全解耦的,彼此是��知的,这是实现Kafka闻�的高�扩展性的一个关键设计元素。例如,生产者从�需�等待消费者。Kafka�供了���样的��,比如精确处�一次事件的能力。 + +事件被组织并�久地存储在主题中。很简�,一个主题类似于文件系统中的一个文件夹,事件就是该文件夹中的文件。一个示例主题�称�以是“payments�。Kafka中的主题总是多生产者和多订阅者:一个主题�以有0个�1个或多个生产者�它写入事件,也�以有0个�1个或多个消费者订阅这些事件。主题中的事件�以根�需��常读�——与传统消�传递系统��,事件在使用��会删除。相�,你�以通过�个主题的�置设置�定义Kafka应该�留你的事件多长时间,之�旧的事件将被丢弃。Kafka的性能相对于数�大��说是��的,所以长时间存储数�是完全�以的。 + +主题是分区的,这�味�一个主题分散在�于��Kafka broker上的多个“桶�上。这�数�的分布��置对于�伸缩性�常��,因为它�许客户机应用程��时从/�多个代�读�和写入数�。当一个新事件被�布到一个主题时,它实际上被附加到主题的一个分区中。具有相�事件键(例如,客户或车辆ID)的事件被写入�一个分区,Kafka��任何给定主题分区的消费者都将始终以写入的完全相�的顺�读�该分区的事件。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-39059344afb24ff7436bf7fb06bddde4_720w.webp) + +
+ +让你的数�容错和�用性,�一个主题�以被�制,甚至跨geo-regions或数�中心,这样总有多个�纪人有一份数�以防出错,你想�代�维护,等等。一个常�的生产设置是�制因�3,也就是说,您的数�总是有三个副本。这个�制是在主题分区级别执行的。 + +## 二.Kafka简介 + +Kafka是一�消�队列,主�用�处�大�数�状�下的消�队列,一般用��日志的处�。既然是消�队列,那么Kafka也就拥有消�队列的相应的特性了。 + +**消�队列的好处** 1. 解耦� 耦�的状�表示当你实现�个功能的时候,是直接接入当�接�,而利用消�队列,�以将相应的消���到消�队列,这样的�,如果接�出了问题,将�会影�到当�的功能。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-e37a18ea7eddc69582d634cc881eb257_720w.webp) + +
+ +1. 异步处� 异步处�替代了之�的�步处�,异步处��需�让�程走完就返回结果,�以将消���到消�队列中,然�返回结果,剩下让其他业务处�接�从消�队列中拉�消费处���。 + +2. ��削峰 高��的时候,使用消�队列作为中间件�以将��的高峰�存在消�队列中,从而防止了系统的高请求,�轻�务器的请求处�压力。 + +## 2.1 Kafka消费模� + +Kafka的消费模�主�有两�:一�是一对一的消费,也�点对点的通信,�一个��一个接收。第二�为一对多的消费,�一个消���到消�队列,消费者根�消�队列的订阅拉�消�消费。 + +**一对一** + +
+ + +![image-20230525200024084](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230525200024084.png) + +
+ +消�生产者�布消�到Queue队列中,通知消费者从队列中拉�消�进行消费。消�被消费之�则删除,Queue支�多个消费者,但对于一�消�而言,�有一个消费者�以消费,�一�消��能被一个消费者消费。 + +**一对多** + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-d97a2898f3bdc417262bc88be616281c_720w.webp) + +
+ +这�模�也称为�布/订阅模�,�利用Topic存储消�,消�生产者将消��布到Topic中,�时有多个消费者订阅此topic,消费者�以从中消费消�,注��布到Topic中的消�会被多个消费者消费,消费者消费数�之�,数��会被清除,Kafka会默认�留一段时间,然��删除。 + +## 2.2 Kafka的基础架构 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-ef94691300117c049301d88c6337c9c2_720w.webp) + +
+ +Kafka�其他Mq一样,也有自己的基础架构,主�存在生产者Producer�Kafka集群Broker�消费者Consumer�注册中心Zookeeper. + +1. Producer:消�生产者,�Kafka中�布消�的角色。 + +2. Consumer:消�消费者,�从Kafka中拉�消�消费的客户端。 + +3. Consumer Group:消费者组,消费者组则是一组中存在多个消费者,消费者消费Broker中当�Topic的��分区中的消�,消费者组之间互�影�,所有的消费者都属于�个消费者组,�消费者组是逻辑上的一个订阅者。�一个分区中的消��能够一个消费者组中的一个消费者所消费 + +4. Broker:�纪人,一�Kafka�务器就是一个Broker,一个集群由多个Broker组�,一个Broker�以容纳多个Topic。 + +5. Topic:主题,�以�解为一个队列,生产者和消费者都是��一个Topic + +6. Partition:分区,为了实现扩展性,一个�常大的Topic�以分布到多个Broker上,一个Topic�以分为多个Partition,�个Partition是一个有�的队列(分区有�,�能��全局有�) + +7. Replica:副本Replication,为��集群中�个节点�生故障,节点上的Partition数��丢失,Kafka�以正常的工作,Kafka�供了副本机制,一个Topic的�个分区有若干个副本,一个Leader和多个Follower + +8. Leader:�个分区多个副本的主角色,生产者��数�的对象,以�消费者消费数�的对象都是Leader。 + +9. Follower:�个分区多个副本的从角色,实时的从Leader中�步数�,��和Leader数�的�步,Leader�生故障的时候,�个Follower会�为新的Leader。 + +上述一个Topic会产生多个分区Partition,分区中分为Leader和Follower,消�一般��到Leader,Follower通过数�的�步与Leader���步,消费的�也是在Leader中�生消费,如果多个消费者,则分别消费Leader和�个Follower中的消�,当Leader�生故障的时候,�个Follower会�为主节点,此时会对�消�的�移�。 + +## �考文章 +https://blog.csdn.net/cao131502 +https://zhuanlan.zhihu.com/p/137811719 \ No newline at end of file diff --git "a/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\345\216\237\347\220\206\345\210\206\346\236\220\346\200\273\347\273\223\347\257\207.md" "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\345\216\237\347\220\206\345\210\206\346\236\220\346\200\273\347\273\223\347\257\207.md" new file mode 100644 index 0000000..58632b3 --- /dev/null +++ "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\345\216\237\347\220\206\345\210\206\346\236\220\346\200\273\347\273\223\347\257\207.md" @@ -0,0 +1,636 @@ +## 一�概述 + +Kakfa起�是由LinkedIn公�开�的一个分布�的消�系统,��为Apache的一部分,它使用Scala编写,以�水平扩展和高��率而被广泛使用。目�越�越多的开�分布�处�系统如Cloudera�Apache Storm�Spark等都支�与Kafka集�。 + +Kafka凭借�自身的优势,越�越�到互�网�业的��,唯�会也采用Kafka作为其内部核心消�引擎之一。Kafka作为一个商业级消�中间件,消���性的��性�想而知。如何确�消�的精确传输?如何确�消�的准确存储?如何确�消�的正确消费?这些都是需�考虑的问题。本文首先从Kafka的架构�手,先了解下Kafka的基本原�,然�通过对kakfa的存储机制��制原���步原����性和�久性��等等一步步对其��性进行分�,最�通过benchmark�增强对Kafka高��性的认知。 + + + + + +[回到顶部](https://www.cnblogs.com/wangzhuxing/p/10051512.html#_labelTop) + +## 二�Kafka的使用场景 + +(1)日志收集:一个公��以用Kafka�以收集���务的log,通过kafka以统一接��务的方�开放给��consumer,例如Hadoop�Hbase�Solr等; + +(2)消�系统:解耦和生产者和消费者�缓存消�等; + +(3)用户活动跟踪:Kafka�常被用�记录web用户或者app用户的��活动,如�览网页��索�点击等活动,这些活动信�被�个�务器�布到kafka的topic中,然�订阅者通过订阅这些topic��实时的监控分�,或者装载到Hadoop�数�仓库中�离线分�和挖掘; + +(4)��指标:Kafka也�常用�记录��监控数�。包括收集��分布�应用的数�,生产���作的集中�馈,比如报警和报告; + +(5)��处�:比如spark streaming和storm; + +(6)事件�; + + + +[回到顶部](https://www.cnblogs.com/wangzhuxing/p/10051512.html#_labelTop) + +## 三�Kafka基本架构 + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181201215942487-1393117307.png) + +如上图所示,一个典型的Kafka体系架构包括: + +* 若干Producer(�以是�务器日志,业务数�,页��端产生的page view等等), +* 若干broker(Kafka支�水平扩展,一般broker数�越多,集群��率越高), +* 若干Consumer (Group),以�一个Zookeeper集群。 + +Kafka通过Zookeeper管�集群�置,选举leader,以�在consumer group�生�化时进行rebalance。Producer使用push(推)模�将消��布到broker,Consumer使用pull(拉)模�从broker订阅并消费消�。 + + + +### 1�Topic & Partition + +一个topic�以认为一个一类消�,�个topic将被分�多个partition,�个partition在存储层�是append log文件。任何�布到此partition的消�都会被追加到log文件的尾部,��消�在文件中的�置称为offset(�移�),offset为一个long型的数字,它唯一标记一�消�。��消�都被append到partition中,是顺�写�盘,因此效率�常高(�验�,顺�写�盘效率比�机写内存还�高,这是Kafka高��率的一个很��的��)。 + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181201220820060-2075971944.png) + +�一�消�被��到broker中,会根�partition规则选择被存储到哪一个partition。partition机制�以通过指定producer的partition.class这一�数�指定,该class必须实现kafka.producer.Partitioner接�。如果partition规则设置的��,所有消��以�匀分布到��的partition里,这样就实现了水平扩展。(如果一个topic对应一个文件,那这个文件所在的机器I/O将会�为这个topic的性能瓶颈,而partition解决了这个问题)。在创建topic时�以在$KAFKA_HOME/config/server.properties中指定这个partition的数�(如下所示),当然�以在topic创建之�去修改partition的数�。 + + + +
# The default number of log partitions per topic. More partitions allow greater
+# parallelism for consumption, but this will also result in more files across
+# the brokers.
+#默认partitions数�
+num.partitions=1
+ + + + +[回到顶部](https://www.cnblogs.com/wangzhuxing/p/10051512.html#_labelTop) + +## 四�高��性存储分�概述 + +Kafka的高��性的�障��于其�壮的副本(replication)策略。通过调节其副本相关�数,�以使得Kafka在性能和��性之间�转的游刃有余。Kafka从0.8.x版本开始�供partition级别的�制,replication的数��以在$KAFKA_HOME/config/server.properties中�置(default.replication.refactor)。 + +这里先从Kafka文件存储机制入手,从最底层了解Kafka的存储细节,进而对其的存储有个微观的认知。之�通过Kafka�制原�和�步方���述�观层�的概念。最�从ISR,HW,leader选举以�数���性和�久性��等等�个维度�丰富对Kafka相关知识点的认知。 + +[回到顶部](https://www.cnblogs.com/wangzhuxing/p/10051512.html#_labelTop) + +## 五�Kafka文件存储机制 + +Kafka中消�是以topic进行分类的,生产者通过topic�Kafka broker��消�,消费者通过topic读�数�。然而topic在物�层��能以partition为分组,一个topic�以分�若干个partition,那么topic以�partition�是怎么存储的呢?partition还�以细分为segment,一个partition物�上由多个segment组�,那么这些segment�是什么呢?下�我们�一一�晓。 + +为了便于说明问题,�设这里�有一个Kafka集群,且这个集群�有一个Kafka broker,��有一�物�机。在这个Kafka broker中�置($KAFKA_HOME/config/server.properties中)log.dirs=/tmp/kafka-logs,以此�设置Kafka消�文件存储目录,与此�时创建一个topic:topic_zzh_test,partition的数�为4($KAFKA_HOME/bin/kafka-topics.sh –create –zookeeper localhost:2181 –partitions 4 –topic topic_vms_test –replication-factor 4)。那么我们此时�以在/tmp/kafka-logs目录中�以看到生�了4个目录: + + + + + +
drwxr-xr-x 2 root root 4096 Apr 10 16:10 topic_zzh_test-0 
+drwxr-xr-x 2 root root 4096 Apr 10 16:10 topic_zzh_test-1 
+drwxr-xr-x 2 root root 4096 Apr 10 16:10 topic_zzh_test-2 
+drwxr-xr-x 2 root root 4096 Apr 10 16:10 topic_zzh_test-3  
+ + + + +在Kafka文件存储中,�一个topic下有多个��的partition,�个partiton为一个目录,partition的�称规则为:topic�称+有���,第一个��从0开始计,最大的��为partition数��1,partition是实际物�上的概念,而topic是逻辑上的概念。 + +上��到partition还�以细分为segment,这个segment�是什么?如果就以partition为最�存储��,我们�以想象当Kafka producer�断��消�,必然会引起partition文件的无�扩张,这样对于消�文件的维护以�已�被消费的消�的清�带�严�的影�,所以这里以segment为���将partition细分。�个partition(目录)相当于一个巨型文件被平�分�到多个大�相等的segment(段)数�文件中(�个segment 文件中消�数��一定相等)这�特性也方便old segment的删除,�方便已被消费的消�的清�,�高�盘的利用率。�个partition�需�支�顺�读写就行,segment的文件生命周期由�务端�置�数(log.segment.bytes,log.roll.{ms,hours}等若干�数)决定。 + + + + + +[![�制代�](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "�制代�") + +
 #在强制刷新数�到�盘�许接收消�的数�
+#log.flush.interval.messages=10000 # 在强制刷新之�,消��以在日志中�留的最长时间
+#log.flush.interval.ms=1000 #一个日志的最�存活时间,�以被删除
+log.retention.hours=168 #  一个基于大�的日志�留策略。段将被从日志中删除��剩下的部分段�低于log.retention.bytes。
+#log.retention.bytes=1073741824 #  �一个日志段大�的最大值。当到达这个大�时,会生�一个新的片段。
+log.segment.bytes=1073741824 # 检查日志段的时间间隔,看是��以根��留策略删除它们
+log.retention.check.interval.ms=300000
+ + +[![�制代�](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "�制代�") + + + +segment文件由两部分组�,分别为“.index�文件和“.log�文件,分别表示为segment索引文件和数�文件。这两个文件的命令规则为:partition全局的第一个segment从0开始,�续�个segment文件�为上一个segment文件最�一�消�的offset值,数值大�为64�,20�数字字符长度,没有数字用0填充,如下: + + + + + + + +[![�制代�](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "�制代�") + +
00000000000000000000.index 00000000000000000000.log 00000000000000170410.index 00000000000000170410.log 00000000000000239430.index 00000000000000239430.log  
+ +[![�制代�](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "�制代�") + + + +以上�的segment文件为例,展示出segment:00000000000000170410的“.index�文件和“.log�文件的对应的关系,如下图: + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181201224133022-2085407889.png) + + + + + +如上图,“.index�索引文件存储大�的元数�,“.log�数�文件存储大�的消�,索引文件中的元数�指�对应数�文件中message的物��移地�。其中以“.index�索引文件中的元数�[3, 348]为例,在“.log�数�文件表示第3个消�,�在全局partition中表示170410+3=170413个消�,该消�的物��移地�为348。 + +那么如何从partition中通过offset查找message呢? + +以上图为例,读�offset=170418的消�,首先查找segment文件,其中00000000000000000000.index为最开始的文件,第二个文件为00000000000000170410.index(起始�移为170410+1=170411),而第三个文件为00000000000000239430.index(起始�移为239430+1=239431),所以这个offset=170418就�到了第二个文件之中。其他�续文件�以�次类推,以其实�移�命�并排列这些文件,然�根�二分查找法就�以快速定�到具体文件�置。其次根�00000000000000170410.index文件中的[8,1325]定�到00000000000000170410.log文件中的1325的�置进行读�。 + +�是读�offset=170418的消�,从00000000000000170410.log文件中的1325的�置进行读�,那么怎么知�何时读完本�消�,�则就读到下一�消�的内容了? + +这个就需��系到消�的物�结构了,消�都具有固定的物�结构,包括:offset(8 Bytes)�消�体的大�(4 Bytes)�crc32(4 Bytes)�magic(1 Byte)�attributes(1 Byte)�key length(4 Bytes)�key(K Bytes)�payload(N Bytes)等等字段,�以确定一�消�的大�,�读�到哪里截止。 + +[回到顶部](https://www.cnblogs.com/wangzhuxing/p/10051512.html#_labelTop) + +## 六��制原�和�步方� + +Kafka中topic的�个partition有一个预写�的日志文件,虽然partition�以继续细分为若干个segment文件,但是对于上层应用�说�以将partition看�最�的存储�元(一个有多个segment文件拼接的“巨型�文件),�个partition都由一些列有�的����的消�组�,这些消�被连续的追加到partition中。 + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181201231403669-958736996.png) + +上图中有两个新��:HW和LEO。这里先介�下LEO,LogEndOffset的缩写,表示�个partition的log最�一�Message的�置。HW是HighWatermark的缩写,是指consumer能够看到的此partition的�置,这个涉�到多副本的概念,这里先��一下,下节�详表。 + +言归正传,为了�高消�的��性,Kafka�个topic的partition有N个副本(replicas),其中N(大于等于1)是topic的�制因�(replica fator)的个数。Kafka通过多副本机制实现故障自动转移,当Kafka集群中一个broker失效情况下�然���务�用。在Kafka中�生�制时确�partition的日志能有�地写到其他节点上,N个replicas中,其中一个replica为leader,其他都为follower, leader处�partition的所有读写请求,与此�时,follower会被动定期地去�制leader上的数�。 + +如下图所示,Kafka集群中有4个broker, �topic有3个partition,且�制因��副本个数也为3: + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181201231724531-2038730622.png) + +Kafka�供了数��制算法��,如果leader�生故障或挂掉,一个新leader被选举并被接�客户端的消��功写入。Kafka确�从�步副本列表中选举一个副本为leader,或者说follower追赶leader数�。leader负责维护和跟踪ISR(In-Sync Replicas的缩写,表示副本�步队列,具体��考下节)中所有follower滞�的状�。当producer��一�消�到broker�,leader写入消�并�制到所有follower。消��交之��被�功�制到所有的�步副本。消��制延迟�最慢的follower�制,��的是快速检测慢副本,如果follower“���太多或者失效,leader将会把它从ISR中删除。 + +[回到顶部](https://www.cnblogs.com/wangzhuxing/p/10051512.html#_labelTop) + +## 七�零拷� + +Kafka中存在大�的网络数��久化到�盘(Producer到Broker)和�盘文件通过网络��(Broker到Consumer)的过程。这一过程的性能直接影�Kafka的整体���。 + + + +### 1�传统模�下的四次拷�与四次上下文切� + +以将�盘文件通过网络��为例。传统模�下,一般使用如下伪代�所示的方法先将文件数�读入内存,然�通过Socket将内存中的数���出去。 + + + +
buffer = File.read
+Socket.send(buffer)
+ + + + +这一过程实际上�生了四次数�拷�。首先通过系统调用将文件数�读入到内核�Buffer(DMA拷�),然�应用程�将内存�Buffer数�读入到用户�Buffer(CPU拷�),接�用户程�通过Socket��数�时将用户�Buffer数�拷�到内核�Buffer(CPU拷�),最�通过DMA拷�将数�拷�到NIC Buffer。�时,还伴��四次上下文切�,如下图所示。 + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181227142339448-1209004133.png) + +### 2�sendfile和transferTo实现零拷� + +Linux 2.4+内核通过`sendfile`系统调用,�供了零拷�。数�通过DMA拷�到内核�Buffer�,直接通过DMA拷�到NIC Buffer,无需CPU拷�。这也是零拷�这一说法的��。除了�少数�拷�外,因为整个读文件-网络��由一个`sendfile`调用完�,整个过程�有两次上下文切�,因此大大�高了性能。零拷�过程如下图所示。 + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181227142423000-1025665055.png) + +从具体实现�看,Kafka的数�传输通过TransportLayer�完�,其�类`PlaintextTransportLayer`通过[Java NIO](http://www.jasongj.com/java/nio_reactor/)的FileChannel的`transferTo`和`transferFrom`方法实现零拷�,如下所示。 + + + +
@Override public long transferFrom(FileChannel fileChannel, long position, long count) throws IOException { return fileChannel.transferTo(position, count, socketChannel);
+}
+ + + + +**注:** `transferTo`和`transferFrom`并���一定能使用零拷�。实际上是�能使用零拷�与�作系统相关,如果�作系统�供`sendfile`这样的零拷�系统调用,则这两个方法会通过这样的系统调用充分利用零拷�的优势,�则并�能通过这两个方法本身实现零拷�。 + + + + + +[回到顶部](https://www.cnblogs.com/wangzhuxing/p/10051512.html#_labelTop) + +## 八� ISR(副本�步队列) + +上节我们涉�到ISR (In-Sync Replicas),这个是指副本�步队列。副本数对Kafka的��率是有一定的影�,但�大的增强了�用性。默认情况下Kafka的replica数�为1,��个partition都有一个唯一的leader,为了确�消�的��性,通常应用中将其值(由broker的�数offsets.topic.replication.factor指定)大�设置为大于1,比如3。 所有的副本(replicas)统称为Assigned Replicas,�AR。ISR是AR中的一个�集,由leader维护ISR列表,follower从leader�步数�有一些延迟(包括延迟时间replica.lag.time.max.ms和延迟�数replica.lag.max.messages两个维度, 当�最新的版本0.10.x中�支�replica.lag.time.max.ms这个维度),任�一个超过阈值都会把follower剔除出ISR, 存入OSR(Outof-Sync Replicas)列表,新加入的follower也会先存放在OSR中。AR=ISR+OSR + +Kafka 0.10.x版本�移除了replica.lag.max.messages�数,��留了replica.lag.time.max.ms作为ISR中副本管�的�数。为什么这样�呢?replica.lag.max.messages表示当��个副本��leaeder的消�数�超过了这个�数的值,那么leader就会把follower从ISR中删除。�设设置replica.lag.max.messages=4,那么如果producer一次传�至broker的消�数�都�于4�时,因为在leader接�到producer��的消�之�而follower副本开始拉�这些消�之�,follower��leader的消�数�会超过4�消�,故此没有follower移出ISR,所以这时候replica.lag.max.message的设置似乎是��的。但是producer�起瞬时高峰��,producer一次��的消�超过4�时,也就是超过replica.lag.max.messages,此时follower都会被认为是与leader副本��步了,从而被踢出了ISR。但实际上这些follower都是存活状�的且没有性能问题。那么在之�追上leader,并被�新加入了ISR。于是就会出现它们�断地剔出ISR然��新回归ISR,这无疑增加了无谓的性能�耗。而且这个�数是broker全局的。设置太大了,影�真正“���follower的移除;设置的太�了,导致follower的频�进出。无法给定一个�适的replica.lag.max.messages的值,故此,新版本的Kafka移除了这个�数。注:ISR中包括:leader和follower。 + + + +上�一节还涉�到一个概念,�HW。HW俗称高水�,HighWatermark的缩写,�一个partition对应的ISR中最�的LEO作为HW,consumer最多�能消费到HW所在的�置。�外�个replica都有HW,leader和follower�自负责更新自己的HW的状�。对于leader新写入的消�,consumer�能立刻消费,leader会等待该消�被所有ISR中的replicas�步�更新HW,此时消��能被consumer消费。这样就��了如果leader所在的broker失效,该消��然�以从新选举的leader中获�。对于�自内部broKer的读�请求,没有HW的�制。 + +下图详细的说明了当producer生产消�至broker�,ISR以�HW和LEO的�转过程: + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181202175002622-1830127657.png) + +由此��,Kafka的�制机制既�是完全的�步�制,也�是�纯的异步�制。事实上,�步�制�求所有能工作的follower都�制完,这�消��会被commit,这��制方��大的影�了��率。而异步�制方�下,follower异步的从leader�制数�,数���被leader写入log就被认为已�commit,这�情况下如果follower都还没有�制完,��于leader时,�然leader宕机,则会丢失数�。而Kafka的这�使用ISR的方�则很好的�衡了确�数��丢失以���率。 + +Kafka的ISR的管�最终都会�馈到Zookeeper节点上。具体�置为:/brokers/topics/[topic]/partitions/[partition]/state。 + +目�有两个地方会对这个Zookeeper的节点进行维护: + +Controller�维护:Kafka集群中的其中一个Broker会被选举为Controller,主�负责Partition管�和副本状�管�,也会执行类似于�分�partition之类的管�任务。在符��些特定�件下,Controller下的LeaderSelector会选举新的leader,ISR和新的leader_epoch�controller_epoch写入Zookeeper的相关节点中。�时�起LeaderAndIsrRequest通知所有的replicas。 + +leader�维护:leader有�独的线程定期检测ISR中follower是�脱离ISR, 如果�现ISR�化,则会将新的ISR的信�返回到Zookeeper的相关节点中。 + + + + + +[回到顶部](https://www.cnblogs.com/wangzhuxing/p/10051512.html#_labelTop) + +## ��数���性和�久性�� + +当producer�leader��数�时,�以通过request.required.acks�数�设置数���性的级别: + + + +* 1(默认):这�味�producer在ISR中的leader已�功收到的数�并得到确认���下一�message。如果leader宕机了,则会丢失数�。 + +* 0:这�味�producer无需等待�自broker的确认而继续��下一批消�。这�情况下数�传输效率最高,但是数���性确是最低的。 + +* -1:producer需�等待ISR中的所有follower都确认接收到数���算一次��完�,��性最高。但是这样也�能��数��丢失,比如当ISR中�有leader时(��ISR那一节讲到,ISR中的�员由于�些情况会增加也会�少,最少就�剩一个leader),这样就��了acks=1的情况。 + + [官网�置说明](http://kafka.apache.org/documentation/#configuration) + +如果��高数�的��性,在设置request.required.acks=-1的�时,也�min.insync.replicas这个�数(�以在broker或者topic层�进行设置)的��,这样�能�挥最大的功效。min.insync.replicas这个�数设定ISR中的最�副本数是多少,默认值为1,当且仅当request.required.acks�数设置为-1时,此�数�生效。如果ISR中的副本数少于min.insync.replicas�置的数�时,客户端会返回异常:org.apache.kafka.common.errors.NotEnoughReplicasExceptoin: Messages are rejected since there are fewer in-sync replicas than required。 + + + +接下�对acks=1和-1的两�情况进行详细分�: + + + + + +### 9.1�request.required.acks=1 + +producer��数�到leader,leader写本地日志�功,返回客户端�功;此时ISR中的副本还没有�得�拉�该消�,leader就宕机了,那么此次��的消�就会丢失。 + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181202181329621-1088596676.png) + + + +### 9.2�request.required.acks=-1 + +�步(Kafka默认为�步,�producer.type=sync)的��模�,replication.factor>=2且min.insync.replicas>=2的情况下,�会丢失数�。 + +有两�典型情况。acks=-1的情况下(如无特殊说明,以下acks都表示为�数request.required.acks),数���到leader, ISR的follower全部完�数��步�,leader此时挂掉,那么会选举出新的leader,数��会丢失。 + +![](https://img2018.cnblogs.com/blog/843808/201812/843808-20181202212242480-242555451.png) + +acks=-1的情况下,数���到leader� ,部分ISR的副本�步,leader此时挂掉。比如follower1h和follower2都有�能��新的leader, producer端会得到返回异常,producer端会�新��数�,数��能会�� +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181202212407453-662912091.png) + +当然上图中如果在leader crash的时候,follower2还没有�步到任何数�,而且follower2被选举为新的leader的�,这样消�就�会��。 + +注:Kafka�处�fail/recover问题,�处�Byzantine问题。 + + + + + +### 9.3�关于HW的进一步探讨 + +考虑上图(�acks=-1,部分ISR副本�步)中的�一�情况,如果在Leader挂掉的时候,follower1�步了消�4,5,follower2�步了消�4,与此�时follower2被选举为leader,那么此时follower1中的多出的消�5该�如何处�呢? + +这里就需�HW的����了。如�所述,一个partition中的ISR列表中,leader的HW是所有ISR列表里副本中最�的那个的LEO。类似于木桶原�,水��决于最低那�短�。 + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181203204010599-1107873190.png) + + + +如上图,�个topic的�partition有三个副本,分别为A�B�C。A作为leader肯定是LEO最高,B紧�其�,C机器由于�置比较低,网络比较差,故而�步最慢。这个时候A机器宕机,这时候如果B�为leader,�如没有HW,在A�新��之�会��步(makeFollower)�作,在宕机时log文件之�直接�追加�作,而�如B的LEO已�达到了A的LEO,会产生数��一致的情况,所以使用HW���这�情况。 + +A在��步�作的时候,先将log文件截断到之�自己的HW的�置,�3,之��从B中拉�消�进行�步。 + +如果失败的follower��过�,它首先将自己的log文件截断到上次checkpointed时刻的HW的�置,之��从leader中�步消�。leader挂掉会�新选举,新的leader会��“指令�让其余的follower截断至自身的HW的�置然��拉�新的消�。 + +当ISR中的个副本的LEO�一致时,如果此时leader挂掉,选举新的leader时并�是按照LEO的高低进行选举,而是按照ISR中的顺�选举。 + + + + + +### 9.4�Leader选举 + +一�消��有被ISR中的所有follower都从leader�制过去�会被认为已�交。这样就��了部分数�被写进了leader,还没�得�被任何follower�制就宕机了,而造�数�丢失。而对于producer而言,它�以选择是�等待消�commit,这�以通过request.required.acks�设置。这�机制确�了��ISR中有一个或者以上的follower,一�被commit的消�就�会丢失。 + +有一个很��的问题是当leader宕机了,怎样在follower中选举出新的leader,因为follower�能��很多或者直接crash了,所以必须确�选择“最新�的follower作为新的leader。一个基本的原则就是,如果leader�在了,新的leader必须拥有原�的leader commit的所有消�。这就需��一个折中,如果leader在表�一个消�被commit�等待更多的follower确认,那么在它挂掉之�就有更多的follower�以�为新的leader,但这也会造���率的下�。 + +一��常常用的选举leader的方�是“少数�从多数�,Kafka并�是采用这�方�。这�模�下,如果我们有2f+1个副本,那么在commit之�必须��有f+1个replica�制完消�,�时为了��能正确选举出新的leader,失败的副本数�能超过f个。这�方�有个很大的优势,系统的延迟�决于最快的几�机器,也就是说比如副本数为3,那么延迟就�决于最快的那个follower而�是最慢的那个。“少数�从多数�的方�也有一些劣势,为了��leader选举的正常进行,它所能容�的失败的follower数比较少,如果�容�1个follower挂掉,那么至少�3个以上的副本,如果�容�2个follower挂掉,必须�有5个以上的副本。也就是说,在生产环境下为了��较高的容错率,必须�有大�的副本,而大�的副本�会在大数��下导致性能的急剧下�。这�算法更多用在Zookeeper这�共享集群�置的系统中而很少在需�大�数�的系统中使用的原因。HDFS的HA功能也是基于“少数�从多数�的方�,但是其数�存储并�是采用这样的方�。 + +实际上,leader选举的算法�常多,比如Zookeeper的Zab�Raft以�Viewstamped Replication。而Kafka所使用的leader选举算法更�是微软的PacificA算法。 + +Kafka在Zookeeper中为�一个partition动�的维护了一个ISR,这个ISR里的所有replication都跟上了leader,�有ISR里的�员�能有被选为leader的�能(unclean.leader.election.enable=false)。在这�模�下,对于f+1个副本,一个Kafka topic能在���丢失已�commit消�的��下容�f个副本的失败,在大多数使用场景下,这�模�是�分有利的。事实上,为了容�f个副本的失败,“少数�从多数�的方�和ISR在commit�需�等待的副本的数�是一样的,但是ISR需�的总的副本的个数几乎是“少数�从多数�的方�的一�。 + +上文�到,在ISR中至少有一个follower时,Kafka�以确�已�commit的数��丢失,但如果�一个partition的所有replica都挂了,就无法��数��丢失了。这�情况下有两��行的方案: + +等待ISR中任�一个replica“活�过�,并且选它作为leader + +选择第一个“活�过�的replica(并�一定是在ISR中)作为leader + +这就需�在�用性和一致性当中作出一个简�的抉择。如果一定�等待ISR中的replica“活�过�,那��用的时间就�能会相对较长。而且如果ISR中所有的replica都无法“活�过�了,或者数�丢失了,这个partition将永远��用。选择第一个“活�过�的replica作为leader,而这个replica�是ISR中的replica,那�使它并��障已�包�了所有已commit的消�,它也会�为leader而作为consumer的数��。默认情况下,Kafka采用第二�策略,�   + + + +* unclean.leader.election.enable=true,也�以将此�数设置为false��用第一�策略。 +* unclean.leader.election.enable这个�数对于leader的选举�系统的�用性以�数�的��性都有至关��的影�。 + +下�我们�分�下几�典型的场景。 + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181203213455180-1212737615.png) + +如果上图所示,�设�个partition中的副本数为3,replica-0, replica-1, replica-2分别存放在broker0, broker1和broker2中。AR=(0,1,2),ISR=(0,1)。 + +设置request.required.acks=-1, min.insync.replicas=2,unclean.leader.election.enable=false。这里讲broker0中的副本也称之为broker0起�broker0为leader,broker1为follower。 + +当ISR中的replica-0出现crash的情况时,broker1选举为新的leader[ISR=(1)],因为�min.insync.replicas=2影�,write�能�务,但是read能继续正常�务。此�情况��方案: + +�试��(��)replica-0,如果能起�,系统正常; +如果replica-0�能��,需�将min.insync.replicas设置为1,��write功能。 + + +当ISR中的replica-0出现crash,紧接�replica-1也出现了crash, 此时[ISR=(1),leader=-1],�能对外�供�务,此�情况��方案: + +�试��replica-0和replica-1,如果都能起�,则系统��正常; +如果replica-0起�,而replica-1�能起�,这时候�然�能选出leader,因为当设置unclean.leader.election.enable=false时,leader�能从ISR中选举,当ISR中所有副本都失效之�,需�ISR中最�失效的那个副本能��之��能选举leader, �replica-0先失效,replica-1�失效,需�replica-1����能选举leader。�守的方案建议把unclean.leader.election.enable设置为true,但是这样会有丢失数�的情况�生,这样�以��read�务。�样需�将min.insync.replicas设置为1,��write功能;replica-1��,replica-0�能��,这个情况上��到过,read�务�用,需�将min.insync.replicas设置为1,��write功能; +replica-0和replica-1都�能��,这�情况�以�考情形2. + +当ISR中的replica-0, replica-1�时宕机,此时[ISR=(0,1)],�能对外�供�务,此�情况��方案:�试��replica-0和replica-1,当其中任�一个副本��正常时,对外�以�供read�务。直到2个副本��正常,write功能�能��,或者将将min.insync.replicas设置为1。 + + + + + +### 9.5�Kafka的��模� + +Kafka的��模�由producer端的�置�数producer.type�设置,这个�数指定了在��线程中消�的��方�是�步的还是异步的,默认是�步的方�,�producer.type=sync。如果设置�异步的模�,�producer.type=async,�以是producer以batch的形�push数�,这样会�大的�高broker的性能,但是这样会增加丢失数�的风险。如果需�确�消�的��性,必须�将producer.type设置为sync。 + +对于异步模�,还有4个�套的�数,如下: + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181203213857717-291133501.png) + +以batch的方�推�数��以�大的�高处�效率,kafka producer�以将消�在内存中累计到一定数��作为一个batch��请求。batch的数�大��以通过producer的�数(batch.num.messages)控制。通过增加batch的大�,�以�少网络请求和�盘IO的次数,当然具体�数设置需�在效率和时效性方��一个�衡。在比较新的版本中还有batch.size这个�数。 + + + +[回到顶部](https://www.cnblogs.com/wangzhuxing/p/10051512.html#_labelTop) + +## ��高��性使用分� + + + +### 10.1�消�传输�障 + +��已�介�了Kafka如何进行有效的存储,以�了解了producer和consumer如何工作。接下�讨论的是Kafka如何确�消�在producer和consumer之间传输。有以下三��能的传输�障(delivery guarantee): + + + +* At most once: 消��能会丢,但��会��传输 +* At least once:消���会丢,但�能会��传输 +* Exactly once:��消�肯定会被传输一次且仅传输一次 + +Kafka的消�传输�障机制�常直观。当producer�broker��消�时,一旦这�消�被commit,由于副本机制(replication)的存在,它就�会丢失。但是如果producer��数�给broker�,�到的网络问题而造�通信中断,那producer就无法判断该�消�是�已��交(commit)。虽然Kafka无法确定网络故障期间�生了什么,但是producer�以retry多次,确�消�已�正确传输到broker中,所以目�Kafka实现的是at least once。 + +consumer从broker中读�消��,�以选择commit,该�作会在Zookeeper中存下该consumer在该partition下读�的消�的offset。该consumer下一次�读该partition时会从下一�开始读�。如未commit,下一次读�的开始�置会跟上一次commit之�的开始�置相�。当然也�以将consumer设置为autocommit,�consumer一旦读�到数�立�自动commit。如果�讨论这一读�消�的过程,那Kafka是确�了exactly once, 但是如果由于��producer与broker之间的��原因导致消�的��,那么这里就是at least once。 + +考虑这样一�情况,当consumer读完消�之�先commit�处�消�,在这�模�下,如果consumer在commit�还没�得�处�消�就crash了,下次�新开始工作�就无法读到刚刚已�交而未处�的消�,这就对应于at most once了。 + +读完消�先处��commit。这�模�下,如果处�完了消�在commit之�consumer crash了,下次�新开始工作时还会处�刚刚未commit的消�,实际上该消�已�被处�过了,这就对应于at least once。 + +��到exactly once就需�引入消�去�机制。 + + + +### 10.2�消�去� + + + +如上一节所述,Kafka在producer端和consumer端都会出现消�的��,这就需�去�处�。 + +Kafka文档中��GUID(Globally Unique Identifier)的概念,通过客户端生�算法得到�个消�的unique id,�时�映射至broker上存储的地�,�通过GUID便�查询��消�内容,也便于��方的幂等性��,需�在broker上�供此去�处�模�,最新版本已�支�。 + +针对GUID, 如果从客户端的角度去�,那么需�引入集中�缓存,必然会增加�赖��度,�外缓存的大�难以界定。 + +��是Kafka, 类似RabbitMQ以�RocketMQ这类商业级中间件也��障at least once, 且也无法从自身去进行消�去�。所以我们建议业务方根�自身的业务特点进行去�,比如业务消�本身具备幂等性,或者借助Redis等其他产�进行去�处�。 + + + + + +### 10.3�高��性�置 + +Kafka�供了很高的数�冗余弹性,对于需�数�高��性的场景,我们�以增加数�冗余备份数(replication.factor),调高最�写入副本数的个数(min.insync.replicas)等等,但是这样会影�性能。�之,性能�高而��性则�低,用户需�自身业务特性在彼此之间�一些�衡性选择。 + +���数�写入到Kafka是安全的,高��的,需�如下的�置: + + + +1. topic的�置:replication.factor>=3,�副本数至少是3个;2<=min.insync.replicas<=replication.factor +2. broker的�置:leader的选举�件unclean.leader.election.enable=false +3. producer的�置:request.required.acks=-1(all),producer.type=sync + + + +[回到顶部](https://www.cnblogs.com/wangzhuxing/p/10051512.html#_labelTop) + +## �一�内部网络框架 + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181212101055804-450926848.png) + +Broker的内部处��水线化,分为多个阶段�进行(SEDA),以�高���和性能,尽���Thead盲等待,以下为过程说明。 + +* Accept Thread负责与客户端建立连接链路,然�把Socket轮转交给Process Thread +* Process Thread负责接收请求和�应数�,Process Thread�次基于Selector事件循环,首先从Response Queue读��应数�,�客户端回��应,然�接收到客户端请求�,读�数�放入Request Queue。 +* Work Thread负责业务逻辑�IO�盘处�等,负责从Request Queue读�请求,并把处�结果放入Response Queue中,待Process Thread��出去。 + +[回到顶部](https://www.cnblogs.com/wangzhuxing/p/10051512.html#_labelTop) + +## �二�rebalance机制 + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181212101229091-1187958161.png) + +Kafka���一consumer group中�有一个consumer会消费��消�,实际上,Kafka��的是稳定状�下�一个consumer实例�会消费�一个或多个特定的数�,而�个partition的数��会被�一个特定的consumer实例所消费。这样设计的劣势是无法让�一个consumer group里的consumer�匀消费数�,优势是�个consumer�用都跟大�的broker通信,�少通信开销,�时也�低了分�难度,实现也更简�。�外,因为�一个partition里的数�是有�的,这�设计�以���个partition里的数�也是有�被消费。 + +如果�consumer group中consumer数�少于partition数�,则至少有一个consumer会消费多个partition的数�,如果consumer的数�与partition数�相�,则正好一个consumer消费一个partition的数�,而如果consumer的数�多于partition的数�时,会有部分consumer无法消费该topic下任何一�消�。 + +**Consumer Rebalance算法如下 :** + + + +
1. 将目标 topic 下的所有 partirtion 排�,存于PT 2. 对� consumer group 下所有 consumer 排�,存于 CG,第 i 个consumer 记为 Ci 3. N=size(PT)/size(CG),�上�整 4. 解除 Ci 对原�分�的 partition 的消费�(i从0开始) 5. 将第i*N到(i+1)*N-1个 partition 分�给 Ci 
+ + + +目�consumer rebalance的控制策略是由�一个consumer通过Zookeeper完�的。具体的控制方�如下: + + + +
在/consumers/[consumer-group]/下注册id
+设置对/consumers/[consumer-group] 的watcher
+设置对�brokers/ids的watcher
+zk下设置watcher的路径节点更改,触�consumer rebalance
+ + + + +在这�策略下,**�一个consumer或者broker的增加或者�少都会触�consumer rebalance**。因为�个consumer�负责调整自己所消费的partition,为了��整个consumer group的一致性,所以当一个consumer触�了rebalance时,该consumer group内的其它所有consumer也应该�时触�rebalance。 + +* Herd effect + +任何broker或者consumer的增�都会触�所有的consumer的rebalance + +* Split Brain + +�个consumer分别�独通过Zookeeper判断哪些partition down了,那么��consumer从Zookeeper“看�到的view就�能�一样,这就会造�错误的reblance�试。而且有�能所有的consumer都认为rebalance已�完�了,但实际上�能并�如此。 + +[回到顶部](https://www.cnblogs.com/wangzhuxing/p/10051512.html#_labelTop) + +## �三�BenchMark + +Kafka在唯�会有�很深的历�渊�,根�唯�会消�中间件团队(VMS团队)所掌�的资料显示,在VMS团队�转的Kafka集群中所支撑的topic数已接近2000,�天的请求�也已达�亿级。这里就以Kafka的高��性为基准点�探究几���场景下的行为表现,以此�加深对Kafka的认知,为大家在以�高效的使用Kafka时�供一份��。 + + + +### 13.1�测试环境 + +Kafka broker用到了4�机器,分别为broker[0/1/2/3]�置如下: + +CPU: 24core/2.6GHZ +Memory: 62G +Network: 4000Mb +OS/kernel: CentOs release 6.6 (Final) +Disk: 1089G +Kafka版本:0.10.1.0 +broker端JVM�数设置: + + + + + +
-Xmx8G -Xms8G -server -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+CMSScavengeBeforeRemark -XX:+DisableExplicitGC -Djava.awt.headless=true -Xloggc:/apps/service/kafka/bin/../logs/kafkaServer-gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=9999 
+ + + +客户端机器�置: + +* CPU: 24core/2.6GHZ +* Memory: 3G +* Network: 1000Mb +* OS/kernel: CentOs release 6.3 (Final) +* Disk: 240G + +### 13.2���场景测试 + +#### 场景1: + +测试��的副本数�min.insync.replicas策略以�request.required.acks策略(以下简称acks策略)对于��速度(TPS)的影�。 + +具体�置:一个producer;��方�为sync;消�体大�为1kB;partition数为12。副本数为:1/2/4;min.insync.replicas分别为1/2/4;acks分别为-1(all)/1/0。 + +具体测试数�如下表(min.insync.replicas�在acks=-1时有效): + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181203221444373-736905445.png) + +测试结果分�: + + + +1. 客户端的acks策略对��的TPS有较大的影�,TPS:acks_0 > acks_1 > ack_-1; +2. 副本数越高,TPS越低;副本数一致时,min.insync.replicas�影�TPS; +3. acks=0/1时,TPS与min.insync.replicas�数以�副本数无关,仅�acks策略的影�。 + +下�将partition的个数设置为1,�进一步确认下��的acks策略���的min.insync.replicas策略以���的副本数对于��速度的影�,详细请看情景2和情景3。 + +#### 场景2: + +在partition个数固定为1,测试��的副本数和min.insync.replicas策略对��速度的影�。 + +具体�置:一个producer;��方�为sync;消�体大�为1kB;producer端acks=-1(all)。��副本数:2/3/4; min.insync.replicas设置为:1/2/4。 + +测试结果如下: + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181203221832812-2007554062.png) + +测试结果分�: + +副本数越高,TPS越低(这点与场景1的测试结论��),但是当partition数为1时差�甚微。min.insync.replicas�影�TPS。 + +#### 场景3: + +在partition个数固定为1,测试��的acks策略和副本数对��速度的影�。 + +具体�置:一个producer;��方�为sync;消�体大�为1kB;min.insync.replicas=1。topic副本数为:1/2/4;acks: 0/1/-1。 + +测试结果如下: + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181203222003811-323209661.png) + + + + + + + + + + + + + +测试结果分�(与情景1一致): + +* 副本数越多,TPS越低; +* 客户端的acks策略对��的TPS有较大的影�,TPS:acks_0 > acks_1 > ack_-1。 + +#### 场景4: + +测试��partition数对��速率的影� + +具体�置:一个producer;消�体大�为1KB;��方�为sync;topic副本数为2;min.insync.replicas=2;acks=-1。partition数�设置为1/2/4/8/12。 + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181203222113272-1167910484.png) + +测试结果分�: + +partition的��会影�TPS,��partition的个数的增长TPS会有所增长,但并�是一直�正比关系,到达一定临界值时,partition数�的增加�而会使TPS略微�低。 + +#### 场景5: + +通过将集群中部分broker设置����务状�,测试对客户端以�消��盘的影�。 + +具体�置:一个producer;消�体大�1KB;��方�为sync;topic副本数为4;min.insync.replicas设置为2;acks=-1;retries=0/100000000;partition数为12。 + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181203222220687-1891442968.png) + +测试结果分�: + + + +1. kill两�broker�,客户端�以继续��。broker�少�,partition的leader分布在剩余的两�broker上,造�了TPS的��; +2. kill三�broker�,客户端无法继续��。Kafka的自动�试功能开始起作用,当大于等于min.insync.replicas数�的broker���,�以继续��; +3. 当retries�为0时,消�有���盘;客户端�功返回的消�都�功�盘,异常时部分消��以�盘。 + +#### 场景6: + +测试�个producer的��延迟,以�端到端的延迟。 + +具体�置:一个producer;消�体大�1KB;��方�为sync;topic副本数为4;min.insync.replicas设置为2;acks=-1;partition数为12。 + +测试数��结果(��为ms): + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/843808-20181203222407063-2086989349.png) + +**�场景测试总结:** + + + +1. 当acks=-1时,Kafka��端的TPS��于topic的副本数�(ISR中),副本越多TPS越低; +2. acks=0时,TPS最高,其次为1,最差为-1,�TPS:acks_0 > acks_1 > ack_-1 +3. min.insync.replicas�数�影�TPS; +4. partition的��会影�TPS,��partition的个数的增长TPS会有所增长,但并�是一直�正比关系,到达一定临界值时,partition数�的增加�而会使TPS略微�低; +5. Kafka在acks=-1,min.insync.replicas>=1时,具有高��性,所有�功返回的消�都�以�盘。 \ No newline at end of file diff --git "a/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\345\270\270\350\247\201\345\221\275\344\273\244\345\217\212\351\205\215\347\275\256\346\200\273\347\273\223.md" "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\345\270\270\350\247\201\345\221\275\344\273\244\345\217\212\351\205\215\347\275\256\346\200\273\347\273\223.md" new file mode 100644 index 0000000..a3eb8fd --- /dev/null +++ "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\345\270\270\350\247\201\345\221\275\344\273\244\345\217\212\351\205\215\347\275\256\346\200\273\347\273\223.md" @@ -0,0 +1,517 @@ +## **�动zookeeper** + +bin/zookeeper-server-start.sh config/zookeeper.properties & + +## **�动kafka:** + +bin/kafka-server-start.sh config/server.properties + +这样�动�一个�处,就是kafka�动完毕之�,�能关闭终端,为此,我们�以�行这�命令: + +nohup bin/kafka-server-start.sh config/server.properties > ./dev/null 2>&1 & + +![](https://img2022.cnblogs.com/blog/796632/202208/796632-20220812161146385-332776455.png) + +多个kafka的�,在�个虚拟机上�行kafka�动命令多次��。 + +当然这个是�机的命令,集群的命令���讲。 + +## **查看是��动** + +jps -lm + +![](https://img2022.cnblogs.com/blog/796632/202208/796632-20220812161210221-836644701.png) + +说明没有�动kfka + +![](https://img2022.cnblogs.com/blog/796632/202208/796632-20220812161224734-562363764.png) + +说明�动kafka了 + +## 查看kafka版本 + +find ./libs/ -name \*kafka_\* | head -1 | grep -o '\kafka[^\n]*' + +kafka_2.12-2.4.1.jar + +结果: + +就�以看到kafka的具体版本了。 + +其中,2.12为scala版本,2.4.1为kafka版本。 + +## **�止kafka** + +bin/kafka-server-stop.sh + +## **�止zookeeper** + +bin/zookeeper-server-stop.sh + +## **创建topic** + +bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test + +多集群创建,执行这个需��建多机器的kafka集群环境,zkq1/zkq2/zkq3分别代表了3�zookeeper集群的三�机器 + +/bin/kafka-topics.sh —create —zookeeper zkq1:2181,zkq2:2181,zkq3:2181 -replication-factor 6 —partition 6 —topic test + +解释: + +--topic��的test0是topic的�称 + +--zookeeper应该和server.properties文件中的zookeeper.connect一样 + +--config指定当�topic上有效的�数值 + +--partitions指定topic的partition数�,如果�指定该数�,默认是server.properties文件中的num.partitions�置值 + +--replication-factor指定�个partition的副本个数,默认是1个 + +也�以�没有的topic��消�的时候创建topic + +需� + +开�自动创建�置:auto.create.topics.enable=true + +使用程�直接往kafka中相应的topic��数�,如果topic�存在就会按默认�置进行创建。 + +## **展示topic** + +bin/kafka-topics.sh --list --zookeeper localhost:2181 + +## **�述topic** + +bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-replicated-topic + +![](https://img2022.cnblogs.com/blog/796632/202208/796632-20220812161250801-1389051022.png) + +解释: + +�查看多个topic用逗�分割 + +**leader**: + +是该partitons所在的所有broker中担任leader的broker id,�个broker都有�能�为leader,负责处�消�的读和写,leader是从所有节点中�机选择的. + +-1表示此broker移除了 + +**Replicas**: + +显示该partiton所有副本所在的broker列表,包括leader,�管该broker是�是存活,�管是�和leader��了�步。列出了所有的副本节点,�管节点是�在�务中. + +**Isr**: + +in-sync replicas的简写,表示存活且副本都已�步的的broker集�,是replicas的�集,是正在�务中的节点. + +举例: + +比如上�结果的第一行:Topic: test0 .Partition:0 ...Leader: 0 ......Replicas: 0,2,1 Isr: 1,0,2 + +Partition: 0[该partition编�是0] + +Replicas: 0,2,1[代表partition0 在broker0,broker1,broker2上�存了副本] + +Isr: 1,0,2 [代表broker0,broker1,broker2都存活而且目�都和leader���步] + +Leader: 0 + +代表�存在broker0,broker1,broker2上的这三个副本中,leader是broker0 + +leader负责读写,broker1�broker2负责从broker0�步信�,平时没他俩什么事 + +## **查看topic的partition�增加partition** + +/kafka-topics.sh –zookeeper 10.2.1.1:2181 –topic mcc-logs –describe. + +## **删除Topic** + +/bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic test + +如果你的server.properties内没有�置相关的�置的�,会出现如下错误: + +Topic test is marked for deletion. + +Note: This will have no impact if delete.topic.enable is not set to true. + +这边是说,你的Topic已�被标记为待删除的Topic,但是呢,你�置文件的开关没有打开,所以�是给它添加了一个标记,实际上,这个Topic并没有被删除。�有,你打开开关之�,会自动删除被标记删除的Topic。 + +解决办法: + +设置server.properties文件内的“delete.topic.enable=true�,并且��Kafka就�以了。 + +如果�想修改�置也�以完全删除 + +1�删除kafka存储目录(server.propertiewenjian log.dirs�置,默认为“/tmp/kafka-logs�)下对应的topic。(��broker下存储的topic�一定相�,所有broker都�看一下) + +2�进入zookeeper客户端删掉对应topic + +zkCli.sh .-server 127.0.0.1:42182 + +找到topic目录: + +ls ../brokers/topics + +删掉对应topic + +rmr ./brokers/topic/topic-name + +找到目录: + +ls .../config/topics + +删掉对应topic + +rmr ./config/topics/topic-name . + +这样就完全删除了 + +## **删除topic中存储的内容** + +在config/server.properties中找到如下的�置 + +![](https://img2022.cnblogs.com/blog/796632/202208/796632-20220812161312458-550425542.png) + +删除log.dirs指定的文件目录, + +登录zookeeper client。 + +命令: + +/home/ZooKeeper/bin/zkCli.sh + +删除zookeeper中该topic相关的目录 + +命令: + +rm -r /kafka/config/topics/test0 + +rm -r /kafka/brokers/topics/test0 + +rm -r /kafka/admin/delete_topics/test0 (topic被标记为marked for deletion时需�这个命令) + +��zookeeper和broker + +## **生产者��消�:** + +bin/kafka-console-producer.sh --broker-list 130.51.23.95:9092 --topic my-replicated-topic + +这里的ip和端�是broker的ip�端�,根�自己kafka机器的ip和端�写就�以 + +## **消费者消费消�:** + +bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --new-consumer --from-beginning --consumer.config config/consumer.properties + +## **查看topic�分区�移�最大(�)值** + +bin/kafka-run-class.sh kafka.tools.GetOffsetShell --topic hive-mdatabase-hostsltable .--time -1 --broker-list node86:9092 --partitions 0 + +注: time为-1时表示最大值,time为-2时表示最�值 + +�指定--partitions 就是指这个topic整体的情况 + +## 查看指定group的消费情况 + +kafka-consumer-groups.sh --bootstrap-server 172.20.72.93:9092 --describe --group mygroup + +�行结果: + +![](https://img2022.cnblogs.com/blog/796632/202208/796632-20220816164455794-344440282.png) + +* GROUP:消费者组 +* TOPIC:topic�字 +* PARTITION :partition id +* CURRENT-OFFSET: .当�消费到的offset . . . . . . . . +* LOG-END-OFFSETSIZE :最新的offset +* LAG:未消费的�数 +* CONSUMER-ID:消费者组中消费者的id,为—代表没有active的消费者 +* HOST:消费者的机器ip,为—代表没有active的消费者 +* CLIENT-ID:消费者clientID,为—代表没有active的消费者 + +## .查看所有group的消费情况 + +kafka-consumer-groups.sh --bootstrap-server 172.20.72.93:9092 --all-groups --all-topics --describe + +![](https://img2022.cnblogs.com/blog/796632/202208/796632-20220816172442100-1560497638.png) + +## 修改group消费的offset + +kafka-consumer-groups.sh --bootstrap-server 172.20.72.93:9092 --group mygroup --reset-offsets --topic mytopic --to-offset 61 --execute + +上�就是把mygroup在mytopic的消费offset修改到了61 + +�设�移有几�选项: + +--to-earliest:. .设置到最早�移处,也就是0 + +--to-latest:. . .设置到最新处,也就是主题分区HW的�置 + +--to-offset NUM: 指定具体的�移�置 + +--shift-by NUM:. 基于当��移��回退多少 + +--by-duration:. .回退到多长时间 + +## 查看指定group中活跃的消费者 + +kafka-consumer-groups.sh --bootstrap-server 172.20.72.93:9092 --describe --group mygroup --members + +## **增加topic分区数** + +(�能增加�能�少) + +为topic t_cdr 增加10个分区 + +bin/kafka-topics.sh --zookeeper node01:2181 .--alter --topic t_cdr --partitions 10 + +## **常用�置�说明** + +kafka 常����置说明,分为四部分 + +* Broker Config:kafka �务端的�置 +* Producer Config:生产端的�置 +* Consumer Config:消费端的�置 +* Kafka Connect Config:kafka 连接相关的�置 + +### **Broker Config** + +1. **zookeeper.connect** + +连接 zookeeper 集群的地�,用于将 kafka 集群相关的元数�信�存储到指定的 zookeeper 集群中 + +**2\. advertised.port** + +注册到 zookeeper 中的地�端�信�,在 IaaS 环境中,默认注册到 zookeeper 中的是内网地�,通过该�置指定外网访问的地��端�,advertised.host.name 和 advertised.port 作用和 advertised.port 差�多,在 0.10.x 之�,直接�置 advertised.port ��,�两个�数被废弃掉了。 + +**3\. auto.create.topics.enable** + +自动创建 topic,默认为 true。其作用是当�一个还没有创建的 topic ��消�时,此时会自动创建一个 topic,并�时设置 -num.partition 1 (partition 个数) 和 default.replication.factor (副本个数,默认为 1) �数。 + +一般该�数需�手动关闭,因为自动创建会影� topic 的管�,我们�以通过 kafka-topic.sh 脚本手动创建 topic,通常也是建议使用这�方�创建 topic。在 0.10.x 之��供了 kafka-admin 包,�以使用其�创建 topic。 + +**4\. auto.leader.rebalance.enable** + +自动 rebalance,默认为 true。其作用是通过��线程定期扫�检查,在一定�件下触��新 leader 选举;在生产环境中,�建议开�,因为替� leader 在性能上没有什么��。 + +**5\. background.threads** + +��线程数,默认为 10。用于���作的线程,�以�用改动。 + +**6\. broker.id** + +Broker 的唯一标识,用于区分��的 Broker。kafka 的检查就是基于此 id 是�在 zookeeper 中/brokers/ids 目录下是�有相应的 id 目录�判定 Broker 是��康。 + +**7\. compression.type** + +压缩类型。此�置�以接�的压缩类型有 gzip�snappy�lz4。�外�以�设置,���和生产端相�的压缩格�。 + +**8\. delete.topic.enable** + +�用删除 topic。如果关闭,则无法使用 admin 工具进行 topic 的删除�作。 + +**9\. leader.imbalance.check.interval.seconds** + +partition 检查�新 rebalance 的周期时间 + +**10\. leader.imbalance.per.broker.percentage** + +标识�个 Broker 失去平衡的比率,如果超过改比率,则执行�新选举 Broker 的 leader + +**11\. log.dir / log.dirs** + +�存 kafka 日志数�的�置。如果 log.dirs 没有设置,则使用 log.dir 指定的目录进行日志数�存储。 + +**12\. log.flush.interval.messages** + +partition 分区的数��达到指定大�时,对数�进行一次刷盘�作。比如设置了 1024k 大�,当 partition 积累的数��达到这个数值时则将数�写入到�盘上。 + +**13\. log.flush.interval.ms** + +数�写入�盘时间间隔,�内存中的数��留多久就�久化一次,如果没有设置,则使用 log.flush.scheduler.interval.ms �数指定的值。 + +**14\. log.retention.bytes** + +表示 topic 的容�达到指定大�时,则对其数�进行清除�作,默认为-1,永远�删除。 + +**15\. log.retention.hours** + +标示 topic 的数�最长�留多久,��是�时 + +**16\. log.retention.minutes** + +表示 topic 的数�最长�留多久,��是分钟,如果没有设置该�数,则使用 log.retention.hours �数 + +**17\. log.retention.ms** + +表示 topic 的数�最长�留多久,��是毫秒,如果没有设置该�数,则使用 log.retention.minutes �数 + +**18\. log.roll.hours** + +新的 segment 创建周期,���时。kafka 数�是以 segment 存储的,当周期时间到达时,就创建一个新的 segment �存储数�。 + +**19\. log.segment.bytes** + +segment 的大�。当 segment 大�达到指定值时,就新创建一个 segment。 + +**20\. message.max.bytes** + +topic 能够接收的最大文件大�。需�注�的是 producer 和 consumer 端设置的大�需�一致。 + +**21\. min.insync.replicas** + +最�副本�步个数。当 producer 设置了 request.required.acks 为-1 时,则 topic 的副本数��步至该�数指定的个数,如果达�到,则 producer 端会产生异常。 + +**22\. num.io.threads** + +指定 io �作的线程数 + +**23\. num.network.threads** + +执行网络�作的线程数 + +**24\. num.recovery.threads.per.data.dir** + +�个数�目录用于��数�的线程数 + +**25\. num.replica.fetchers** + +从 leader 备份数�的线程数 + +**26\. offset.metadata.max.bytes** + +�许消费者端�存 offset 的最大个数 + +**27\. offsets.commit.timeout.ms** + +offset �交的延迟时间 + +**28\. offsets.topic.replication.factor** + +topic 的 offset 的备份数�。该�数建议设置更高��系统更高的�用性 + +**29\. port** + +端��,Broker 对外�供访问的端��。 + +**30\. request.timeout.ms** + +Broker 接收到请求�的最长等待时间,如果超过设定时间,则会给客户端��错误信� + +**31\. zookeeper.connection.timeout.ms** + +客户端和 zookeeper 建立连接的超时时间,如果没有设置该�数,则使用 zookeeper.session.timeout.ms 值 + +**32\. connections.max.idle.ms** + +空连接的超时时间。�空闲连接超过该时间时则自动销�连接。 + +### **Producer Config** + +1. **bootstrap.servers** + +�务端列表。�接收生产消�的�务端列表 + +**2\. key.serializer** + +消�键的�列化方�。指定 key 的�列化类型 + +3..**value.serializer** + +消�内容的�列化方�。指定 value 的�列化类型 + +4..**acks** + +消�写入 Partition 的个数。通常�以设置为 0,1,all;当设置为 0 时,�需�将消���完��就完�消���功能;当设置为 1 时,� Leader Partition 接收到数�并完��盘;当设置为 all 时,�主从 Partition 都接收到数�并�盘。 + +5..**buffer.memory** + +客户端缓存大�。� Producer 生产的数��缓存达到指定值时,将缓存数�一次��的 Broker 上。 + +6..**compression.type** + +压缩类型。指定消����的压缩类型,通常有 none, gzip, snappy, or, lz4 四�。�指定时消�默认�压缩。 + +7..**retries** + +消���失败时�试次数。当该值设置大于 0 时,消�因为网络异常等因素导致消���失败进行�新��的次数。 + +### **Consumer Config** + +1. **bootstrap.servers** + +�务端列表。�消费端从指定的�务端列表中拉�消�进行消费。 + +2..**key.deserializer** + +消�键的��列化方�。指定 key 的��列化类型,与�列化时指定的类型相对应。 + +3..**value.deserializer** + +消�内容的��列化方�。指定 value 的��列化类型,与�列化时指定的类型相对应。 + +4..**fetch.min.bytes** + +抓�消�的最�内容。指定�次��务端拉�的最�消��。 + +5..**group.id** + +消费组中�个消费者的唯一表示。 + +6..**heartbeat.interval.ms** + +心跳检查周期。�在周期性的� group coordinator ��心跳,当�务端�生 rebalance 时,会将消���给�个消费者。该�数值需��于 session.timeout.ms,通常为�者的 1/3。 + +7..**max.partition.fetch.bytes** + +Partition �次返回的最大数��大�。 + +**8\. session.timeout.ms** + +consumer 失效的时间。� consumer 在指定的时间�,还没有�应则认为该 consumer 已��生故障了。 + +**9\. auto.offset.reset** + +当 kafka 中没有�始�移�或�务器上�存在�移�时,指定从哪个�置开始消�消�。earliest:指定从头开始;latest:从最新的数�开始消费。 + +### **Kafka Connect Config** + +1. **group.id** + +消费者在消费组中的唯一标识 + +**2\. internal.key.converter** + +内部 key 的转�类型。 + +**3\. internal.value.converter** + +内部 value 的转�类型。 + +**4\. key.converter** + +�务端接收到 key 时指定的转�类型。 + +5..**value.converter** + +�务端接收到 value 时指定的转�类型。 + +**6\. bootstrap.servers** + +�务端列表。 + +**7\. heartbeat.interval.ms** + +心跳检测,与 consumer 中指定的�置�义相�。 + +**8\. session.timeout.ms** + +session 有效时间,与 consumer 中指定的�置�义相�。 + +## **总结** + +本文总结了平时�常用到的一些 Kafka �置�命令说明,方便�时查看;喜欢的朋��以收�以备�时之需。 + + +## �考文章 +https://blog.csdn.net/cao131502 +https://zhuanlan.zhihu.com/p/137811719 \ No newline at end of file diff --git "a/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\346\236\266\346\236\204\344\273\213\347\273\215.md" "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\346\236\266\346\236\204\344\273\213\347\273\215.md" new file mode 100644 index 0000000..2d35efe --- /dev/null +++ "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\346\236\266\346\236\204\344\273\213\347\273\215.md" @@ -0,0 +1,298 @@ +## 一. 工作�程 + +Kafka中消�是以topic进行分类的,Producer生产消�,Consumer消费消�,都是��topic的。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-b9d626794f6625526598db6627b780e7_720w.webp) + +
+ +Topic是逻辑上的改�,Partition是物�上的概念,�个Partition对应�一个log文件,该log文件中存储的就是producer生产的数�,topic=N*partition;partition=log + +Producer生产的数�会被�断的追加到该log文件的末端,且��数�都有自己的offset,consumer组中的�个consumer,都会实时记录自己消费到了哪个offset,以便出错��的时候,�以从上次的�置继续消费。�程:Producer => Topic(Log with offset)=> Consumer. + +## 二. 文件存储 + +Kafka文件存储也是通过本地�盘的方�存储的,主�是通过相应的log与index等文件�存具体的消�文件。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-116ebd7dffd85595d69f080e5b5f6948_720w.webp) + +
+ +生产者�断的�log文件追加消�文件,为了防止log文件过大导致定�效率低下,Kafka的log文件以1G为一个分界点,当.log文件大�超过1G的时候,此时会创建一个新的.log文件,�时为了快速定�大文件中消��置,Kafka采�了分片和索引的机制�加速定�。 + +在kafka的存储log的地方,�文件的地方,会存在消费的�移�以�具体的分区信�,分区信�的�主�包括.index和.log文件组� + +
+ + +![](https://pic3.zhimg.com/80/v2-c6de61f43ecbe58d4f3e7aa29541220e_720w.webp) + +
+ +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-8345e4966d8c5274a1e74e29151bd9c6_720w.webp) + +
+ +副本目的是为了备份,所以�一个分区存储在��的broker上,�当third-2存在当�机器kafka01上,实际上�kafka03中也有这个分区的文件(副本),分区中包�副本,�一个分区�以设置多个副本,副本中有一个是leader,其余为follower。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-6e8de9e7dcbdac0b7bd424eaaf4f8568_720w.webp) + +
+ +如果.log文件超出大�,则会产生新的.log文件。如下所示: + + + +``` +00000000000000000000.index +00000000000000000000.log +00000000000000170410.index +00000000000000170410.log +00000000000000239430.index +00000000000000239430.log + +``` + + + +**此时如何快速定�数�,步骤:** + + + +``` +.index文件存储的消�的offset+真实的起始�移�。.log中存放的是真实的数�。 + +``` + + + +首先通过二分查找.index文件到查找到当�消�具体的�移,如上图所示,查找为2,�现第二个文件为6,则定�到一个文件中。 然�通过第一个.index文件通过seek定�元素的�置3,定�到之�获�起始�移�+当�文件大�=总的�移�。 获�到总的�移�之�,直接定�到.log文件��快速获得当�消�大�。 + +## 三. 生产者分区策略 + +**分区的原因** 1\. 方便在集群中扩展:�个partition通过调整以适应它所在的机器,而一个Topic��以有多个partition组�,因此整个集群�以适应适�的数�。 2\. �以�高并�:以Partition为��进行读写。类似于多路。 + +**分区的原则** 1\. 指明partition(这里的指明是指第几个分区)的情况下,直接将指明的值作为partition的值 2\. 没有指明partition的情况下,但是存在值key,此时将key的hash值与topic的partition总数进行�余得到partition值 3\. 值与partition�无的情况下,第一次调用时�机生�一个整数,���次调用在这个整数上自增,将这个值与topic�用的partition总数�余得到partition值,�round-robin算法。 + +## 四. 生产者ISR + +为��producer��的数�能够��的��到指定的topic中,topic的�个partition收到producer��的数��,都需��producer��ackacknowledgement,如果producer收到ack就会进行下一轮的��,�则�新��数�。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-409ea1af4f66bd2f44398850cc2ba9e2_720w.webp) + +
+ +**��ack的时机** 确�有follower与leader�步完�,leader���ack,这样�以��在leader挂掉之�,follower中�以选出新的leader(主�是确�follower中数��丢失) + +**follower�步完�多少���ack** 1\. �数以上的follower�步完�,����ack 2\. 全部的follower�步完�,��以��ack + +## 4.1 副本数��步策略 + +### 4.1.1 �数follower�步完����ack + +优点是延迟低 + +缺点是选举新的leader的时候,容�n�节点的故障,需�2n+1个副本(因为需��数��,所以故障的时候,能够选举的��是剩下的副本超过�数),容错率为1/2 + +### 4.1.2 全部follower�步完�完���ack + +优点是容错率�,选举新的leader的时候,容�n�节点的故障�需�n+1个副本��,因为�需�剩下的一个人������ack了 + +缺点是延迟高,因为需�全部副本�步完��� + +### 4.1.3 kafka的选择 + +kafka选择的是第二�,因为在容器率上�更加有优势,�时对于分区的数�而言,�个分区都有大�的数�,第一�方案会造�大�数�的冗余。虽然第二�网络延迟较高,但是网络延迟对于Kafka的影�较�。 + +## 4.2 ISR(�步副本集) + +**猜想** 采用了第二�方案进行�步ack之�,如果leader收到数�,所有的follower开始�步数�,但有一个follower因为��故障,迟迟�能够与leader进行�步,那么leader就�一直等待下去,直到它�步完�,��以��ack,此时需�如何解决这个问题呢? + +**解决** leader中维护了一个动�的ISR(in-sync replica set),�与leader���步的follower集�,当ISR中的follower完�数�的�步之�,给leader��ack,如果follower长时间没有�leader�步数�,则该follower将从ISR中被踢出,该之间阈值由replica.lag.time.max.ms�数设定。当leader�生故障之�,会从ISR中选举出新的leader。 + +## 五. 生产者ack机制 + +对于�些�太��的数�,对数�的��性�求�是很高,能够容�数�的少�丢失,所以没有必�等到ISR中所有的follower全部接��功。 + +Kafka为用户�供了三���性级别,用户根���性和延迟的�求进行�衡选择��的�置。 + +**ack�数�置** 0:producer�等待broker的ack,这一�作�供了最低的延迟,broker接收到还没有写入�盘就已�返回,当broker故障时有�能丢失数� + +1:producer等待broker的ack,partition的leader�盘�功�返回ack,如果在follower�步�功之�leader故障,那么将丢失数�。(�是leader�盘) + +
+ + +![](https://pic1.zhimg.com/80/v2-a219d261edd97432347f4edf5794e170_720w.webp) + +
+ +-1(all):producer等待broker的ack,partition的leader和ISR的follower全部�盘�功�返回ack,但是如果在follower�步完��,broker��ack之�,如果leader�生故障,会造�数���。(这里的数���是因为没有收到,所以继续��导致的数���) + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-c9741a10f418f7ea4eed929f0f266bbb_720w.webp) + +
+ +producer返ack,0无�盘直接返,1�leader�盘然�返,-1全部�盘然�返 + +## 六. 数�一致性问题 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-031d84a2012f64b122dd64ab67a4e52a_720w.webp) + +
+ +LEO(Log End Offset):�个副本最�的一个offset HW(High Watermark):高水�,指代消费者能�到的最大的offset,ISR队列中最�的LEO。 + +**follower故障和leader故障** 1\. follower故障:follower�生故障�会被临时踢出ISR,等待该follower���,follower会读�本地�盘记录的上次的HW,并将log文件高于HW的部分截�掉,从HW开始�leader进行�步,等待该follower的LEO大于等于该partition的HW,�follower追上leader之�,就�以�新加入ISR了。 2\. leader故障:leader�生故障之�,会从ISR中选出一个新的leader,为了��多个副本之间的数�的一致性,其余的follower会先将�自的log文件高于HW的部分截掉,然�从新的leader中�步数�。 + +**这�能��副本之间的数�一致性,并�能��数��丢失或者���** + +## 七. ExactlyOnce + +将�务器的ACK级别设置为-1(all),�以��producer到Server之间�会丢失数�,�At Least Once至少一次语义。将�务器ACK级别设置为0,�以��生产者��消��会被��一次,�At Most Once至多一次。 + +At Least Once�以��数��丢失,但是�能��数����,而At Most Once�以��数����,但是�能��数��丢失,对于��的数�,则�求数����也�丢失,�Exactly Once�精确的一次。 + +在0.11版本的Kafka之�,�能��数��丢失,在下游对数�的��进行去��作,多余多个下游应用的情况,则分别进行全局去�,对性能有很大影�。 + +0.11版本的kafka,引入了一项�大特性:幂等性,幂等性指代Producer�论�Server��了多少次��数�,Server端都�会�久化一�数�。幂等性结�At Least Once语义就构�了Kafka的Exactly Once语义。 + +�用幂等性,�在Producer的�数中设置enable.idempotence=true��,Kafka的幂等性实现实际是将之�的去��作放在了数�上游��,开�幂等性的Producer在�始化的时候会被分�一个PID,�往�一个Partition的消�会附带Sequence Number,而Broker端会对�缓存,当具有相�主键的消�的时候,Broker�会�久化一�。 + +但PID在��之�会�生�化,�时��的Partition也具有��的主键,所以幂等性无法��跨分区跨会�的Exactly Once。 + +�解决跨分区跨会�的Exactly Once,就引入了生产者事务的概念。 + +## 八. Kafka消费者分区分�策略 + +**消费方�:** consumer采用pull拉的方��从broker中读�数�。 + +push推的模�很难适应消费速率��的消费者,因为消���率是由broker决定的,它的目标是尽�能以最快的速度传递消�,但是这样容易造�consumer���处�消�,典型的表现就是拒��务以�网络拥塞。而pull方�则�以让consumer根�自己的消费处�能力以适当的速度消费消�。 + +pull模��足在于如果Kafka中没有数�,消费者�能会陷入循环之中 (因为消费者类似监�状�获�数�消费的),一直返回空数�,针对这一点,Kafka的消费者在消费数�时会传入一个时长�数timeout,如果当�没有数��供消费,consumer会等待一段时间之��返回,时长为timeout。 + +## 8.1\. 分区分�策略 + +一个consumer group中有多个consumer,一个topic有多个partition,所以必然会涉�到partition的分�问题,�确定那个partition由那个consumer消费的问题。 + +**Kafka的两�分�策略:** 1\. round-robin循环 2\. range + +**Round-Robin** 主�采用轮询的方�分�所有的分区,该策略主�实现的步骤: �设存在三个topic:t0/t1/t2,分别拥有1/2/3个分区,共有6个分区,分别为t0-0/t1-0/t1-1/t2-0/t2-1/t2-2,这里�设我们有三个Consumer,C0�C1�C2,订阅情况为C0:t0,C1:t0�t1,C2:t0/t1/t2。 + +此时round-robin采�的分�方�,则是按照分区的字典对分区和消费者进行排�,然�对分区进行循环�历,�到自己订阅的则消费,�则�下轮询下一个消费者。�按照分区轮询消费者,继而消�被消费。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-21eed325191d7d72c9d4c39455c4cae5_720w.webp) + +
+ +分区在循环�历消费者,自己被当�消费者订阅,则消�与消费者共��下(消�被消费),�则消费者�下消�继续�历(消�没有被消费)。轮询的方�会导致�个Consumer所承载的分区数��一致,从而导致�个Consumer压力��。上�的C2因为订阅的比较多,导致承�的压力也相对较大。 + +**Range** Range的�分�策略,首先计算�个Consumer将会承载的分区数�,然�将指定数�的分区分�给该Consumer。�设存在两个Consumer,C0和C1,两个Topic,t0和t1,这两个Topic分别都有三个分区,那么总共的分区有6个,t0-0,t0-1,t0-2,t1-0,t1-1,t1-2。分�方�如下: + +range按照topic一次进行分�,�消费者�历topic,t0,�有三个分区,�时有两个订阅了该topic的消费者,将这些分区和消费者按照字典�排列。 按照平�分�的方�计算�个Consumer会得到多少个分区,如果没有除尽,多出�的分区则按照字典�挨个分�给消费者。按照此方�以此分��一个topic给订阅的消费者,最�完�topic分区的分�。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-d642ed5512a4abdca9a8f35f2d27c277_720w.webp) + +
+ +## 8.2\. 消费者offset的存储 + +由于Consumer在消费过程中�能会出现断电宕机等故障,Consumer��以�,需�从故障�的�置继续消费,所以Consumer需�实时记录自己消费到了那个offset,以便故障���继续消费。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-f2a50fd7f054821e36a80b1f6d99ecb0_720w.webp) + +
+ +Kafka0.9版本之�,consumer默认将offset�存在zookeeper中,从0.9版本之�,consumer默认将offset�存在kafka一个内置的topic中,该topic为__consumer_offsets + +## �. 高效读写&Zookeeper作用 + +## 9.1 高效读写 + +**顺�写�盘** Kafka的producer生产数�,需�写入到log文件中,写的过程是追加到文件末端,顺�写的方�,官网有数�表明,�样的�盘,顺�写能够到600M/s,而�机写�有200K/s,这与�盘的机械结构有关,顺�写之所以快,是因为其�去了大��头寻�的时间。 + +**零�制技术** + +NIC:Network Interface Controller网络接�控制器 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-2807d010381d304949bf8cea16ba1744_720w.webp) + +
+ +这是常规的读��作: 1\. �作系统将数�从�盘文件中读�到内核空间的页�缓存 2\. 应用程�将数�从内核空间读入到用户空间缓冲区 3\. 应用程�将读到的数�写回内核空间并放入到socket缓冲区 4\. �作系统将数�从socket缓冲区�制到网�接�,此时数�通过网络��给消费者 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-390cbabdeaba6f9e79a8ba6f4d08d75f_720w.webp) + +
+ +零拷�技术�用将�盘文件的数��制到页�缓存中一次,然�将数�从页�缓存直接��到网络中(��给��的订阅者时,都�以使用�一个页�缓存),从而��了���制的�作。 + +如果有10个消费者,传统方�下,数��制次数为4*10=40次,而使用“零拷�技术��需�1+10=11次,一次为从�盘�制到页�缓存,10次表示10个消费者�自读�一次页�缓存。 + +## 9.2 zookeeper作用 + +Kafka集群中有一个broker会被选举为Controller,负责管�集群broker的上下线�所有topic的分区副本分�和leader的选举等工作。Controller的工作管�是�赖于zookeeper的。 + +**Partition的Leader的选举过程** + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-fc64ea72cba32e702b15344767bdace9_720w.webp) + +
+ +## �. 事务 + +kafka从0.11版本开始引入了事务支�,事务�以��Kafka在Exactly Once语义的基础上,生产和消费�以跨分区的会�,�么全部�功,�么全部失败。 + +## 10.1 Producer事务 + +为了按跨分区跨会�的事务,需�引入一个全局唯一的Transaction ID,并将Producer获得的PID(�以�解为Producer ID)和Transaction ID进行绑定,这样当Producer��之�就�以通过正在进行的Transaction ID获得原�的PID。 + +为了管�Transaction,Kafka引入了一个新的组件Transaction Coordinator,Producer就是通过有和Transaction Coordinator交互获得Transaction ID对应的任务状�,Transaction Coordinator还负责将事务信�写入内部的一个Topic中,这样�使整个�务��,由于事务状�得到�存,进行中的事务状��以��,从而继续进行。 + +## 10.2 Consumer事务 + +对于Consumer而言,事务的��相比Producer相对较弱,尤其是无法��Commit的信�被精确消费,这是由于Consumer�以通过offset访问任�信�,而且��的Segment File声明周期��,�一事务的消��能会出现���被删除的情况。 + +## �考文章 + +https://blog.csdn.net/cao131502 +https://zhuanlan.zhihu.com/p/137811719 \ No newline at end of file diff --git "a/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\347\232\204\351\233\206\347\276\244\345\267\245\344\275\234\345\216\237\347\220\206.md" "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\347\232\204\351\233\206\347\276\244\345\267\245\344\275\234\345\216\237\347\220\206.md" new file mode 100644 index 0000000..cd6122e --- /dev/null +++ "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\347\232\204\351\233\206\347\276\244\345\267\245\344\275\234\345\216\237\347\220\206.md" @@ -0,0 +1,127 @@ +**�言** + +上篇文章讲到了消�在 Partition 上的存储形�,本�准备接����生产中的一些使用方�,想了想还有些很��的工作组件原�没有讲清楚,比如一个 Topic 由 N 个 Partition 组�,那么这些 Partition 是如何�匀的分布在��的 Broker 上?�比如当一个 Broker 宕机�,其上负责读写请求的主 Partition 无法正常访问,如何让从 Partition 转��主 Partition �继续�供正常的读写�务?想�解决这些问题,就必须先�了解一下 Kafka 集群内部的管�机制,其中一个�常��的控制器就是 KafkaController。本文我们就�讲讲 KafkaController 是如何�解决上��到的那些问题的。 + +### **文章概览** + +1. KafkaController 是什么�其选举策略。 +2. KafkaController 监控 ZK 的目录分布。 +3. Partition 分布算法。 +4. Partition 的状�转移。 +5. Kafka 集群的负载�衡处��程解�。 + +## **KafkaController 是什么�其选举策略** + +Kafka 集群由多� Broker 构�,�� Broker 都有一个 KafkaController 用于管�当�的 Broker。试想一下,如果一个集群没有一个“领导者�,那么�去和“外界�(比如 ZK)沟通呢?�去�调 Partition 应该如何分布在集群中的�� Broker 上呢?�去处� Broker 宕机�,在其 Broker 上的主 Partition 无法正常�供读写�务�,将对应的从 Partition 转��主 Partition 继续正常对外�供�务呢?那么由哪个 Broker 的 KafkaController �担当“领导者�这个角色呢? + +Kafka 的设计者很�明,Zookeeper 既然是分布�应用�调�务,那么干脆就让它�帮 Kafka 集群选举一个“领导者�出�,这个“领导者�对应的 KafkaController 称为 Leader,其他的 KafkaController 被称为 Follower,在�一时刻,一个 Kafka 集群�能有一个 Leader 和 N 个 Follower。 + +### **Zookeeper 是怎么实现 KafkaController 的选主工作呢?** + +�微熟悉 Zookeeper 的�伙伴应该都比较清楚,Zookeeper 是通过监控目录(zNode)的�化,从而�出一些相应的动作。 + +Zookeeper 的目录分为四�,第一�是永久的,被称作为 `Persistent`; + +第二�是顺�且永久的,被称作为 `Persistent_Sequential`; + +第三�是临时的,被称为 `Ephemeral`; + +第四�是顺�且临时的,被称作为 `Ephemeral_Sequential`。 + +KafkaController 正是利用了临时的这一特性�完�选主的,在 Broker �动时,�个 Broker 的 KafkaController 都会� ZK 的 `/controller` 目录写入 BrokerId,�先写入�就是 Leader,剩余的 KafkaController 是 Follower,当 Leader 在周期内没有� ZK ��报告的�,则认为 Leader 挂了,此时 ZK 删除临时的 `/controller` 目录,Kafka 集群中的其他 KafkaController 开始新的一轮争主�作,�程和上�一样。下�是选 Leader 的�程图。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-af1f22f109f85fe6b169c6e4a271016f_720w.webp) + +
Leader选举�程图
+ +
+ +从上图�以看出,第一次,Broker1 �功抢先在 Zookeeper 的 /controller 目录上写入信�,所以 Broker1 的 KafkaController 为 Leader,其他两个为 Follower。第二次,Broker1 宕机或者下线,此时 Broker2 和 Broker3 检测到,于是开始新一轮的争抢将信�写入 Zookeeper,从图中�以看出,Broker2 争到了 Leader,所以 Broker3 是 Follower 状�。 + +正常情况下,上�这个�程没有问题,但是如果在 Broker1 离线的情况下,Zookeeper 准备删除 /controller 的临时 node 时,系统 hang �没办法删除,改怎么办呢?这里留个�疑问供大家�考。��会用一篇文章专门�解答 Kafka 相关的问题(包括�试题哦,敬请期待)。 + +## **KafkaController 监控的 ZK 目录分布** + +KafkaController 在�始化的时候,会针对��的 zNode 注册���样的监�器,以便处���的用户请求或者系统内部�化请求。监控 ZK 的目录大概�以分为两部分,分别是 `/admin` 目录和 `/brokers` 目录。�目录�其对应的功能如下表所示,需�的朋�自�。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-2a603adc2e06f3663e693259e8bf16d4_720w.webp) + +
+ +## **Partition 分布算法** + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-36d40cb264f6432a81ad83c9365d7997_720w.webp) + +
Partition分布算法图
+ +
+ +图解:�设集群有 3 个 Broker,Partition 因�为 2。 + +1. �机选� Broker 集群中的一个 Broker 节点,然�以轮询的方�将主 Partition �匀的分布到��的 Broker 上。 +2. 主 Partition 分布完��,将从 Partition 按照 AR 组内顺�以轮询的方�将 Partition �匀的分布到��的 Broker 上。 + +## **Partition 的状�转移** + +用户针对特定的 Topic 创建了相应的 Partition ,但是这些 Partition �一定时刻都能够正常工作,所有 Partition 在�一时刻会对应 4 个状�中的�一个;其整个生命周期会�历如下状�的转移,分别是 NonExistentPartition�NewPartition�OnlinePartition�OfflinePartition,其对应的状�转移情况如下图所示。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-58a8609aa2698130679d9fb80541d19b_720w.webp) + +
Partition状�转移图
+ +
+ +从上图�以看出,Partition 的状�会由�置状��能够转移到目标状�的,而�是胡乱转移状�的。 + +`NonExistentPartition:`代表没有创建 Partition 时的状�,也有�能是离线的 Partition 被删除�的状�。 + +`NewPartition:`当 Partition 被创建时,此时�有 AR(Assigned Replica),还没有 ISR(In-Synic Replica),此时还�能接�数�的写入和读�。 + +`OnlinePartition:`由 NewPartition 状�转移为 OnlinePartition 状�,此时 Partition 的 Leader 已�被选举出�了,并且也有对应的 ISR 列表等。此时已��以对外�供读写请求了。 + +`OfflinePartition:`当 Partition 对应的 Broker 宕机或者网络异常等问题,由 OnlinePartition 转移到 OfflinePartition,此时的 Partition 已��能在对外�供读写�务。当 Partition 被彻底删除�状�就转移� NonExistentPartition,当网络��或者 Broker ���,其状���以转移到 OnlinePartition,从而继续对外�供读写�务。 + +## **Kafka 集群的负载�衡处��程解�** + +��的文章讲到过,Partition 有 Leader Replica 和 Preferred Replica 两�角色,Leader Replica 负责对外�供读写�务 Preferred Replica 负责�步 Leader Replica 上的数�。现在集群中�设有 3 个 Broker,3 个 Partition,�个 Partition 有 3 个 Replica,当集群�行一段时候�,集群中�些 Broker 宕机,Leader Replica 进行转移,其过程如下图所示。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-dc0bcd6f072f7e6cef8289882259d59e_720w.webp) + +
Partition的Leader转移图
+ +
+ +从上图�以看出,集群�行一段时间�,Broker1 挂掉了,在其上�行的 Partition0 对应的 Leader Replica 转移到了 Broker2 上。�设一段时间� Broker3 也挂了,则 Broker3 上的 Partition3 对应的 Leader Replica 也转移到了 Broker2 上,集群中�有 Broker2 上的 Partition 在对外�供读写�务,从而造� Broker2 上的�务压力比较大,之� Broker1 和 Broker3 ���,其上�有 Preferred Replica �备份�作。 + +针对以上这���时间的推移,集群�在�刚开始时那样平衡,需�通过��线程将 Leader Replica �新分�到�� Broker 上,从而使得读写�务尽��匀的分布在��的节点上。 + +�平衡�作是由 partition-rebalance-thread ��线程�作的,由于其优先级很低,所以�会在集群空闲的时候�会执行。集群的�平衡的评判标准是由`leader.imbalance.per.broker.percentage`�置决定的,当集群的�平衡度达到 10%(默认)时,会触���线程�动�平衡�作,其具体执行步骤如下: + +1. 对 Partition 的 AR 列表根� Preferred Replica 进行分组�作。 +2. �历 Broker,对其上的 Partition 进行处�。 +3. 统计 Broker 上的 Leader Replica 和 Preferred Replica �相等的 Partition 个数。 +4. 统计 Broker 上的 Partition 个数。 +5. Partition 个数 / �相等的 Partition 个数,如果大于 10%,则触��平衡�作;�之,则��任何处�。 + +## **总结** + +本文主�介�了 Kafka 集群�务内部的一些工作机制,相信�伙伴们掌�了这部分内容�,对 Broker �务端的工作�程有了进一步的�解,从而更好的把控整体集群�务。下篇文章我们�正�介�一下**Kafka 常用的命令行�作**,敬请期待。 + +# �考文章 +https://blog.csdn.net/cao131502 +https://zhuanlan.zhihu.com/p/137811719 \ No newline at end of file diff --git "a/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\351\207\215\350\246\201\347\237\245\350\257\206\347\202\271+\351\235\242\350\257\225\351\242\230\345\244\247\345\205\250.md" "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\351\207\215\350\246\201\347\237\245\350\257\206\347\202\271+\351\235\242\350\257\225\351\242\230\345\244\247\345\205\250.md" new file mode 100644 index 0000000..77ac95f --- /dev/null +++ "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232Kafka\351\207\215\350\246\201\347\237\245\350\257\206\347\202\271+\351\235\242\350\257\225\351\242\230\345\244\247\345\205\250.md" @@ -0,0 +1,518 @@ +## ���试知识点 + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-75cd70ad3052ba44bf706a3ab39e59d5_720w.webp) + + +Kafka 消费端确�一个 Partition 在一个消费者组内�能被一个消费者消费。这��改怎么�解呢? + +1. 在�一个消费者组内,一个 Partition �能被一个消费者消费。 +2. 在�一个消费者组内,所有消费者组�起�必定�以消费一个 Topic 下的所有 Partition。 +3. 在�一个消费组内,一个消费者�以消费多个 Partition 的信�。 +4. 在��消费者组内,�一个分区�以被多个消费者消费。 +5. �个消费者组一定会完整消费一个 Topic 下的所有 Partition。 + +### **消费组存在的�义** + +了解了消费者与消费组的关系�,有朋�会比较疑惑消费者组有啥实际存在的�义呢?或者说消费组的作用是什么? + +作者对消费组的作用归结了如下两点。 + +1. 在实际生产中,对于�一个 Topic,�能有 A�B�C 等 N 个消费方想�消费。比如一份用户点击日志,A 消费方想用��一个用户近 N 天点击过哪些商�;B 消费方想用��一个用户近 N 天点击过� TopN 个相似的商�;C 消费方想用��一个根�用户点击过的商�推�相关周边的商�需求。对于多应用场景,就�以使用消费组�隔离��的业务使用场景,从而达到一个 Topic �以被多个消费组��消费的目的。 +2. 消费组与 Partition 的消费进度绑定。当有新的消费者加入或者有消费者从消费组退出时,会触�消费组的 Repartition �作(��会详细介� Repartition);在 Repartition �,Partition1 被消费组的消费者 A 进行消费,Repartition �,Partition1 消费组的消费者 B 进行消费,为了��消�被��消费,需�从消费组记录的 Partition 消费进度读�当�消费到的�置(� OffSet �置),然�在继续消费,从而达到消费者的平滑�移,�时也�高了系统的�用性。 + +## **Repartition 触�时机** + +使用过 Kafka 消费者客户端的�学肯定知�,消费者组内�尔会触� Repartition �作,所谓 Repartition � Partition 在�些情况下�新被分�给�与消费的消费者。基本�以分为如下几�情况。 + +1. 消费组内�消费者宕机,触� Repartition �作,如下图所示。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-a9ef6a29cb9ba3456a05ad75cb91cb03_720w.webp) + +
消费者宕机情况
+ +
+ +2\. 消费组内新增消费者,触� Repartition �作,如下图所示。一般这�情况是为了�高消费端的消费能力,从而加快消费进度。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-8803223d712fdde035b8e7b9170dd3fb_720w.webp) + +
新增消费者情况
+ +
+ +3.Topic 下的 Partition 增多,触� Repartition �作,如下图所示。一般这�调整 Partition 个数的情况也是为了�高消费端消费速度的,因为当消费者个数大于等于 Partition 个数时,在增加消费者个数是没有用的(原因是:在一个消费组内,消费者:Partition = 1:N,当 N �于 1 时,相当于消费者过剩了),所以一方�增加 Partition 个数�时增加消费者个数�以�高消费端的消费速度。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-8f1a427c6842d9babf139454ce23cfa3_720w.webp) + +
新增Partition个数情况
+ +
+ +## **消费者与 ZK 的关系** + +众所周知,ZK �仅�存了消费者消费 partition 的进度,�时也�存了消费组的�员列表�partition 的所有者。消费者想�消费 Partition,需�从 ZK 中获�该消费者对应的分区信��当�分区对应的消费进度,� OffSert 信�。那么 Partition 应该由那个消费者进行消费,决定因素有哪些呢?从之�的图中�难得出,两个��因素分别是:消费组中存活的消费者列表和 Topic 对应的 Partition 列表。通过这两个因素结� Partition 分�算法,��得出消费者与 Partition 的对应关系,然�将信�存储到 ZK 中。Kafka 有高级 API 和低级 API,如果�需��作 OffSet �移�的�交,�通过高级 API 直接使用,从而�低使用者的难度。对于一些比较特殊的使用场景,比如想�消费特定 Partition 的信�,Kafka 也�供了低级 API �进行手动�作。 + +## **消费端工作�程** + +在介�消费端工作�程�,先�熟悉一下用到的一些组件。 + +* `KakfaConsumer`:消费端,用于�动消费者进程�消费消�。 +* `ConsumerConfig`:消费端�置管�,用于给消费端�置相关�数,比如指定 Kafka 集群,设置自动�交和自动�交时间间隔等等�数,都由其�管�。 +* `ConsumerConnector`:消费者连接器,通过消费者连接器�以获得 Kafka 消��,然�通过消��就能获得消�从而使得客户端开始消费消�。 + +以上三者之间的关系�以概括为:消费端使用消费者�置管�创建出了消费者连接器,通过消费者连接器创建队列(这个队列的作用也是为了缓存数�),其中队列中的消�由专门的拉�线程从�务端拉�然�写入,最�由消费者客户端轮询队列中的消�进行消费。具体�作�程如下图所示。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-122b4a706de39655d257928005a83ff1_720w.webp) + +
消费端工作�程
+ +
+ +我们在从消费者与 ZK 的角度�看看其工作�程是什么样的? + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-4ed25ebb9236986b2084ce8a042f65b9_720w.webp) + +
消费端与ZK之间的工作�程
+ +
+ +从上图�以看出,首先拉�线程�拉�一次消�,�步更新一次拉�状�,其作用是为了下一次拉�消�时能够拉�到最新产生的消�;拉�线程将拉�到的消�写入到队列中等待消费消费线程去真正读�处�。消费线程以轮询的方��续读�队列中的消�,���现队列中有消�就开始消费,消费完消��更新消费进度,此处需�注�的是,消费线程�是�次都和 ZK �步消费进度,而是将消费进度暂时写入本地。这样�的目的是为了�少消费者与 ZK 的频��步消�,从而�低 ZK 的压力。 + +## **消费者的三�消费情况** + +消费者从�务端的 Partition 上拉�到消�,消费消�有三�情况,分别如下: + +1. 至少一次。�一�消�至少被消费一次,消���能丢失,但是�能会被��消费。 +2. 至多一次。�一�消�最多�以被消费一次,消���能被��消费,但是消�有�能丢失。 +3. 正好一次。�一�消�正好被消费一次,消���能丢失也��能被��消费。 + +### **1.至少一次** + +消费者读�消�,先处�消�,在�存消费进度。消费者拉�到消�,先消费消�,然�在�存�移�,当消费者消费消��还没�得��存�移�,则会造�消�被��消费。如下图所示: + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-1a047ed616ba44daebdb4b6ce786a61a_720w.webp) + +
先消费��存消费进度
+ +
+ +### **2.至多一次** + +消费者读�消�,先�存消费进度,在处�消�。消费者拉�到消�,先�存了�移�,当�存了�移��还没消费完消�,消费者挂了,则会造�未消费的消�丢失。如下图所示: + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-1f9f91ae54396c5e5d93ae89251eb1ed_720w.webp) + +
先�存消费进度�消费消�
+ +
+ +### **3.正好一次** + +正好消费一次的办法�以通过将消费者的消费进度和消�处�结果�存在一起。��能��两个�作是一个原��作,就能达到正好消费一次的目的。通常�以将两个�作�存在一起,比如 HDFS 中。正好消费一次�程如下图所示。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-a0bbb114e2ad551227f81c1f26d4bd5d_720w.webp) + +
正好消费一次
+ +
+ +## Partition�Replica�Log 和 LogSegment 的关系 + +�设有一个 Kafka 集群,Broker 个数为 3,Topic 个数为 1,Partition 个数为 3,Replica 个数为 2。Partition 的物�分布如下图所示。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-f8f21631b138321f25c8821c677c5579_720w.webp) + +
Partition分布图
+ +
+ +从上图�以看出,该 Topic 由三个 Partition 构�,并且�个 Partition 由主从两个副本构�。�个 Partition 的主从副本分布在��的 Broker 上,通过这点也�以看出,当�个 Broker 宕机时,�以将分布在其他 Broker 上的从副本设置为主副本,因为�有主副本对外�供读写请求,当然在最新的 2.x 版本中从副本也�以对外读请求了。将主从副本分布在��的 Broker 上从而�高系统的�用性。 + +Partition 的实际物�存储是以 Log 文件的形�展示的,而�个 Log 文件�以多个 LogSegment 组�。Kafka 为什么�这么设计呢?其实原因比较简�,��消�的�断写入,Log 文件肯定是越�越大,Kafka 为了方便管�,将一个大文件切割�一个一个的 LogSegment �进行管�;�个 LogSegment 由数�文件和索引文件构�,数�文件是用�存储实际的消�内容,而索引文件是为了加快消�内容的读�。 + +�能�有朋�会问,Kafka 本身消费是以 Partition 维度顺�消费消�的,�盘在顺�读的时候效率很高完全没有必�使用索引啊。其实 Kafka 为了满足一些特殊业务需求,比如��机消费 Partition 中的消�,此时�以先通过索引文件快速定�到消�的实际存储�置,然�进行处�。 + +总结一下 Partition�Replica�Log 和 LogSegment 之间的关系。消�是以 Partition 维度进行管�的,为了�高系统的�用性,�个 Partition 都�以设置相应的 Replica 副本数,一般在创建 Topic 的时候�时指定 Replica 的个数;Partition 和 Replica 的实际物�存储形�是通过 Log 文件展现的,为了防止消��断写入,导致 Log 文件大��续增长,所以将 Log 切割�一个一个的 LogSegment 文件。 + +**注�:** 在�一时刻,�个主 Partition 中有且�有一个 LogSegment 被标识为�写入状�,当一个 LogSegment 文件大�超过一定大��(比如当文件大�超过 1G,这个就类似于 HDFS 存储的数�文件,HDFS 中数�文件达到 128M 的时候就会被分出一个新的文件�存储数�),就会新创建一个 LogSegment �继续接收新写入的消�。 + +## 写入消��程分� + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-eb66e4ecf7cf07fcb6b12029bfdd9b71_720w.webp) + +
消�写入��盘�程
+ +
+ +�程解� + +在第 3 篇文章讲过,生产者客户端对于�个 Partition 一次会��一批消�到�务端,�务端收到一批消��写入相应的 Partition 上。上图�程主�分为如下几步: + +1. **客户端消�收集器收集属于�一个分区的消�,并对��消�设置一个�移�,且�一批消�总是从 0 开始�调递增。比如第一次�� 3 �消�,则对三�消��次编� [0,1,2],第二次�� 4 �消�,则消��次编�为 [0,1,2,3]。注�此处设置的消��移�是相对�移�。** +2. **客户端将消���给�务端,�务端拿到下一�消�的�对�移�,将传到�务端的这批消�的相对�移�修改��对�移�。** +3. **将修改�的消�以追加的方�追加到当�活跃的 LogSegment ��,然�更新�对�移�。** +4. **将消�集写入到文件通�。** +5. **文件通�将消�集 flush 到�盘,完�消�的写入�作。** + +了解以上过程�,我们在�看看消�的具体构�情况。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-6e993c95decd5d274b032cd423936504_720w.webp) + +
消�构�细节图
+ +
+ +一�消�由如下三部分构�: + +* **OffSet:�移�,消�在客户端���将相对�移�存储到该�置,当消�存储到 LogSegment �,先将其修改为�对�移�在写入�盘。** +* **Size:本� Message 的内容大�** +* **Message:消�的具体内容,其具体�由 7 部分组�,crc 用于校验消�,Attribute 代表了属性,key-length 和 value-length 分别代表 key 和 value 的长度,key 和 value 分别代表了其对应的内容。** + +### 消��移�的计算过程 + +通过以上�程�以看出,��消�在被实际存储到�盘时都会被分�一个�对�移���能被写入�盘。在�一个分区内,消�的�对�移�都是从 0 开始,且�调递增;在��分区内,消�的�对�移�是没有任何关系的。接下�讨论下消�的�对�移�的计算规则。 + +确定消��移�有两�方�,一�是顺�读��一�消��确定,此�方�代价比较大,实际上我们并�想知�消�的内容,而�是想知�消�的�移�;第二�是读���消�的 Size 属性,然�计算出下一�消�的起始�移�。比如第一�消�内容为 “abc�,写入�盘�的�移�为:8(OffSet)+ 4(Message 大�)+ 3(Message 内容的长度)= 15。第二�写入的消�内容为“defg�,其起始�移�为 15,下一�消�的起始�移�应该是:15+8+4+4=31,以此类推。 + +## 消费消��副本�步�程分� + +和写入消��程��,读�消��程分为两�情况,分别是消费端消费消�和从副本(备份副本)�步主副本的消�。在开始分�读��程之�,需�先明白几个用到的��,�然�程分��能会看的比较糊涂。 + +* **BaseOffSet**:基准�移�,�个 Partition 由 N 个 LogSegment 组�,�个 LogSegment 都有基准�移�,大概由如下构�,数组中�个数代表一个 LogSegment 的基准�移�:[0,200,400,600, ...]。 +* **StartOffSet**:起始�移�,由消费端�起读�消�请求时,指定从哪个�置开始消费消�。 +* **MaxLength**:拉�大�,由消费端�起读�消�请求时,指定本次最大拉�消�内容的数�大�。该�数�以通过[max.partition.fetch.bytes](https://link.zhihu.com/?target=https%3A//xie.infoq.cn/draft/3020%23)�指定,默认大�为 1M。 +* **MaxOffSet**:最大�移�,消费端拉�消�时,最高�拉�消�的�置,�俗称的“高水��。该�数由�务端指定,其作用是为了防止生产端还未写入的消�就被消费端进行消费。此�数对于从副本�步主副本�会用到。 +* **MaxPosition**:LogSegment 的最大�置,确定了起始�移�在�个 LogSegment 上开始,读� MaxLength �,�能超过 MaxPosition。MaxPosition 是一个实际的物��置,而��移�。 + +�设消费端从 000000621 �置开始消费消�,关于几个��的关系如下图所示。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-cd9c62a71cddccd7bc8a5d810d5af216_720w.webp) + +
�置关系图
+ +
+ +消费端和从副本拉��程如下: + +1. **客户端确定拉�的�置,� StartOffSet 的值,找到主副本对应的 LogSegment。** +2. **LogSegment 由索引文件和数�文件构�,由于索引文件是从�到大排列的,首先从索引文件确定一个�于等于 StartOffSet 最近的索引�置。** +3. **根�索引�置找到对应的数�文件�置,由于数�文件也是从�到大排列的,从找到的数�文件�置顺����历,直到找到和 StartOffSet 相等的�置,�为消费或拉�消�的�置。** +4. **从 StartOffSet 开始��拉� MaxLength 大�的数�,返回给消费端或者从副本进行消费或备份�作。** + +�设拉�消�起始�置为 00000313,消�拉��程图如下: + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-9417ca60a0c5e9474ec49a77fff18b1b_720w.webp) + +
消�拉��程图
+ +
+ +## kafka 如何��系统的高�用�数�的��性和数�的一致性的? + +### kafka 的高�用性: + +1. **Kafka 本身是一个分布�系统,�时采用了 Zookeeper 存储元数�信�,�高了系统的高�用性。** +2. **Kafka 使用多副本机制,当状�为 Leader 的 Partition 对应的 Broker 宕机或者网络异常时,Kafka 会通过选举机制从对应的 Replica 列表中�新选举出一个 Replica 当� Leader,从而继续对外�供读写�务(当然,需�注�的一点是,在新版本的 Kafka 中,Replica 也�以对外�供读请求了),利用多副本机制在一定程度上�高了系统的容错性,从而��了系统的高�用。** + +### Kafka 的��性: + +1. **从 Producer 端�看,��性是指生产的消�能够正常的被存储到 Partition 上且消��会丢失。Kafka 通过 [request.required.acks](https://link.zhihu.com/?target=https%3A//xie.infoq.cn/edit/49a133ad2b2f2671aa60706b0%23)和[min.insync.replicas](https://link.zhihu.com/?target=https%3A//xie.infoq.cn/edit/49a133ad2b2f2671aa60706b0%23) 两个�数��,在一定程度上��消��会丢失。** +2. **[request.required.acks](https://link.zhihu.com/?target=https%3A//xie.infoq.cn/edit/49a133ad2b2f2671aa60706b0%23) �设置为 1�0�-1 三�情况。** + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-7946f258c85fb8ca3d4aa423269c483a_720w.webp) + +
request.required.acks=1
+ +
+ +设置为 1 时代表当 Leader 状�的 Partition 接收到消�并�久化时就认为消����功,如果 ISR 列表的 Replica 还没�得��步消�,Leader 状�的 Partition 对应的 Broker 宕机,则消�有�能丢失。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-382c9f37f644feb37dd975c67bc1038f_720w.webp) + +
request.required.acks=0
+ +
+ +设置为 0 时代表 Producer ��消��就认为�功,消�有�能丢失。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-592996f264baadc64967d6f4b28f4d23_720w.webp) + +
request.required.acks=-1
+ +
+ +设置为-1 时,代表 ISR 列表中的所有 Replica 将消��步完���认为消����功;但是如果�存在主 Partition 的时候,Broker 异常时�样会导致消�丢失。所以此时就需�[min.insync.replicas](https://link.zhihu.com/?target=https%3A//xie.infoq.cn/edit/49a133ad2b2f2671aa60706b0%23)�数的��,该�数需�设定值大于等于 2,当 Partition 的个数�于设定的值时,Producer ��消�会直接报错。 + +上�这个过程看似已�很完美了,但是�设如果消�在�步到部分从 Partition 上时,主 Partition 宕机,此时消�会�传,虽然消��会丢失,但是会造��一�消�会存储多次。在新版本中 Kafka �出了幂等性的概念,通过给��消�设置一个唯一 ID,并且该 ID �以唯一映射到 Partition 的一个固定�置,从而��消���存储的问题(作者到目�还没有使用过该特性,感兴趣的朋��以自行在深入研究一下)。 + +### Kafka 的一致性: + +1. **从 Consumer 端�看,�一�消�在多个 Partition 上读�到的消�是一直的,Kafka 通过引入 HW(High Water)�实现这一特性。** + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-9975539d98bf1a4e1a3038f2eceb2bb9_720w.webp) + +
消��步图
+ +
+ +从上图�以看出,�设 Consumer 从主 Partition1 上消费消�,由于 Kafka 规定��许消费 HW 之�的消�,所以最多消费到 Message2。�设当 Partition1 异常�,Partition2 被选举为 Leader,此时�旧�以从 Partition2 上读�到 Message2。其实 HW 的��利用了木桶效应,始终��最短�的那个�置。 + +从上�我们也�以看出,使用 HW 特性�会使得消��有被所有副本�步��能被消费,所以在一定程度上�低了消费端的性能,�以通过设置[replica.lag.time.max.ms](https://link.zhihu.com/?target=https%3A//xie.infoq.cn/edit/49a133ad2b2f2671aa60706b0%23)�数���消��步的最大时间。 + +## kafka 为什么那么快? + +kafka 使用了顺�写入和“零拷��技术,�达到�秒钟 200w(Apache 官方给出的数�) 的�盘数�写入�,�外 Kafka 通过压缩数�,�低 I/O 的负担。 + +1. **顺�写入** + +大家都知�,对于�盘而已,如果是�机写入数�的�,�次数�在写入时�先进行寻��作,该�作是通过移动�头完�的,�其耗费时间,而顺�读写就能够��该�作。 + +1. **“零拷��技术** + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-6930901956f341f1ab4a6e5650a0680b_720w.webp) + +
普通数�拷��程图
+ +
+ +普通的数�拷��程如上图所示,数�由�盘 copy 到内核�,然�在拷�到用户�,然��由用户�拷�到 socket,然�由 socket �议引擎,最�由�议引擎将数���到网络中。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-9e44873a63d8addca917e658667f0b61_720w.webp) + +
&quot;零拷�&quot;�程图
+ +
+ +采用了“零拷��技术��以看出,数��在�过用户�传输,而是直接在内核�完��作,�少了两次 copy �作。从而大大�高了数�传输速度。 + +1. **压缩** + +Kafka 官方�供了多�压缩�议,包括 gzip�snappy�lz4 等等,从而�低了数�传输的�本。 + +## Kafka 中的消�是�会丢失和��消费? + +1. **Kafka 是�会丢消�,答案相信仔细看过��两个问题的�学都比较清楚了,这里就�在赘述了。** +2. **在低版本中,比如作者公�在使用的 Kafka0.8 版本中,还没有幂等性的特性的时候,消�有�能会��被存储到 Kafka 上(原因�上一个问题的),在这�情况下消�肯定是会被��消费的。** + +**这里给大家一个解决��消费的�路,作者公�使用了 Redis 记录了被消费的 key,并设置了过期时间,在 key 还没有过期内,对于�一个 key 的消�全部当���消�直接抛弃掉。** 在网上看到过�外一�解决方案,使用 HDFS 存储被消费过的消�,是�具有�行性存疑(需�读者朋�自行探索),读者朋�们�以根�自己的实际情况选择相应的策略,如果朋�们还有其他比较好的方案,欢迎留言交�。 + +## 为什么�使用 kafka,为什么�使用消�队列? + +### 先�说说为什么�使用消�队列? + +这�题比较主观一些(自认为没有网上其他文章写得�,轻喷),但是都相信大家使用消�队列无�就是为了 **解耦**�**异步**�**消峰**。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-f7c1bb87ab46ddd03255c58109ce360f_720w.webp) + +
系统调用图
+ +
+ +��业务的�展,相信有�少朋�公��到过如上图所示的情况,系统 A 处�的结构被 B�C�D 系统所�赖,当新增系统 E 时,也需�系统 A ��进行�调和上线等�作;还有当系统 A �生�更时�样需�告知 B�C�D�E 系统需��步�级改造。 + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-0f0c8f9531a38f6d79b2cbb2973bfbfc_720w.webp) + +
引入消�队列图
+ +
+ +引入消�队列�有两个好处: + +1. **�个系统进行了解耦,从上图也�以看出,当系统 A �然�生热点事件时,�一时间产生大�结果,MQ 充当了消�暂存的效果,防止 B�C�D�E 系统也跟�崩溃。** +2. **当新系统 E 需�接入系统 A 的数�,�需�和 MQ 对接就�以了,从而��了与系统 A 的调试上线等�作。** + +引入消�队列的�处: + +万事皆具备两�性,看似引入消�队列这件事情很美好,但是�时也增加了系统的��度�系统的维护�本�高(如果 MQ 挂了怎么办)�引入了一致性等等问题需�去解决。 + +## 为什么�使用 Kafka? + +作者认为采用 Kafka 的原因有如下几点: + +1. **Kafka 目�在业界被广泛使用,社区活跃度高,版本更新迭代速度也快。** +2. **Kafka 的生产者和消费者都用 Java 语言进行了�写,在一定程度�低了系统的维护�本(作者的主观��,因为当下 Java 的使用群体相当庞大)。** +3. **Kafka 系统的���高,达到了�秒 10w 级别的处�速度。** +4. **Kafka �以和很多当下优秀的大数�组件进行集�,包括 Spark�Flink�Flume�Storm 等等。** + +## 为什么 Kafka �支�读写分离? + +这个问题有个先决�件,我们�讨论 Kafka0.9 版本的情况。对于高版本,从 Partition 也�以承担读请求了,这里�多赘述。 + +Kafka 如果支�读写分离的�,有如下几个问题。 + +1. **系统设计的��度会比较大,当然这个比较牵强,毕竟高版本的 Kafka 已�实现了。** + +
+ + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/v2-98093ad82970feb7a0c52954c6942aa1_720w.webp) + +
+ +**2\. 从上图å�¯ä»¥çœ‹å‡ºï¼Œä»Žä»Ž Partition 上读å�–æ•°æ�®ä¼šæœ‰ä¸¤ä¸ªé—®é¢˜ã€‚一ã€�æ•°æ�®ä»Žä¸» Partition 上å�Œæ­¥åˆ°ä»Ž Partition 有数æ�®å»¶è¿Ÿé—®é¢˜ï¼Œå› ä¸ºæ•°æ�®ä»Žç”Ÿäº§åˆ°æ¶ˆè´¹ä¼šç»�历 3 次网络传输æ‰�能够被消费,对于时效性è¦�求比较高的场景本身就ä¸�适å�ˆäº†ã€‚二ã€�æ•°æ�®ä¸€è‡´æ€§é—®é¢˜ï¼Œå�‡è®¾ä¸» Partition 将数æ�®ç¬¬ä¸€æ¬¡ä¿®æ”¹æˆ�了 A,然å�Žå�ˆå°†è¯¥æ•°æ�®ä¿®æ”¹æˆ�了 B,由于从主 Partition å�Œæ­¥åˆ°ä»Ž Partition 会有延迟问题,所以也就会产生数æ�®ä¸€è‡´æ€§é—®é¢˜ã€‚** + +分æž�得出,通过解决以上问题æ�¥æ�¢å�–从 Partition 承担读请求,æˆ�本å�¯æƒ³è€ŒçŸ¥ï¼Œè€Œä¸”对于写入压力大,读å�–压力å°�的场景,本身也就没有什么æ„�义了。 + +## 总结 + +本文介ç»�了几个常è§�çš„ Kafka çš„é�¢è¯•题 + +### 常è§�é�¢è¯•题一览 + +#### 1.1 Kafka 中的 ISR(InSyncRepli)ã€� OSR(OutSyncRepli)ã€� AR(AllRepli)代表什么? + +ISR:速率和leader相差低于10sçš„follower的集å�ˆ + +OSR:速率和leader相差大于10sçš„follwer + +AR:所有分区的follower + +#### 1.2 Kafka 中的 HWã€� LEO 等分别代表什么? + +HW:High Water高水ä½�,根æ�®å�Œä¸€åˆ†åŒºä¸­æœ€ä½Žçš„LEO决定(Log End Offset) + +LEO:æ¯�个分区最大的Offset + +#### 1.3 Kafka 中是怎么体现消æ�¯é¡ºåº�性的? + +在æ¯�个分区内,æ¯�æ�¡æ¶ˆæ�¯éƒ½æœ‰offset,所以消æ�¯åœ¨å�Œä¸€åˆ†åŒºå†…有åº�,无法å�šåˆ°å…¨å±€æœ‰åº�性 + +#### 1.4 Kafka 中的分区器ã€�åº�列化器ã€�拦截器是å�¦äº†è§£ï¼Ÿå®ƒä»¬ä¹‹é—´çš„处ç�†é¡ºåº�是什么? + +分区器Partitioner用æ�¥å¯¹åˆ†åŒºè¿›è¡Œå¤„ç�†çš„,å�³æ¶ˆæ�¯å�‘é€�到哪一个分区的问题。åº�列化器,这个是对数æ�®è¿›è¡Œåº�列化和å��åº�列化的工具。拦截器,å�³å¯¹äºŽæ¶ˆæ�¯å�‘é€�进行一个æ��å‰�处ç�†å’Œæ”¶å°¾å¤„ç�†çš„ç±»Interceptor,处ç�†é¡ºåˆ©é¦–先通过拦截器=>åº�列化器=>分区器 + +#### 1.5 Kafka 生产者客户端的整体结构是什么样å­�的?使用了几个线程æ�¥å¤„ç�†ï¼Ÿåˆ†åˆ«æ˜¯ä»€ä¹ˆï¼Ÿ + +使用两个线程:mainå’Œsender 线程,main线程会一次ç»�过拦截器ã€�åº�列化器ã€�分区器将数æ�®å�‘é€�到RecoreAccumulator线程共享å�˜é‡�,å†�ç”±sender线程从共享å�˜é‡�中拉å�–æ•°æ�®å�‘é€�到kafka broker + +batch.size达到此规模消æ�¯æ‰�å�‘é€�,linger.ms未达到规模,等待当å‰�æ—¶é•¿å°±å�‘é€�æ•°æ�®ã€‚ + +#### 1.6 消费组中的消费者个数如果超过 topic 的分区,那么就会有消费者消费ä¸�到数æ�®â€�è¿™å�¥ è¯�是å�¦æ­£ç¡®ï¼Ÿ + +è¿™å�¥è¯�是对的,超过分区个数的消费者ä¸�会在接收数æ�®ï¼Œä¸»è¦�原因是一个分区的消æ�¯å�ªèƒ½å¤Ÿè¢«ä¸€ä¸ªæ¶ˆè´¹è€…组中的一个消费者消费。 + +#### 1.7 消费者æ��交消费ä½�移时æ��交的是当å‰�消费到的最新消æ�¯çš„ offset 还是 offset+1? + +生产者å�‘é€�æ•°æ�®çš„offset是从0开始的,消费者消费的数æ�®çš„offset是从1开始,故最新消æ�¯æ˜¯offset+1 + +#### 1.8 有哪些情形会造æˆ�é‡�å¤�消费? + +先消费å�Žæ��交offset,如果消费完宕机了,则会造æˆ�é‡�å¤�消费 + +#### 1.9 那些情景会造æˆ�消æ�¯æ¼�消费? + +å…ˆæ��交offset,还没消费就宕机了,则会造æˆ�æ¼�消费 + +#### 1.10 当你使用 kafka-topics.sh 创建(删除)了一个 topic 之å�Žï¼Œ Kafka 背å�Žä¼šæ‰§è¡Œä»€ä¹ˆé€»è¾‘? + +会在 zookeeper 中的/brokers/topics 节点下创建一个新的 topic 节点,如:/brokers/topics/first 触å�‘ Controller 的监å�¬ç¨‹åº� kafka Controller è´Ÿè´£ topic 的创建工作,并更新 metadata cache + +#### 1.11 topic 的分区数å�¯ä¸�å�¯ä»¥å¢žåŠ ï¼Ÿå¦‚æžœå�¯ä»¥æ€Žä¹ˆå¢žåŠ ï¼Ÿå¦‚æžœä¸�å�¯ä»¥ï¼Œé‚£å�ˆæ˜¯ä¸ºä»€ä¹ˆï¼Ÿ + +å�¯ä»¥å¢žåŠ ï¼Œä¿®æ”¹åˆ†åŒºä¸ªæ•°--alterå�¯ä»¥ä¿®æ”¹åˆ†åŒºä¸ªæ•° + +#### 1.12 topic 的分区数å�¯ä¸�å�¯ä»¥å‡�少?如果å�¯ä»¥æ€Žä¹ˆå‡�少?如果ä¸�å�¯ä»¥ï¼Œé‚£å�ˆæ˜¯ä¸ºä»€ä¹ˆï¼Ÿ + +ä¸�å�¯ä»¥å‡�少,å‡�少了分区之å�Žï¼Œä¹‹å‰�的分区中的数æ�®ä¸�好处ç�† + +#### 1.13 Kafka 有内部的 topic å�—?如果有是什么?有什么所用? + +有,__consumer_offsets主è¦�用æ�¥åœ¨0.9版本以å�Žä¿�存消费者消费的offset + +#### 1.14 Kafka 分区分é…�的概念? + +Kafka分区对于Kafka集群æ�¥è¯´ï¼Œåˆ†åŒºå�¯ä»¥å�šåˆ°è´Ÿè½½å�‡è¡¡ï¼Œå¯¹äºŽæ¶ˆè´¹è€…æ�¥è¯´åˆ†åŒºå�¯ä»¥æ��高并å�‘度,æ��高读å�–效率 + +#### 1.15 简述 Kafka 的日志目录结构? + +æ¯�一个分区对应ç�€ä¸€ä¸ªæ–‡ä»¶å¤¹ï¼Œå‘½å��为topic-0/topic-1…,æ¯�个文件夹内有.indexå’Œ.log文件。 + +#### 1.16 如果我指定了一个 offset, Kafka Controller 怎么查找到对应的消æ�¯ï¼Ÿ + +offset表示当å‰�消æ�¯çš„ç¼–å�·ï¼Œé¦–å…ˆå�¯ä»¥é€šè¿‡äºŒåˆ†æ³•定ä½�当å‰�消æ�¯å±žäºŽå“ªä¸ª.index文件中,éš�å�Žé‡‡ç”¨seek定ä½�的方法查找到当å‰�offset在.index中的ä½�置,此时å�¯ä»¥æ‹¿åˆ°åˆ�å§‹çš„å��ç§»é‡�。通过åˆ�å§‹çš„å��ç§»é‡�å†�通过seek定ä½�到.log中的消æ�¯å�³å�¯æ‰¾åˆ°ã€‚ + +#### 1.17 è�Šä¸€è�Š Kafka Controller 的作用? + +Kafka集群中有一个broker会被选举为Controller,负责管ç�†é›†ç¾¤broker的上下线ã€�所有topic的分区副本分é…�å’Œleader的选举等工作。Controller的工作管ç�†æ˜¯ä¾�赖于zookeeper的。 + +#### 1.18 Kafka 中有那些地方需è¦�选举?这些地方的选举策略å�ˆæœ‰å“ªäº›ï¼Ÿ + +在ISR中需è¦�选举出Leader,选择策略为先到先得。在分区中需è¦�选举,需è¦�选举出Leaderå’Œfollower。 + +#### 1.19 失效副本是指什么?有那些应对措施? + +失效副本为速率比leader相差大于10sçš„follower,ISR会将这些失效的follower踢出,等速率接近leaderçš„10s内,会é‡�新加入ISR + +#### 1.20 Kafka 的哪些设计让它有如此高的性能? + +1. Kafka天生的分布å¼�æž¶æž„ +2. 对log文件进行了分segment,并对segment建立了索引 +3. 对于å�•节点使用了顺åº�读写,顺åº�读写是指的文件的顺åº�追加,å‡�少了ç£�盘寻å�€çš„开销,相比éš�机写速度æ��å�‡å¾ˆå¤š +4. 使用了零拷è´�技术,ä¸�需è¦�切æ�¢åˆ°ç”¨æˆ·æ€�,在内核æ€�å�³å�¯å®Œæˆ�读写æ“�作,且数æ�®çš„æ‹·è´�次数也更少。 + +## å�‚考文章 +https://blog.csdn.net/cao131502 +https://zhuanlan.zhihu.com/p/137811719 \ No newline at end of file diff --git "a/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232\345\246\202\344\275\225\345\256\236\347\216\260\345\273\266\350\277\237\351\230\237\345\210\227.md" "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232\345\246\202\344\275\225\345\256\236\347\216\260\345\273\266\350\277\237\351\230\237\345\210\227.md" new file mode 100644 index 0000000..584cb61 --- /dev/null +++ "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232\345\246\202\344\275\225\345\256\236\347\216\260\345\273\266\350\277\237\351\230\237\345\210\227.md" @@ -0,0 +1,173 @@ +KafkaÊÇÒ»¸ö·Ö²¼Ê½ÏûϢϵͳ£¬±»¹ã·ºÓ¦ÓÃÓÚ»¥ÁªÍøºÍ´óÊý¾ÝÁìÓò¡£ÔÚʵ¼ÊÓ¦ÓÃÖУ¬¾­³£ÐèҪʵÏÖÑÓ³Ù¶ÓÁеŦÄÜ£¬ÒÔ±ãÔÚÒ»¶¨Ê±¼äºóÖ´ÐÐijЩÈÎÎñ»òÕß·¢ËÍijЩÏûÏ¢¡£KafkaÌṩÁ˶àÖÖ·½Ê½À´ÊµÏÖÑÓ³Ù¶ÓÁУ¬±¾ÎĽ«½éÉÜÆäÖÐÒ»ÖÖ³£¼ûµÄʵÏÖ·½·¨¡£ + + + + + +### Ò»¡¢ÑÓ³Ù¶ÓÁиÅÊö + + + + + +ÑÓ³Ù¶ÓÁÐÊÇÒ»ÖÖÓÃÓÚÔÚÒ»¶¨Ê±¼äºóÖ´ÐÐÈÎÎñ»ò·¢ËÍÏûÏ¢µÄ»úÖÆ¡£³£¼ûµÄÓ¦Óó¡¾°°üÀ¨¶¨Ê±ÈÎÎñ¡¢ÏûÏ¢ÍÆËÍ¡¢¶©µ¥³¬Ê±µÈµÈ¡£ÑÓ³Ù¶ÓÁеÄʵÏÖ·½Ê½ÓжàÖÖ£¬ÆäÖÐÒ»ÖֱȽϳ£¼ûµÄʵÏÖ·½·¨ÊÇ»ùÓÚÏûÏ¢¶ÓÁеÄÑÓ³ÙÏûÏ¢»úÖÆ¡£ + + + + + +ÔÚKafkaÖУ¬ÑÓ³ÙÏûÏ¢ÊÇÖ¸ÔÚ·¢ËÍÏûϢʱ£¬Ö¸¶¨Ò»¸öÑÓ³Ùʱ¼ä£¬ÏûÏ¢½«ÔÚÑÓ³Ùʱ¼äµ½´ïºó²Å±»Ïû·ÑÕßÏû·Ñ¡£KafkaÌṩÁËÒ»Ð©ÌØÊâµÄTopicÓÃÓÚ´æ´¢ÑÓ³ÙÏûÏ¢£¬ÀýÈç"delayed-messages"¡£Ïû·ÑÕß½ø³Ì¿ÉÒÔ¶¨ÆÚ´ÓÕâЩTopicÖÐÏû·ÑÏûÏ¢£¬²¢½«ÏûÏ¢ÖØÐ·¢Ë͵½Ä¿±êTopicÖУ¬´Ó¶øÊµÏÖÑÓ³Ù¶ÓÁеŦÄÜ¡£ + + + + + +### ¶þ¡¢KafkaÖеÄÑÓ³ÙÏûϢʵÏÖÔ­Àí + + + + + +KafkaµÄÑÓ³ÙÏûϢʵÏÖÔ­Àí±È½Ï¼òµ¥£¬Ö÷񻃾¼°µ½ÏûÏ¢µÄkeyºÍʱ¼ä´Á¡£ÔÚÏûÏ¢µÄkeyÖУ¬¿ÉÒÔÉèÖÃÒ»¸öʱ¼ä´Á£¬±íʾÏûÏ¢µÄÑÓ³Ùʱ¼ä¡£ÔÚÉú²úÕß·¢ËÍÏûϢʱ£¬½«ÏûÏ¢·¢Ë͵½"delayed-messages" TopicÖУ¬²¢ÉèÖÃÏûÏ¢µÄkeyÖеÄʱ¼ä´Á¡£Ïû·ÑÕß½ø³Ì»á¶¨ÆÚ´Ó"delayed-messages" TopicÖÐÏû·ÑÏûÏ¢£¬¼ì²éÏûÏ¢µÄkeyÖеÄʱ¼ä´ÁÊÇ·ñÒѾ­¹ýÆÚ¡£Èç¹ûʱ¼ä´ÁÒѾ­¹ýÆÚ£¬Ôò½«ÏûÏ¢ÖØÐ·¢Ë͵½Ä¿±êTopicÖУ¬ÀýÈç"target-messages"¡£Èç¹ûʱ¼ä´Á»¹Î´¹ýÆÚ£¬Ôò½«ÏûÏ¢ÖØÐ·¢Ë͵½"delayed-messages" TopicÖУ¬²¢ÉèÖÃÒ»¸öеÄÑÓ³Ùʱ¼ä´Á¡£ÕâÑù£¬¾Í¿ÉÒÔʵÏÖÑÓ³Ù¶ÓÁеŦÄÜ¡£ + + + +![image-20230526211424767](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230526211424767.png) + + + + + +### Èý¡¢KafkaÖÐÑÓ³Ù¶ÓÁеÄʵÏÖ²½Öè + + + + + +ʵÏÖKafkaÖеÄÑÓ³Ù¶ÓÁУ¬¿ÉÒÔ°´ÕÕÒÔϲ½Öè½øÐУº + + + + + +1.´´½¨Ò»¸öרÃŵÄTopicÓÃÓÚ´æ´¢ÑÓ³ÙÏûÏ¢£¬ÀýÈç"delayed-messages"¡£¿ÉÒÔʹÓÃKafkaÃüÁîÐй¤¾ß»òKafka API½øÐд´½¨¡£ + + + + + +2.ÔÚÏûÏ¢µÄkeyÖÐÉèÖÃÑÓ³Ùʱ¼ä´Á¡£¿ÉÒÔʹÓõ±Ç°Ê±¼ä´Á¼ÓÉÏÑÓ³Ùʱ¼ä×÷Ϊkey£¬ÀýÈ磺"key":"message_body"¡£¿ÉÒÔʹÓÃKafka API·¢ËÍÏûÏ¢µ½"delayed-messages" TopicÖС£ + + + + + +3.Æô¶¯Ò»¸öÏû·ÑÕß½ø³Ì£¬ÓÃÓÚÏû·Ñ"delayed-messages" TopicÖеÄÏûÏ¢¡£¿ÉÒÔʹÓÃKafka APIʵÏÖÏû·ÑÕß½ø³Ì¡£ + + + + + +4.ÔÚÏû·ÑÕß½ø³ÌÖУ¬¼ì²éÏûÏ¢µÄkeyÖеÄʱ¼ä´ÁÊÇ·ñÒѾ­¹ýÆÚ¡£¿ÉÒÔʹÓõ±Ç°Ê±¼ä´ÁÓëÏûÏ¢µÄkeyÖеÄʱ¼ä´Á½øÐбȽϡ£Èç¹ûʱ¼ä´ÁÒѾ­¹ýÆÚ£¬Ôò½«ÏûÏ¢ÖØÐ·¢Ë͵½Ä¿±êTopicÖУ¬ÀýÈç"target-messages"¡£¿ÉÒÔʹÓÃKafka APIʵÏÖÏûÏ¢µÄÖØÐ·¢ËÍ¡£ + + + + + +5.Èç¹ûʱ¼ä´Á»¹Î´¹ýÆÚ£¬Ôò½«ÏûÏ¢ÖØÐ·¢Ë͵½"delayed-messages" TopicÖУ¬²¢ÉèÖÃÒ»¸öеÄÑÓ³Ùʱ¼ä´Á¡£¿ÉÒÔʹÓÃKafka APIʵÏÖÏûÏ¢µÄÖØÐ·¢ËÍ£¬²¢ÔÚÏûÏ¢µÄkeyÖÐÉèÖÃеÄÑÓ³Ùʱ¼ä´Á¡£ + + + + + +6.µÈ´ýÒ»¶¨Ê±¼äºó£¬Öظ´Ö´ÐеÚ4ºÍµÚ5²½£¬Ö±µ½ÏûÏ¢µÄkeyÖеÄʱ¼ä´ÁÒѾ­¹ýÆÚ¡£ + + + + + +ͨ¹ýÒÔÉϲ½Ö裬¾Í¿ÉÒÔʵÏÖKafkaÖеÄÑÓ³Ù¶ÓÁй¦ÄÜ¡£ÐèҪעÒâµÄÊÇ£¬Ïû·ÑÕß½ø³ÌÐèÒª¶¨ÆÚ´Ó"delayed-messages" TopicÖÐÏû·ÑÏûÏ¢£¬²¢¼ì²éÏûÏ¢µÄkeyÖеÄʱ¼ä´ÁÊÇ·ñÒѾ­¹ýÆÚ¡£¿ÉÒÔ¸ù¾Ý¾ßÌåµÄÓ¦Óó¡¾°ÉèÖò»Í¬µÄÑÓ³Ùʱ¼ä¡£ + + + + + +![image-20230526211452328](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230526211452328.png) + + + + + +### ËÄ¡¢ÑÓ³ÙÏûϢʵÏÖµÄÓÅȱµã + + + + + +![image-20230526211506828](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230526211506828.png) + + + + + +KafkaÖÐʵÏÖÑÓ³Ù¶ÓÁеķ½·¨¾ßÓÐÒÔÏÂÓŵ㣺 + + + + + +1.¿ÉÒÔÔÚ·Ö²¼Ê½ÏµÍ³ÖÐʵÏÖÑÓ³Ù¶ÓÁй¦ÄÜ£¬¾ßÓнϸߵĿÉÀ©Õ¹ÐԺͿɿ¿ÐÔ¡£ + + + + + +2.ʵÏÖ¼òµ¥£¬Ö»ÐèҪʹÓÃKafka API¼´¿É£¬ÎÞÐè¶îÍâµÄ×é¼þ»ò¹¤¾ß¡£ + + + + + +3.Ö§³ÖÏûÏ¢µÄÅúÁ¿·¢ËͺÍÏû·Ñ£¬¿ÉÒÔÌá¸ßÐÔÄܺÍÍÌÍÂÁ¿¡£ + + + + + +4.¿ÉÒÔÁé»îµØµ÷ÕûÑÓ³Ùʱ¼äºÍÄ¿±êTopic£¬ÊÊÓÃÓÚ²»Í¬µÄÓ¦Óó¡¾°¡£ + + + + + +µ«ÊÇ£¬KafkaÖÐʵÏÖÑÓ³Ù¶ÓÁÐÒ²´æÔÚһЩȱµã£º + + + + + +1.ÐèÒªÏû·ÑÕß½ø³Ì¶¨ÆÚ´Ó"delayed-messages" TopicÖÐÏû·ÑÏûÏ¢£¬Èç¹ûÏû·ÑÕß½ø³Ìå´»ú»òÕßÍ£Ö¹¹¤×÷£¬Ôò»áÓ°ÏìÑÓ³Ù¶ÓÁеŦÄÜ¡£ + + + + + +2.Ïû·ÑÕß½ø³ÌÐèÒª¶ÔÏûÏ¢½øÐÐÖØÐ·¢Ëͺͼì²é£¬ÐèÒªÏûºÄÒ»¶¨µÄ×ÊÔ´ºÍʱ¼ä¡£ + + + + + +3.ÑÓ³Ùʱ¼ä¾«¶ÈÓÐÏÞ£¬×îСֻÄÜ´ïµ½ºÁÃë¼¶±ð¡£ + + + + + +### ËÄ¡¢×ܽá + + + + + +KafkaÊÇÒ»¸ö¹¦ÄÜÇ¿´óµÄ·Ö²¼Ê½ÏûϢϵͳ£¬¿ÉÒÔʵÏÖÑÓ³Ù¶ÓÁеŦÄÜ¡£Í¨¹ýÔÚÏûÏ¢µÄkeyÖÐÉèÖÃÑÓ³Ùʱ¼ä´Á£¬½áºÏÏû·ÑÕß½ø³ÌµÄ¶¨ÆÚÏû·ÑºÍÖØÐ·¢ËÍ£¬¿ÉÒÔʵÏÖÑÓ³Ù¶ÓÁеŦÄÜ¡£KafkaÖÐʵÏÖÑÓ³Ù¶ÓÁеķ½·¨¾ßÓÐʵÏÖ¼òµ¥¡¢¿ÉÀ©Õ¹ÐԸߡ¢ÐÔÄܺõÈÓŵ㣬µ«Ò²´æÔÚһЩȱµã¡£ÔÚʵ¼ÊÓ¦ÓÃÖУ¬ÐèÒª¸ù¾Ý¾ßÌåµÄÓ¦Óó¡¾°ºÍÐèÇóÑ¡ÔñºÏÊʵÄÑÓ³Ù¶ÓÁÐʵÏÖ·½·¨¡£ \ No newline at end of file diff --git "a/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232\345\246\202\344\275\225\345\256\236\347\216\260\346\255\273\344\277\241\351\230\237\345\210\227.md" "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232\345\246\202\344\275\225\345\256\236\347\216\260\346\255\273\344\277\241\351\230\237\345\210\227.md" new file mode 100644 index 0000000..5617b88 --- /dev/null +++ "b/docs/mq/kafka/\346\266\210\346\201\257\351\230\237\345\210\227kafka\350\257\246\350\247\243\357\274\232\345\246\202\344\275\225\345\256\236\347\216\260\346\255\273\344\277\241\351\230\237\345\210\227.md" @@ -0,0 +1,578 @@ +### Apache Kafka ÖÐÓÃÓÚ´íÎó´¦ÀíµÄËÀÐŶÓÁУºÀ´×Ô Uber ºÍ Crowdstrike µÄÌæ´ú·½°¸¡¢×î¼Ñʵ¼ùºÍ°¸ÀýÑо¿¡£ + + + + + +ʶ±ðºÍ´¦Àí´íÎó¶ÔÓÚÈκοɿ¿µÄÊý¾ÝÁ÷¹ÜµÀ¶¼ÊDZز»¿ÉÉٵġ£ÕâÆª²©ÎÄ̽ÌÖÁË** ÔÚ Apache Kafka »ù´¡¼Ü¹¹ÖÐ****ʹÓÃËÀÐŶÓÁÐʵÏÖ´íÎó´¦ÀíµÄ×î¼Ñʵ¼ù**¡£ÕâЩѡÏî°üÀ¨×Ô¶¨ÒåʵÏÖ¡¢Kafka Streams¡¢Kafka Connect¡¢Spring ¿ò¼ÜºÍ²¢ÐÐÏû·ÑÕß¡£ÕæÊµ°¸ÀýÑо¿Õ¹Ê¾ÁË Uber¡¢CrowdStrike ºÍɣ̹µÂÒøÐÐÈçºÎÒÔ¼«¶Ë¹æÄ£¹¹½¨¿É¿¿µÄʵʱ´íÎó´¦Àí¡£ + + + + + +Apache Kafka ³ÉΪÐí¶àÆóÒµ¼Ü¹¹×îϲ»¶µÄ¼¯³ÉÖмä¼þ¡£¼´Ê¹¶ÔÓÚÔÆÓÅÏÈÕ½ÂÔ£¬ÆóÒµÒ²¿ÉÒÔÀûÓà Kafka µÄÊý¾ÝÁ÷×÷ÎªÔÆÔ­Éú¼¯³Éƽ̨¼´·þÎñ (iPaaS)¡£ + + + + + +### Apache Kafka Êý¾ÝÁ÷ÖеÄÏûÏ¢¶ÓÁÐģʽ + + + + + +ÔÚÎÒ¿ªÊ¼ÕâÆªÎÄÕÂ֮ǰ£¬ÎÒÏëÈÃÄãÖªµÀÕâ¸öÄÚÈÝÊÇ**¹ØÓÚ¡°JMS¡¢ÏûÏ¢¶ÓÁÐºÍ Apache Kafka¡±µÄ²©¿ÍϵÁÐ**µÄÒ»²¿·Ö£º + + + + + +* JMS ÏûÏ¢´úÀíÓë Apache Kafka Êý¾ÝÁ÷µÄ**10 ¸ö±È½Ï±ê×¼** +* _**ÕâÆªÎÄÕÂ**_**¨C ͨ¹ýApache Kafka ÖеÄËÀÐŶÓÁÐ (DQL)**½øÐдíÎó´¦ÀíµÄÌæ´ú·½·¨ +* ʹÓà Apache KafkaʵÏÖ**ÇëÇó-»Ø¸´Ä£Ê½** +* _¼´½«_ÍÆ³ö¡ª¡ª**ÓÃÓÚÑ¡ÔñÕýÈ·ÏûϢϵͳµÄ¾ö²ßÊ÷**£¨JMS Óë Apache Kafka£© +* _¼´½«ÍƳö_¡ª¡ª´Ó JMS ÏûÏ¢´úÀíµ½ Apache Kafka£º**¼¯³É¡¢Ç¨ÒƺÍ/»òÌæ»»** + + + + + +### ʲôÊÇËÀÐŶÓÁм¯³Éģʽ£¨ÔÚ Apache Kafka ÖУ©£¿ + + + + + +**ËÀÐŶÓÁÐ (DLQ)**ÊÇÏûϢϵͳ»òÊý¾ÝÁ÷ƽ̨ÄÚµÄÒ»ÖÖ·þÎñʵÏÖ£¬ÓÃÓÚ**´æ´¢Î´³É¹¦´¦ÀíµÄÏûÏ¢**¡£ÏµÍ³²»ÊDZ»¶¯µØ×ª´¢ÏûÏ¢£¬¶øÊǽ«ÆäÒÆ¶¯µ½ËÀÐŶÓÁС£ + + + + + +ÆóÒµ**¼¯³Éģʽ (EIP)**¸ÄΪµ÷ÓÃÉè¼ÆÄ£Ê½ËÀÐÅͨµÀ¡£ÎÒÃÇ¿ÉÒÔ½«Á½ÕßÓÃ×÷ͬÒå´Ê¡£ + + + + + +![image-20230526224702433](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230526224702433.png) + + + + + +±¾ÎÄÖØµã½éÉÜÊý¾ÝÁ÷ƽ̨ Apache Kafka¡£**ÔÚ Kafka Öн«ÏûÏ¢·ÅÈë DLQ µÄ**Ö÷ÒªÔ­Òòͨ³£ÊÇÏûÏ¢¸ñʽ´íÎó»òÏûÏ¢ÄÚÈÝÎÞЧ/ȱʧ¡£ÀýÈ磬Èç¹ûÔ¤ÆÚÖµÊÇÕûÊý£¬µ«Éú²úÕß·¢ËÍÁË×Ö·û´®£¬Ôò»á·¢ÉúÓ¦ÓóÌÐò´íÎó¡£ÔÚ¸ü¶¯Ì¬µÄ»·¾³ÖУ¬¡°Ö÷Ìâ²»´æÔÚ¡±Òì³£¿ÉÄÜÊÇÎÞ·¨´«µÝÏûÏ¢µÄÁíÒ»¸ö´íÎó¡£ + + + + + +Òò´Ë£¬Í¨³£²»ÒªÊ¹ÓÃÏÖÓÐÖмä¼þ¾­ÑéÖеÄ֪ʶ¡£Message Queue Öмä¼þ£¨Èç·ûºÏ JMS µÄ IBM MQ¡¢TIBCO EMS »ò RabbitMQ£©Óë·Ö²¼Ê½Ìá½»ÈÕÖ¾£¨Èç Kafka£©µÄ¹¤×÷·½Ê½²»Í¬¡£ÓÉÓÚÐí¶àÆäËûÔ­Òò£¬ÏûÏ¢¶ÓÁÐÖÐµÄ DLQ ÓÃÓÚÏûÏ¢¶ÓÁÐϵͳ£¬ÕâЩԭÒò²»ÄÜÒ»¶ÔÒ»µØÓ³Éäµ½ Kafka¡£ÀýÈ磬MQ ϵͳÖеÄÏûÏ¢ÓÉÓÚÿÌõÏûÏ¢µÄ TTL£¨Éú´æÊ±¼ä£©¶ø¹ýÆÚ¡£ + + + + + +Òò´Ë£¬**ÔÚ Kafka Öн«ÏûÏ¢·ÅÈë DLQ µÄÖ÷ÒªÔ­ÒòÊÇÏûÏ¢¸ñʽ´íÎó»òÏûÏ¢ÄÚÈÝÎÞЧ/ȱʧ**¡£ + + + + + +### Apache Kafka ÖÐËÀÐŶÓÁеÄÌæ´ú·½°¸ + + + + + +Kafka ÖеÄËÀÐŶÓÁÐÊÇÒ»¸ö»ò¶à¸ö Kafka Ö÷Ì⣬ËüÃÇ**½ÓÊպʹ洢ÓÉÓÚ´íÎó¶øÎÞ·¨ÔÚÁíÒ»¸öÁ÷¹ÜµÀÖд¦ÀíµÄÏûÏ¢**¡£´Ë¸ÅÄîÔÊÐíʹÓÃÒÔÏ´«ÈëÏûÏ¢¼ÌÐøÏûÏ¢Á÷£¬¶ø²»»áÓÉÓÚÎÞЧÏûÏ¢µÄ´íÎó¶øÍ£Ö¹¹¤×÷Á÷¡£ + + + + + +### Kafka Broker ºÜ±¿¡ª¡ªÖÇÄܶ˵ãÌṩ´íÎó´¦Àí + + + + + +**Kafka ¼Ü¹¹²»Ö§³Ö broker** r ÖеÄDLQ¡£ÓÐÒâµØ£¬Kafka ½¨Á¢ÔÚÓëÏÖ´ú΢·þÎñÏàͬµÄÔ­ÔòÉÏ£¬Ê¹Óá°ÑƹܵÀºÍÖÇÄܶ˵㡱ԭÔò¡£Õâ¾ÍÊÇΪʲôÓ봫ͳÏûÏ¢´úÀíÏà±È£¬Kafka µÄÀ©Õ¹ÐÔÈç´ËÖ®ºÃ¡£¹ýÂ˺ʹíÎó´¦Àí·¢ÉúÔÚ¿Í»§¶ËÓ¦ÓóÌÐòÖС£ + + + + + +Êý¾ÝÁ÷ƽ̨µÄÕæÕý½âñî¿ÉÒÔʵÏÖ¸ü¸É¾»µÄÁìÓòÇý¶¯Éè¼Æ¡£**ÿ¸ö΢·þÎñ»òÓ¦ÓóÌÐò¶¼Í¨¹ý×Ô¼ºÑ¡ÔñµÄ¼¼Êõ¡¢Í¨ÐÅ·¶Ê½ºÍ´íÎó´¦ÀíÀ´ÊµÏÖÆäÂß¼­**¡£ + + + + + +ÔÚ´«Í³µÄÖмä¼þºÍÏûÏ¢¶ÓÁÐÖУ¬´úÀíÌṩÁËÕâÖÖÂß¼­¡£½á¹ûÊÇÓòÖеĿÉÀ©Õ¹ÐÔºÍÁé»îÐԽϲÒòΪֻÓÐÖмä¼þÍŶӲÅÄÜʵÏÖ¼¯³ÉÂß¼­¡£ + + + + + +### ÓÃÈκαà³ÌÓïÑÔ×Ô¶¨ÒåʵÏÖ Kafka ËÀÐŶÓÁÐ + + + + + +Kafka ÖеÄËÀÐŶÓÁжÀÁ¢ÓÚÄúʹÓõĿò¼Ü¡£Ò»Ð©×é¼þΪ´íÎó´¦ÀíºÍËÀÐŶÓÁÐÌṩÁË¿ªÏä¼´ÓõŦÄÜ¡£µ«ÊÇ£¬Ê¹ÓÃJava¡¢Go¡¢C++¡¢Python µÈ**Èκαà³ÌÓïÑÔΪ Kafka Ó¦ÓóÌÐò±àдËÀÐŶÓÁÐÂß¼­**Ò²ºÜÈÝÒס£ + + + + + +**ËÀÐŶÓÁÐʵÏÖ**µÄÔ´´úÂë°üº¬Ò»¸ö try-catch ¿éÀ´´¦ÀíÔ¤ÆÚ»òÒâÍâÒì³£¡£Èç¹ûûÓз¢Éú´íÎó£¬Ôò´¦Àí¸ÃÏûÏ¢¡£Èç¹û·¢ÉúÈκÎÒì³££¬Ç뽫ÏûÏ¢·¢Ë͵½×¨ÓÃµÄ DLQ Kafka Ö÷Ìâ¡£ + + + + + +**ʧ°ÜÔ­ÒòÓ¦Ìí¼Óµ½ Kafka ÏûÏ¢µÄ±êÍ·**ÖС£²»Ó¦¸ü¸Ä¼üºÍÖµ£¬ÒԱ㽫À´¶ÔÀúʷʼþ½øÐÐÖØÐ´¦ÀíºÍ¹ÊÕÏ·ÖÎö¡£ + + + + + +### ËÀÐŶÓÁеĿªÏä¼´Óà Kafka ʵÏÖ + + + + + +Äã²¢²»×ÜÊÇÐèҪʵÏÖÄãµÄËÀÐŶÓÁС£**Ðí¶à×é¼þºÍ¿ò¼ÜÒѾ­ÌṩÁËËüÃÇµÄ DLQ ʵÏÖ**¡£ + + + + + +ʹÓÃÄú×Ô¼ºµÄÓ¦ÓóÌÐò£¬Äúͨ³£¿ÉÒÔ¿ØÖÆ´íÎó»òÔÚ³öÏÖ´íÎóʱÐÞ¸´´úÂë¡£µ«ÊÇ£¬**Óë 3rd ·½Ó¦ÓóÌÐòµÄ¼¯³É²¢²»Ò»¶¨ÔÊÐíÄú´¦Àí¿ÉÄܿ缯³ÉÕϰ­ÒýÈëµÄ´íÎó**¡£Òò´Ë£¬DLQ ±äµÃ¸ü¼ÓÖØÒª£¬²¢±»°üº¬ÔÚijЩ¿ò¼ÜÖС£ + + + + + +### Kafka Connect ÄÚÖÃËÀÐŶÓÁÐ + + + + + +**Kafka Connect ÊÇ Kafka µÄ¼¯³É¿ò¼Ü**¡£Ëü°üº¬ÔÚ¿ªÔ´ Kafka ÏÂÔØÖС£²»ÐèÒªÆäËûÒÀÀµÏ³ýÁËÄú²¿Êðµ½ Connect ¼¯ÈºÖеÄÁ¬½ÓÆ÷±¾Éí£©¡£ + + + + + +ĬÈÏÇé¿öÏ£¬Èç¹ûÓÉÓÚʹÓÃÎÞЧÏûÏ¢¶ø·¢Éú´íÎó£¨ÀýÈçʹÓôíÎóµÄ JSON ת»»Æ÷¶ø²»ÊÇÕýÈ·µÄ AVRO ת»»Æ÷ʱ£©£¬Kafka Connect ÈÎÎñ½«Í£Ö¹¡£É¾³ýÎÞЧÏûÏ¢ÊÇÁíÒ»ÖÖÑ¡Ôñ¡£ºóÕßÈÝÈÌ´íÎó¡£ + + + + + +Kafka Connect ÖÐ DLQ µÄÅäÖúܼòµ¥¡£Ö»Ð轫Á½¸öÅäÖÃÑ¡Ïî ' errors.tolerance' ºÍ ' errors.deadletterqueue.topic.name' µÄÖµÉèÖÃΪÕýÈ·µÄÖµ£º + + + + + +![image-20230526224856544](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230526224856544.png) + + + + + +²©¿ÍÎÄÕ¡° Kafka Connect Deep Dive ¨C ´íÎó´¦ÀíºÍËÀÐŶÓÁС±ÏÔʾÁËʹÓà DLQ µÄÏêϸ¶¯ÊÖ´úÂëʾÀý¡£ + + + + + +**Kafka Connect ÉõÖÁ¿ÉÒÔÓÃÓÚ´¦Àí DLQ ÖеĴíÎóÏûÏ¢**¡£Ö»Ð貿ÊðÁíÒ»¸öʹÓà te DLQ Ö÷ÌâµÄÁ¬½ÓÆ÷¡£ÀýÈ磬Èç¹ûÄúµÄÓ¦ÓóÌÐò´¦Àí Avro ÏûÏ¢²¢ÇÒ´«ÈëÏûÏ¢ÊÇ JSON ¸ñʽ¡£È»ºóÁ¬½ÓÆ÷ʹÓà JSON ÏûÏ¢²¢½«Æäת»»Îª AVRO ÏûÏ¢ÒԳɹ¦ÖØÐ´¦Àí£º + + + + + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/61aa7624a01c5016d3ab9aaa8ee6938d5514.jpeg)Çë×¢Ò⣬Kafka Connect **ûÓÐÓÃÓÚÔ´Á¬½ÓÆ÷µÄËÀÐŶÓÁÐ**¡£ + + + + + +### Kafka Streams Ó¦ÓóÌÐòÖеĴíÎó´¦Àí + + + + + +**Kafka Streams ÊÇ Kafka µÄÁ÷´¦Àí¿â**¡£Ëü¿ÉÓëÆäËûÁ÷ʽ´«Êä¿ò¼ÜÏàæÇÃÀ£¬ÀýÈç Apache Flink¡¢Storm¡¢Beam ºÍÀàËÆ¹¤¾ß¡£µ«ÊÇ£¬ËüÊÇ Kafka Ô­ÉúµÄ¡£ÕâÒâζ×ÅÄú¿ÉÒÔÔÚµ¥¸ö¿ÉÀ©Õ¹ÇÒ¿É¿¿µÄ»ù´¡¼Ü¹¹Öй¹½¨ÍêÕûµÄ¶Ëµ½¶ËÊý¾ÝÁ÷¡£ + + + + + +Èç¹ûÄú·Ö±ðʹÓà Java£¨JVM Éú̬ϵͳ£©À´¹¹½¨ Kafka Ó¦ÓóÌÐò£¬**½¨Ò鼸ºõ×ÜÊÇʹÓà Kafka Streams ¶ø²»ÊÇ Kafka µÄ±ê×¼ Java ¿Í»§¶Ë**¡£ÎªÊ²Ã´£¿ + + + + + +* Kafka Streams¡°Ö»ÊÇ¡±Ò»¸öÎ§ÈÆ³£¹æ Java Éú²úÕߺÍÏû·ÑÕß API µÄ°ü×°Æ÷£¬ÒÔ¼°Ðí¶àÄÚÖõĸ½¼Ó¹¦ÄÜ¡£ +* Á½Õß¶¼Ö»ÊÇǶÈëµ½ Java Ó¦ÓóÌÐòÖеĿ⣨JAR Îļþ£©¡£ +* Á½Õß¶¼ÊÇ¿ªÔ´ Kafka ÏÂÔØµÄÒ»²¿·Ö - ûÓжîÍâµÄÒÀÀµÏî»òÐí¿ÉÖ¤¸ü¸Ä¡£ +* Ðí¶àÎÊÌâÒѾ­¿ªÏä¼´Óõؽâ¾ö£¬ÒÔ¹¹½¨³ÉÊìµÄÁ÷´¦Àí·þÎñ£¨Á÷¹¦ÄÜ¡¢ÓÐ״̬µÄǶÈëʽ´æ´¢¡¢»¬¶¯´°¿Ú¡¢½»»¥Ê½²éѯ¡¢´íÎó´¦ÀíµÈµÈ£©¡£ + + + + + +Kafka StreamsµÄ**ÄÚÖù¦ÄÜÖ®Ò»ÊÇĬÈϵķ´ÐòÁл¯Òì³£´¦Àí³ÌÐò**¡£ËüÔÊÐíÄú¹ÜÀíÎÞ·¨·´ÐòÁл¯µÄ**¼Ç¼Òì³£¡£**Ë𻵵ÄÊý¾Ý¡¢²»ÕýÈ·µÄÐòÁл¯Âß¼­»òδ´¦ÀíµÄ¼Ç¼ÀàÐͶ¼¿ÉÄܵ¼Ö´íÎ󡣸ù¦Äܲ»³ÆÎªËÀÐŶÓÁУ¬µ«¿ªÏä¼´Óõؽâ¾öÁËÏàͬµÄÎÊÌâ¡£ + + + + + +### Spring Kafka ºÍ Spring Cloud Stream µÄ´íÎó´¦Àí + + + + + +Spring ¿ò¼Ü¶Ô Apache Kafka ÓкܺõÄÖ§³Ö¡£ËüÌṩÁËÐí¶àÄ£°åÒÔ±ÜÃâ×Ô¼º±àдÑù°å´úÂë¡£**Spring-Kafka ºÍ Spring Cloud Stream Kafka Ö§³Ö¸÷ÖÖÖØÊԺʹíÎó´¦ÀíÑ¡Ïî**£¬°üÀ¨»ùÓÚʱ¼ä/¼ÆÊýµÄÖØÊÔ¡¢ËÀÐŶÓÁеȡ£ + + + + + +¾¡¹Ü Spring ¿ò¼Ü¹¦Äܷdz£·á¸»£¬µ«ËüÓеãÖØ£¬²¢ÇÒÓÐÒ»¸öѧϰÇúÏß¡£Òò´Ë£¬Ëü·Ç³£ÊʺÏн¨ÏîÄ¿£¬»òÕßÈç¹ûÄúÒѾ­½« Spring ÓÃÓÚÆäËû³¡¾°µÄÏîÄ¿¡£ + + + + + +ÓкܶàºÜ°ôµÄ²©¿ÍÎÄÕÂչʾÁ˲»Í¬µÄʾÀýºÍÅäÖÃÑ¡Ïî¡£»¹ÓÐÓÃÓÚËÀÐŶÓÁеĹٷ½ Spring Cloud Stream ʾÀý¡£Spring ÔÊÐíʹÓüòµ¥µÄ×¢Ê͹¹½¨Âß¼­£¬ÀýÈç DLQ¡£ÕâÖÖ±à³Ì·½·¨ÊÇһЩ¿ª·¢ÈËÔ±ÖÓ°®µÄ·¶Àý£¬¶øÁíһЩÔò²»Ï²»¶Ëü¡£Ö»ÐèÁ˽âÑ¡ÏΪ×Ô¼ºÑ¡ÔñºÏÊʵÄÑ¡Ïî¼´¿É¡£ + + + + + +### Apache Kafka ²¢ÐÐÏû·ÑÕߵĿÉÀ©Õ¹´¦ÀíºÍ´íÎó´¦Àí + + + + + +ÔÚÐí¶à¿Í»§¶Ô»°ÖУ¬ÊÂʵ֤Ã÷£¬**ÇëÇóËÀÐŶÓÁеÄÖ÷ÒªÔ­Òòͨ³£ÊÇ´¦ÀíÁ¬½Óµ½Íⲿ Web ·þÎñ»òÊý¾Ý¿âµÄʧ°Ü**¡£³¬Ê±»ò Kafka ÎÞ·¨²¢Ðз¢Ë͸÷ÖÖÇëÇó»áµ¼ÖÂijЩӦÓóÌÐò̱»¾¡£Õâ¸öÎÊÌâÓÐÒ»¸öºÜºÃµÄ½â¾ö·½°¸£º + + + + + +Apache KafkaµÄ**²¢ÐÐÏû·ÑÕß**ÊÇApache 2.0 Ðí¿ÉÏÂ**µÄ¿ªÔ´ÏîÄ¿¡£**ËüÌṩÁËÒ»¸ö´øÓпͻ§¶Ë¶ÓÁеIJ¢ÐÐ Apache Kafka ¿Í»§¶Ë°ü×°Æ÷¡¢Ò»¸ö¾ßÓÐ**¹Ø¼ü²¢·¢ÐԵĸü¼òµ¥µÄÏû·ÑÕß/Éú²úÕß API£¬**ÒÔ¼°**¿ÉÀ©Õ¹µÄ·Ç×èÈû IO**´¦Àí¡£ + + + + + +¸Ã¿âÔÊÐíÄú**ͨ¹ýµ¥¸ö Kafka Consumer ²¢Ðд¦ÀíÏûÏ¢£¬ÕâÒâζ×ÅÄú¿ÉÒÔÔÚ²»Ôö¼Ó**Òª´¦ÀíµÄÖ÷ÌâÖеķÖÇøÊýÁ¿µÄÇé¿öÏÂÔö¼Ó Kafka Consumer ²¢Ðжȡ£**¶ÔÓÚÐí¶àÓÃÀý£¬Õâͨ¹ý¼õÉÙ Kafka ´úÀíµÄ¸ºÔØÀ´**Ìá¸ßÍÌÍÂÁ¿ºÍÑÓ³Ù¡£Ëü»¹¿ª±ÙÁËеÄÓÃÀý£¬ÀýÈ缫¶Ë²¢ÐÐÐÔ¡¢ÍⲿÊý¾Ý·á¸»ºÍÅŶӡ£ + + + + + +Ò»¸ö¹Ø¼üÌØÐÔÊÇ**ÔÚµ¥¸ö Kafka Ïû·ÑÕßÓ¦ÓóÌÐòÖд¦Àí/ÖØ¸´ Web ·þÎñºÍÊý¾Ý¿âµ÷ÓÃ**¡£²¢Ðл¯±ÜÃâÁËÒ»´Î·¢Ë͵¥¸ö Web ÇëÇóµÄÐèÒª£º + + + + + +![image-20230526224910457](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230526224910457.png) + + + + + +**Parallel Consumer ¿Í»§¶Ë¾ßÓÐÇ¿´óµÄÖØÊÔ**Âß¼­¡£Õâ°üÀ¨¿ÉÅäÖõÄÑӳٺͶ¯Ì¬´íÎó»ò´¦Àí¡£´íÎóÒ²¿ÉÒÔ·¢Ë͵½ËÀÐŶÓÁС£ + + + + + +### ʹÓÃËÀÐŶÓÁÐÖеÄÏûÏ¢ + + + + + +**½«´íÎó·¢Ë͵½ËÀÐŶÓÁкó£¬Äú»¹Ã»ÓÐÍê³É£¡»µÏûÏ¢ÐèÒª±»´¦Àí»òÖÁÉÙ±»¼à¿Ø£¡** + + + + + +ËÀÐŶÓÁÐÊÇ**´Óʼþ´¦ÀíÖдøÍâ´¦ÀíÊý¾Ý´íÎó´¦Àí**µÄ¾ø¼Ñ·½Ê½£¬ÕâÒâζ×Å´íÎó´¦Àí³ÌÐò¿ÉÒÔÓëʼþ´¦Àí´úÂë·Ö¿ª´´½¨»òÑݱ䡣 + + + + + +´æÔÚ´óÁ¿Ê¹ÓÃËÀÐŶÓÁеĴíÎó´¦Àí²ßÂÔ¡£DO ºÍ DONT ̽Ë÷×î¼Ñʵ¼ùºÍ¾­Ñé½Ìѵ¡£ + + + + + +### ´íÎó´¦Àí²ßÂÔ + + + + + +Óм¸¸öÑ¡Ïî¿ÉÓÃÓÚ´¦Àí´æ´¢ÔÚËÀÐŶÓÁÐÖеÄÏûÏ¢£º + + + + + +* **ÖØÐ´¦Àí**£ºDLQÖеÄһЩÏûÏ¢ÐèÒªÖØÐ´¦Àí¡£µ«ÊÇ£¬Ê×ÏÈ£¬ÐèÒª½â¾öÕâ¸öÎÊÌâ¡£½â¾ö·½°¸¿ÉÒÔÊÇ×Ô¶¯½Å±¾¡¢±à¼­ÏûÏ¢µÄÈ˹¤½»»¥£¬»òÏòÉú²úÕß·µ»Ø´íÎó£¬ÒªÇóÖØÐ·¢ËÍ£¨¸üÕýµÄ£©ÏûÏ¢¡£ +* **ɾ³ý´íÎóÏûÏ¢£¨¾­¹ý½øÒ»²½·ÖÎö£©**£º¸ù¾ÝÄúµÄÉèÖ㬿ÉÄÜ»á³öÏÖ´íÎóÏûÏ¢¡£µ«ÊÇ£¬ÔÚɾ³ýËüÃÇ֮ǰ£¬ÒµÎñÁ÷³ÌÓ¦¸Ã¼ì²éËüÃÇ¡£ÀýÈ磬ÒDZí°åÓ¦ÓóÌÐò¿ÉÒÔʹÓôíÎóÏûÏ¢²¢½«ËüÃÇ¿ÉÊÓ»¯¡£ +* **¸ß¼¶·ÖÎö**£ºÁíÒ»ÖÖÑ¡ÔñÊÇ·ÖÎö´«ÈëÊý¾ÝÒÔ»ñȡʵʱ¶´²ì»òÎÊÌ⣬¶ø²»ÊÇ´¦Àí DLQ ÖеÄÿÌõÏûÏ¢¡£ÀýÈ磬һ¸ö¼òµ¥µÄ ksqlDB Ó¦ÓóÌÐò¿ÉÒÔÓ¦ÓÃÁ÷´¦Àí½øÐмÆË㣬ÀýÈçÿСʱ´íÎóÏûÏ¢µÄƽ¾ùÊýÁ¿»òÈÎºÎÆäËûÓÐÖúÓÚÈ·¶¨ Kafka Ó¦ÓóÌÐòÖеĴíÎóµÄ¼û½â¡£ +* **Í£Ö¹¹¤×÷Á÷**£ºÈç¹ûºÜÉÙ»á³öÏÖ»µÏûÏ¢£¬½á¹û¿ÉÄÜÊÇÍ£Ö¹Õû¸öÒµÎñÁ÷³Ì¡£¸Ã¶¯×÷¿ÉÒÔÊÇ×Ô¶¯µÄ£¬Ò²¿ÉÒÔÓÉÈ˾ö¶¨¡£µ±È»£¬Í£Ö¹¹¤×÷Á÷Ò²¿ÉÒÔÔÚÅ׳ö´íÎóµÄ Kafka Ó¦ÓóÌÐòÖÐÍê³É¡£Èç¹ûÐèÒª£¬DLQ ½«ÎÊÌâºÍ¾ö²ßÍⲿ»¯¡£ +* **ºöÂÔ**£ºÕâÌýÆðÀ´¿ÉÄÜÊÇ×îÔã¸âµÄÑ¡Ôñ¡£Ö»ÊÇÈÃËÀÐŶÓÁÐÌîÂú£¬Ê²Ã´¶¼²»×ö¡£È»¶ø£¬¼´Ê¹ÕâÑùÔÚijЩÓÃÀýÖÐÒ²ºÜºÃ£¬±ÈÈç¼à¿Ø Kafka Ó¦ÓóÌÐòµÄÕûÌåÐÐΪ¡£Çë¼Çס£¬Kafka Ö÷Ìâ¾ßÓб£Áôʱ¼ä£¬²¢ÇÒÔÚ¸Ãʱ¼äÖ®ºó´ÓÖ÷ÌâÖÐɾ³ýÏûÏ¢¡£Ö»ÐèΪÄúÉèÖÃÕýÈ·µÄ·½Ê½¼´¿É¡£²¢¼à¿Ø DQL Ö÷ÌâÊÇ·ñ´æÔÚÒâÍâÐÐΪ£¨ÀýÈçÌî³äÌ«¿ì£©¡£ + + + + + +### Apache Kafka ÖÐËÀÐŶÓÁеÄ×î¼Ñʵ¼ù + + + + + +ÒÔÏÂÊÇÔÚ Kafka Ó¦ÓóÌÐòÖÐʹÓÃËÀÐŶÓÁнøÐдíÎó´¦ÀíµÄһЩ**×î¼Ñʵ¼ùºÍ¾­Ñé½Ìѵ£º** + + + + + +* ¶¨Òå**´¦ÀíÎÞЧÏûÏ¢µÄÒµÎñÁ÷³Ì**£¨×Ô¶¯ÓëÈ˹¤£© + * ÏÖʵ£ºÍ¨³££¬¸ù±¾Ã»ÓÐÈË´¦Àí DLQ ÏûÏ¢ + * ±¸Ñ¡·½°¸ 1£ºÊý¾ÝËùÓÐÕßÐèÒª½ÓÊÕ¾¯±¨£¬¶ø²»½ö½öÊÇ»ù´¡¼Ü¹¹ÍÅ¶Ó + * ±¸Ñ¡·½°¸ 2£º¾¯±¨Ó¦Í¨Öª¼Ç¼ÍŶÓϵͳÊý¾Ý´íÎó£¬ËûÃǽ«ÐèÒª´Ó¼ÇÂ¼ÏµÍ³ÖØÐ·¢ËÍ/ÐÞ¸´Êý¾Ý¡£ + * Èç¹ûûÓÐÈ˹ØÐÄ»ò±§Ô¹£¬Ç뿼ÂÇÖÊÒɺÍÉó²é DLQ ´æÔڵıØÒªÐÔ¡£Ïà·´£¬ÕâЩÏûÏ¢Ò²¿ÉÒÔÔÚ³õʼ Kafka Ó¦ÓóÌÐòÖб»ºöÂÔ¡£Õâ½ÚÊ¡ÁË´óÁ¿µÄÍøÂç¸ºÔØ¡¢»ù´¡ÉèÊ©ºÍ×ʽ𡣠+* ¹¹½¨**´øÓÐÊʵ±¾¯±¨µÄÒDZí°å**²¢ÕûºÏÏà¹ØÍŶӣ¨ÀýÈ磬ͨ¹ýµç×ÓÓʼþ»ò Slack ¾¯±¨£© +* ¶¨Òåÿ¸ö Kafka Ö÷ÌâµÄ**´íÎó´¦ÀíÓÅÏȼ¶£¨Í£Ö¹¡¢É¾³ýºÍÖØÐ´¦Àí£©** +* **½ö½«²»¿ÉÖØÊԵĴíÎóÏûÏ¢ÍÆË͵½ DLQ** - Á¬½ÓÎÊÌâÊÇÏû·ÑÕßÓ¦ÓóÌÐòµÄÔðÈΡ£ +* **±£ÁôԭʼÏûÏ¢**²¢½«ËüÃÇ´æ´¢ÔÚ DLQ ÖУ¨´øÓжîÍâµÄ±êÍ·£¬ÀýÈç´íÎóÏûÏ¢¡¢´íÎóʱ¼ä¡¢·¢Éú´íÎóµÄÓ¦ÓóÌÐòÃû³ÆµÈ£©¡ª¡ªÕâʹµÃÖØÐ´¦ÀíºÍ¹ÊÕÏÅųý±äµÃ¸ü¼ÓÈÝÒס£ +* **ÏëÏëÄãÐèÒª¶àÉÙ Dead Letter Queue Kafka Ö÷Ìâ**¡£×ÜÊÇÓÐÈ¡Éá¡£µ«Êǽ«ËùÓдíÎó´æ´¢ÔÚµ¥¸ö DLQ ÖпÉÄܶԽøÒ»²½·ÖÎöºÍÖØÐ´¦ÀíûÓÐÒâÒå¡£ + + + + + +Çë¼Çס£¬**DLQ »áÒÔÓб£Ö¤µÄ˳ÐòÖÕÖ¹´¦Àí£¬²¢Ê¹ÈκÎÀàÐ͵ÄÀëÏß´¦Àí±äµÃ¸ü¼ÓÀ§ÄÑ**¡£Òò´Ë£¬Kafka DQL ²¢²»ÊʺÏÿ¸öÓÃÀý¡£ + + + + + +### ºÎʱ²»ÔÚ Kafka ÖÐʹÓÃËÀÐŶÓÁУ¿ + + + + + +ÈÃÎÒÃÇ̽ÌÖһϲ»Ó¦¸Ã½«ÄÄЩÀàÐ͵ÄÏûÏ¢·ÅÈë Kafka µÄËÀÐŶÓÁÐÖУº + + + + + +* **DLQ ÓÃÓÚ±³Ñ¹´¦Àí£¿**ÓÉÓÚ´óÁ¿ÏûÏ¢µÄ·åÖµ¶øÊ¹Óà DLQ ½øÐнÚÁ÷²¢²»ÊÇÒ»¸öºÃÖ÷Òâ¡£Kafka ÈÕÖ¾±³ºóµÄ´æ´¢»á×Ô¶¯´¦Àí±³Ñ¹¡£Ïû·ÑÕßÒÔËü¿ÉÒÔ°´×Ô¼ºµÄËÙ¶È»ñÈ¡Êý¾ÝµÄ·½Ê½ÌáÈ¡Êý¾Ý£¨»òÕßÅäÖôíÎ󣩡£Èç¹û¿ÉÄܵϰ£¬µ¯ÐÔµØÀ©Õ¹Ïû·ÑÕß¡£¼´Ê¹ÄúµÄ´æ´¢¿Õ¼äÒÑÂú£¬DLQ Ò²ÎÞ¼ÃÓÚÊ¡£ÕâÊÇËüµÄÎÊÌ⣬ÓëÊÇ·ñʹÓà DLQ Î޹ء£ +* **Á¬½Óʧ°ÜµÄDLQ£¿**ÓÉÓÚÁ¬½Óʧ°Ü¶ø½«ÏûÏ¢·ÅÈë DQL ÎÞ¼ÃÓÚÊ£¨¼´Ê¹ÔÚ¶à´ÎÖØÊÔÖ®ºó£©¡£ÒÔÏÂÏûÏ¢Ò²ÎÞ·¨Á¬½Óµ½¸Ãϵͳ¡£ÄúÐèÒª½â¾öÁ¬½ÓÎÊÌâ¡£ÏûÏ¢¿ÉÒÔ¸ù¾ÝÐèÒª´æ´¢ÔÚ³£¹æÖ÷ÌâÖУ¨È¡¾öÓÚ±£Áôʱ¼ä£©¡£ + + + + + +### ÓÃÓÚÊý¾ÝÖÎÀíºÍ´íÎóÔ¤·ÀµÄģʽע²á±í + + + + + +×îºóµ«Í¬ÑùÖØÒªµÄÊÇ£¬ÈÃÎÒÃÇ̽ÌÖÔÚijЩÇé¿öÏÂ**¼õÉÙÉõÖÁÏû³ý¶ÔËÀÐŶÓÁеÄÐèÇóµÄ¿ÉÄÜÐÔ¡£** + + + + + +**¿¨·ò¿¨**µÄSchema Registry**ÊÇÒ»ÖÖÈ·±£Êý¾ÝÇåÀíÒÔ·ÀÖ¹Éú²úÕßÔÚ¸ºÔØÖгö´íµÄ·½·¨**¡£ËüÔÚ Kafka Éú²úÕßÖÐÇ¿ÖÆÖ´ÐÐÕýÈ·µÄÏûÏ¢½á¹¹£º + +![image-20230526224926155](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230526224926155.png) + + + + + +ģʽע²á±íÊÇģʽµÄ¿Í»§¶Ë¼ì²é¡£Confluent Server µÈһЩʵÏÖÔÚ´úÀí¶ËÌṩÁ˶îÍâµÄģʽ¼ì²é£¬ÒԾܾøÀ´×ÔδʹÓÃģʽע²á±íµÄÉú²úÕßµÄÎÞЧ»ò¶ñÒâÏûÏ¢¡£ + + + + + +### Kafka ËÀÐŶÓÁеݸÀýÑо¿ + + + + + +ÈÃÎÒÃÇ¿´¿´**Uber¡¢CrowdStrike ºÍ Santander Bank µÄÈý¸ö°¸ÀýÑо¿£¬ËüÃÇÔÚ Kafka »ù´¡ÉèÊ©ÖÐʵ¼Ê²¿ÊðËÀÐŶÓÁÐ**¡£Çë¼Çס£¬ÕâЩ¶¼ÊǷdz£³ÉÊìµÄÀý×Ó¡£²»ÊÇÿ¸öÏîÄ¿¶¼ÐèÒªÄÇô¸´ÔÓ¡£ + + + + + +### Uber - ¹¹½¨¿É¿¿µÄÔÙ´¦ÀíºÍËÀÐŶÓÁÐ + + + + + +ÔÚ·Ö²¼Ê½ÏµÍ³ÖУ¬ÖØÊÔÊDz»¿É±ÜÃâµÄ¡£´ÓÍøÂç´íÎ󵽸´ÖÆÎÊÌ⣬ÉõÖÁÏÂÓÎÒÀÀµ¹ØÏµµÄÖжϣ¬´ó¹æÄ£ÔËÐеķþÎñ±ØÐë×¼±¸ºÃ¾¡¿ÉÄÜÓÅÑŵØÓöµ½¡¢Ê¶±ðºÍ´¦Àí¹ÊÕÏ¡£ + + + + + +¼øÓÚ Uber µÄÔËÓª·¶Î§ºÍËÙ¶È£¬ËüµÄϵͳ±ØÐë¾ßÓÐ**ÈÝ´íÄÜÁ¦£¬²¢ÇÒÔÚÖÇÄÜʧ°ÜʱºÁ²»Í×Э**¡£Uber ½« Apache Kafka ÓÃÓÚ¸÷ÖÖ¼«¶Ë¹æÄ£µÄÓÃÀýÒÔʵÏÖÕâһĿ±ê¡£ + + + + + +ÀûÓÃÕâÐ©ÌØÐÔ£¬Uber ±£ÏÕ¹¤³ÌÍŶÓÀ©Õ¹ÁË Kafka ÔÚÆäÏÖÓÐʼþÇý¶¯¼Ü¹¹ÖеÄ×÷Óã¬Í¨¹ýʹÓà n**¸ö×èÈûÇëÇóÖØÐ´¦ÀíºÍËÀÐŶÓÁÐÀ´ÊµÏÖ½âñî¡¢¿É¹Û²ìµÄ´íÎó´¦Àí£¬¶ø²»»áÖжÏʵʱÁ÷Á¿**¡£¸Ã²ßÂÔÓÐÖúÓÚËûÃÇÑ¡Ôñ¼ÓÈëµÄ¼ÝʻԱÉ˺¦±£»¤¼Æ»®ÔÚ 200 ¶à¸ö³ÇÊпɿ¿ÔËÐУ¬²¢Îª×¢²á¼ÝʻԱ¿Û³ýÿ´ÎÐг̵ÄÿӢÀï±£·Ñ¡£ + + + + + +ÕâÊÇ Uber ´íÎó´¦ÀíµÄʾÀý¡£´íÎó»á½µµÍÖØÊÔÖ÷ÌâµÄ¼¶±ð£¬Ö±µ½µÇ½ DLQ£º + + + + + +![](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230526225030750.png) + + + + + +Óйظü¶àÐÅÏ¢£¬ÇëÔĶÁ Uber ·Ç³£ÏêϸµÄ¼¼ÊõÎÄÕ£º¡°Ê¹Óà Apache Kafka ¹¹½¨¿É¿¿µÄÔÙ´¦ÀíºÍËÀÐŶÓÁС±¡£ + + + + + +### CrowdStrike - ´¦ÀíÊýÍòÒÚʼþµÄ´íÎó + + + + + +CrowdStrike ÊÇÒ»¼ÒλÓڵ¿ËÈøË¹ÖݰÂ˹͡µÄ**ÍøÂ簲ȫ¼¼Êõ¹«Ë¾¡£**ËüÌṩ**ÔÆ¹¤×÷¸ºÔغͶ˵㰲ȫ¡¢ÍþвÇ鱨ºÍÍøÂç¹¥»÷ÏìÓ¦·þÎñ**¡£ + + + + + +CrowdStrike µÄ»ù´¡ÉèÊ©** ÿÌìʹÓà Apache Kafka ´¦ÀíÊýÍòÒÚ¸öʼþ**¡£ÔÚÎҵġ° Apache Kaka ÍøÂ簲ȫ²©¿ÍϵÁС±ÖУ¬ÎÒ½éÉÜÁËÒÔÈκιæÄ£ÊµÊ±´´½¨Ì¬ÊƸÐÖªºÍÍþвÇ鱨µÄÏà¹ØÓÃÀý¡£ + + + + + +CrowdStrike ¶¨ÒåÁËÈý¸ö×î¼Ñʵ¼ù À´³É¹¦ÊµÏÖËÀÐŶÓÁкʹíÎó´¦Àí£º + + + + + +* **ÔÚÕýÈ·µÄϵͳÖд洢´íÎóÏûÏ¢**£º¶¨Òå»ù´¡ÉèÊ©ºÍ´úÂëÒÔ²¶»ñºÍ¼ìË÷ËÀÐÅ¡£CrowdStrike ʹÓà S3 ¶ÔÏó´æ´¢À´´æ´¢Ç±ÔڵĴóÁ¿´íÎóÏûÏ¢¡£Çë×¢Ò⣬Kafka µÄ·Ö²ã´æ´¢¿ªÏä¼´Óõؽâ¾öÁËÕâ¸öÎÊÌ⣬ÎÞÐèÆäËû´æ´¢½Ó¿Ú£¨ÀýÈ磬ÀûÓà Confluent Cloud ÖеÄÎÞÏÞ´æ´¢£©¡£ +* **ʹÓÃ×Ô¶¯»¯**£º·ÅÖù¤¾ßÒÔʹÐÞ¸´ÍòÎÞһʧ£¬ÒòΪÊÖ¶¯Íê³É´íÎó´¦Àí¿ÉÄܷdz£ÈÝÒ׳ö´í¡£ +* **¼Ç¼ҵÎñÁ÷³Ì²¢Æ¸ÇëÏà¹ØÍŶÓ**£º±ê×¼»¯ºÍ¼Ç¼Á÷³ÌÒÔÈ·±£Ò×ÓÚʹÓᣲ¢·ÇËùÓй¤³Ìʦ¶¼ÊìϤ×éÖ¯´¦ÀíËÀÐÅÏûÏ¢µÄ²ßÂÔ¡£ + + + + + +ÔÚ**Ïñ CrowdStrike ÕâÑùµÄÍøÂ簲ȫƽ̨ÖУ¬´ó¹æÄ£ÊµÊ±Êý¾Ý´¦ÀíÖÁ¹ØÖØÒª**¡£´ËÒªÇóÒ²ÊÊÓÃÓÚ´íÎó´¦Àí¡£**ÏÂÒ»´ÎÍøÂç¹¥»÷¿ÉÄÜÊǹÊÒâ°üº¬²»Êʵ±»òÎÞЧÄÚÈݵĶñÒâÏûÏ¢**£¨Èç JavaScript ©¶´ÀûÓã©¡£Òò´Ë£¬±ØÐëͨ¹ýËÀÐŶÓÁÐʵʱ´¦Àí´íÎó¡£ + + + + + +### ɣ̹µÂÒøÐÐ - ÓÃÓÚÖØÊÔºÍ DLQ ×éºÏµÄÓÊÏä 2.0 + + + + + +ɣ̹µÂÒøÐÐ**ÔÚÓÊÏäÓ¦ÓóÌÐòÖд¦Àíº£Á¿Êý¾ÝµÄͬ²½Êý¾Ý´¦ÀíÃæÁÙ¾Þ´óÌôÕ½**¡£ËûÃÇÖØÐ¼ܹ¹ÁËËûÃǵĻù´¡¼Ü¹¹²¢¹¹½¨ÁËÒ»¸ö½âñîÇÒ¿ÉÀ©Õ¹µÄ¼Ü¹¹£¬³ÆÎª¡°Santander Mailbox 2.0¡±¡£ + + + + + +Santander µÄ¹¤×÷¸ºÔز¢×ªÒƵ½**ÓÉ Apache Kafka Ìṩ֧³ÖµÄʼþËÝÔ´**£º + + + + + +![image-20230526225045196](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230526225045196.png) + + + + + +еĻùÓÚÒ첽ʼþµÄ¼Ü¹¹ÖеÄÒ»¸ö¹Ø¼üÌôÕ½ÊÇ´íÎó´¦Àí¡£** Santander ʹÓÃÖØÊÔºÍ DQL Kafka Ö÷Ìâ¹¹½¨µÄ´íÎó´¦Àí**½â¾öÁËÕâЩÎÊÌ⣺ + + + + + +![image-20230526225057151](https://java-tutorial.oss-cn-shanghai.aliyuncs.com/image-20230526225057151.png) + + + + + +²é¿´À´×Ô Santander µÄ¼¯³ÉºÏ×÷»ï°é ConsdataµÄ Kafka ·å»áÑݽ²¡°»ùÓÚÖØÊÔ²ßÂÔºÍËÀÐÅÖ÷ÌâµÄ Apache Kafka ÖеĿɿ¿Ê¼þ´«µÝ¡±ÖеÄÏêϸÐÅÏ¢¡£ + + + + + +### Apache Kafka Öпɿ¿ÇÒ¿ÉÀ©Õ¹µÄ´íÎó´¦Àí + + + + + +**´íÎó´¦Àí¶ÔÓÚ¹¹½¨¿É¿¿µÄÊý¾ÝÁ÷¹ÜµÀºÍƽ̨ÖÁ¹ØÖØÒª**¡£´æÔÚ²»Í¬µÄÌæ´ú·½°¸À´½â¾öÕâ¸öÎÊÌâ¡£¸Ã½â¾ö·½°¸°üÀ¨ËÀÐŶÓÁеÄ×Ô¶¨ÒåʵÏÖ»òÀûÓÃÕýÔÚʹÓõĿò¼Ü£¬ÀýÈç Kafka Streams¡¢Kafka Connect¡¢Spring ¿ò¼Ü»ò Kafka µÄ²¢ÐÐÏû·ÑÕß¡£ + + + + + +ÓŲ½¡¢CrowdStrike ºÍɣ̹µÂÒøÐеݸÀýÑо¿±íÃ÷£¬´íÎó´¦Àí²¢²»×ÜÊǺÜÈÝÒ×ʵÏÖ¡£µ±ÄúÉè¼ÆÐµÄÓ¦ÓóÌÐò»ò¼Ü¹¹Ê±£¬ÐèÒª´ÓÒ»¿ªÊ¼¾Í¿¼Âǵ½ÕâÒ»µã¡£**ʹÓà Apache Kafka ½øÐÐʵʱÊý¾ÝÁ÷´«ÊäºÜÓÐÎüÒýÁ¦£¬µ«Ö»ÓÐÔÚÄúÄܹ»´¦ÀíÒâÍâÐÐΪʱ²ÅÄܳɹ¦**¡£ËÀÐŶÓÁÐÊÇÐí¶à³¡¾°µÄ¾ø¼ÑÑ¡Ôñ¡£ \ No newline at end of file