service/library/httpserver/httpserver.go

120 lines
2.6 KiB
Go
Raw Normal View History

2023-12-21 22:17:40 +08:00
package httpserver
import (
"context"
2024-05-14 09:48:34 +08:00
"fmt"
2023-12-21 22:17:40 +08:00
"net/http"
"os"
2024-05-15 19:21:37 +08:00
"os/exec"
2023-12-21 22:17:40 +08:00
"os/signal"
"service/library/configcenter"
2024-05-14 09:48:34 +08:00
"service/library/servicediscovery"
2023-12-21 22:17:40 +08:00
"syscall"
"time"
"service/library/logger"
)
2024-05-15 00:34:23 +08:00
const (
ServerStatusFDRun = "RUN" // 服务运行中
ServerStatusFDStop = "STOP" // 服务停止
)
2024-05-14 09:48:34 +08:00
func StartHttpServer(srv *http.Server, cfg *configcenter.DefaultConfig, ip string, port int) {
2023-12-21 22:17:40 +08:00
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
logger.Fatal("listen: %v", err)
2024-05-14 09:48:34 +08:00
return
2023-12-21 22:17:40 +08:00
}
2024-05-14 09:48:34 +08:00
2023-12-21 22:17:40 +08:00
}()
2024-05-14 09:48:34 +08:00
// 注册服务
go func() {
2024-05-15 00:34:23 +08:00
err := registerSD(ip, port)
if err != nil {
2024-05-17 11:46:18 +08:00
logger.Fatal("registerSD: %v", err)
2024-05-15 00:34:23 +08:00
return
2024-05-14 09:48:34 +08:00
}
2024-05-15 00:34:23 +08:00
setServerStatusFD(ServerStatusFDRun)
2024-05-14 09:48:34 +08:00
}()
2023-12-21 22:17:40 +08:00
2024-05-17 14:35:19 +08:00
done := make(chan int)
go func() {
2024-05-17 14:49:29 +08:00
quit := make(chan os.Signal, 1)
2024-05-17 14:35:19 +08:00
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
for {
select {
case <-quit:
logger.Info("Shutdown Server ...")
2024-05-17 14:49:29 +08:00
for i := 0; i < 10; i++ {
logger.Info("__Shutdown sleep %v", i+1)
time.Sleep(time.Second)
}
2024-05-17 14:35:19 +08:00
if err := servicediscovery.DeRegister(ip, port); err != nil {
logger.Fatal("DeRegister fail: %v", err)
}
2023-12-21 22:17:40 +08:00
2024-05-17 14:35:19 +08:00
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
if err := srv.Shutdown(ctx); err != nil {
logger.Fatal("Server Shutdown:", err)
}
2024-05-14 09:48:34 +08:00
2024-05-17 14:35:19 +08:00
select {
case <-ctx.Done():
logger.Info("timeout of 1 seconds.")
}
2023-12-21 22:17:40 +08:00
2024-05-17 14:35:19 +08:00
logger.Info("Server exited")
setServerStatusFD(ServerStatusFDStop)
cancel()
done <- 1
return
}
}
}()
2023-12-21 22:17:40 +08:00
2024-05-17 14:35:19 +08:00
<-done
logger.Info("Server done")
2023-12-21 22:17:40 +08:00
}
2024-05-14 09:48:34 +08:00
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
}
}
}
}
2024-05-15 00:34:23 +08:00
func setServerStatusFD(status string) {
2024-05-17 14:37:03 +08:00
serverStatusFdPath := "/app/SERVER_STATUS_FD"
2024-05-16 20:43:21 +08:00
cmd := exec.Command("sh", "-c", fmt.Sprintf("echo %s > %s", status, serverStatusFdPath))
2024-05-15 19:21:37 +08:00
err := cmd.Run()
if err != nil {
logger.Info("run cmd fail, p: %v, err: %v", serverStatusFdPath, err)
return
}
2024-05-15 00:34:23 +08:00
logger.Info("SetServerStatusFD success: %v", status)
}