Коммуникационный протокол Nebula
Nebula разделяет сетевые сообщения на запросы (request) и ответы (response). На самом деле, все типы сетевых сообщений можно отнести к запросам или ответам.
Nebula поддерживает такие протоколы связи, как protobuf, http и websocket. Основанный на protobuf3, разработанный по индивидуальному проекту, коммуникационный протокол Nebula является основным протоколом связи Nebula. Он используется для обмена данными между распределёнными сервисными узлами Nebula, а также для взаимодействия с внешними клиентами распределённых сервисов. Протоколы http, websocket и другие, поддерживаемые Nebula, после декодирования в слое подключения Nebula преобразуются в протокол связи Nebula и используются для обмена данными между узлами. В качестве слоя бизнес-логики данные структуры могут быть непосредственно прочитаны и записаны. Ниже приведено определение протокола Nebula:
syntax = "proto3";
/**
* @brief 消息头
* @note MsgHead всегда имеет длину 15 байт. Если длина MsgHead не равна 15 байтам, отправка сообщения завершится ошибкой.
* В версии proto2 длина MsgHead всегда равна 15 байтам. В этой версии cmd, seq и len являются обязательными полями.
* В версии proto3 длина MsgHead должна быть равна 15 байтам. При этом cmd, seq и len должны быть ненулевыми, иначе невозможно будет правильно выполнить кодирование и декодирование отправки и получения.
*/
message MsgHead {
fixed32 cmd = 1; // команда (1 байт, старший бит представляет алгоритм сжатия и шифрования)
fixed32 seq = 2; // порядковый номер
sfixed32 len = 3; // длина сообщения
}
/**
* @brief Тело сообщения
* @note Тело сообщения — это data. Вся бизнес-логика содержится в data. req_target используется на стороне сервера для маршрутизации и должен быть заполнен в запросе. rsp_result должен быть заполнен в ответе.
*/
message MsgBody {
oneof msg_type {
Request req_target = 1; // цель запроса (заполняется в запросе)
Response rsp_result = 2; // результат ответа (заполняется в ответе)
}
bytes data = 3; // тело сообщения
bytes add_on = 4; // данные, добавленные на стороне сервера в запрос (клиент не обращает внимания)
string trace_id = 5; // для трассировки журнала
message Request {
uint32 route_id = 1; // идентификатор маршрута
string route = 2; // идентификатор маршрута (используется, когда route_id не может выразить маршрут)
}
message Response {
int32 code = 1; // код ошибки
bytes msg = 2; // сообщение об ошибке
}
}
Протокол Nebula состоит из MsgHead и MsgBody. Это широко используемый протокол TLV. MsgHead имеет фиксированную длину 15 байт. Команда cmd указывает функцию обработчика сообщений, и в Nebula принято, что если cmd является нечётным числом, то сообщение является запросом, а если оно является чётным числом, то сообщением является ответ. Таким образом, можно избежать поля типа сообщения request/response. Длина команды составляет 32 бита (4 байта), но только младшие 2 байта используются в качестве функции команды, а старшие 2 байта представляют алгоритм сжатия, шифрования и версию. Это делается для того, чтобы максимально сэкономить пропускную способность, поскольку 2-байтовая команда уже может представлять 32 266 функций (65 535/2, 0 не может использоваться в качестве команды, и исключая зарезервированные команды запроса Nebula 500), которых достаточно для использования в бизнесе.
Поле data в MsgBody хранит тело сообщения, и любые пользовательские данные могут быть записаны в двоичном потоке данных в data.
msg_type используется для определения того, является ли сообщение запросом или ответом. Если это запрос, вы можете выбрать заполнение route_id или route в Request. Если они заполнены, фреймворк может автоматически пересылать их без необходимости анализа прикладного протокола (и не может анализировать), а приложению не нужно разбирать содержимое data для пересылки в соответствии с настраиваемой логикой. Если это ответ, он определяет унифицированный стандарт ошибок и предоставляет удобство для обработки ошибок, не связанных с бизнесом.
add_on — это данные, прикреплённые к длительному соединению. Фреймворк не анализирует их, но добавляет их при каждой пересылке сообщения. Они предоставляют чрезвычайно удобные и мощные функции для приложений. Например, при входе пользователя в систему IM клиент отправляет только идентификатор пользователя и пароль на сервер. После успешной проверки входа сервер использует метод SetClientData() для добавления информации о псевдониме и аватаре пользователя в соответствующее длительное соединение Channel этого пользователя. Затем все запросы, поступающие через это соединение, будут автоматически заполнять поле add_on фреймворком, а другая логика сервера получает только данные бизнес-логики (например, сообщения чата) из data, но может получить информацию об отправителе из поля add_on. Дизайн add_on упрощает логику разработки приложений и снижает объём данных, передаваемых между клиентом и сервером.
trace_id используется для распределённой трассировки журналов. Распределённая служба ошибок очень сложна. Nebula предоставляет функцию распределённой службы трассировки, которая позволяет фреймворку помечать все журналы с одним и тем же trace_id для отправки на указанный сервер журналов без дополнительной работы со стороны разработчиков приложений (обычная запись LOG4_INFO без дополнительной работы). Например, если сообщение, отправленное пользователем IM, не удаётся отправить, trace_id будет добавлен при отправке сообщения на сторону сервера. Этот идентификатор будет передаваться на каждом этапе пути обработки и ошибок. Вы можете найти путь обработки и ошибок из сообщения.
Реализация кодирования и декодирования MsgHead и MsgBody см. в https://github.com/Bwar/Nebula/blob/master/src/codec/CodecProto.cpp в рамках Nebula.
Http-протокол является лучшим выбором для предоставления внешних услуг. Будучи универсальным сетевым фреймворком, http-протокол, естественно, является наиболее важным протоколом для Nebula для предоставления внешних служб. Nebula превращает http-протокол в protobuf и анализирует текстовый протокол http для преобразования в HttpMsg, который обрабатывается внутри службы. Разработчики приложений заполняют HttpMsg, а слой подключения преобразует ответный HttpMsg обратно в текстовый протокол http и отправляет его запрашивающей стороне. Независимо от того, сколько раз происходит внутренняя передача, существует только один этап декодирования текстового протокола http и один этап кодирования текстового протокола http. Ниже приводится определение protobuf для http-протокола:
syntax = "proto3";
message HttpMsg {
int32 type = 1; // тип http_parser_type (запрос или ответ)
int32 http_major = 2; // основная версия http
int32 http_minor = 3; // дополнительная версия http
int32 content_length = 4; // длина содержимого
int32 method = 5; // метод запроса
int32 status_code = 6; // статус ответа
int32 encoding = 7; // кодировка передачи (используется только при кодировании, когда Transfer-Encoding: chunked, используется для обозначения номера чанка, 0 означает первый чанк, увеличивается последовательно)
string url = 8; // адрес
}
``` map<string, string> headers = 9; // http头域
bytes body = 10; // 消息体(当 Transfer-Encoding: chunked 时,只存储一个 chunk)
map<string, string> params = 11; // GET方法参数,POST方法表单提交的参数
Upgrade upgrade = 12; // 升级协议
float keep_alive = 13; // keep alive time
string path = 14; // Http Decode时从 url 中解析出来,不需要人为填充(encode时不需要填)
bool is_decoding = 15; // 是否正在解码(true 正在解码, false 未解码或已完成解码)
message Upgrade {
bool is_upgrade = 1;
string protocol = 2;
}
  HttpMsg的编解码实现见 Nebula 框架的 [https://github.com/Bwar/Nebula/blob/master/src/codec/CodecHttp.cpp](https://github.com/Bwar/Nebula/blob/master/src/codec/CodecHttp.cpp)。
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )