Бэкэнд ситуация

задняя часть программист

После месяца метаний наконец-то разошлись.

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

Мастер дал этим независимым системам причудливое название: микросервисы!

Некоторые микросервисы являются сердцем владельца. Они «занимают» одну или несколько машин. Например, мой поинт-модуль, о нет, это точечная система, которая не популярна, и ее можно только обидеть, и еще несколько парней делят машину. .

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

Оказалось, что все жили в JVM, и были прямые вызовы функций между модулями.Теперь все предоставляют API на основе HTTP: Если вы хотите получить доступ к другим, вам нужно подготовить данные JSON, а затем отправить их в прошлое через HTTP. После того, как люди обработают его, отправьте ответ JSON.

Действительно хлопотно, даже быть одним из самых простых коммуникаций по всей сети.

Повторение

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

Тридцать миллисекунд назад парень, отвечающий за заказ, позвонил в мой интерфейс, чтобы добавить 200 баллов пользователю с именем U0002, что я с радостью и сделал.

POST /xxx/BonusPoint/U0002

{"value:200"}

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

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

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

Как и ожидалось, пользователь "U0002" не является причиной для увеличения интеграции двух!

Парень по заказу сказал: «Это нехорошо, вы должны помнить, что я уже звонил раньше, чтобы его не пришлось выполнять во второй раз!»

«Шучу! HTTP не имеет состояния, как я могу регистрировать ваши звонки?»

«Мы можем добавить немного статуса. Каждый раз, когда мы звоним, я буду присылать вам идентификатор транзакции, или сокращенно TxID. После того, как вы его обработаете, вам нужно сохранить этот TxID, UserID, баллы и другую информацию в базу данных».

POST /xxx/BonusPoint/U0002

{"txid":"T0001","value":"200"}

Я сказал: «Какая от этого польза?»

"Каждый раз, когда вы выполняете его, вы можете проверить его из базы данных. Если вы видите, что такой же TxID уже существует, это означает, что он выполнялся ранее, поэтому вам не нужно повторять его. Если он не существует , вы действительно можете выполнить его».

Это хорошая идея.Хотя я добавил немного нагрузки, мне нужно немного дополнительного места для хранения (просто воспользуйтесь этой возможностью, чтобы иметь хороший сервер!), Но есть хорошая особенность: для одного и того же TXID, независимо от того, сколько раз вызовы, эффект выполнения такой же, как выполненный, и он точно не будет неправильным.

Позже мы узнали, что люди поставили эту функцию под названием идемпотент.

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

неисполнение

Рассказываю всем о новом API: обязательно передайте мне TxID, иначе не вините меня за то, что я не разобрался!

В этот день я получил два HTTP-вызова, первый из них был таким:

POST /xxx/BonusPoint/U0002

{"txid":"T0010","value":"200"}

Поэтому я с радостью выполнил его и сохранил txid T0010.

Затем второй звонок приходит снова, точно так же, как первый:

POST /xxx/BonusPoint/U0002

{"txid":"T0010","value":"200"}

Я использую проверку T0010, база данных уже существует, я знаю, не нужно иметь дело, и сказать друг другу: обработка завершена.

Неожиданно пользователи поспешили пожаловаться: почему я увеличил баллы дважды (каждый раз по 200), а только один раз?

Это точно не моя кастрюля, с моей стороны проблем нет, все работает как задумано. Я сказал: «Кто только что звонил, проверьте журнал вызовов!»

Изучив журнал звонящего, я обнаружил, что два звонка были сделаны двумя системами!

Так случилось, что две системы генерируют один и тот же TxID: T0010, что наводит меня на мысль о двух попытках одного и того же вызова, хотя на самом деле это два совершенно разных вызова.

Правда понятно, виноват TxID.Видно, что этот TxID не может повторяться во всей распределенной системе, и должен быть уникальным.

Распределенный идентификатор

Как сгенерировать уникальный идентификатор в распределенной системе?

Парень по заказу сказал: «Это очень просто, мы можем просто использовать UUID. UUID содержит MAC-адрес, метку времени, случайное число и другую информацию сетевой карты, что гарантирует уникальность во времени и пространстве и точно не будет повторяться».

UUID можно легко сгенерировать локально, нет необходимости инициировать какие-либо удаленные вызовы, а эффективность чрезвычайно высока.

844A6D2B-CF7B-47C9-9B2B-2AC5C1B1C56B

Я сказал: «Просто 128-значные числа и буквы беспорядочны, и их нельзя отсортировать и увеличить по порядку (особенно в базах данных, где упорядоченные идентификаторы легче найти)».

Все кивнули, и UUID был отклонен.

MySQL предлагает: «Вы забыли обо мне! Я могу поддерживать столбцы auto_increment, натуральные идентификаторы, товарищи, абсолютно гарантированную упорядоченность».

"А? Воспользуйтесь базой данных? Что, если вы объявите забастовку? У нас нет удостоверения личности, поэтому мы ничего не можем сделать!" Все думают о медлительном старике, пусть все полагаются на него и передают сила жизни и смерти Когда дело доходит до ее рук, она немного несчастна.

Nginx сказал: «Вы боитесь, что он нанесет удар, поэтому вы можете получить еще несколько MySQL, например 2.

Начальное значение первого равно 1, и каждый раз, когда оно увеличивается на 2, генерируемый им идентификатор равен 1, 3, 5, 7...

Начальное значение второго равно 2, и каждый раз оно увеличивается на 2. Генерируемые им идентификаторы: 2, 4, 6, 8, 10...

Получите другой сервис генерации идентификаторов, и если один MySQL выйдет из строя, получите доступ к другому. "

«Что, если эта служба генерации идентификаторов тоже мертва?» — спросил кто-то.

«Тогда вы можете развернуть еще несколько сервисов генерации идентификаторов. Разве это не преимущество ваших микросервисов?» — спросил в ответ Nginx.

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

«Однако каждый раз, когда мне нужен TxID, мне нужно один раз получить доступ к базе данных, как же это медленно!» — сказал парень по заказу.

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

"Кэшировать? Как кэшировать?"

Redis сказал: «Каждый раз, когда вы обращаетесь к базе данных, вы можете получить пакет идентификаторов, например 10, и сохранить их в памяти, чтобы другие могли использовать их напрямую, не обращаясь к базе данных. Конечно, база данных должна записывать текущий максимальный идентификатор: сколько."

Предполагая, что начальный максимальный идентификатор равен 1, получите 10 идентификаторов, а именно 1, 2, 3...10, и сохраните их в памяти, и в это время максимальный идентификатор станет равным 10.

В следующий раз получите еще 10, а именно 11, 12, 13...20, максимальный ID станет 20.

«Однако ваш единственный MySQL бастует, и система все равно будет отключена!» — сказал я.

Ngnix сказал: «Это очень просто, добавьте лишний MySQL, получите структуру master-slave, ах, если нет времени копировать данные с Master на Slave время, Master бастует, на этот раз в Slave Max Идентификационный номер его не актуален, то в следующем будут проблемы, может и займемся двойным основным строением......»

Увы, так сложно создать распределенный уникальный ID!

Ngnix что-то бормотал, и никто этого не заметил, появился новый сервис, и как только он появился, он сказал: «Всем привет, я снежинка…»

(Код-фермер перешел к записке Лао Лю: место слишком длинное, так что остановитесь здесь и в следующий раз напишите снежинка...)

Jingdong сверхценные мероприятия! Купите все книги по науке и технике, а также оригинальные книги на сумму более 40 юаней, просто добавьте 25 юаней, чтобы получить «Code Farmer Turning Over»!