Обсуждение окончательного решения Spring Cloud Distributed Transaction

Spring Boot Java

Введение

В этой программе есть лекции по:Лекциядобро пожаловать зрители

Конференция Alibaba 2017 Yunqi "Решайте мировые технические проблемы! GTS делает распределенные транзакции простыми и эффективными", Али утверждал, что предложил крэквсемирная проблемаОкончательное решение для распределенных транзакций, надежность и скорость обработки которого опережают все технологии на рынке. Но, к сожалению, проектНе с открытым исходным кодом, а во-вторых, необходимоДоверьтесь облаку Alibabaраспределенная база данных. после всего,Парень, который ест, не может легко показать людям.

Тем не менее, статья «Мировые проблемы...» довольно хорошо резюмирует транзакции: «Кажется простой функцией может потребоваться вызов нескольких «сервисов» и работа с несколькими базами данных или сегментами для достижения этой цели. Единое техническое средство и решение больше не могут чтобы соответствовать этим сложным сценариям приложений, поэтому распределенные транзакции в архитектуре распределенной системы представляют собой неизбежную проблему.

Что такое распределенная транзакция? Проще говоря, большая операция состоит из разных мелких операций.Распределенные по разным серверам распределенные транзакции должны гарантировать, что эти небольшие операции либо все завершатся успешно, либо все завершатся неудачно.. "

Возьмите каштан:

Когда вы покупаете что-то на Таобао, вам нужно сначала вычесть деньги, а затем товарный запас будет равен -1. Однако вычет и инвентаризация относятся к двум службам соответственно. Эти две службы должны пройти через ряд промежуточных уровней, таких как сеть, шлюз и хост. это приведет к несоответствию. Например, если вычет успешен, но инвентарь не равен -1, будет явление перепроданности, и это проблема, которую необходимо решить распределенным транзакциям.

Два двухэтапных коммита (2PC, 3PC и т. д.)

Двухфазная фиксация — это традиционное решение для распределенных транзакций, и оно широко доступно до тех пор, пока не будет расширено. Когда транзакция охватывает несколько узлов, чтобы сохранить транзакциюACIDфункция, вам необходимо ввестикоординаторЧтобы единообразно контролировать результаты операций всех узлов (называемых участниками) и, наконец, инструктировать эти узлы, действительно ли отправлять результаты операций (например, запись обновленных данных на диск и т. д.). Таким образом, идею алгоритма двухэтапной подачи можно резюмировать так:участникУведомить координатора об успехе или неудаче операции, а затем координатор решает, должен ли каждый участник отправить операцию или прервать операцию, на основе информации обратной связи всех участников.

Возьмем встречу в качестве примера

A, B, D и Дин хотят организовать встречу, и им нужно определить время встречи Пусть A будет координатором, а B, B, Дин и Дин — участниками.

стадия голосования

  1. А отправляет электронное письмо Бинг Дину, есть ли время для встречи в 20:00 на этой неделе?
  2. У А есть время ответить;
  3. B успевает ответить;
  4. C долго не отвечает, в это время для этой активности и A, и B, и C находятся в состоянии блокировки, и алгоритм не может продолжаться;
  5. C имеет время (или нет времени) ответить;

этап фиксации

  1. Координатор A возвращает собранные результаты E-B-D (когда и какие результаты обратной связи, в данном случае зависит от времени и решения C-C);
  2. Б получил;
  3. С получено;
  4. Дин получил;

Нужно не только блокировать все ресурсы участников, но и ресурсы координатора, что дорого. Резюме одного предложения: 2PC очень неэффективен и недружелюбен к высокому параллелизму.

Цитировать《世界性难题...》Оригинальные слова статьи «Для коммерческих продуктов распределенных транзакций, основанных на модели XA с многолетней историей и накоплением технологий за рубежом, при одинаковых программно-аппаратных условиях пропускная способность часто падает на порядки после включения распределенной транзакции. "

Кроме того, существуют трехэтапные коммиты.

Кому интересно, может учиться

Три гибких дела

так называемыйгибкие делаЭто связано с жесткой транзакцией, которая обеспечивает блокировку таблицы. Процесс выглядит следующим образом: если транзакция сервера A выполняется гладко, то первой будет отправлена ​​транзакция A. Если транзакция B также выполнена успешно, то транзакция B также будет отправлена, и вся транзакция будет завершена. Однако, если транзакция B не выполняется, откатывается сама транзакция B. В это время транзакция A была зафиксирована, поэтому необходимо выполнить компенсационную операцию, чтобы отменить операцию, выполненную транзакцией A, которая была зафиксирована, и восстановить состояние транзакции А до того, как она не была выполнена.

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

Решение для обеспечения согласованности четырех сообщений RocketMQ

В настоящее время решения, основанные на очередях сообщений, включают в себя AliRocketMQ, он достигает半消息решение, чем-то похожее наАлгоритм Паксос, конкретный процесс выглядит следующим образом

Первый этап: вышестоящее приложение выполняет бизнес и отправляет сообщение MQ.

  1. Приложение восходящего потока отправляет ожидающее сообщение в надежную систему обмена сообщениями.
  2. Надежная система сообщений сохраняет ожидающие сообщения и возвращает
  3. Приложения вверх по течению выполняют локальный бизнес
  4. Вышестоящее приложение уведомляет надежную систему обмена сообщениями о том, что бизнес был выполнен, и отправляет сообщение.

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

Второй этап: нижестоящие приложения прослушивают сообщения MQ и выполняют бизнес.

Нижестоящие приложения прослушивают сообщения MQ и выполняют службы, а также уведомляют надежную службу сообщений о результатах использования сообщений.

  1. Нижестоящие приложения прослушивают компонент сообщений MQ и получают сообщения.
  2. Нижестоящие приложения обрабатывают локальный бизнес на основе информации тела сообщения MQ.
  3. Нижестоящее приложение для MQ
  4. Подтвердите, что сообщение было использовано
  5. Нижестоящее приложение уведомляет надежную систему сообщений о том, что сообщение было успешно использовано, и надежное сообщение изменяет статус сообщения на завершенное.

RocketMQКажется, это продвинутая реализация, но проблема в том,缺乏文档, будь то на домашней странице проекта Apache или на странице Али, в лучшем случае он только говорит вам, как его использовать, а принципа или руководства очень не хватает.

Конечно, если вы специально покупали на Alibaba CloudRocketMQСервис, наверное, другое дело. Но если вы попытаетесь развернуть и использовать его в своей собственной сервисной среде, потребуется значительное обучение.毕竟是人家吃饭的家伙嘛

Пять реализаций RabbitMQ решения для окончательной согласованности сообщений

RabbitMQпоследовалAMQP规范, используя механизм подтверждения сообщения, чтобы гарантировать:Пока сообщение отправлено, можно гарантировать, что оно будет использовано потребителями.Для достижения конечной согласованности сообщения. Кроме того, он с открытым исходным кодом и очень богатой документацией, кажется, это хороший носитель для реализации распределенных транзакций.

5.1 Механизм подтверждения сообщения RabbitMQ


Весь процесс отправки rabbitmq выглядит следующим образом

#####1. Производитель отправляет сообщение в службу сообщений ##### 2. Если посадка и сохранение сообщения завершены, производителю возвращается флаг. После того, как производитель получит это подтверждение, он может с уверенностью сказать, что сообщение, наконец, успешно отправлено в службу сообщений. В противном случае введите процесс обработки исключений. rabbitTemplate.setConfirmCallback((correlationData, ack, причина) -> { если (!подтвердить) { //попытаться повторно отправить сообщение } еще { //удалить сообщение в БД } }); #####3. Служба сообщений отправляет сообщение потребителю ##### 4. Потребитель принимает и обрабатывает сообщение и вручную подтверждает, успешно ли прошел процесс. Когда служба сообщений получает это подтверждение, она может с уверенностью сказать, что потребление наконец завершено. В противном случае повторите передачу или введите обработку исключений. конечный потребитель-потребитель = новый DefaultConsumer(канал) { @Override public void handleDelivery (String ConsumerTag, конверт Envelope, свойства AMQP.BasicProperties, тело byte []) throws IOException { Строковое сообщение = новая строка (тело, "UTF-8");

    System.out.println(" [x] Received '" + message + "'");
    try {
      doWork(message);
    } finally {
       //确认收到消息
      channel.basicAck(envelope.getDeliveryTag(), false);
        }
      }
    };

5.2 Исключения


Давайте рассмотрим четыре типа исключений, которые могут быть отправлены.

1. Служба сообщений недоступна напрямую

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

    connectionFactory.setChannelCacheSize(100);

2. Сообщение дошло до сервера, но при возврате возникает исключение

rabbitmqПредусмотрен механизм подтверждения подтверждения, который можно использовать для подтверждения того, возвращено ли сообщение. Поэтому мы можем сохранить сообщение в db (памяти или реляционной базе данных) перед отправкой и повторно отправить сообщение, если подтверждение ненормальное.

    /**confirmcallback用来确认消息是否有送达消息队列*/     
    rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
    if (!ack) {
        //try to resend msg
    } else {
        //delete msg in db
    }
    });
     /**若消息找不到对应的Exchange会先触发returncallback */
    rabbitTemplate.setReturnCallback((message, replyCode, replyText, tmpExchange, tmpRoutingKey) -> {
        try {
            Thread.sleep(Constants.ONE_SECOND);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    
        log.info("send message failed: " + replyCode + " " + replyText);
        rabbitTemplate.send(message);
    });

3. После доставки сообщения служба сообщений зависает сама по себе.

Если установлено сохранение сообщения, тоack= trueОно отправляется после завершения персистентности сообщения, т. е. сохраняется на жестком диске.Убедитесь, что сообщение уже сохранено на жестком диске.В случае зависания службы сообщений служба сообщений может возобновить сообщение и повторно отправить сообщение.

4. Недоставка до потребителей

После того, как служба сообщений получит сообщение, оно будет находиться в состоянии «UNACK», пока клиент не подтвердит получение сообщения.

    channel.basicQos(1); // accept only one unack-ed message at a time (see below)
    final Consumer consumer = new DefaultConsumer(channel) {
      @Override
      public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
        String message = new String(body, "UTF-8");

    System.out.println(" [x] Received '" + message + "'");
    try {
      doWork(message);
    } finally {
       //确认收到消息
      channel.basicAck(envelope.getDeliveryTag(), false);
    }
      }
    };
    boolean autoAck = false;
    channel.basicConsume(TASK_QUEUE_NAME, autoAck, consumer);

5. Сообщение подтверждения потеряно

Служба сообщений повторно отправит сообщение, предполагая, что сообщение подтверждения будет потеряно при возврате сообщения. Обратите внимание, что если вы установитеautoAck= false, но нет ответаchannel.baskAckтоже не ответилchannel.baskNack, то это вызовет очень серьезную ошибку: очередь сообщений будет заблокирована, поэтому вам все равно придется отвечать

6. Исключение для обработки потребительского бизнеса

Слушатель сообщений принимает сообщение и обрабатывает его.Предполагая, что выброшено исключение, первый этап завершен.Если вы хотите настроить откат, это слишком хлопотно.Даже если вы выполняете компенсацию транзакции, компенсация транзакции может не сработать. , поэтому здесь вы можете выполнить повторное выполнение, напримерguavaизretry, установите экспоненциальное время для циклического выполнения, если оно все еще терпит неудачу после n раз, отправляйте электронные письма, текстовые сообщения и используйте человеческую плоть, чтобы получить прибыль.

Шесть резюме

《世界性难题...》В этой статье визуально представлены несколько реализаций распределенных транзакций.

Вы каждый день ходите на работу, и вам нужно пересечь 10-километровую дорогу с двумя полосами движения, чтобы добраться до компании. Эта дорога очень загружена, часто это занимает два-три часа, и время работы не гарантировано, в чем проблема 2PC - медленный.

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

Выбрать горную дорогу протяженностью 20 километров, немного извилистую, дорога неровная, по ней могут ходить только внедорожники, это проблема эвентуальной непротиворечивости сообщений о транзакциях. Представлено новое промежуточное ПО для обмена сообщениями, требующее дополнительных затрат на разработку. Но наша компания разработалаCoolMQКомпонент был инкапсулирован, и ему нужно только отправлять и получать данные, чтобы соответствовать требованиям транзакции. В настоящее время естьЛекции по программе, вы можете выбрать в соответствии с вашими потребностями.

Ну наконец тоGTS,GTSБыл построен виадук с 4 полосами, без объездов, а это еще 10 километров. Отсутствие пробок, высокая производительность для транзакций, отсутствие обходных путей, простота использования для транзакций, отсутствие вмешательства в бизнес, отсутствие необходимости рефакторинга для транзакций, отсутствие ограничений модели, отсутствие функциональных ограничений для транзакций, обеспечение строго согласованных транзакций. В эпоху отсутствия виадуков появление виадуков является прорывной инновацией для транспорта, и многие проблемы, которые раньше казались неразрешимыми, были решены.Также GTS надеется изменить статус-кво отрасли в области обработки данных с помощью инноваций. но, к сожалению并未开源, и нужно совместить阿里云服务использовать.