Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 每分钟发送35000条jms消息_Java_Scheduled Tasks_Spring Jms_Scheduledexecutorservice - Fatal编程技术网

Java 每分钟发送35000条jms消息

Java 每分钟发送35000条jms消息,java,scheduled-tasks,spring-jms,scheduledexecutorservice,Java,Scheduled Tasks,Spring Jms,Scheduledexecutorservice,我们有一个spring引导应用程序,用于在另一个组件上执行负载测试。我们需要每分钟最多发送35000条JMS消息,因此我使用调度器每分钟运行一次任务 问题是,当我保持低强度时,它会设法在指定的时间间隔(一分钟)内发送消息。但是,当强度较高时,发送这段消息需要1分钟以上的时间。对以下实施有何建议 调度程序类 @Component public class MessageScheduler { private final Logger log = LoggerFactory.getLogger(g

我们有一个spring引导应用程序,用于在另一个组件上执行负载测试。我们需要每分钟最多发送35000条JMS消息,因此我使用调度器每分钟运行一次任务

问题是,当我保持低强度时,它会设法在指定的时间间隔(一分钟)内发送消息。但是,当强度较高时,发送这段消息需要1分钟以上的时间。对以下实施有何建议

调度程序类

@Component
public class MessageScheduler {

private final Logger log = LoggerFactory.getLogger(getClass());
private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(16);
private final static int TIME_PERIOD = ConfigFactory.getConfig().getInt("messages.period").orElse(60000);

@Autowired
JmsSender sender;

    public void startScheduler() {
       Runnable runnableTask = sender::sendMessagesChunk;
       executorService.scheduleAtFixedRate(runnableTask, 0, TIME_PERIOD, 
       TimeUnit.MILLISECONDS);
    }
}
@Component
public class JmsSender {

@Autowired
TrackingManager manager;

private final Logger log = LoggerFactory.getLogger(getClass());
private final static int TOTAL_MESSAGES = ConfigFactory.getConfig().getInt("total.tracking.messages").orElse(10);
private final static int TIME_PERIOD = ConfigFactory.getConfig().getInt("messages.period").orElse(60000);
private static int failedPerPeriod=0;
private static int totalFailed=0;
private static int totalMessageCounter=0;

public void sendMessagesChunk() {
    log.info("Started  at: {}", Instant.now());
    log.info("Sending messages with intensity {} messages/minute", TOTAL_MESSAGES);
    for (int i=0; i<TOTAL_MESSAGES; i++) {
        try {
            long start = System.currentTimeMillis();
            MessageDTO msg = manager.createMessage();
            send(msg);
            long stop = System.currentTimeMillis();
            if (timeOfDelay(stop-start)>=0L) {
                Thread.sleep(timeOfDelay(stop-start));
            }
        } catch (Exception e) {
            log.info("Error :  " + e.getMessage());
            failedPerPeriod++;
        }
    }
    totalMessageCounter += TOTAL_MESSAGES;
    totalFailed += failedPerPeriod;
    log.info("Finished  at: {}", Instant.now());
    log.info("Success rate(of last minute): {} %, Succeeded: {}, Failed: {}, Success rate(in total): {} %, Succeeded: {}, Failed: {}"
            ,getSuccessRatePerPeriod(), getSuccededPerPeriod(), failedPerPeriod,
            getTotalSuccessRate(), getTotalSucceded(), totalFailed);
    failedPerPeriod =0;
}

private long timeOfDelay(Long elapsedTime){
    return (TIME_PERIOD / TOTAL_MESSAGES) - elapsedTime;
}
private int getSuccededPerPeriod(){
    return TOTAL_MESSAGES - failedPerPeriod;
}

private int getTotalSucceded(){
    return totalMessageCounter - totalFailed;
}

private double getSuccessRatePerPeriod(){
    return getSuccededPerPeriod()*100D / TOTAL_MESSAGES;
}

private double getTotalSuccessRate(){
    return getTotalSucceded()*100D / totalMessageCounter;
}

private void send(MessageDTO messageDTO) throws Exception {
    requestContextInitializator();
    JmsClient client = JmsClientBuilder.newClient(UriScheme.JmsType.AMQ);
    client.target(new URI("activemq:queue:" + messageDTO.getDestination()))
            .msgTypeVersion(messageDTO.getMsgType(), messageDTO.getVersion())
            .header(Header.MSG_VERSION, messageDTO.getVersion())
            .header(Header.MSG_TYPE, messageDTO.getMsgType())
            .header(Header.TRACKING_ID, UUID.randomUUID().toString())
            .header(Header.CLIENT_ID, "TrackingJmsClient")
            .post(messageDTO.getPayload());
}
用于发送消息的类

@Component
public class MessageScheduler {

private final Logger log = LoggerFactory.getLogger(getClass());
private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(16);
private final static int TIME_PERIOD = ConfigFactory.getConfig().getInt("messages.period").orElse(60000);

@Autowired
JmsSender sender;

    public void startScheduler() {
       Runnable runnableTask = sender::sendMessagesChunk;
       executorService.scheduleAtFixedRate(runnableTask, 0, TIME_PERIOD, 
       TimeUnit.MILLISECONDS);
    }
}
@Component
public class JmsSender {

@Autowired
TrackingManager manager;

private final Logger log = LoggerFactory.getLogger(getClass());
private final static int TOTAL_MESSAGES = ConfigFactory.getConfig().getInt("total.tracking.messages").orElse(10);
private final static int TIME_PERIOD = ConfigFactory.getConfig().getInt("messages.period").orElse(60000);
private static int failedPerPeriod=0;
private static int totalFailed=0;
private static int totalMessageCounter=0;

public void sendMessagesChunk() {
    log.info("Started  at: {}", Instant.now());
    log.info("Sending messages with intensity {} messages/minute", TOTAL_MESSAGES);
    for (int i=0; i<TOTAL_MESSAGES; i++) {
        try {
            long start = System.currentTimeMillis();
            MessageDTO msg = manager.createMessage();
            send(msg);
            long stop = System.currentTimeMillis();
            if (timeOfDelay(stop-start)>=0L) {
                Thread.sleep(timeOfDelay(stop-start));
            }
        } catch (Exception e) {
            log.info("Error :  " + e.getMessage());
            failedPerPeriod++;
        }
    }
    totalMessageCounter += TOTAL_MESSAGES;
    totalFailed += failedPerPeriod;
    log.info("Finished  at: {}", Instant.now());
    log.info("Success rate(of last minute): {} %, Succeeded: {}, Failed: {}, Success rate(in total): {} %, Succeeded: {}, Failed: {}"
            ,getSuccessRatePerPeriod(), getSuccededPerPeriod(), failedPerPeriod,
            getTotalSuccessRate(), getTotalSucceded(), totalFailed);
    failedPerPeriod =0;
}

private long timeOfDelay(Long elapsedTime){
    return (TIME_PERIOD / TOTAL_MESSAGES) - elapsedTime;
}
private int getSuccededPerPeriod(){
    return TOTAL_MESSAGES - failedPerPeriod;
}

private int getTotalSucceded(){
    return totalMessageCounter - totalFailed;
}

private double getSuccessRatePerPeriod(){
    return getSuccededPerPeriod()*100D / TOTAL_MESSAGES;
}

private double getTotalSuccessRate(){
    return getTotalSucceded()*100D / totalMessageCounter;
}

private void send(MessageDTO messageDTO) throws Exception {
    requestContextInitializator();
    JmsClient client = JmsClientBuilder.newClient(UriScheme.JmsType.AMQ);
    client.target(new URI("activemq:queue:" + messageDTO.getDestination()))
            .msgTypeVersion(messageDTO.getMsgType(), messageDTO.getVersion())
            .header(Header.MSG_VERSION, messageDTO.getVersion())
            .header(Header.MSG_TYPE, messageDTO.getMsgType())
            .header(Header.TRACKING_ID, UUID.randomUUID().toString())
            .header(Header.CLIENT_ID, "TrackingJmsClient")
            .post(messageDTO.getPayload());
}
@组件
公共类JmsSender{
@自动连线
跟踪经理;
私有最终记录器log=LoggerFactory.getLogger(getClass());
private final static int TOTAL_MESSAGES=ConfigFactory.getConfig().getInt(“TOTAL.tracking.MESSAGES”).orElse(10);
private final static int TIME_PERIOD=ConfigFactory.getConfig().getInt(“messages.PERIOD”).orElse(60000);
私有静态int failedperperperperperperperiod=0;
私有静态int totalFailed=0;
私有静态int totalMessageCounter=0;
public void sendMessagesChunk(){
log.info(“开始于:{}”,Instant.now());
log.info(“发送强度为{}条消息/分钟的消息”,消息总数);
用于(int i=0;i=0L){
休眠(延迟时间(停止-启动));
}
}捕获(例外e){
log.info(“错误:+e.getMessage());
失败的perperperiod++;
}
}
totalMessageCounter+=消息总数;
totalFailed+=每个周期的失败次数;
log.info(“完成于:{}”,Instant.now());
log.info(“成功率(最后一分钟):{}%,成功:{},失败:{},成功率(总计):{}%,成功:{},失败:{}”
,GetSuccessRatePerPerPerPerPerPerPeriod(),GetSuccessedPerPerPerPerPerPeriod(),FailedPerPerPerPeriod,
getTotalSuccessRate()、GetTotalSuccessed()、totalFailed);
failedperperperperiod=0;
}
私人长延时(长延时){
返回(时间段/总消息)-elapsedTime;
}
private int getSucceedPerPerPerPerPerPerPeriod()函数{
返回总_消息-每个周期失败;
}
private int getTotalSuccedd(){
返回totalMessageCounter-totalFailed;
}
私有双GetSuccessRatePerPerPerPerPerPerPerPerPerPerPerPeriod(){
返回GetSucceedPerPerperiod()*100D/总消息数;
}
私有双getTotalSuccessRate(){
返回GetTotalSuccedd()*100D/totalMessageCounter;
}
私有void发送(MessageDTO MessageDTO)引发异常{
requestContextInitializator();
jmsclientclient=JmsClientBuilder.newClient(UriScheme.JmsType.AMQ);
target(新URI(“activemq:queue:+messageDTO.getDestination()))
.msgTypeVersion(messageDTO.getMsgType(),messageDTO.getVersion())
.header(header.MSG_VERSION,messageDTO.getVersion())
.header(header.MSG_TYPE,messageDTO.getMsgType())
.header(header.TRACKING\u ID,UUID.randomUUID().toString())
.header(header.CLIENT_ID,“TrackingJmsClient”)
.post(messageDTO.getPayload());
}

您应该解决两个问题:

  • 总发送操作时间必须低于最大时间
  • 消息不应尽可能快地发送,而是应在所有可用时间内统一发送
  • 显然,如果
    send
    方法太慢,将超过最大时间

    发送消息的更快方法是使用某种批量操作。如果你的MQ API不支持批量操作,你就不能使用它!由于第二个限制(“一致”)

    您可以异步发送消息,但如果您的MQ API为此创建线程而不是“非阻塞”异步,则可能会出现内存问题

    使用
    javax.jms.MessageProducer.send
    可以异步发送消息,但会为每个消息创建一个新的线程(将创建大量内存和服务器线程)

    另一个加速可能是只创建一个JMS客户机(您的
    send
    方法)

    要实现第二个要求,您应该修复
    timeOfDelay
    函数,它是错误的。实际上,您应该考虑
    send
    函数的概率分布来估计适当的值,但是,您可以简单地执行以下操作:

    long acktime=0L;
    
    对于(int i=0;iIDK关于Spring的任何内容,但似乎在send方法中不断创建JmsClient可能会导致性能问题?感谢您的评论!我肯定只需要实例化一次jms客户端…感谢您的回复!不幸的是,我的MQ API不支持批量操作。现在我在timeOfDelay方法中看到了错误..我不会请尝试执行您的建议并再次检查。我有一个问题。我想如果accTime>TIME\u PERIOD在这段时间内我应该停止发送更多消息…对吗?@DimitrisBaltas批量操作并不重要。停止发送取决于什么更重要,发送所有消息或不使用更多时间。