diff --git a/README.md b/README.md index 755cf78..621b35e 100644 --- a/README.md +++ b/README.md @@ -92,8 +92,8 @@ docker run --rm --name goma-gateway \ ``` ### 4. Healthcheck -- Goma Gateway readiness: `/readyz` -- Routes health check: `/healthz` +- Goma Gateway health check: `/health/live` +- Routes health check: `health/live` ### 5. Simple deployment in docker compose file @@ -103,7 +103,7 @@ services: image: jkaninda/goma-gateway command: server healthcheck: - test: curl -f http://localhost/readyz || exit 1 + test: curl -f http://localhost/heath/live || exit 1 interval: 30s retries: 5 start_period: 20s @@ -121,8 +121,6 @@ Example of a configuration file ```yaml # Goma Gateway configurations gateway: - ########## Global settings - listenAddr: :80 #:443 SSL # Proxy write timeout writeTimeout: 15 # Proxy read timeout diff --git a/docs/quickstart.md b/docs/quickstart.md index f04a3c9..9f25f6b 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -28,8 +28,8 @@ docker run --rm --name goma-gateway \ ``` ### 4. Healthcheck -- Goma Gateway readiness: `/readyz` -- Routes health check: `/healthz` +- Goma Gateway health check: `/health/live` +- Routes health check: `health/live` ### 5. Simple deployment in docker compose file @@ -46,6 +46,7 @@ services: timeout: 10s ports: - "80:80" + - "443:443" volumes: - ./config:/config/ ``` @@ -56,8 +57,6 @@ Example of a configuration file ```yaml # Goma Gateway configurations gateway: - ########## Global settings - listenAddr: :80 #:443 SSL # Proxy write timeout writeTimeout: 15 # Proxy read timeout diff --git a/examples/compose.yaml b/examples/compose.yaml index beb1c4c..03d6e2b 100644 --- a/examples/compose.yaml +++ b/examples/compose.yaml @@ -10,5 +10,6 @@ services: timeout: 10s ports: - "80:80" + - "443:443" volumes: - ./config:/config/ \ No newline at end of file diff --git a/examples/kubernetes.yaml b/examples/kubernetes.yaml index 29a76fa..c3b4df1 100644 --- a/examples/kubernetes.yaml +++ b/examples/kubernetes.yaml @@ -23,14 +23,14 @@ spec: - containerPort: 80 livenessProbe: httpGet: - path: /healthz + path: /health/live port: 80 initialDelaySeconds: 15 periodSeconds: 30 timeoutSeconds: 10 readinessProbe: httpGet: - path: /readyz + path: /health/live port: 80 initialDelaySeconds: 15 periodSeconds: 40 diff --git a/goma.yml b/goma.yml index 905e145..9d862bc 100644 --- a/goma.yml +++ b/goma.yml @@ -1,7 +1,5 @@ # Goma Gateway configurations gateway: - ########## Global settings - listenAddr: :80 #:443 SSL # Proxy write timeout writeTimeout: 15 # Proxy read timeout diff --git a/internal/config.go b/internal/config.go index fa4f294..ffdbed9 100644 --- a/internal/config.go +++ b/internal/config.go @@ -85,7 +85,6 @@ func initConfig(configFile string) { } conf := &GatewayConfig{ GatewayConfig: Gateway{ - ListenAddr: ":80", WriteTimeout: 15, ReadTimeout: 15, IdleTimeout: 60, diff --git a/internal/route.go b/internal/route.go index e47c7fb..e810eeb 100644 --- a/internal/route.go +++ b/internal/route.go @@ -35,8 +35,10 @@ func (gatewayServer GatewayServer) Initialize() *mux.Router { // Routes health check if !gateway.DisableHealthCheckStatus { r.HandleFunc("/healthz", heath.HealthCheckHandler).Methods("GET") + r.HandleFunc("/health/routes", heath.HealthCheckHandler).Methods("GET") } - // Readiness + // Health check + r.HandleFunc("/health/live", heath.HealthReadyHandler).Methods("GET") r.HandleFunc("/readyz", heath.HealthReadyHandler).Methods("GET") if gateway.RateLimiter != 0 { diff --git a/internal/server.go b/internal/server.go index 3508a1a..1fa4295 100644 --- a/internal/server.go +++ b/internal/server.go @@ -29,6 +29,7 @@ import ( func (gatewayServer GatewayServer) Start(ctx context.Context) error { logger.Info("Initializing routes...") route := gatewayServer.Initialize() + logger.Debug("Routes count=%d Middlewares count=%d", len(gatewayServer.gateway.Routes), len(gatewayServer.middlewares)) logger.Info("Initializing routes...done") tlsConfig := &tls.Config{} var listenWithTLS = false @@ -41,8 +42,17 @@ func (gatewayServer GatewayServer) Start(ctx context.Context) error { listenWithTLS = true } - srv := &http.Server{ - Addr: gatewayServer.gateway.ListenAddr, + // HTTP Server + httpServer := &http.Server{ + Addr: ":80", + WriteTimeout: time.Second * time.Duration(gatewayServer.gateway.WriteTimeout), + ReadTimeout: time.Second * time.Duration(gatewayServer.gateway.ReadTimeout), + IdleTimeout: time.Second * time.Duration(gatewayServer.gateway.IdleTimeout), + Handler: route, // Pass our instance of gorilla/mux in. + } + // HTTPS Server + httpsServer := &http.Server{ + Addr: ":443", WriteTimeout: time.Second * time.Duration(gatewayServer.gateway.WriteTimeout), ReadTimeout: time.Second * time.Duration(gatewayServer.gateway.ReadTimeout), IdleTimeout: time.Second * time.Duration(gatewayServer.gateway.IdleTimeout), @@ -53,36 +63,52 @@ func (gatewayServer GatewayServer) Start(ctx context.Context) error { printRoute(gatewayServer.gateway.Routes) } // Set KeepAlive - srv.SetKeepAlivesEnabled(!gatewayServer.gateway.DisableKeepAlive) + httpServer.SetKeepAlivesEnabled(!gatewayServer.gateway.DisableKeepAlive) + httpsServer.SetKeepAlivesEnabled(!gatewayServer.gateway.DisableKeepAlive) + go func() { + logger.Info("Starting HTTP server listen=0.0.0.0:80") + if err := httpServer.ListenAndServe(); err != nil { + logger.Fatal("Error starting Goma Gateway HTTP server: %v", err) + } + }() go func() { - logger.Info("Started Goma Gateway server on %v", gatewayServer.gateway.ListenAddr) if listenWithTLS { - logger.Info("Server is running securely over HTTPS on %v ", gatewayServer.gateway.ListenAddr) - if err := srv.ListenAndServeTLS("", ""); err != nil { - logger.Fatal("Error starting Goma Gateway server: %v", err) - } - } else { - if err := srv.ListenAndServe(); err != nil { - logger.Fatal("Error starting Goma Gateway server: %v", err) + logger.Info("Starting HTTPS server listen=0.0.0.0:443") + if err := httpsServer.ListenAndServeTLS("", ""); err != nil { + logger.Fatal("Error starting Goma Gateway HTTPS server: %v", err) } } }() var wg sync.WaitGroup - wg.Add(1) - + wg.Add(2) go func() { defer wg.Done() <-ctx.Done() shutdownCtx := context.Background() shutdownCtx, cancel := context.WithTimeout(shutdownCtx, 10*time.Second) defer cancel() - if err := srv.Shutdown(shutdownCtx); err != nil { - _, err := fmt.Fprintf(os.Stderr, "error shutting down Goma Gateway server: %s\n", err) + if err := httpServer.Shutdown(shutdownCtx); err != nil { + _, err := fmt.Fprintf(os.Stderr, "error shutting down HTTP server: %s\n", err) if err != nil { return } } }() + go func() { + defer wg.Done() + <-ctx.Done() + shutdownCtx := context.Background() + shutdownCtx, cancel := context.WithTimeout(shutdownCtx, 10*time.Second) + defer cancel() + if listenWithTLS { + if err := httpsServer.Shutdown(shutdownCtx); err != nil { + _, err := fmt.Fprintf(os.Stderr, "error shutting HTTPS server: %s\n", err) + if err != nil { + return + } + } + } + }() wg.Wait() return nil diff --git a/internal/types.go b/internal/types.go index dc7bce8..51a6e06 100644 --- a/internal/types.go +++ b/internal/types.go @@ -133,12 +133,10 @@ type Route struct { // Gateway contains Goma Proxy Gateway's configs type Gateway struct { - // ListenAddr Defines the server listenAddr - // - //e.g: localhost:8080 - ListenAddr string `yaml:"listenAddr" env:"GOMA_LISTEN_ADDR, overwrite"` + // SSLCertFile SSL Certificate file SSLCertFile string `yaml:"sslCertFile" env:"GOMA_SSL_CERT_FILE, overwrite"` - SSLKeyFile string `yaml:"sslKeyFile" env:"GOMA_SSL_KEY_FILE, overwrite"` + // SSLKeyFile SSL Private key file + SSLKeyFile string `yaml:"sslKeyFile" env:"GOMA_SSL_KEY_FILE, overwrite"` // WriteTimeout defines proxy write timeout WriteTimeout int `yaml:"writeTimeout" env:"GOMA_WRITE_TIMEOUT, overwrite"` // ReadTimeout defines proxy read timeout