> For the complete documentation index, see [llms.txt](https://yuliyas-organization-3.gitbook.io/prokhodim-sobesedovanie-na-golang-razrabotchika/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yuliyas-organization-3.gitbook.io/prokhodim-sobesedovanie-na-golang-razrabotchika/protokoly-http-udp-tcp-i-t.d..md).

# Протоколы HTTP/UDP/TCP и т.д.

<details>

<summary>TCP vs UDP, как гарантируется доставка в TCP, TCP-handshake</summary>

TCP и UDP - два основных протокола передачи данных в сети. TCP, или Transmission Control Protocol, обеспечивает надежную и упорядоченную доставку данных, гарантируя, что большие файлы передаются правильно и без потерь.&#x20;

В TCP доставка данных гарантируется за счет механизмов, таких как установка соединения и надежное управление потоком данных. TCP-handshake - это процесс установки соединения между клиентом и сервером, который включает три этапа: SYN, SYN-ACK и ACK, где обе стороны обмениваются информацией для начала коммуникации.&#x20;

В отличие от TCP, UDP, или User Datagram Protocol, не гарантирует доставку данных и может передавать пакеты вразнобой, что делает его быстрым и эффективным, но менее надежным.

</details>

<details>

<summary>Из каких частей состоит HTTP запрос?</summary>

HTTP-запрос состоит из следующих основных частей:

1. Стартовая строка (Request Line):
   * Метод HTTP (GET, POST, PUT, DELETE и др.) - указывает, что именно нужно сделать с ресурсом
   * URI (Uniform Resource Identifier) - адрес запрашиваемого ресурса
   * Версия HTTP-протокола
2. Заголовки (Headers):
   * Ключ-значение пары, разделенные двоеточием
   * Содержат дополнительную информацию о запросе, например, тип данных, авторизацию, кэширование и т.д.
3. Пустая строка:
   * Отделяет заголовки от тела запроса
4. Тело запроса (Request Body):
   * Содержит данные, которые отправляются на сервер, например, в POST-запросах

Таким образом, HTTP-запрос состоит из стартовой строки, заголовков, пустой строки и опционального тела запроса, которые вместе формируют структуру для передачи данных между клиентом и сервером.

</details>

<details>

<summary>HTTP vs HTTPS, зачем надо шифровать?</summary>

HTTP и HTTPS - два протокола передачи данных в сети, отличающихся уровнем безопасности. HTTP (HyperText Transfer Protocol) передает данные в открытом виде, что делает их уязвимыми для перехвата злоумышленниками. В отличие от HTTP, HTTPS (HyperText Transfer Protocol Secure) обеспечивает шифрование данных с помощью криптографических протоколов SSL или TLS, что защищает информацию от несанкционированного доступа и обеспечивает конфиденциальность и целостность передаваемых данных.

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

</details>

<details>

<summary>Какие методы шифрования используются в https?</summary>

Протокол HTTPS использует различные методы шифрования для обеспечения безопасности передачи данных между клиентом и сервером. В частности, HTTPS использует криптографические протоколы SSL (Secure Sockets Layer) и TLS (Transport Layer Security) для шифрования данных.

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

Таким образом, методы шифрования, используемые в HTTPS, включают SSL и TLS, которые играют ключевую роль в обеспечении безопасности и конфиденциальности при передаче данных в интернете.

</details>

<details>

<summary>Зачем нужны таймаут и как их подобрать HTTP?</summary>

Таймауты в 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/>

</details>

<details>

<summary>Что происходить когда вбиваешь google.com в браузере, зачем нужен DNS?</summary>

Когда пользователь вводит "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>

</details>

<details>

<summary>Расскажите про протоколы связи (rest, grpс, шины)</summary>

Существует несколько популярных протоколов для связи между распределенными системами:

\## 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>

</details>

<details>

<summary>gRPC: чем stream отличается от unary?</summary>

Основные отличия 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/>

</details>

<details>

<summary>Представим, что идет синхронный вызов по gRPC в множество сервисов. В одном из них получаем ошибки, но ошибка не несет инфы о сервисе. Как быстро понять где ошибка?</summary>

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

#### 1. Логирование

**Логирование** — это один из самых эффективных способов отслеживания ошибок. Убедитесь, что каждый сервис ведет подробные логи, включая информацию о входящих и исходящих запросах, а также о возникающих ошибках.

* **Включите идентификаторы запросов**: Используйте уникальные идентификаторы запросов (например, UUID) для отслеживания запросов через все сервисы.
* **Логируйте метаданные**: Включите в логи метаданные, такие как имя сервиса, имя метода, временные метки и идентификаторы запросов.

Пример логирования в Go:

```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:

```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:

```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:

```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. Эти методы обеспечат вам необходимую видимость и контроль над вашими сервисами.

</details>
