All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.likavn.eventbus.provider.redis.RedisStreamExpiredTask Maven / Gradle / Ivy

There is a newer version: 2.5.0-RC3
Show newest version
/**
 * Copyright 2023-2033, likavn ([email protected]).
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.github.likavn.eventbus.provider.redis; import com.github.likavn.eventbus.core.ListenerRegistry; import com.github.likavn.eventbus.core.TaskRegistry; import com.github.likavn.eventbus.core.base.Lifecycle; import com.github.likavn.eventbus.core.support.task.CronTask; import com.github.likavn.eventbus.core.utils.Func; import com.github.likavn.eventbus.prop.BusProperties; import com.github.likavn.eventbus.provider.redis.support.RedisListener; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.script.DefaultRedisScript; import java.util.Collections; import java.util.List; /** * redis stream过期消息处理 * * @author likavn * @date 2024/3/26 **/ @Slf4j public class RedisStreamExpiredTask implements Runnable, Lifecycle { /** * 数据清理定时任务,默认:每个小时21分进行清理 */ private static final String CRON = "0 21 1/1 * * ?"; private final BusProperties busProperties; private final RLock rLock; private final StringRedisTemplate redisTemplate; private final List redisSubscribers; private final DefaultRedisScript script; private boolean versionGe62 = false; private CronTask task; private final TaskRegistry taskRegistry; public RedisStreamExpiredTask(StringRedisTemplate redisTemplate, TaskRegistry taskRegistry, BusProperties busProperties, ListenerRegistry registry, RLock rLock) { this.busProperties = busProperties; this.taskRegistry = taskRegistry; this.rLock = rLock; this.redisTemplate = redisTemplate; // 及时消息订阅 this.redisSubscribers = Func.distinct(RedisListener.getAllListeners(registry), RedisListener::getStreamKey); String redisVersion = busProperties.getRedis().getRedisVersion(); // 判断最低版本是否大于等于 6.2 if (redisVersion.contains("-")) { redisVersion = redisVersion.substring(0, redisVersion.indexOf("-")); } String[] versions = redisVersion.split("\\."); String bigVersion = versions[0]; if (bigVersion.compareTo("6") >= 0 && (bigVersion.compareTo("7") >= 0 || (versions.length >= 2 && versions[1].compareTo("2") >= 0))) { versionGe62 = true; } // 过期消息处理脚本 String cmd = versionGe62 ? "'MINID'" : "'MAXLEN', '~'"; this.script = new DefaultRedisScript<>("return redis.call('XTRIM', KEYS[1]," + cmd + ", ARGV[1]);", Long.class); } @Override public void register() { task = CronTask.create(this.getClass().getName(), CRON, this); taskRegistry.createTask(task); } @Override public void run() { redisSubscribers.stream().map(RedisListener::getStreamKey).forEach(this::cleanExpired); } /** * 截取过期的消息 */ private void cleanExpired(String streamKey) { String lockKey = streamKey + ".deleteExpiredLock"; boolean lock = rLock.getLock(lockKey); try { if (!lock) { return; } String param; if (versionGe62) { // stream 过期时间,单位:小时 Long expiredHours = busProperties.getRedis().getStreamExpiredHours(); // 过期时间毫秒数 long expiredMillis = System.currentTimeMillis() - (1000L * 60 * 60 * expiredHours); param = expiredMillis + "-0"; } else { Long streamExpiredLength = busProperties.getRedis().getStreamExpiredLength(); param = null == streamExpiredLength ? null : streamExpiredLength.toString(); } if (null == param) { return; } Long deleteCount = redisTemplate.execute(script, Collections.singletonList(streamKey), param); log.debug("clean expired:streamKey={}, deleteCount={}", streamKey, deleteCount); } catch (Exception e) { log.error("clean expired:streamKey={}", streamKey, e); } finally { if (lock) { try { rLock.releaseLock(lockKey); } catch (Exception e) { log.error("cleanExpired release lock error", e); } } } } @Override public void destroy() { taskRegistry.removeTask(task); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy