10 changed files with 75 additions and 208 deletions
@ -1,37 +1,21 @@ |
|||||
package com.bx.imclient.task; |
package com.bx.imclient.task; |
||||
|
|
||||
import com.bx.imcommon.util.ThreadPoolExecutorFactory; |
import cn.hutool.core.util.StrUtil; |
||||
import lombok.SneakyThrows; |
import com.bx.imcommon.mq.RedisMQConsumer; |
||||
import lombok.extern.slf4j.Slf4j; |
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.boot.CommandLineRunner; |
import org.springframework.beans.factory.annotation.Value; |
||||
|
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor; |
|
||||
import java.util.concurrent.TimeUnit; |
|
||||
|
|
||||
@Slf4j |
@Slf4j |
||||
public abstract class AbstractMessageResultTask implements CommandLineRunner { |
public abstract class AbstractMessageResultTask<T> extends RedisMQConsumer<T> { |
||||
|
|
||||
private static final ScheduledThreadPoolExecutor EXECUTOR_SERVICE = ThreadPoolExecutorFactory.getThreadPoolExecutor(); |
@Value("${spring.application.name}") |
||||
|
private String appName; |
||||
|
|
||||
@Override |
@Override |
||||
public void run(String... args) { |
public String generateKey() { |
||||
// 初始化定时器
|
return StrUtil.join(":", super.generateKey(), appName); |
||||
EXECUTOR_SERVICE.execute(new Runnable() { |
|
||||
@SneakyThrows |
|
||||
@Override |
|
||||
public void run() { |
|
||||
try { |
|
||||
pullMessage(); |
|
||||
} catch (Exception e) { |
|
||||
log.error("任务调度异常", e); |
|
||||
} |
|
||||
if (!EXECUTOR_SERVICE.isShutdown()) { |
|
||||
EXECUTOR_SERVICE.schedule(this,100, TimeUnit.MICROSECONDS); |
|
||||
} |
|
||||
} |
|
||||
}); |
|
||||
} |
} |
||||
|
|
||||
|
|
||||
public abstract void pullMessage() throws InterruptedException; |
|
||||
} |
} |
||||
|
|||||
@ -1,58 +1,27 @@ |
|||||
package com.bx.imclient.task; |
package com.bx.imclient.task; |
||||
|
|
||||
import cn.hutool.core.util.StrUtil; |
|
||||
import com.alibaba.fastjson.JSONObject; |
|
||||
import com.bx.imclient.listener.MessageListenerMulticaster; |
import com.bx.imclient.listener.MessageListenerMulticaster; |
||||
import com.bx.imcommon.contant.IMRedisKey; |
import com.bx.imcommon.contant.IMRedisKey; |
||||
import com.bx.imcommon.enums.IMListenerType; |
import com.bx.imcommon.enums.IMListenerType; |
||||
import com.bx.imcommon.model.IMSendResult; |
import com.bx.imcommon.model.IMSendResult; |
||||
import com.bx.imcommon.mq.RedisMQTemplate; |
import com.bx.imcommon.mq.RedisMQListener; |
||||
import lombok.RequiredArgsConstructor; |
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
|
||||
import org.springframework.beans.factory.annotation.Value; |
|
||||
import org.springframework.stereotype.Component; |
import org.springframework.stereotype.Component; |
||||
import java.util.LinkedList; |
|
||||
import java.util.List; |
import java.util.List; |
||||
import java.util.Objects; |
|
||||
|
|
||||
|
|
||||
@Component |
@Component |
||||
@RequiredArgsConstructor |
@RequiredArgsConstructor |
||||
public class GroupMessageResultResultTask extends AbstractMessageResultTask { |
@RedisMQListener(queue = IMRedisKey.IM_RESULT_GROUP_QUEUE, batchSize = 100) |
||||
|
public class GroupMessageResultResultTask extends AbstractMessageResultTask<IMSendResult> { |
||||
@Autowired |
|
||||
private RedisMQTemplate redisMQTemplate; |
|
||||
|
|
||||
@Value("${spring.application.name}") |
|
||||
private String appName; |
|
||||
|
|
||||
@Value("${im.result.batch:100}") |
|
||||
private int batchSize; |
|
||||
|
|
||||
private final MessageListenerMulticaster listenerMulticaster; |
private final MessageListenerMulticaster listenerMulticaster; |
||||
|
|
||||
@Override |
@Override |
||||
public void pullMessage() { |
public void onMessage(List<IMSendResult> results) { |
||||
List<IMSendResult> results; |
listenerMulticaster.multicast(IMListenerType.GROUP_MESSAGE, results); |
||||
do { |
|
||||
results = loadBatch(); |
|
||||
if(!results.isEmpty()){ |
|
||||
listenerMulticaster.multicast(IMListenerType.GROUP_MESSAGE, results); |
|
||||
} |
|
||||
} while (results.size() >= batchSize); |
|
||||
} |
} |
||||
|
|
||||
List<IMSendResult> loadBatch() { |
|
||||
String key = StrUtil.join(":", IMRedisKey.IM_RESULT_GROUP_QUEUE, appName); |
|
||||
//这个接口redis6.2以上才支持
|
|
||||
//List<Object> list = redisMQTemplate.opsForList().leftPop(key, batchSize);
|
|
||||
List<IMSendResult> results = new LinkedList<>(); |
|
||||
JSONObject jsonObject = (JSONObject) redisMQTemplate.opsForList().leftPop(key); |
|
||||
while (!Objects.isNull(jsonObject) && results.size() < batchSize) { |
|
||||
results.add(jsonObject.toJavaObject(IMSendResult.class)); |
|
||||
jsonObject = (JSONObject) redisMQTemplate.opsForList().leftPop(key); |
|
||||
} |
|
||||
return results; |
|
||||
} |
|
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,59 +1,26 @@ |
|||||
package com.bx.imclient.task; |
package com.bx.imclient.task; |
||||
|
|
||||
import cn.hutool.core.util.StrUtil; |
|
||||
import com.alibaba.fastjson.JSONObject; |
|
||||
import com.bx.imclient.listener.MessageListenerMulticaster; |
import com.bx.imclient.listener.MessageListenerMulticaster; |
||||
import com.bx.imcommon.contant.IMRedisKey; |
import com.bx.imcommon.contant.IMRedisKey; |
||||
import com.bx.imcommon.enums.IMListenerType; |
import com.bx.imcommon.enums.IMListenerType; |
||||
import com.bx.imcommon.model.IMSendResult; |
import com.bx.imcommon.model.IMSendResult; |
||||
import com.bx.imcommon.mq.RedisMQTemplate; |
import com.bx.imcommon.mq.RedisMQListener; |
||||
import lombok.RequiredArgsConstructor; |
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
|
||||
import org.springframework.beans.factory.annotation.Value; |
|
||||
import org.springframework.stereotype.Component; |
import org.springframework.stereotype.Component; |
||||
import java.util.LinkedList; |
|
||||
import java.util.List; |
import java.util.List; |
||||
import java.util.Objects; |
|
||||
|
|
||||
@Slf4j |
|
||||
@Component |
@Component |
||||
@RequiredArgsConstructor |
@RequiredArgsConstructor |
||||
public class PrivateMessageResultResultTask extends AbstractMessageResultTask { |
@RedisMQListener(queue = IMRedisKey.IM_RESULT_PRIVATE_QUEUE, batchSize = 100) |
||||
|
public class PrivateMessageResultResultTask extends AbstractMessageResultTask<IMSendResult> { |
||||
@Autowired |
|
||||
private RedisMQTemplate redisMQTemplate; |
|
||||
|
|
||||
@Value("${spring.application.name}") |
|
||||
private String appName; |
|
||||
|
|
||||
@Value("${im.result.batch:100}") |
|
||||
private int batchSize; |
|
||||
|
|
||||
private final MessageListenerMulticaster listenerMulticaster; |
private final MessageListenerMulticaster listenerMulticaster; |
||||
|
|
||||
@Override |
@Override |
||||
public void pullMessage() { |
public void onMessage(List<IMSendResult> results) { |
||||
List<IMSendResult> results; |
listenerMulticaster.multicast(IMListenerType.PRIVATE_MESSAGE, results); |
||||
do { |
|
||||
results = loadBatch(); |
|
||||
if(!results.isEmpty()){ |
|
||||
listenerMulticaster.multicast(IMListenerType.PRIVATE_MESSAGE, results); |
|
||||
} |
|
||||
} while (results.size() >= batchSize); |
|
||||
} |
|
||||
|
|
||||
List<IMSendResult> loadBatch() { |
|
||||
String key = StrUtil.join(":", IMRedisKey.IM_RESULT_PRIVATE_QUEUE, appName); |
|
||||
//这个接口redis6.2以上才支持
|
|
||||
//List<Object> list = redisMQTemplate.opsForList().leftPop(key, batchSize);
|
|
||||
List<IMSendResult> results = new LinkedList<>(); |
|
||||
JSONObject jsonObject = (JSONObject) redisMQTemplate.opsForList().leftPop(key); |
|
||||
while (!Objects.isNull(jsonObject) && results.size() < batchSize) { |
|
||||
results.add(jsonObject.toJavaObject(IMSendResult.class)); |
|
||||
jsonObject = (JSONObject) redisMQTemplate.opsForList().leftPop(key); |
|
||||
} |
|
||||
return results; |
|
||||
} |
} |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,45 +1,23 @@ |
|||||
package com.bx.imserver.task; |
package com.bx.imserver.task; |
||||
|
|
||||
import com.bx.imcommon.util.ThreadPoolExecutorFactory; |
import com.bx.imcommon.mq.RedisMQConsumer; |
||||
import com.bx.imserver.netty.IMServerGroup; |
import com.bx.imserver.netty.IMServerGroup; |
||||
import lombok.SneakyThrows; |
|
||||
import lombok.extern.slf4j.Slf4j; |
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.CommandLineRunner; |
|
||||
|
|
||||
import javax.annotation.PreDestroy; |
|
||||
import java.util.concurrent.ExecutorService; |
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor; |
|
||||
import java.util.concurrent.TimeUnit; |
|
||||
|
|
||||
@Slf4j |
@Slf4j |
||||
public abstract class AbstractPullMessageTask implements CommandLineRunner { |
public abstract class AbstractPullMessageTask<T> extends RedisMQConsumer<T> { |
||||
|
|
||||
private static final ScheduledThreadPoolExecutor EXECUTOR_SERVICE = ThreadPoolExecutorFactory.getThreadPoolExecutor(); |
|
||||
|
|
||||
@Autowired |
@Autowired |
||||
private IMServerGroup serverGroup; |
private IMServerGroup serverGroup; |
||||
|
|
||||
@Override |
@Override |
||||
public void run(String... args) { |
public String generateKey() { |
||||
EXECUTOR_SERVICE.execute(new Runnable() { |
return String.join(":", super.generateKey(), IMServerGroup.serverId + ""); |
||||
@SneakyThrows |
|
||||
@Override |
|
||||
public void run() { |
|
||||
try { |
|
||||
if (serverGroup.isReady()) { |
|
||||
pullMessage(); |
|
||||
} |
|
||||
} catch (Exception e) { |
|
||||
log.error("任务调度异常", e); |
|
||||
} |
|
||||
if (!EXECUTOR_SERVICE.isShutdown()) { |
|
||||
EXECUTOR_SERVICE.schedule(this,100, TimeUnit.MICROSECONDS); |
|
||||
} |
|
||||
} |
|
||||
}); |
|
||||
} |
} |
||||
|
|
||||
|
@Override |
||||
public abstract void pullMessage() throws InterruptedException; |
public Boolean isReady() { |
||||
|
return serverGroup.isReady(); |
||||
|
} |
||||
} |
} |
||||
|
|||||
@ -1,38 +1,25 @@ |
|||||
package com.bx.imserver.task; |
package com.bx.imserver.task; |
||||
|
|
||||
import com.alibaba.fastjson.JSONObject; |
|
||||
import com.bx.imcommon.contant.IMRedisKey; |
import com.bx.imcommon.contant.IMRedisKey; |
||||
import com.bx.imcommon.enums.IMCmdType; |
import com.bx.imcommon.enums.IMCmdType; |
||||
import com.bx.imcommon.model.IMRecvInfo; |
import com.bx.imcommon.model.IMRecvInfo; |
||||
import com.bx.imserver.netty.IMServerGroup; |
import com.bx.imcommon.mq.RedisMQListener; |
||||
import com.bx.imserver.netty.processor.AbstractMessageProcessor; |
import com.bx.imserver.netty.processor.AbstractMessageProcessor; |
||||
import com.bx.imserver.netty.processor.ProcessorFactory; |
import com.bx.imserver.netty.processor.ProcessorFactory; |
||||
import lombok.RequiredArgsConstructor; |
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.data.redis.core.RedisTemplate; |
|
||||
import org.springframework.stereotype.Component; |
import org.springframework.stereotype.Component; |
||||
|
|
||||
import java.util.Objects; |
|
||||
|
|
||||
@Slf4j |
@Slf4j |
||||
@Component |
@Component |
||||
@RequiredArgsConstructor |
@RequiredArgsConstructor |
||||
public class PullGroupMessageTask extends AbstractPullMessageTask { |
@RedisMQListener(queue = IMRedisKey.IM_MESSAGE_GROUP_QUEUE, batchSize = 10) |
||||
|
public class PullGroupMessageTask extends AbstractPullMessageTask<IMRecvInfo> { |
||||
private final RedisTemplate<String, Object> redisTemplate; |
|
||||
|
|
||||
@Override |
@Override |
||||
public void pullMessage() { |
public void onMessage(IMRecvInfo recvInfo) { |
||||
// 从redis拉取消息
|
AbstractMessageProcessor processor = ProcessorFactory.createProcessor(IMCmdType.GROUP_MESSAGE); |
||||
String key = String.join(":", IMRedisKey.IM_MESSAGE_GROUP_QUEUE, IMServerGroup.serverId + ""); |
processor.process(recvInfo); |
||||
JSONObject jsonObject = (JSONObject) redisTemplate.opsForList().leftPop(key); |
|
||||
while (!Objects.isNull(jsonObject)) { |
|
||||
IMRecvInfo recvInfo = jsonObject.toJavaObject(IMRecvInfo.class); |
|
||||
AbstractMessageProcessor processor = ProcessorFactory.createProcessor(IMCmdType.GROUP_MESSAGE); |
|
||||
processor.process(recvInfo); |
|
||||
// 下一条消息
|
|
||||
jsonObject = (JSONObject) redisTemplate.opsForList().leftPop(key); |
|
||||
} |
|
||||
} |
} |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,37 +1,25 @@ |
|||||
package com.bx.imserver.task; |
package com.bx.imserver.task; |
||||
|
|
||||
import com.alibaba.fastjson.JSONObject; |
|
||||
import com.bx.imcommon.contant.IMRedisKey; |
import com.bx.imcommon.contant.IMRedisKey; |
||||
import com.bx.imcommon.enums.IMCmdType; |
import com.bx.imcommon.enums.IMCmdType; |
||||
import com.bx.imcommon.model.IMRecvInfo; |
import com.bx.imcommon.model.IMRecvInfo; |
||||
import com.bx.imserver.netty.IMServerGroup; |
import com.bx.imcommon.mq.RedisMQListener; |
||||
import com.bx.imserver.netty.processor.AbstractMessageProcessor; |
import com.bx.imserver.netty.processor.AbstractMessageProcessor; |
||||
import com.bx.imserver.netty.processor.ProcessorFactory; |
import com.bx.imserver.netty.processor.ProcessorFactory; |
||||
import lombok.RequiredArgsConstructor; |
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.data.redis.core.RedisTemplate; |
|
||||
import org.springframework.stereotype.Component; |
import org.springframework.stereotype.Component; |
||||
|
|
||||
import java.util.Objects; |
|
||||
|
|
||||
@Slf4j |
@Slf4j |
||||
@Component |
@Component |
||||
@RequiredArgsConstructor |
@RequiredArgsConstructor |
||||
public class PullPrivateMessageTask extends AbstractPullMessageTask { |
@RedisMQListener(queue = IMRedisKey.IM_MESSAGE_PRIVATE_QUEUE, batchSize = 10) |
||||
|
public class PullPrivateMessageTask extends AbstractPullMessageTask<IMRecvInfo> { |
||||
private final RedisTemplate<String, Object> redisTemplate; |
|
||||
|
|
||||
@Override |
@Override |
||||
public void pullMessage() { |
public void onMessage(IMRecvInfo recvInfo) { |
||||
// 从redis拉取消息
|
AbstractMessageProcessor processor = ProcessorFactory.createProcessor(IMCmdType.PRIVATE_MESSAGE); |
||||
String key = String.join(":", IMRedisKey.IM_MESSAGE_PRIVATE_QUEUE, IMServerGroup.serverId + ""); |
processor.process(recvInfo); |
||||
JSONObject jsonObject = (JSONObject) redisTemplate.opsForList().leftPop(key); |
|
||||
while (!Objects.isNull(jsonObject)) { |
|
||||
IMRecvInfo recvInfo = jsonObject.toJavaObject(IMRecvInfo.class); |
|
||||
AbstractMessageProcessor processor = ProcessorFactory.createProcessor(IMCmdType.PRIVATE_MESSAGE); |
|
||||
processor.process(recvInfo); |
|
||||
// 下一条消息
|
|
||||
jsonObject = (JSONObject) redisTemplate.opsForList().leftPop(key); |
|
||||
} |
|
||||
} |
} |
||||
|
|
||||
} |
} |
||||
|
|||||
Loading…
Reference in new issue