На стороне клиента:
Обратите внимание, что параметры не обязательно являются исчерпывающими. Приведённое описание представляет собой общий план, а не детальный низкоуровневый дизайн. Низкоуровневый дизайн будет развиваться в процессе разработки, и документация веб-сайта API предоставит точную и подробную информацию о конечных точках и способах их использования.
Метод запроса будет POST.
Запросы будут направляться на определённый URL, например, «/query-stream» (это можно настроить).
Тело запроса представляет собой объект JSON в кодировке UTF-8, содержащий аргументы для операции (здесь добавлены новые строки для ясности, но реальный JSON не должен содержать неэкранированные новые строки):
{
"sql": "select * from foo", <----- SQL-запрос для выполнения
"properties": { <----- Необязательные свойства для запроса
"prop1": "val1",
"prop2": "val2"
}
}
В случае успешного запроса:
{
"queryId", "xyz123", <---- уникальный идентификатор запроса, используемый при завершении запроса
"columnNames":["col", "col2", "col3"], <---- имена столбцов
"columnTypes":["BIGINT", "STRING", "BOOLEAN"] <---- типы столбцов
}
Далее следуют ноль или более массивов JSON:
[123, "blah", true]
[432, "foo", true]
[765, "whatever", false]
Каждый массив или строка JSON разделяются новой строкой.
Для запроса на вытягивание ответ будет завершён сервером после записи всех строк, для запроса на отправку ответ останется открытым до тех пор, пока соединение не будет закрыто или запрос не будет явно завершён.
Запрос на отправку может быть явно завершён клиентом путём отправки запроса на эту конечную точку:
Метод запроса — POST.
Запросы направляются на определённый URL, например, "/close-query".
Тело запроса — это объект JSON в кодировке UTF-8, содержащий аргументы для операции (новые строки добавлены здесь для ясности, но настоящий JSON не должен содержать новые строки):
{
"queryId": "xyz123", <----- идентификатор запроса для завершения
}
Метод запроса — POST.
Запросы отправляются на определённую конечную точку, например, "/insert-stream" (можно настроить).
Тело запроса — объект JSON в кодировке UTF-8, содержащий аргументы для операции (добавлены новые строки для ясности, настоящий JSON не должен содержать новых строк):
{
"target": "my-stream" <----- имя KSQL-потока для вставки
}
Затем следуют ноль или больше объектов JSON, представляющих значения для вставки:
{
"col1" : "val1",
"col2": 2.3,
"col3": true
}
Каждый объект JSON отделяется новой строкой.
Чтобы завершить поток вставки, клиент должен завершить запрос.
Подтверждения будут записаны в ответ, когда каждая строка будет успешно зафиксирована в базовой теме. Строки фиксируются в порядке их предоставления. Каждый акк в ответе является объектом JSON, разделённым новыми строками:
{"status":"ok","seq":0}
{"status":"ok","seq":2}
{"status":"ok","seq":1}
{"status":"ok","seq":3}
Успешный акк будет содержать поле status
со значением ok
.
Все ответы акка также содержат поле seq
с 64-битным целым числом со знаком. Это число соответствует последовательности вставки в запросе. Первый отправленный имеет последовательность 0
, второй — 1
, третий — 2
и т. д. Это позволяет клиенту сопоставить подтверждение с соответствующим отправлением.
В случае ошибки будет отправлен ответ об ошибке (см. ниже). Для ответа об ошибке на отправку поле seq
также будет включено.
Обратите внимание, что подтверждения могут быть возвращены в другой последовательности по сравнению с отправленными вставками.
Соответствующие коды состояния будут возвращаться из неудачных запросов. Ответ также будет содержать JSON с дополнительной информацией об ошибке:
{ "status": "error" "error_code": <код ошибки> "message": <сообщение об ошибке> } Потоковая передача результатов
API предназначен для эффективной потоковой передачи строк от клиента к серверу или от сервера к клиенту.
Объём данных, передаваемых в рамках одного запроса или потока вставки, может быть огромным, поэтому мы хотим избежать решений, которые буферизуют все данные в памяти одновременно или требуют специализированных парсеров для анализа.
По этой причине мы не предоставляем результаты запросов (или не принимаем потоки вставок) по умолчанию в виде единого объекта JSON. Если бы мы это сделали, то вынудили бы пользователей искать и использовать потоковый парсер JSON, чтобы анализировать результаты по мере их поступления. Если на их платформе нет доступного парсера, им пришлось бы анализировать весь набор результатов как единый объект JSON в памяти — это может оказаться невозможным или нежелательным из-за ограничений памяти и задержки. Новые строки очень легко анализировать практически на любой целевой платформе без необходимости полагаться на специализированные библиотеки.
Однако есть некоторые случаи использования, когда мы можем гарантировать, что результаты запроса невелики, например, при использовании предложения limit. В этом случае более общий случай использования потоковой передачи вырождается в случай использования RPC. В этой ситуации может быть удобно принять результаты в виде единого объекта JSON, поскольку мы всегда хотим анализировать их как единый объект в памяти. Чтобы поддержать этот вариант использования, мы можем разрешить запросу содержать заголовок accept, указывающий тип содержимого ответа. Для получения ответа в виде единого объекта тип содержимого должен быть указан как «text/json», для нашего формата с разделителями мы укажем собственный пользовательский тип содержимого. Формат с разделителями будет использоваться по умолчанию, так как API в первую очередь является потоковым API.
Миграция существующего «REST» API
Мы перенесём существующий «REST» API на основе Jetty в новую реализацию на основе Vert.x как есть или с небольшими изменениями.
Мы также перенесём существующие плагины, специфичные для Jetty, в Vert.x.
Реализация сервера
Новый серверный API будет реализован с использованием Vert.x.
Реализация будет спроектирована реактивным / неблокирующим способом, чтобы обеспечить наилучшую производительность / масштабируемость с низким потреблением ресурсов. Это также повлияет на общую модель потоков сервера и позволит нам создать более масштабируемую внутреннюю архитектуру сервера, которая поможет в будущем усовершенствовать сервер ksqlDB.
Что не входит в рамки проекта
Ценность / возврат
Мы надеемся, что предоставление удобного в использовании клиента и нового серверного API на базе HTTP2 позволит разработчикам приложений легко создавать мощные приложения, которые более эффективно используют платформу данных / потоковой передачи событий.
Это может стать преобразующим фактором для проекта с точки зрения внедрения, поскольку позиционирует ksqlDB как отличный выбор для написания типичных приложений в стиле источников событий / CQRS / DDD, которые в настоящее время сложно написать только с помощью ksqlDB.
Также существуют дополнительные косвенные преимущества, получаемые благодаря этой работе. Используя современную серверную реализацию, такую как Vert.x, можно получить преимущества в отношении производительности, масштабируемости, простоты реализации и модели потоков. Не говоря уже о сокращении зависимостей и улучшении использования ресурсов. Это подготовит нас к высокопроизводительным операциям, которые нам необходимо эффективно реализовать сейчас, когда проект перешёл к более активному серверу, ориентированному на приложения, а не к более пассивному движку DDL.
Публичные API
Произойдут следующие изменения / дополнения в API:
Дизайн
Клиент на Java предоставит API, основанный на Reactive Streams и completable future. Мы также можем рассмотреть возможность предоставления прокладки JDK 9 с использованием Flow API для пользователей, использующих Java 9+.
Сетевое взаимодействие будет осуществляться через Vert.x (который использует Netty).
У клиента будут минимальные транзитивные зависимости jar — это важно, поскольку клиент будет встроен в приложения конечных пользователей.
Соединения клиента предназначены для повторного использования.
Клиент будет потокобезопасным.
Сервер
На стороне сервера будет использоваться инструментарий Vert.x.
Текущее использование Jetty / JAX-RS будет прекращено.
Текущие не потоковые HTTP/REST-конечные точки будут перенесены на Vert.x — это должно модернизировать и радикально упростить и прояснить реализацию на стороне сервера, что приведёт к более чистой реализации и сокращению строк кода.
Текущие конечные точки потоковой передачи запросов (фрагментированный ответ и Websockets) будут удалены.
Любые текущие плагины Jetty (например, плагины безопасности) будут перенесены в Vert.x
Vert.x имеет отличную поддержку для работы с различными сетевыми протоколами и обладает непревзойдёнными характеристиками производительности/масштабируемости для инструментария JVM. Это также хорошо подготовит нас к полностью асинхронной / реактивной внутренней модели потоков на сервере, к которой мы должны стремиться в будущем.
План тестирования
Нам потребуются модульные/модульные тесты и интеграционные тесты для всех новых или изменённых компонентов в соответствии со стандартной передовой практикой.
Обновления документации
Последствия совместимости
Текущая конечная точка потоковой передачи с фрагментированным ответом будет удалена, поэтому всем пользователям, которые в настоящее время её используют, придётся обновиться.
Текущая конечная точка Websockets потоковой передачи запроса будет удалена, поэтому всем пользователям, которые в настоящее время её используют, придётся обновить. Эта конечная точка в настоящее время не документирована, поэтому ожидается, что её использует не так много пользователей. Она используется C3 (?) поэтому её необходимо перенести на новый API.
Могут произойти некоторые незначительные несовместимые изменения в перенесённом старом API сервера.
Влияние на производительность
Последствия для безопасности
Новый протокол должен быть доступен через TLS, и мы должны поддерживать тот же подход к аутентификации, который мы используем с текущим API, поэтому дополнительных последствий для безопасности не должно быть.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )