Тип http.Server

Тип http.Server представляет собой HTTP-сервер, который позволяет настраивать параметры обработки входящих запросов. В структуре сервера можно задать адрес прослушивания, обработчик запросов, таймауты и другие параметры. Основными методами типа являются ListenAndServe для запуска сервера, Shutdown для graceful остановки и Close для немедленного закрытия.

Синтаксис

goserver := &http.Server{
  Addr:     ":8080",
  Handler:    nil,
  ReadTimeout:  5 * time.Second,
  WriteTimeout: 10 * time.Second,
}

Для создания экземпляра сервера используется литерал структуры с указанием необходимых полей. Поле Addr задает адрес и порт для прослушивания, поле Handler определяет обработчик всех входящих запросов (если nil, используется DefaultServeMux), поля ReadTimeout и WriteTimeout устанавливают ограничения на время чтения и записи запросов.

Пример

Давайте создадим простой HTTP-сервер с обработчиком, возвращающим приветственное сообщение:

gopackage main

import (
  "fmt"
  "net/http"
  "time"
)

func main() {
  mux := http.NewServeMux()
  mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, World!")
  })

  server := &http.Server{
    Addr:     ":8080",
    Handler:    mux,
    ReadTimeout:  5 * time.Second,
    WriteTimeout: 10 * time.Second,
  }

  fmt.Println("Server started on :8080")
  err := server.ListenAndServe()
  if err != nil {
    fmt.Println("Server error:", err)
  }
}

Результат выполнения при запуске сервера:

go"Server started on :8080"

При обращении к http://localhost:8080 в браузере будет выведено сообщение "Hello, World!".

Пример

Давайте реализуем graceful shutdown сервера с использованием метода Shutdown, который позволяет корректно завершить обработку текущих запросов:

gopackage main

import (
  "context"
  "fmt"
  "net/http"
  "os"
  "os/signal"
  "time"
)

func main() {
  server := &http.Server{
    Addr:     ":8080",
    ReadTimeout:  5 * time.Second,
    WriteTimeout: 10 * time.Second,
  }

  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, graceful shutdown!")
  })

  go func() {
    fmt.Println("Server started on :8080")
    if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
      fmt.Printf("ListenAndServe error: %s\n", err)
    }
  }()

  stop := make(chan os.Signal, 1)
  signal.Notify(stop, os.Interrupt)

  <-stop
  fmt.Println("Shutting down server...")

  ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  defer cancel()

  if err := server.Shutdown(ctx); err != nil {
    fmt.Printf("Shutdown error: %s\n", err)
  }
  fmt.Println("Server stopped gracefully")
}

Результат выполнения при остановке сервера:

go"Shutting down server..."
"Server stopped gracefully"

В этом примере сервер запускается в отдельной горутине, а основной поток ожидает сигнал прерывания (Ctrl+C). После получения сигнала вызывается метод Shutdown с контекстом, ограничивающим время ожидания завершения текущих запросов.

Пример

Рассмотрим использование метода Close для немедленного закрытия сервера без ожидания завершения текущих запросов:

gopackage main

import (
  "fmt"
  "net/http"
  "time"
)

func main() {
  server := &http.Server{
    Addr: ":8080",
  }

  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    time.Sleep(5 * time.Second)
    fmt.Fprintf(w, "Slow response")
  })

  go func() {
    fmt.Println("Server started on :8080")
    if err := server.ListenAndServe(); err != nil {
      fmt.Printf("ListenAndServe error: %s\n", err)
    }
  }()

  time.Sleep(2 * time.Second)
  fmt.Println("Closing server immediately...")
  if err := server.Close(); err != nil {
    fmt.Printf("Close error: %s\n", err)
  }
  fmt.Println("Server closed")
}

Результат выполнения:

go"Server started on :8080"
"Closing server immediately..."
"Server closed"

Метод Close закрывает сервер немедленно, прерывая все текущие соединения. В отличие от Shutdown, этот метод не ждет завершения обработки текущих запросов.

Смотрите также

  • метод http.Server.ListenAndServe,
    который запускает сервер и начинает прослушивание
  • метод http.Server.Shutdown,
    который выполняет graceful остановку сервера
  • метод http.Server.Close,
    который немедленно закрывает сервер
  • функцию http.ListenAndServe,
    которая запускает сервер с настройками по умолчанию