Анализ структуры RPC Framework Ant Financial

Redis задняя часть сервер Открытый исходный код
Анализ структуры RPC Framework Ant Financial

Ant Financial недавно открыла набор фреймворков SOFA, которые разрабатывались в течение многих лет, включая базовый фреймворк RPC под названием SOFA-BOLT. Сегодня редактор потратил почти день на чтение и тщательное исследование его исходного кода.В процессе чтения я столкнулся со многими проблемами.Соответствующий технический персонал Ant Financial был очень терпелив и своевременно отвечал на мои вопросы. Здесь я поделюсь с вами тем, что я узнал.

SOFA-BOLT основан на платформе Netty с открытым исходным кодом и обеспечивает как серверную, так и клиентскую реализацию. Его исходный код очень достоин прочтения, структура проста и продумана до мелочей, и это отнюдь не обычная игрушка. Он не злоупотребляет шаблонами проектирования, исходный код относительно прост для чтения, и в нем не так уж много сложных структур.

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

Протокол

Коммуникационный протокол — это язык для связи между клиентом и сервером. SOFA определяет собственный набор коммуникационных протоколов. Его кодирование и декодирование делятся на два уровня. Первый уровень — это двоичная сериализация объекта тела сообщения. Эта часть с открытым исходным кодом по умолчанию Сериализация библиотеки протоколов Hession завершена, и второй уровень отвечает за добавление ряда полей упаковки в сериализованное тело сообщения для формирования полного сообщения. Включая идентификатор запроса, длину тела сообщения, номер версии протокола и контрольную цифру CRC32 и т. д.

Если вы хотите дополнительно оптимизировать производительность сети, SOFA также предоставляет протокол сжатия Snappy, который может добавить третий уровень на основе существующего двухуровневого протокола, что может значительно снизить нагрузку на передачу по сети. Сжатие — это время для пространства. Повышая производительность сети, оно также увеличивает нагрузку на ЦП, поэтому его необходимо правильно сбалансировать при его использовании.

пул соединений

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

Когда мы используем клиент Jedis для связи с сервером Redis, мы также получаем соединение через пул соединений. Соединение с Jedis должно быть потокоисключающим, поскольку оно не является потокобезопасным. Когда соединение получено из пула соединений, другие потоки не могут временно получить соединение.После обработки текущего потока соединение должно быть возвращено в пул потоков, чтобы другие потоки могли продолжать использовать соединение.

Клиентские запросы и ответы Redis являются последовательными, один вопрос и один ответ, поэтому запрос и ответ могут быть связаны без уникального идентификатора.

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

балансировки нагрузки

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

  1. ConsistentHashLoaderBalancer Согласованный хеш, связь между клиентом и сервером (кто с кем подключен) относительно стабильна
  2. LocalPreferenceLoadBalancer Локальный петлевой адрес предпочтителен для повышения производительности локальных вызовов.
  3. RoundRobinLoadBalancer выполняет циклы по очереди
  4. WeightedRoundRobinLoadBalancer Взвешенный цикл идет по очереди
  5. RandomLoadBalancer Это случайный вес, по умолчанию используется Ali

Потоковая модель сервера

Сервер использует традиционную модель многопоточности netty.Поток-акцептор специально используется для получения соединения, а затем передает его потоку ввода-вывода для обработки прочитанного сообщения и декодирования его в объект запроса, и, наконец, передает его бизнесу. пул потоков для обработки.

сердцебиение

Между клиентом и сервером будет регулярный тактовый импульс для определения выживания соединения, которое по умолчанию происходит раз в 30 секунд. О закрытии tcp другая сторона уведомляется через пакет FIN.Если другая сторона не может даже получить пакет FIN из-за проблем с сетью, то даже если одна сторона закроет сокет, другая сторона может подумать, что соединение нормальное. Таким образом, механизм выживания обнаружения сердцебиения очень распространен в приложениях с длинным соединением. Если клиент отправляет три последовательных пульса и не получает ответа от сервера, то соединение считается закрытым. На сервере также будет обнаружение выживания соединения.Если клиент не получает никаких сообщений в течение 90 секунд после соединения, то соединение считается разорванным. Сервер не отправляет активно сообщения пульса.

дуплексная связь

RPC обычно означает, что клиент инициирует запрос к серверу, а затем получает ответ от сервера. RPC Bolt представляет собой дуплексную связь, и сервер также может активно инициировать запросы к клиенту, и они совместно используют TCP-соединение. Соединения TCP по своей природе являются дуплексными, так что это тоже не чудо. Просто серверу нужно активно инициировать запрос к клиенту, в каком бизнес-сценарии этот муравей подробно не объяснил.

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

Повторное подключение

Стратегия переподключения клиента — это отдельный модуль, и есть два места, которые станут записью переподключения. Во-первых, обычное отключение соединения вызывает обратный вызов channelInActive, а во-вторых, требуется повторная попытка, когда повторное соединение не может быть успешно установлено. У Bolt есть отдельный поток переподключения. Все подключения, которые необходимо переподключить, будут упакованы в задачу и помещены в очередь задач потока. Поток будет постоянно брать задачи из очереди для обработки переподключения. Если переподключение не удалось, он попытается снова ● Переупакуйте задачу в очередь, чтобы отложить обработку. По умолчанию для обработки задачи переподключения используется 1 с.

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

одностороннее сообщение

RPC обычно представляет собой один ответ и один ответ.Клиент может ожидать ответа синхронно или предоставить интерфейс обратного вызова для ожидания уведомления о результате. В дополнение к предоставлению режима ответа, Bolt также предоставляет односторонние односторонние сообщения.Этот тип сервера сообщений не должен отвечать после его получения.После того, как клиент отправит запрос, он сразу же возвращает, не дожидаясь результата.

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

отслеживание сообщений

Bolt предоставляет интерфейс обратного вызова, чтобы система мониторинга могла анализировать статус вызова запроса. Отслеживаемый клиент может реализовать этот интерфейс и зарегистрироваться на клиенте и сервере RPC для сбора журналов, а затем отправить их в систему анализа журналов.

interface Tracer {
    void startRpc(SofaRequest request);
    void serverReceived(SofaRequest request);
    void serverSend(SofaRequest request, SofaResponse response, Throwable throwable);
    void clientReceived(SofaRequest request, SofaResponse response, Throwable throwable);
    ...
}

Суммировать

Bolt — зрелая и сложная RPC-система, и эта небольшая статья объясняет только ее часть, и еще предстоит изучить множество деталей внутренней реализации.

Чтобы прочитать статьи по теме, обратите внимание на общедоступную учетную запись «Code Cave». Код серии с открытым исходным кодом SOFA является большим сокровищем для программистов Java. В нем слишком много проектов и кодов, которые заставят многих пользователей чувствовать себя запуганными. В будущем, Я буду выпускать другие модули серии SOFA с открытым исходным кодом один за другим.Аналитическая статья поможет всем легко понять проект SOFA.