service/library/httpserver/httpserver.go

131 lines
3.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package httpserver
import (
"context"
"fmt"
"net/http"
"os"
"os/exec"
"os/signal"
"service/library/configcenter"
"service/library/servicediscovery"
"syscall"
"time"
"service/library/logger"
)
const (
ServerStatusFDRun = "RUN" // 服务运行中
ServerStatusFDStop = "STOP" // 服务停止
)
func StartHttpServer(srv *http.Server, cfg *configcenter.DefaultConfig, ip string, port int) {
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
logger.Fatal("listen: %v", err)
return
}
}()
// 注册服务
go func() {
err := registerSD(ip, port)
if err != nil {
logger.Fatal("registerSD: %v", err)
return
}
setServerStatusFD(ServerStatusFDRun)
}()
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
logger.Info("Shutdown Server ...")
if err := servicediscovery.DeRegister(ip, port); err != nil {
logger.Fatal("DeRegister fail: %v", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
if err := srv.Shutdown(ctx); err != nil {
logger.Fatal("Server Shutdown:", err)
}
defer cancel()
select {
case <-ctx.Done():
logger.Info("timeout of 1 seconds.")
}
logger.Info("Server exited")
setServerStatusFD(ServerStatusFDStop)
}
func registerSD(ip string, port int) error {
// 要等服务起来后再注册到consul否则会有问题
// 方法:调用 healthcheck
idx := 0
timer := time.NewTimer(time.Second * 5)
timerRetry := time.NewTicker(time.Second * 1)
for {
select {
case <-timer.C:
return fmt.Errorf("registerSD fail, ip: %v, port: %v", ip, port)
case <-timerRetry.C:
idx += 1
resp, err := http.Get(fmt.Sprintf("http://%s:%v/healthcheck", ip, port))
if err != nil {
logger.Error("healthcheck fail, err: %v", err)
continue
}
if resp.StatusCode == http.StatusOK {
if err := servicediscovery.Register(ip, port); err != nil {
logger.Error("registerSD fail, ip: %v, port: %v, err: %v", ip, port, err)
continue
}
return nil
}
}
}
}
func setServerStatusFD(status string) {
serverStatusFdPath := "/app/SERVER_STATUS_FD"
cmd := exec.Command("sh", "-c", fmt.Sprintf("echo %s > %s", status, serverStatusFdPath))
err := cmd.Run()
if err != nil {
logger.Info("run cmd fail, p: %v, err: %v", serverStatusFdPath, err)
return
}
logger.Info("SetServerStatusFD success: %v", status)
}
func StartOfflineHttpServer(srv *http.Server, cfg *configcenter.DefaultConfig) {
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
logger.Fatal("listen: %v", err)
}
}()
logger.Info("Server %s start at %s", cfg.App.AppName, srv.Addr)
quit := make(chan os.Signal)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
logger.Info("Shutdown Server ...")
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
logger.Fatal("Server Shutdown: %v", err)
}
select {
case <-ctx.Done():
logger.Info("timeout of 1 seconds.")
}
logger.Info("Server exited")
}