线程VS RabbitMQ工作者资源消耗

时间:2015-07-14 12:31:31

标签: java multithreading rabbitmq worker

我正在使用JAVA ExecutorService线程发送亚马逊电子邮件,这有助于我通过API与AmazonSES建立并发连接并以闪电般的速度发送邮件。所以亚马逊在一秒钟内接受了一些连接,所以对我来说,它在一秒钟内就有50个请求。所以我每秒执行50个线程,每天发送大约100万封电子邮件。

这工作得很好,但现在邮件的数量会增加。而且我不想在RAM和处理器上投入更多资金。

我的一位朋友建议我使用RabbitMQ Workers而不是线程,所以我将有50名工作人员来代替50个线程。

所以在更改一些代码来测试资源管理之前,我只是想知道消费会有什么巨大差异吗?因此,当我执行我的线程时,JAVA消耗了20-30%的内存。所以,如果我使用工人,它会是低还是高?

或者他们对此有任何替代选择吗? 这是我的线程邮件发送功能:

@Override
public void run() {
    Destination destination = new Destination().withToAddresses(new String[] { this.TO });
    Content subject = new Content().withData(SUBJECT);
    Content textBody = new Content().withData(BODY);
    Body body = new Body().withHtml(textBody);
    Message message = new Message().withSubject(subject).withBody(body);
    SendEmailRequest request = new SendEmailRequest().withSource(FROM).withDestination(destination).withMessage(message);
    Connection connection = new Connection();
    java.util.Date dt = new java.util.Date();
    java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String insert = "";
    try {
        System.out.println("Attempting to send an email to " + this.TO);

        ctr++;
        client.sendEmail(request);
        insert = "INSERT INTO email_histories (campaign_id,contact_id,group_id,is_opened,mail_sent_at,mail_opened_at,ip_address,created_at,updated_at,is_sent) VALUES (" + this.campaign_id + ", " + this.contact_id + ", " + this.group_id + ", false, '" + sdf.format(dt) + "', null, null, '" + sdf.format(dt) + "', '" + sdf.format(dt) + "', true);";
        connection.insert(insert);
        System.out.println("Email sent! to " + this.TO);
    } catch (Exception ex) {
        System.out.println("The email was not sent.");
        System.out.println("Error message: " + ex.getMessage());
    }

}

2 个答案:

答案 0 :(得分:0)

我没有使用RabbitMQ的经验,因此我不得不留下让其他人回答。

  

或者他们是否有其他选择?

不是每个邮件使用一个线程,而是将该代码移动到可运行的内容中。添加共享Timer,其中包含许可数=您希望每秒发送的邮件数。每封邮件获得一个许可,每秒从另一个帖子重新填写许可(即单独的SchedledExecutorService$scope.posts = []; [ { title: ..., content: ... }, { title: ..., content: ... }, { title: ..., content: ... }, ].foreEach(function(post) { $scope.posts.push(new Posts(post)); }); )。然后将Executor线程池大小调整为服务器可以处理的任何内容。

答案 1 :(得分:0)

从RabbitMQ的角度来看,消耗了少量的内存和网络资源,尽管每个连接都是不变的。如果您使用工作线程池来读取RabbitMQ队列或队列,则可能会节省一些资源,因为您不是垃圾收集单个线程。就替代方案而言,我会在任何情况下使用线程池。虽然可能对你的使用太重了,Spring Framework有一个我以前用过的非常好的线程池。