service/library/httpserver/httpserver.go

120 lines
2.6 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) {
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)
}()
done := make(chan int)
go func() {
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
for {
select {
case <-quit:
logger.Info("Shutdown Server ...")
for i := 0; i < 10; i++ {
logger.Info("__Shutdown sleep %v", i+1)
time.Sleep(time.Second)
}
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)
}
select {
case <-ctx.Done():
logger.Info("timeout of 1 seconds.")
}
logger.Info("Server exited")
setServerStatusFD(ServerStatusFDStop)
cancel()
done <- 1
return
}
}
}()
<-done
logger.Info("Server done")
}
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)
}