Динамично создающие асинхронные очереди сообщений в Java

Я только что нашел , ZiYa производит некоторые действительно сексуальные диаграммы и является конкретными направляющими.

оборотные стороны, это использует Flash и если Вы не хотите, чтобы сайты связались со страницей XML/SWF, это стоит 50$ за сайт.

[я еще не выбрал его, но хотел бросить его там в случае, если люди хотят проголосовать за него]

7
задан Fionnuala 16 December 2009 в 12:41
поделиться

5 ответов

Я согласен с Адамом, вариант использования звучит так, как будто JMS накладные расходы. Достаточно встроенной функциональности Java:

package de.mhaller;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;

import org.junit.Assert;
import org.junit.Test;

public class Mailer {

    @Test
    public void testMailer() throws Exception {
        ExecutorService executor = Executors.newCachedThreadPool();
        ArrayList<Mail> log = new ArrayList<Mail>();
        LinkedBlockingDeque<Mail> incoming = new LinkedBlockingDeque<Mail>();

        // TODO: Put mails to be sent into the incoming queue
        incoming.offer(new Mail("foo1@localhost", "localhost"));
        incoming.offer(new Mail("foo2@otherhost", "otherhost"));
        incoming.offer(new Mail("foo3@otherhost", "otherhost"));
        incoming.offer(new Mail("foo4@localhost", "localhost"));

        Map<Mailserver, Queue<Mail>> queues = new HashMap<Mailserver, Queue<Mail>>();
        while (!incoming.isEmpty()) {
            Mail mail = incoming.pollFirst();
            Mailserver mailserver = findMailserver(mail);
            if (!queues.containsKey(mailserver)) {
                ArrayDeque<Mail> serverQueue = new ArrayDeque<Mail>();
                queues.put(mailserver, serverQueue);
                executor.execute(new SendMail(mailserver, serverQueue));
            }
            Queue<Mail> slot = queues.get(mailserver);
            slot.offer(mail);
        }

        assertMailSentWithCorrectServer(log);
    }

    private void assertMailSentWithCorrectServer(ArrayList<Mail> log) {
        for (Mail mail : log) {
            if (!mail.server.equals(mail.sentBy.mailserver)) {
                Assert.fail("Mail sent by wrong server: " + mail);
            }
        }
    }

    private Mailserver findMailserver(Mail mail) {
        // TODO: Your lookup logic which server to use
        return new Mailserver(mail.server);
    }

    private static class Mail {
        String recipient;
        String server;
        SendMail sentBy;

        public Mail(String recipient, String server) {
            this.recipient = recipient;
            this.server = server;
        }

        @Override
        public String toString() {
            return "mail for " + recipient;
        }
    }

    public static class SendMail implements Runnable {

        private final Deque<Mail> queue;
        private final Mailserver mailserver;

        public SendMail(Mailserver mailserver, Deque<Mail> queue) {
            this.mailserver = mailserver;
            this.queue = queue;
        }

        @Override
        public void run() {
            while (!queue.isEmpty()) {
                Mail mail = queue.pollFirst();
                // TODO: Use SMTP to send the mail via mailserver
                System.out.println(this + " sent " + mail + " via " + mailserver);
                mail.sentBy = this;
            }
        }

    }

    public static class Mailserver {
        String hostname;

        public Mailserver(String hostname) {
            this.hostname = hostname;
        }

        @Override
        public String toString() {
            return hostname;
        }

        @Override
        public int hashCode() {
            return hostname.hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            return hostname.equals(((Mailserver) obj).hostname);
        }

    }

}
6
ответ дан 7 December 2019 в 05:25
поделиться

Сам JMS как спецификация довольно умалчивает об этой проблеме. Большинство реализаций позволяют делать это, но не через сам JMS, а с помощью собственного API. Но вы не сможете подключить к динамической очереди что-то формальное, например MDB. Скорее вам нужно будет управлять своими собственными подключениями и слушателями.

1
ответ дан 7 December 2019 в 05:25
поделиться

В последний раз, когда мы рассматривали это в среде WebSphere, было на удивление сложно / невозможно создавать очереди динамически (временные очереди, я думаю, для вас слишком временны). Хотя API-интерфейсы для создания очередей существовали, они требовали перезапуска сервера впоследствии, чтобы стать активными. Затем упоминается проблема MDB.

Как насчет грязного обходного пути, основанного на пословице, что все проблемы могут быть решены с помощью дополнительного уровня косвенного обращения, который предполагает, что набор доступных принтеров сравнительно невелик.

Создайте очереди от Printer01 до Printer99 (или какое-то меньшее число). Имейте «базу данных», которая сопоставляет очереди с реальными принтерами. По мере поступления запросов на принтеры вы можете добавлять их в таблицу сопоставления. У вас могут быть некоторые накладные расходы на MDB, просматривающие очереди, которые никогда не будут использоваться,

1
ответ дан 7 December 2019 в 05:25
поделиться

Редактировать: Упс, упустил простую вещь из-за глупости. Это решение неверно, хотя я сохраняю его здесь, поскольку оно все еще является средним (n + log (n)). Спасибо ShreevatsaR за указание на мою глупость. Я рассматривал поиск по дереву, но совершенно упустил идею поиска с возвратом второго по величине числа в log (n).

В любом случае, здесь следует мое доказательство того, почему низший алгоритм не больше, чем avg (n + log ( п)). В реальной жизни он должен, по крайней мере, работать довольно хорошо.

  • Сначала сравните со вторым по величине зарегистрированным числом.
  • Только если это сравнение окажется успешным, сравните с наибольшим зарегистрированным числом.

Чтобы доказать, что это среднее число. n + log n, нам просто нужно доказать, что первое сравнение в среднем выполняется только log (n) раз.

0
ответ дан 7 December 2019 в 05:25
поделиться

Я проделал это с помощью activemq - я фактически разместил вопрос по этому поводу в то время, так как у меня были аналогичные проблемы (документация JMS в то время говорила, что это не поддерживается) и было заверил, что его поддержали.

0
ответ дан 7 December 2019 в 05:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: