service/library/httpserver/httpserver.go

106 lines
2.4 KiB
Go
Raw 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) {
quit := make(chan os.Signal)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
logger.Fatal("listen: %v", err)
quit <- syscall.SIGTERM
return
}
}()
// 注册服务
go func() {
err := registerSD(ip, port)
if err != nil {
quit <- syscall.SIGTERM
return
}
setServerStatusFD(ServerStatusFDRun)
}()
<-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)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
logger.Fatal("Server Shutdown:", err)
}
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)
}