0%

Kafka 消费者组(Consumer Group)详解:机制与重平衡

Kafka 消费者组是实现高可用、高扩展消费的核心机制,通过协调多个消费者实例共同消费主题分区,既保证了负载均衡,又提供了容错能力。本文将深入解析消费者组的核心概念、消费模式及重平衡(Rebalance)机制,包括其触发条件、过程及潜在问题。

消费者组核心概念

定义与特性

消费者组是由一个或多个消费者实例组成的集合,所有成员共享同一个 group.id(消费者组 ID)。其核心特性是:

  • 分区独占性:一个主题的每个分区只能被消费者组内的一个消费者消费(避免重复消费)。
  • 扩展性:通过增加消费者数量(≤ 分区数),可分摊消费压力,提升吞吐量。
  • 容错性:若某个消费者故障,其负责的分区会被其他消费者接管(通过重平衡)。

与分区的关系

假设一个主题有 5 个分区(P0-P4),消费者组有 3 个消费者(C0-C2),则分区分配可能为:

  • C0:P0、P1
  • C1:P2、P3
  • C2:P4

若增加消费者至 5 个(C0-C4),则每个消费者可独占一个分区;若消费者超过 5 个,多余的消费者会处于空闲状态(无分区可消费)。

两种消费模式

消费者组机制使 Kafka 同时支持 “点对点” 和 “发布订阅” 两种模式:

阅读全文 »

Spring 事务源码全解析:从 <tx:annotation-driven/> 到事务提交的完整链路

Spring 事务管理是 AOP 思想的典型应用,其核心是通过 <tx:annotation-driven/> 配置开启注解式事务,底层依赖 “自定义标签解析→事务组件注册→AOP 代理增强→事务生命周期管理” 的完整机制。从配置解析到事务执行,逐环节拆解 Spring 事务的实现原理。

事务配置的解析:<tx:annotation-driven/> 标签处理

与 AOP 的 <aop:aspectj-autoproxy/> 类似,<tx:annotation-driven/> 是 Spring 事务的核心配置标签,其解析依赖自定义标签机制,最终目的是向容器注册事务管理的核心组件。

自定义标签映射与处理器初始化

<tx:annotation-driven/> 的命名空间为 http://www.springframework.org/schema/tx,Spring 通过 META-INF/spring.handlers 映射到对应的处理器 TxNamespaceHandler

1
2
# spring.handlers 配置
http\://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler

TxNamespaceHandlerinit() 方法注册了标签解析器,其中 <tx:annotation-driven/> 对应 AnnotationDrivenBeanDefinitionParser

1
2
3
4
5
6
7
8
9
10
11
public class TxNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
// 解析 <tx:advice/> 标签(XML 方式配置事务通知)
registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
// 解析 <tx:annotation-driven/> 标签(注解方式开启事务)
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
// 解析 <tx:jta-transaction-manager/> 标签(JTA 事务管理器)
registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
}
}

AnnotationDrivenBeanDefinitionParser:事务核心组件的注册

AnnotationDrivenBeanDefinitionParserparse() 方法是事务配置解析的核心,根据 mode 属性(默认 proxy)决定事务增强方式,最终通过 AopAutoProxyConfigurer.configureAutoProxyCreator() 注册事务管理的核心组件。

configureAutoProxyCreator () 方法解析

该方法向容器注册 4 个关键组件,构成事务管理的基础:

阅读全文 »

Redis 统计信息详解(基于 info 命令)

Redis 的 info 命令是监控和诊断 Redis 实例的核心工具,它返回服务器运行状态、内存使用、持久化、主从复制等多维度的统计信息。本文基于 Redis 6.2.1 版本,解析 info 命令的输出结构及关键指标,帮助你快速定位问题并优化性能。

info 命令基础

  • 使用方式
    redis-cli 中执行 info 查看完整信息,或通过 info <section> 查看指定模块(如 info memory 查看内存信息)。
  • 输出结构:信息按模块划分(如 ServerClientsMemory 等),每个模块包含若干键值对指标。

核心模块及关键指标解析

1. Server:服务器基础信息

记录 Redis 版本、运行模式、进程信息等基础参数,核心指标:

指标 说明 关注点
redis_version Redis 版本号(如 6.2.1)。 确认版本是否兼容新特性(如 6.0+ 支持多线程)。
redis_mode 运行模式(standalone 单机 / cluster 集群 / sentinel 哨兵)。 验证部署模式是否符合预期。
process_id Redis 进程 PID。 用于定位进程(如 kill -9 <pid> 终止进程)。
uptime_in_seconds 运行时长(秒)。 结合故障时间判断是否刚重启过。
lru_clock LRU 时钟(分钟级自增),用于过期键淘汰。 无直接监控意义,内部用于 LRU 算法。

2. Clients:客户端连接信息

监控客户端连接状态,核心指标:

阅读全文 »

网络活动主机扫描脚本:快速检测局域网内在线设备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/bin/bash

# 配置参数
NETWORK="192.168.0" # 网络前缀
START=1 # 起始IP
END=255 # 结束IP
TIMEOUT=1 # ping超时时间(秒)
COUNT=1 # ping包数量
THREADS=50 # 并发线程数
OUTPUT_FILE="alive_hosts.txt" # 结果保存文件

# 显示脚本使用帮助
usage() {
echo "用法: $0 [选项]"
echo "选项:"
echo " -n <网络前缀> 设置网络前缀(默认: 192.168.0)"
echo " -s <起始IP> 设置起始IP(默认: 1)"
echo " -e <结束IP> 设置结束IP(默认: 255)"
echo " -t <超时时间> 设置ping超时时间(秒)(默认: 1)"
echo " -c <包数量> 设置ping包数量(默认: 1)"
echo " -T <线程数> 设置并发线程数(默认: 50)"
echo " -o <文件> 设置结果输出文件(默认: alive_hosts.txt)"
echo " -h 显示帮助信息"
exit 1
}

# 解析命令行参数
while getopts "n:s:e:t:c:T:o:h" opt; do
case $opt in
n) NETWORK="$OPTARG" ;;
s) START="$OPTARG" ;;
e) END="$OPTARG" ;;
t) TIMEOUT="$OPTARG" ;;
c) COUNT="$OPTARG" ;;
T) THREADS="$OPTARG" ;;
o) OUTPUT_FILE="$OPTARG" ;;
h) usage ;;
*) usage ;;
esac
done

# 检查参数有效性
if [ $START -gt $END ]; then
echo "错误: 起始IP不能大于结束IP"
exit 1
fi

if [ $THREADS -lt 1 ] || [ $THREADS -gt 255 ]; then
echo "错误: 线程数必须在1-255之间"
exit 1
fi

# 初始化结果文件
> $OUTPUT_FILE

# 扫描函数
scan_host() {
local ip="$NETWORK.$1"
# 执行ping命令,静默模式
if ping -c $COUNT -W $TIMEOUT $ip &> /dev/null; then
# 获取主机名(如果能解析)
local hostname=$(nslookup $ip 2>/dev/null | grep 'name =' | awk '{print $4}' | sed 's/\.$//')
if [ -n "$hostname" ]; then
echo "$ip is alive (主机名: $hostname)"
echo "$ip $hostname" >> $OUTPUT_FILE
else
echo "$ip is alive"
echo "$ip" >> $OUTPUT_FILE
fi
fi
}

# 显示扫描信息
echo "开始扫描网络 $NETWORK.$START-$NETWORK.$END ..."
echo "并发线程数: $THREADS, 超时时间: $TIMEOUT秒"
echo "结果将保存至: $OUTPUT_FILE"
echo "----------------------------------------"

# 多线程扫描
for ((i=START; i<=END; i++)); do
scan_host $i &
# 控制并发线程数
while [ $(jobs -r | wc -l) -ge $THREADS ]; do
sleep 0.1
done
done

# 等待所有线程完成
wait

# 显示扫描结果汇总
echo "----------------------------------------"
echo "扫描完成! 共发现 $(wc -l < $OUTPUT_FILE) 台活动主机:"
cat $OUTPUT_FILE

使用示例:

1
2
3
4
5
# 扫描192.168.1.1-100,使用30线程
./scan_alive_hosts.sh -n 192.168.1 -s 1 -e 100 -T 30

# 快速扫描(1个包,0.5秒超时)
./scan_alive_hosts.sh -c 1 -t 0.5

Spring Cloud Config 加密解密:保护敏感配置信息

在分布式系统中,数据库密码、API 密钥等敏感配置需要加密存储,避免明文泄露。Spring Cloud Config 提供了完善的加密解密机制,支持对称加密和非对称加密两种方式,确保敏感信息在传输和存储过程中的安全性。

加密解密的前提准备

Spring Cloud Config 的加密功能依赖 Java 加密扩展(JCE),需先确保环境配置正确:

  1. 下载 JCE
    对于 JDK 8 及以下版本,需手动下载 Java Cryptography Extension (JCE) Unlimited Files

    JDK 9+ 已内置无限制强度的 JCE,无需额外配置。

  2. 安装 JCE
    将下载的 JCE 包中的 local_policy.jarUS_export_policy.jar 复制到 $JAVA_HOME/jre/lib/security/ 目录,覆盖原有文件。

对称加密(Symmetric Encryption)

对称加密使用相同的密钥进行加密和解密,配置简单,适合中小规模系统。

1. 配置加密密钥

在配置中心(Config Server)的 bootstrap.yml 中指定加密密钥:

阅读全文 »