Как сделать сбор статистики в MDBs на современном уровне? - PullRequest
2 голосов
/ 10 января 2012

У меня есть несколько MDB (и множество экземпляров mdb) в качестве потребителей сообщений. Я должен собрать определенную статистику внутри этих Бинов и отправлять их каждые X (в настоящее время 30) секунд в место назначения JMS.

Можно ли делать это в самом бине?

например: бин собирает данные локально и имеет метод writeStatistic (), который использует аннотацию @Scheduled.

Можно ли централизовать статистику?

центральный компонент собирает все статистические данные из всех экземпляров компонента и отправляет их. Если это возможно, как это можно сделать?

EDIT

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

@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
@Asynchronous
public class StatisticsCollector {

    private ConcurrentMap<Integer, ConcurrentMap<String, AtomicInteger>> statistics = new ConcurrentHashMap<Integer, ConcurrentMap<String, AtomicInteger>>();

    public void trackDatum(int projectId, String property, int increment) {
        LOG.debug("Tracking datum: project: " + projectId + ", property: " + property + ", increment: " + increment);

        // get statistics for project
        ConcurrentMap<String, AtomicInteger> productstats;
        if (!statistics.containsKey(projectId)) {
            synchronized (statistics) {
                if (!statistics.containsKey(projectId)) {
                    productstats = new ConcurrentHashMap<String, AtomicInteger>();
                    statistics.put(projectId, productstats);
                } else {
                    productstats = statistics.get(projectId);
                }
            }
        } else {
            productstats = statistics.get(projectId);
        }

        // get current counter for property
        AtomicInteger value;
        if (!productstats.containsKey(property)) {
            synchronized (productstats) {
                if (!productstats.containsKey(property)) {
                    value = new AtomicInteger();
                    productstats.put(property, value);
                } else {
                    value = productstats.get(property);
                }
            }
        } else {
            value = productstats.get(property);
        }

        // increment
        value.addAndGet(increment);
    }

    @Schedule(minute = "*", hour = "*", second = "*/30", persistent = false)
    public void sendStatistics() {
        // send statistics to remote consumer via JMS
    }
}

Я сам управлял параллелизмом, так как хотел получить как можно больше производительности от компонента.

1 Ответ

2 голосов
/ 10 января 2012

Можно ли делать это в самом бине?

Полагаю, вы имеете в виду следующее:

@MessageDriven(...)
public MDBean implements MessageListener {
     private Statistic statisticForThisBean;
     // ...

     @Timeout
     public void sendStatisticForThisBean() {
         // ...
     }
}

Это, конечно, не вариант .Нет никакой гарантии, что метод, помеченный @Timeout, будет работать для всех экземпляров компонента на всех , не говоря уже о том, что вы должны запускаться каждые 30 секунд.Метод тайм-аута запускается на одном из свободных экземпляров MDB, и контейнер выбирает его.

Можно ли централизовать статистику?

Лично ясделать это следующим образом: все MDB (все экземпляры) отправляют частичную статистику в очередь в конце своей логики обработки.Я бы написал отдельный компонент, который бы:

  • существовал только в одном экземпляре,
  • собирал все сообщения из очереди статистики в течение 30 секунд (в цикле), создавая сводкузатем отправьте его в конечный пункт назначения, а затем перезапустите.

«Компонентом» может быть задача таймера или отдельное автономное приложение.

Другим возможным решением может бытьодин бин с отслеживанием состояния, который MDB по очереди будут вызывать для обновления статистики.Однако применяются следующие ограничения:

  • это может вызвать проблемы с производительностью, если только вызовы методов SFSB не являются быстрыми (т. Е. Когда статистика не сложна),
  • это не может бытьработать асинхронно, поэтому вы не можете гарантировать 30-секундный интервал между вызовами в механизм сбора статистики;если JMS-трафик полностью останавливается, SFSB тоже перестает отвечать.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...