🚆Протоколы 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-запрос состоит из следующих основных частей:

  1. Стартовая строка (Request Line):

    • Метод HTTP (GET, POST, PUT, DELETE и др.) - указывает, что именно нужно сделать с ресурсом

    • URI (Uniform Resource Identifier) - адрес запрашиваемого ресурса

    • Версия HTTP-протокола

  2. Заголовки (Headers):

    • Ключ-значение пары, разделенные двоеточием

    • Содержат дополнительную информацию о запросе, например, тип данных, авторизацию, кэширование и т.д.

  3. Пустая строка:

    • Отделяет заголовки от тела запроса

  4. Тело запроса (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" в браузере, происходит следующее:

  1. Браузер отправляет запрос к DNS-серверам: Браузер начинает процесс разрешения доменного имени "google.com" в IP-адрес, необходимый для связи с сервером, на котором находится сайт[2][4].

  2. DNS-серверы находят IP-адрес сайта: Если браузер не обнаруживает записи об IP-адресе сайта в своем кэше, он отправляет запрос к DNS-серверам, которые содержат информацию об IP-адресах сайтов. DNS-серверы находят IP-адрес сервера, где расположен сайт "google.com"[2][4].

  3. Браузер отправляет 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