🚆Протоколы HTTP/UDP/TCP и т.д.
TCP vs UDP, как гарантируется доставка в TCP, TCP-handshake
TCP и UDP - два основных протокола передачи данных в сети. TCP, или Transmission Control Protocol, обеспечивает надежную и упорядоченную доставку данных, гарантируя, что большие файлы передаются правильно и без потерь.
В TCP доставка данных гарантируется за счет механизмов, таких как установка соединения и надежное управление потоком данных. TCP-handshake - это процесс установки соединения между клиентом и сервером, который включает три этапа: SYN, SYN-ACK и ACK, где обе стороны обмениваются информацией для начала коммуникации.
В отличие от TCP, UDP, или User Datagram Protocol, не гарантирует доставку данных и может передавать пакеты вразнобой, что делает его быстрым и эффективным, но менее надежным.
Из каких частей состоит HTTP запрос?
HTTP-запрос состоит из следующих основных частей:
Стартовая строка (Request Line):
Метод HTTP (GET, POST, PUT, DELETE и др.) - указывает, что именно нужно сделать с ресурсом
URI (Uniform Resource Identifier) - адрес запрашиваемого ресурса
Версия HTTP-протокола
Заголовки (Headers):
Ключ-значение пары, разделенные двоеточием
Содержат дополнительную информацию о запросе, например, тип данных, авторизацию, кэширование и т.д.
Пустая строка:
Отделяет заголовки от тела запроса
Тело запроса (Request Body):
Содержит данные, которые отправляются на сервер, например, в POST-запросах
Таким образом, HTTP-запрос состоит из стартовой строки, заголовков, пустой строки и опционального тела запроса, которые вместе формируют структуру для передачи данных между клиентом и сервером.
HTTP vs HTTPS, зачем надо шифровать?
HTTP и HTTPS - два протокола передачи данных в сети, отличающихся уровнем безопасности. HTTP (HyperText Transfer Protocol) передает данные в открытом виде, что делает их уязвимыми для перехвата злоумышленниками. В отличие от HTTP, HTTPS (HyperText Transfer Protocol Secure) обеспечивает шифрование данных с помощью криптографических протоколов SSL или TLS, что защищает информацию от несанкционированного доступа и обеспечивает конфиденциальность и целостность передаваемых данных.
Шифрование в HTTPS играет ключевую роль в обеспечении безопасности в сети, так как оно предотвращает перехват и чтение конфиденциальной информации, такой как личные данные, пароли, банковские данные и другие чувствительные сведения. Поэтому шифрование в HTTPS необходимо для защиты конфиденциальности пользователей и обеспечения безопасности передачи данных в интернете.
Какие методы шифрования используются в https?
Протокол HTTPS использует различные методы шифрования для обеспечения безопасности передачи данных между клиентом и сервером. В частности, HTTPS использует криптографические протоколы SSL (Secure Sockets Layer) и TLS (Transport Layer Security) для шифрования данных.
SSL и TLS обеспечивают защиту данных путем создания зашифрованного канала связи, который предотвращает несанкционированный доступ к информации и обеспечивает конфиденциальность передаваемых данных. При обмене данными между клиентом и сервером, SSL и TLS используют симметричное и асимметричное шифрование для защиты информации и обеспечения безопасности соединения.
Таким образом, методы шифрования, используемые в HTTPS, включают SSL и TLS, которые играют ключевую роль в обеспечении безопасности и конфиденциальности при передаче данных в интернете.
Зачем нужны таймаут и как их подобрать HTTP?
Таймауты в HTTP играют важную роль в обеспечении эффективности и безопасности взаимодействия между клиентом и сервером. Они определяют максимальное время ожидания ответа от сервера или установления соединения, что позволяет избежать блокировки ресурсов и повысить производительность сервиса. Подбор таймаутов в HTTP зависит от конкретного случая и требует учета различных факторов, таких как тип запроса, характеристики сети, нагрузка на сервер и другие параметры.
Для подбора оптимальных таймаутов в HTTP необходимо учитывать следующие аспекты:
Установление соединения: таймаут соединения определяет максимальное время ожидания установления соединения с сервером.
Ответ от сервера: таймаут ответа определяет максимальное время ожидания ответа от сервера на запрос клиента.
Подбор оптимальных значений таймаутов важен для предотвращения блокировки ресурсов и обеспечения быстрой обработки запросов. Установка слишком больших или слишком маленьких таймаутов может негативно сказаться на производительности и надежности сервиса. Поэтому рекомендуется внимательно настраивать таймауты в HTTP, учитывая специфику приложения и требования к производительности.
Citations: [1] https://ru.wikipedia.org/wiki/HTTP [2] https://habr.com/ru/companies/avito/articles/710660/ [3] https://otus.ru/journal/http-zaprosy-ot-a-do-ya/ [4] https://firstvds.ru/technology/metody-http-zaprosa [5] https://habr.com/ru/articles/755750/
Что происходить когда вбиваешь google.com в браузере, зачем нужен DNS?
Когда пользователь вводит "google.com" в браузере, происходит следующее:
Браузер отправляет запрос к DNS-серверам: Браузер начинает процесс разрешения доменного имени "google.com" в IP-адрес, необходимый для связи с сервером, на котором находится сайт[2][4].
DNS-серверы находят IP-адрес сайта: Если браузер не обнаруживает записи об IP-адресе сайта в своем кэше, он отправляет запрос к DNS-серверам, которые содержат информацию об IP-адресах сайтов. DNS-серверы находят IP-адрес сервера, где расположен сайт "google.com"[2][4].
Браузер отправляет HTTP-запрос на найденный IP-адрес: Получив IP-адрес сервера, браузер отправляет HTTP-запрос на этот адрес, запрашивая контент сайта "google.com"[2].
Таким образом, DNS (Domain Name System) играет ключевую роль в процессе преобразования доменного имени в IP-адрес, позволяя браузеру найти правильный сервер, где хранится запрашиваемый сайт[2][4]. DNS необходим для того, чтобы установить соединение с нужным сервером, где хранится контент сайта, и обеспечить корректную передачу данных между клиентом и сервером.
Citations: [1] https://habr.com/ru/companies/htmlacademy/articles/254825/ [2] https://vc.ru/selectel/76371-chto-proishodit-kogda-polzovatel-nabiraet-v-brauzere-adres-sayta [3] https://support.google.com/chrome/answer/7665664?co=GENIE.Platform%3DAndroid&hl=ru [4] https://support.google.com/websearch/answer/2466433?hl=ru [5] https://webanetlabs.net/publ/8
Расскажите про протоколы связи (rest, grpс, шины)
Существует несколько популярных протоколов для связи между распределенными системами:
## REST (Representational State Transfer)
REST - это архитектурный стиль для построения распределенных систем[1][2][3]. Он основан на следующих принципах:
- Использование HTTP методов (GET, POST, PUT, DELETE) для взаимодействия с ресурсами
- Передача данных в простых форматах (JSON, XML)
- Отсутствие состояния между запросами
- Иерархическая структура ресурсов, адресуемых URI
REST API предоставляет простой и масштабируемый способ интеграции систем[1][2]. Однако у REST есть ограничения, например, отсутствие двунаправленной связи.
## gRPC (Google Remote Procedure Call)
gRPC - это фреймворк для построения распределенных систем, разработанный Google[3][4]. Он использует:
- Бинарный протокол поверх HTTP/2 для эффективной передачи данных
- Определение интерфейсов на языке Protocol Buffers
- Генерацию клиентского и серверного кода на разных языках
gRPC позволяет создавать высокопроизводительные и масштабируемые системы[3][4]. Он подходит для сценариев с высокой нагрузкой и двунаправленной связью.
## Интеграционные шины
Интеграционные шины (ESB - Enterprise Service Bus) - это программная инфраструктура для интеграции различных приложений[2][5]. Они предоставляют:
- Единую точку доступа к приложениям
- Преобразование форматов данных
- Маршрутизацию сообщений между приложениями
- Обработку ошибок и исключений
Шины позволяют связывать разнородные системы, но требуют больше настройки и конфигурирования[2][5].
Выбор протокола зависит от конкретных требований системы, таких как производительность, двунаправленность связи, сложность интеграции. REST подходит для простых интеграций, gRPC для высоконагруженных, а шины для сложных корпоративных систем[1][2][3][4][5].
Citations:
[1] https://habr.com/ru/articles/667012/
[2] https://habr.com/ru/articles/249183/
[3] https://gist.github.com/pavlov200912/c290a3d773776378a39fa8fab3e4f215
[4] https://platform-docs.v-serv.ru/online-documentation/home/files/General_Description_of_the_Platform.pdf
[5] https://systems.education/integrations/tproduct/694069189-427788538021-osnovi-proektirovaniya-integratsii-it-si
gRPC: чем stream отличается от unary?
Основные отличия gRPC stream и unary RPC:
Unary RPC
Клиент отправляет одно сообщение, сервер отправляет одно ответное сообщение[1][2]
Каждый unary вызов создает новый HTTP/2 запрос, что добавляет некоторый накладные расходы[3]
Unary RPC проще в реализации и отладке[1]
Stream RPC
Клиент отправляет поток сообщений, сервер отправляет поток ответных сообщений[4]
Сообщения отправляются по существующему HTTP/2 соединению, что быстрее чем создание нового запроса для каждого unary вызова[3]
Поток может быть прерван ошибкой сервиса или соединения, требуется логика для перезапуска потока[3]
Более сложная реализация и отладка[1]
Преимущества stream:
Высокая пропускная способность и низкая задержка[3]
Удобно для сценариев, когда клиент отправляет много данных серверу порциями[4]
Преимущества unary:
Проще в реализации и отладке[1]
Сообщения могут быть перенаправлены на другой сервер если текущий упал[5]
Рекомендации:
Используйте unary, если только большие проблемы не могут быть решены потоками[2]
Используйте stream когда требуется высокая пропускная способность или низкая задержка, и gRPC является узким местом[3]
В целом, unary RPC проще и надежнее, stream RPC предпочтительнее для высокопроизводительных сценариев, но добавляет сложности.
Citations: [1] https://www.reddit.com/r/golang/comments/p50382/grpc_unary_vs_stream_for_small_vs_large_file/ [2] https://stackoverflow.com/questions/56766921/multiple-unary-rpc-calls-vs-long-running-bidirectional-streaming-in-grpc [3] https://learn.microsoft.com/en-us/aspnet/core/grpc/performance?view=aspnetcore-8.0 [4] https://techdozo.dev/grpc-client-streaming/ [5] https://www.reddit.com/r/grpc/comments/10710zv/client_streaming_rpc_vs_multiple_unary_rpc/
Представим, что идет синхронный вызов по gRPC в множество сервисов. В одном из них получаем ошибки, но ошибка не несет инфы о сервисе. Как быстро понять где ошибка?
Когда вы работаете с распределенными системами и используете gRPC для синхронных вызовов между множеством сервисов, важно иметь возможность быстро идентифицировать источник ошибки. Если ошибка не содержит информации о сервисе, это может затруднить диагностику. Вот несколько стратегий, которые помогут вам быстро понять, где возникла ошибка:
1. Логирование
Логирование — это один из самых эффективных способов отслеживания ошибок. Убедитесь, что каждый сервис ведет подробные логи, включая информацию о входящих и исходящих запросах, а также о возникающих ошибках.
Включите идентификаторы запросов: Используйте уникальные идентификаторы запросов (например, UUID) для отслеживания запросов через все сервисы.
Логируйте метаданные: Включите в логи метаданные, такие как имя сервиса, имя метода, временные метки и идентификаторы запросов.
Пример логирования в Go:
import (
"context"
"log"
"google.golang.org/grpc"
)
func callService(ctx context.Context, client SomeServiceClient, request *SomeRequest) (*SomeResponse, error) {
response, err := client.SomeMethod(ctx, request)
if err != nil {
log.Printf("Error calling SomeMethod: %v", err)
return nil, err
}
return response, nil
}
2. Трассировка (Tracing)
Трассировка позволяет отслеживать путь запроса через все сервисы. Используйте распределенные системы трассировки, такие как Jaeger или Zipkin, чтобы визуализировать путь запроса и быстро определить, где произошла ошибка.
Инструментируйте ваши сервисы: Добавьте код для отправки трассировок в систему трассировки.
Используйте контекст: Передавайте контекст (context) через все вызовы, чтобы трассировка могла связывать все части запроса.
Пример использования OpenTelemetry для трассировки в Go:
import (
"context"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/trace"
)
func callService(ctx context.Context, client SomeServiceClient, request *SomeRequest) (*SomeResponse, error) {
tracer := otel.Tracer("example.com/trace")
ctx, span := tracer.Start(ctx, "callService")
defer span.End()
response, err := client.SomeMethod(ctx, request)
if err != nil {
span.RecordError(err)
return nil, err
}
return response, nil
}
3. Обогащение ошибок
Обогащение ошибок дополнительной информацией о сервисе и методе, где произошла ошибка, может значительно упростить диагностику.
Используйте обертки для ошибок: Оборачивайте ошибки с дополнительной информацией о сервисе и методе.
gRPC метаданные: Используйте метаданные gRPC для передачи информации об ошибках.
Пример обогащения ошибок в Go:
import (
"fmt"
"google.golang.org/grpc/status"
"google.golang.org/grpc/codes"
)
func callService(ctx context.Context, client SomeServiceClient, request *SomeRequest) (*SomeResponse, error) {
response, err := client.SomeMethod(ctx, request)
if err != nil {
return nil, status.Errorf(codes.Internal, "Error in SomeService.SomeMethod: %v", err)
}
return response, nil
}
4. Мониторинг и алертинг
Мониторинг и алертинг помогут вам быстро обнаружить и реагировать на ошибки.
Используйте системы мониторинга: Интегрируйте ваши сервисы с системами мониторинга, такими как Prometheus и Grafana.
Настройте алерты: Настройте алерты для уведомления о критических ошибках и сбоях.
Пример мониторинга с Prometheus в Go:
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"net/http"
)
var (
errorCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "service_errors_total",
Help: "Total number of errors in the service",
},
[]string{"service", "method"},
)
)
func init() {
prometheus.MustRegister(errorCounter)
}
func callService(ctx context.Context, client SomeServiceClient, request *SomeRequest) (*SomeResponse, error) {
response, err := client.SomeMethod(ctx, request)
if err != nil {
errorCounter.WithLabelValues("SomeService", "SomeMethod").Inc()
return nil, err
}
return response, nil
}
func main() {
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":2112", nil)
}
Заключение
Использование логирования, трассировки, обогащения ошибок и мониторинга поможет вам быстро идентифицировать и диагностировать ошибки в распределенных системах, использующих gRPC. Эти методы обеспечат вам необходимую видимость и контроль над вашими сервисами.
Last updated