0%

Java Timer 定时任务调度详解

Timer 是 Java 原生提供的定时任务调度工具,虽然功能相对简单,但在简单场景下可以满足定时执行任务的需求。本文将详细解析 Timer 的核心组件、调度方式及使用细节。

Timer 核心组件

Timer 框架主要由两个核心类构成:TimerTimerTask

TimerTask:任务载体

TimerTask 是一个抽象类,实现了 Runnable 接口,代表一个可以被 Timer 调度的任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public abstract class TimerTask implements Runnable {
// 任务状态常量
static final int VIRGIN = 0; // 未调度
static final int SCHEDULED = 1; // 已调度(等待执行)
static final int EXECUTED = 2; // 已执行(非重复任务)
static final int CANCELLED = 3; // 已取消

int state = VIRGIN; // 初始状态为未调度

// 抽象方法,需用户实现具体任务逻辑
public abstract void run();

// 取消任务
public boolean cancel() { ... }

// 获取任务下次执行时间
public long scheduledExecutionTime() { ... }
}
阅读全文 »

Lombok 常用注解全解析:简化 Java 代码的利器

Lombok 是一款 Java 开发工具,通过注解自动生成模板代码(如 getter/setter、构造函数等),减少冗余代码,提高开发效率。本文将详细介绍 Lombok 的核心注解、使用场景及注意事项,帮助你快速掌握其用法。

Lombok 依赖配置

在 Maven 或 Gradle 项目中引入 Lombok 依赖,注意需配合 IDE 插件(如 IntelliJ IDEA 的 Lombok Plugin)使用,否则可能出现编译错误。

Maven 配置

1
2
3
4
5
6
<dependency>  
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version> <!-- 推荐使用最新稳定版 -->
<scope>provided</scope> <!-- 编译时生效,不打包到运行环境 -->
</dependency>

Gradle 配置

1
2
3
4
dependencies {  
compileOnly 'org.projectlombok:lombok:1.18.30'
annotationProcessor 'org.projectlombok:lombok:1.18.30'
}

核心注解详解

简化 Getter/Setter:@Getter / @Setter

  • 作用:自动生成成员变量的 getXxx()setXxx() 方法。
  • 使用场景:POJO 类、DTO 类等需要频繁定义 getter/setter 的场景。
阅读全文 »

Linux 端口映射配置指南:使用 iptables 实现网络地址转换

在 Linux 系统中,端口映射(端口转发)是实现不同网络间通信的重要手段,通常用于将外部网络的请求转发到内部网络的特定服务。以下是基于 iptables 的端口映射配置详解,包括临时配置和永久生效方案。

基础配置:启用数据包转发

端口映射依赖内核的 IP 转发功能,需先开启:

临时启用 IP 转发(立即生效,重启失效)

1
2
3
4
5
# 允许 IPv4 数据包转发
echo 1 > /proc/sys/net/ipv4/ip_forward

# 验证配置(返回 1 表示已启用)
cat /proc/sys/net/ipv4/ip_forward

配置 iptables 转发规则

1
2
3
4
5
6
7
8
9
10
# 1. 允许 NAT 表的 POSTROUTING 链进行地址伪装(适用于动态 IP 环境)
iptables -t nat -A POSTROUTING -j MASQUERADE

# 2. 允许内网网卡的转发请求
# 替换 [内网网卡名称] 为实际网卡(如 ens33、eth0)
iptables -A FORWARD -i [内网网卡名称] -j ACCEPT

# 3. 针对特定内网网段的地址转换(适用于静态 IP 环境)
# 替换 [内网网段](如 192.168.50.0/24)和 [外网网卡名称](如 ens37)
iptables -t nat -A POSTROUTING -s [内网网段] -o [外网网卡名称] -j MASQUERADE

示例(假设内网网卡为 ens33,外网网卡为 ens37,内网网段为 192.168.50.0/24):

1
2
3
iptables -t nat -A POSTROUTING -j MASQUERADE
iptables -A FORWARD -i ens33 -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.50.0/24 -o ens37 -j MASQUERADE

核心配置:设置端口映射规则

使用 iptablesDNAT(目的地址转换)实现端口映射,将外部请求转发到内部服务。

基本语法

阅读全文 »

生产者如何保证不丢失数据:从机制到实践

Kafka 生产者确保数据不丢失的核心是通过确认机制(ACK)副本同步策略故障重试机制的协同作用,同时辅以幂等性和业务层去重解决潜在的数据重复问题。以下是具体实现方案:

核心机制:ACK 确认与副本同步

生产者数据不丢失的基础是 “消息必须被可靠写入并同步到足够多的副本”,这依赖于 ACK 确认级别和 ISR(同步副本集)的设计。

ISR(In-Sync Replica Set):同步副本集的作用

  • 定义:ISR 是与 Leader 副本保持实时同步的 Follower 副本集合(Leader 自身也包含在 ISR 中)。
  • 同步判断:Follower 需在 replica.lag.time.max.ms(默认 30 秒)内成功从 Leader 拉取消息,否则会被踢出 ISR。
  • 意义:ISR 确保了 “即使 Leader 故障,仍有其他副本持有最新数据”,新 Leader 会从 ISR 中选举,避免数据丢失。

ACK 确认级别:控制消息写入的可靠性

通过 acks 参数配置,决定生产者收到 Broker 确认的时机,直接影响数据可靠性:

ACK 级别 确认时机 可靠性 性能 数据丢失风险
acks=0 生产者不等待任何确认,直接发送下一条消息 最低 最高 极高(Broker 崩溃时,消息可能未写入磁盘)
acks=1(默认) Leader 副本写入本地日志后立即确认 中等 中等 存在(Leader 写入后崩溃,Follower 未同步,则新 Leader 无此消息)
acks=-1(或 acks=all Leader 与所有 ISR 中的 Follower 均写入日志后确认 最高 最低 极低(只要 ISR 中至少 1 个副本存活,数据就不丢失)
阅读全文 »

Kafka 消费者的分区分配策略:从原理到实践

在 Kafka 中,当消费者组(Consumer Group)包含多个消费者时,如何将主题的分区(Partition)合理分配给消费者,直接影响消费效率和负载均衡。Kafka 提供了四种核心分区分配策略,每种策略适用于不同场景。本文将详细解析这些策略的原理、优缺点及适用场景。

分区分配的核心概念

  • 消费者组(Consumer Group):多个消费者组成的群体,共同消费一个或多个主题的消息,每个分区只能被组内一个消费者消费(避免重复消费)。
  • 分配主体:分区分配由消费者组的协调者(Coordinator) 负责,通常是分区的 Leader 所在的 Broker。
  • 触发时机:当消费者组发生以下变化时,会触发重新分配(Rebalance):
    • 消费者加入或离开组(如启动新消费者、消费者崩溃)。
    • 主题的分区数量变化(如增加分区)。
    • 消费者订阅的主题变化。

四种分区分配策略详解

1. RangeAssignor(范围分配,默认策略)

原理
  • 按主题分组分配:先将消费者订阅的所有主题按名称排序,再为每个主题单独分配分区。
  • 范围划分:对每个主题,将其分区按序号排序,然后平均分配给消费者。若分区数不能被消费者数整除,前几个消费者会多分配 1 个分区。
示例
  • 场景:2 个消费者(C0、C1),1 个主题 T0(5 个分区:P0-P4)。
  • 计算:5 个分区 ÷ 2 个消费者 = 2 个 / 人,余 1 个。
  • 分配结果:
    • C0:P0、P1、P2(多分配 1 个分区)
    • C1:P3、P4
优缺点
  • 优点:实现简单,保证每个主题的分区分配相对集中,减少跨消费者的分区分散。
  • 缺点:当多个主题的分区数相同时,可能导致负载不均(前几个消费者分配更多分区)。
  • 适用场景:消费者订阅相同的主题,且分区数较少的场景。
阅读全文 »