Как я обрабатываю отказ сообщения в привязке MSMQ для WCF

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

17
задан abatishchev 28 May 2012 в 10:03
поделиться

4 ответа

Существует образец в SDK, который мог бы быть полезным в Вашем случае. В основном то, что это делает, присоединить реализацию IErrorHandler к Вашему сервису, который зафиксирует ошибку, когда WCF объявит, что сообщение "яд" (т.е. когда все настроенные повторения были исчерпаны). То, что делает образец, переместить сообщение к другой очереди и затем перезапустить ServiceHost, связанный с сообщением (так как это даст сбой, когда подозрительное сообщение было найдено).

Это не очень симпатичный образец, но это может быть полезно. Существует несколько ограничений, хотя:

1-, Если у Вас есть несколько конечных точек, связанных с Вашим сервисом (т.е. представленный через несколько очередей), нет никакого способа знать, которые ставят в очередь подозрительное сообщение, прибывшее в. Если у Вас только будет единственная очередь, это не будет проблемой. Я не видел официального обходного решения для этого, но я экспериментировал с одной возможной альтернативой, которую я зарегистрировал здесь: http://winterdom.com/weblog/2008/05/27/NetMSMQAndPoisonMessages.aspx

2-Однажды проблемное сообщение перемещен к другой очереди, это становится Вашей ответственностью, так Вам решать для положения обратно его очереди обработки, как только тайм-аут сделан (или присоедините новый сервис для той очереди обработать его).

Честно говоря, в любом случае, Вы смотрите на некоторую "ручную" работу здесь, что WCF просто не покрывает на своем собственном.

я недавно работал над различным проектом, где у меня есть требование для явного управления, как часто повторения происходят, и мое текущее решение состояло в том, чтобы создать ряд очередей повторной попытки и вручную переместить сообщения между очередями повторной попытки и основной очередью обработки на основе ряда таймеров и некоторой эвристики, просто с помощью необработанной Системы. Обмен сообщениями материала для обработки очередей MSMQ. Это, кажется, работает довольно приятно, хотя существует несколько глюков, если Вы идете этим путем.

9
ответ дан 30 November 2019 в 12:51
поделиться

Я думаю с MSMQ (avaiable только на Vista), Вы могли бы быть в состоянии, чтобы сделать как это:

<bindings>
    <netMsmqBinding>
        <binding name="PosionMessageHandling"
             receiveRetryCount="3"
             retryCycleDelay="00:05:00"
             maxRetryCycles="3"
             receiveErrorHandling="Move" />
    </netMsmqBinding>
</bindings>

WCF сразу повторит в течение времен ReceiveRetryCount после первого сбоя вызова. После того, как пакет перестал работать, сообщение перемещено к очереди повторной попытки. После задержки минуты RetryCycleDelay повторено сообщение, перемещенное от очереди повторной попытки к очереди конечной точки и пакету. Это будет повторенным временем MaxRetryCycle. Если все, что приводит сообщение к сбою, обрабатывается согласно receiveErrorHandling, который может быть перемещением (для отравления очереди), отклонение, отбрасывание или отказ

хороший текст о WCF, и MSMQ является главой 9 книги Progammig WCF от Juval Lowy

14
ответ дан 30 November 2019 в 12:51
поделиться

При использовании SQL Server тогда, необходимо использовать распределенную транзакцию, и начиная с MSMQ и начиная с ПОДДЕРЖКИ SQL SERVER он. То, что происходит, является Вами, обертывают Вашу запись базы данных в блок TransactionScope и объем вызова. Завершенный (), только если это успешно выполняется. Если это перестанет работать, то, когда Ваш метод WCF возвращается, сообщение будет помещено назад в очередь, чтобы быть попробованным еще раз. Вот обрезанная версия кода, который я использую:

    [OperationBehavior(TransactionScopeRequired=true, TransactionAutoComplete=true)]
    public void InsertRecord(RecordType record)
    {
        try
        {
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
            {
                SqlConnection InsertConnection = new SqlConnection(ConnectionString);
                InsertConnection.Open();

                // Insert statements go here

                InsertConnection.Close();

                // Vote to commit the transaction if there were no failures
                scope.Complete();
            }
        }
        catch (Exception ex)
        {
            logger.WarnException(string.Format("Distributed transaction failure for {0}", 
                Transaction.Current.TransactionInformation.DistributedIdentifier.ToString()),
                ex);
        }
     }

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

у менеджера по Распределенной транзакции есть окружающее присутствие, и когда Вы создаете новый экземпляр TransactionScope, он автоматически ищет текущую транзакцию в рамках вызова метода - который уже должен был быть создан WCF, когда он вытолкал сообщение от очереди и вызвал Ваш метод.

4
ответ дан 30 November 2019 в 12:51
поделиться

К сожалению, я застреваю на Windows XP и Windows Server 2003 так, чтобы не была опция для меня. - (Я повторно разъясню, что в моем вопросе, поскольку нашел это решение после регистрации и понял, что я не мог использовать его)

я нашел, что одно решение состояло в том, чтобы установить пользовательский обработчик, который перейдет мое сообщение на другую очередь или отравит очередь и перезапустит мой сервис. Это казалось сумасшедшим мне. Предположите, что мой SQL-сервер снизился, как часто сервис будет перезапущен.

ПОЭТОМУ то, что я закончил тем, что делал, позволяет Строке давать сбой и оставлять сообщения на очереди. Я также регистрирую фатальное сообщение к своему системному сервису входа, что это произошло. Как только наш вопрос решен, я перезапускаю сервис, и все сообщения начинают обрабатываться снова.

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

aogan, у Вас был идеальный ответ для MSMQ 4.0, но к сожалению не для меня

1
ответ дан 30 November 2019 в 12:51
поделиться
Другие вопросы по тегам:

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