本文目录导读:

在Java分布式系统中,数据监听器的回调机制通常涉及以下几个关键部分:
基于Zookeeper的回调实现
Watcher回调机制
public class ZKDataListener implements Watcher {
private ZooKeeper zooKeeper;
private String watchPath;
public ZKDataListener(String connectString, String watchPath) throws Exception {
this.watchPath = watchPath;
this.zooKeeper = new ZooKeeper(connectString, 3000, this);
// 监听数据变化
zooKeeper.getData(watchPath, this, null);
}
@Override
public void process(WatchedEvent event) {
if (event.getType() == Event.EventType.NodeDataChanged) {
// 数据变更回调
handleDataChange(event.getPath());
// 重新注册监听(Zookeeper是一次性监听)
try {
zooKeeper.getData(watchPath, this, null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void handleDataChange(String path) {
try {
byte[] data = zooKeeper.getData(path, false, null);
String newValue = new String(data);
System.out.println("数据变更: " + path + " -> " + newValue);
// 执行你的业务逻辑
} catch (Exception e) {
e.printStackTrace();
}
}
}
基于Redis的发布订阅回调
Redis Pub/Sub模式
public class RedisDataListener implements MessageListener {
private JedisPool jedisPool;
public RedisDataListener() {
this.jedisPool = new JedisPool("localhost", 6379);
startListening();
}
public void startListening() {
new Thread(() -> {
try (Jedis jedis = jedisPool.getResource()) {
// 订阅频道
jedis.subscribe(new JedisPubSub() {
@Override
public void onMessage(String channel, String message) {
// 回调方法
handleDataChange(channel, message);
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {
System.out.println("订阅成功: " + channel);
}
}, "data_channel");
}
}).start();
}
private void handleDataChange(String channel, String message) {
System.out.println("数据变更通知: " + message);
// 处理数据变更业务逻辑
}
}
基于消息队列的回调(Kafka示例)
Kafka消费者回调
public class KafkaDataListener {
private KafkaConsumer<String, String> consumer;
public KafkaDataListener() {
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "data-listener-group");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
this.consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("data-topic"));
}
public void startListening() {
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<String, String> record : records) {
// 回调处理
handleDataChange(record.key(), record.value());
}
}
}
private void handleDataChange(String key, String value) {
System.out.printf("数据变更 - key: %s, value: %s%n", key, value);
// 业务逻辑处理
}
}
自定义分布式监听器框架
public class DistributedDataListener {
private final ExecutorService callbackExecutor;
private final List<DataChangeCallback> callbacks;
public DistributedDataListener() {
this.callbackExecutor = Executors.newCachedThreadPool();
this.callbacks = new CopyOnWriteArrayList<>();
}
// 注册回调
public void registerCallback(DataChangeCallback callback) {
callbacks.add(callback);
}
// 触发回调
public void notifyDataChange(String dataKey, String oldValue, String newValue) {
callbackExecutor.submit(() -> {
for (DataChangeCallback callback : callbacks) {
try {
callback.onDataChange(dataKey, oldValue, newValue);
} catch (Exception e) {
// 异常处理,避免影响其他回调
System.err.println("回调执行失败: " + e.getMessage());
}
}
});
}
@FunctionalInterface
public interface DataChangeCallback {
void onDataChange(String key, String oldValue, String newValue);
}
}
Spring Cloud Config的回调
@Component
public class ConfigChangeListener {
@Autowired
private ConfigurableApplicationContext applicationContext;
@EventListener
public void onConfigChange(EnvironmentChangeEvent event) {
Set<String> changedKeys = event.getKeys();
changedKeys.forEach(key -> {
String newValue = applicationContext.getEnvironment().getProperty(key);
System.out.println("配置变更: " + key + " = " + newValue);
// 执行配置变更后的业务逻辑
});
}
// 或者使用特定注解
@ConfigurationProperties("app.config")
@RefreshScope
public class ConfigProperties {
private String dataKey;
// getter/setter
}
}
最佳实践建议
- 异步处理:回调操作建议使用线程池异步执行,避免阻塞监听线程
- 异常处理:回调中必须处理异常,防止影响其他监听器
- 幂等性设计:回调操作应该支持重复执行
- 超时控制:设置回调执行超时时间
- 顺序保证:如果业务需要保证顺序,使用同步回调队列
// 异步回调执行器示例
public class AsyncCallbackExecutor {
private final ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, 20, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1000),
new ThreadPoolExecutor.CallerRunsPolicy()
);
public void executeCallback(Runnable callback) {
CompletableFuture.runAsync(callback, executor)
.orTimeout(5, TimeUnit.SECONDS)
.exceptionally(throwable -> {
System.err.println("回调执行超时或异常: " + throwable.getMessage());
return null;
});
}
}
选择哪种回调机制取决于你的具体需求:Zookeeper适合配置管理,Redis适合实时通知,Kafka适合大数据处理,Spring Cloud Config适合微服务配置管理。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播