Контекст в HTTP- и вызовах к базе данных
Передача контекста по цепочке вызовов
«Контекст в HTTP- и вызовах к базе данных» — бесплатный урок Go Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
HTTP-клиент с контекстом
Передавайте контекст исходящему HTTP-запросу с помощью req.WithContext(ctx). Запрос отменяется, если контекст отменён до получения ответа.
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
resp, err := http.DefaultClient.Do(req)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
// timeout
}
}http.NewRequestWithContext
Предпочитайте http.NewRequestWithContext (Go 1.13+) созданию запроса с последующим вызовом WithContext: этот способ чище и не требует промежуточного выделения памяти.
Отмена HTTP-запроса
Создайте отменяемый контекст с помощью WithCancel, передайте его запросу и вызовите cancel после завершения или при возникновении ошибки. Клиент прерывает TCP-соединение.
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)database/sql с контекстом
Все методы database/sql имеют варианты с суффиксом *Context: QueryContext, ExecContext, PrepareContext. Они отменяют запрос, когда работа с контекстом завершается.
rows, err := db.QueryContext(ctx, "SELECT id FROM users WHERE active = $1", true)
if err != nil { return err }
defer rows.Close()Проверка контекста перед запросом
Проверяйте контекст перед запуском долгого запроса, чтобы немедленно завершить выполнение, если запрос уже отменён.
if err := ctx.Err(); err != nil {
return err // context already done
}
rows, err := db.QueryContext(ctx, ...)Контекст и пул соединений
Если контекст отменён во время выполнения запроса, database/sql помечает соединение как неисправное, когда драйвер это поддерживает. Это не позволяет вернуть повреждённое соединение в пул.
gRPC и контекст
gRPC использует контекст для передачи крайнего срока. Клиент задаёт крайний срок контекста, а сервер проверяет его при получении каждого элемента потока. Метаданные также передаются через контекст.
resp, err := client.GetUser(ctx, &pb.GetUserRequest{Id: id})Контекст входящего запроса
HTTP-сервер добавляет контекст к каждому входящему запросу с помощью r.Context(). Этот контекст отменяется, когда клиент отключается.
func handler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
result, err := db.QueryContext(ctx, query)
}Контекст в цепочках промежуточного ПО
Промежуточное ПО дополняет контекст запроса крайними сроками, данными Auth или идентификаторами трассировки, а затем передаёт дополненный запрос следующему обработчику.
Передача контекста через вызовы служб
В микросервисной архитектуре идентификатор трассировки из контекста входящего запроса следует добавлять во все исходящие заголовки HTTP и RPC, чтобы распределённая трассировка работала от начала до конца.
Тестирование с контекстом
В тестах используйте context.Background() или context.WithTimeout, чтобы горутины не оставались выполняться между тестовыми случаями.
Быстрая проверка
Какая функция создаёт HTTP-запрос с присоединённым контекстом?
Итоги: контекст в HTTP и базе данных
Основные положения:
- Используйте http.NewRequestWithContext для исходящих HTTP-вызовов
- Методы database/sql с суффиксом *Context отменяют запросы после завершения работы с контекстом
- У входящих запросов используйте r.Context(); контекст отменяется при отключении клиента
- Передавайте контекст и идентификатор трассировки во все последующие вызовы
Изучай Go с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 51
- Уроки
- 203
Часто задаваемые вопросы
Урок «Контекст в HTTP- и вызовах к базе данных» бесплатный?
Да — полный текст урока «Контекст в HTTP- и вызовах к базе данных» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «Контекст в HTTP- и вызовах к базе данных»?
Передача контекста по цепочке вызовов Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Контекст в HTTP- и вызовах к базе данных»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Зачем нужен context.Context
- WithCancel и WithTimeout
- WithDeadline и WithValue
- Контекст в HTTP- и вызовах к базе данных