mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-06 18:10:26 +08:00
支持优雅退出
This commit is contained in:
@@ -5,15 +5,19 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeNode/internal/apps"
|
"github.com/TeaOSLab/EdgeNode/internal/apps"
|
||||||
teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
|
teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/nodes"
|
"github.com/TeaOSLab/EdgeNode/internal/nodes"
|
||||||
|
"github.com/iwind/TeaGo/Tea"
|
||||||
_ "github.com/iwind/TeaGo/bootstrap"
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := apps.NewAppCmd().
|
app := apps.NewAppCmd().
|
||||||
Version(teaconst.Version).
|
Version(teaconst.Version).
|
||||||
Product(teaconst.ProductName).
|
Product(teaconst.ProductName).
|
||||||
Usage(teaconst.ProcessName + " [-v|start|stop|restart|sync|update|test]")
|
Usage(teaconst.ProcessName + " [-v|start|stop|restart|quit|sync|update|test]")
|
||||||
|
|
||||||
app.On("test", func() {
|
app.On("test", func() {
|
||||||
err := nodes.NewNode().Test()
|
err := nodes.NewNode().Test()
|
||||||
@@ -29,6 +33,27 @@ func main() {
|
|||||||
// TODO
|
// TODO
|
||||||
fmt.Println("not implemented yet")
|
fmt.Println("not implemented yet")
|
||||||
})
|
})
|
||||||
|
app.On("quit", func() {
|
||||||
|
pidFile := Tea.Root + "/bin/pid"
|
||||||
|
data, err := ioutil.ReadFile(pidFile)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("[ERROR]quit failed: " + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pid := types.Int(string(data))
|
||||||
|
if pid == 0 {
|
||||||
|
fmt.Println("[ERROR]quit failed: pid=0")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
process, err := os.FindProcess(pid)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if process != nil {
|
||||||
|
_ = process.Signal(syscall.SIGQUIT)
|
||||||
|
}
|
||||||
|
})
|
||||||
app.Run(func() {
|
app.Run(func() {
|
||||||
node := nodes.NewNode()
|
node := nodes.NewNode()
|
||||||
node.Start()
|
node.Start()
|
||||||
|
|||||||
@@ -150,9 +150,6 @@ func (this *AppCmd) Run(main func()) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 记录PID
|
|
||||||
_ = this.writePid()
|
|
||||||
|
|
||||||
// 日志
|
// 日志
|
||||||
writer := new(LogWriter)
|
writer := new(LogWriter)
|
||||||
writer.Init()
|
writer.Init()
|
||||||
@@ -227,8 +224,3 @@ func (this *AppCmd) runStatus() {
|
|||||||
func (this *AppCmd) checkPid() *os.Process {
|
func (this *AppCmd) checkPid() *os.Process {
|
||||||
return CheckPid(Tea.Root + "/bin/pid")
|
return CheckPid(Tea.Root + "/bin/pid")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 写入PID
|
|
||||||
func (this *AppCmd) writePid() error {
|
|
||||||
return WritePid(Tea.Root + "/bin/pid")
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package apps
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/TeaOSLab/EdgeNode/internal/events"
|
||||||
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
@@ -50,11 +52,15 @@ func CheckPid(path string) *os.Process {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 写入Pid
|
// 写入Pid
|
||||||
func WritePid(path string) error {
|
func WritePid() error {
|
||||||
|
path := Tea.Root + "/bin/pid"
|
||||||
fp, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_RDONLY, 0666)
|
fp, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_RDONLY, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
events.On(events.EventQuit, func() {
|
||||||
|
_ = fp.Close()
|
||||||
|
})
|
||||||
|
|
||||||
if runtime.GOOS != "windows" {
|
if runtime.GOOS != "windows" {
|
||||||
err = LockFile(fp)
|
err = LockFile(fp)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeNode/internal/events"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/logs"
|
"github.com/TeaOSLab/EdgeNode/internal/logs"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/utils"
|
"github.com/TeaOSLab/EdgeNode/internal/utils"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
@@ -557,6 +558,13 @@ func (this *FileStorage) initList() error {
|
|||||||
|
|
||||||
// 启动定时清理任务
|
// 启动定时清理任务
|
||||||
this.ticker = utils.NewTicker(30 * time.Second)
|
this.ticker = utils.NewTicker(30 * time.Second)
|
||||||
|
events.On(events.EventQuit, func() {
|
||||||
|
logs.Println("CACHE", "quit clean timer")
|
||||||
|
var ticker = this.ticker
|
||||||
|
if ticker != nil {
|
||||||
|
ticker.Stop()
|
||||||
|
}
|
||||||
|
})
|
||||||
go func() {
|
go func() {
|
||||||
for this.ticker.Next() {
|
for this.ticker.Next() {
|
||||||
this.purgeLoop()
|
this.purgeLoop()
|
||||||
|
|||||||
7
internal/events/events.go
Normal file
7
internal/events/events.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package events
|
||||||
|
|
||||||
|
type Event = string
|
||||||
|
|
||||||
|
const (
|
||||||
|
EventQuit Event = "quit" // quit node gracefully
|
||||||
|
)
|
||||||
27
internal/events/utils.go
Normal file
27
internal/events/utils.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package events
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
var eventsMap = map[string][]func(){} // event => []callbacks
|
||||||
|
var locker = sync.Mutex{}
|
||||||
|
|
||||||
|
// 增加事件回调
|
||||||
|
func On(event string, callback func()) {
|
||||||
|
locker.Lock()
|
||||||
|
defer locker.Unlock()
|
||||||
|
|
||||||
|
callbacks, _ := eventsMap[event]
|
||||||
|
callbacks = append(callbacks, callback)
|
||||||
|
eventsMap[event] = callbacks
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通知事件
|
||||||
|
func Notify(event string) {
|
||||||
|
locker.Lock()
|
||||||
|
callbacks, _ := eventsMap[event]
|
||||||
|
locker.Unlock()
|
||||||
|
|
||||||
|
for _, callback := range callbacks {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
16
internal/events/utils_test.go
Normal file
16
internal/events/utils_test.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package events
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestOn(t *testing.T) {
|
||||||
|
On("hello", func() {
|
||||||
|
t.Log("world")
|
||||||
|
})
|
||||||
|
On("hello", func() {
|
||||||
|
t.Log("world2")
|
||||||
|
})
|
||||||
|
On("hello2", func() {
|
||||||
|
t.Log("world2")
|
||||||
|
})
|
||||||
|
Notify("hello")
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/caches"
|
"github.com/TeaOSLab/EdgeNode/internal/caches"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/errors"
|
"github.com/TeaOSLab/EdgeNode/internal/errors"
|
||||||
|
"github.com/TeaOSLab/EdgeNode/internal/events"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/logs"
|
"github.com/TeaOSLab/EdgeNode/internal/logs"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/rpc"
|
"github.com/TeaOSLab/EdgeNode/internal/rpc"
|
||||||
"io"
|
"io"
|
||||||
@@ -27,7 +28,14 @@ func NewAPIStream() *APIStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *APIStream) Start() {
|
func (this *APIStream) Start() {
|
||||||
|
isQuiting := false
|
||||||
|
events.On(events.EventQuit, func() {
|
||||||
|
isQuiting = true
|
||||||
|
})
|
||||||
for {
|
for {
|
||||||
|
if isQuiting {
|
||||||
|
return
|
||||||
|
}
|
||||||
err := this.loop()
|
err := this.loop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logs.Error("API_STREAM", err.Error())
|
logs.Error("API_STREAM", err.Error())
|
||||||
@@ -43,15 +51,29 @@ func (this *APIStream) loop() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err)
|
return errors.Wrap(err)
|
||||||
}
|
}
|
||||||
|
isQuiting := false
|
||||||
|
events.On(events.EventQuit, func() {
|
||||||
|
isQuiting = true
|
||||||
|
})
|
||||||
nodeStream, err := rpcClient.NodeRPC().NodeStream(rpcClient.Context())
|
nodeStream, err := rpcClient.NodeRPC().NodeStream(rpcClient.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if isQuiting {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return errors.Wrap(err)
|
return errors.Wrap(err)
|
||||||
}
|
}
|
||||||
this.stream = nodeStream
|
this.stream = nodeStream
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
if isQuiting {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
message, err := nodeStream.Recv()
|
message, err := nodeStream.Recv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if isQuiting {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return errors.Wrap(err)
|
return errors.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,6 +102,8 @@ func (this *APIStream) loop() error {
|
|||||||
logs.Error("API_STREAM", "handle message failed: "+err.Error())
|
logs.Error("API_STREAM", "handle message failed: "+err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 连接API节点成功
|
// 连接API节点成功
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeNode/internal/events"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/logs"
|
"github.com/TeaOSLab/EdgeNode/internal/logs"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -47,6 +48,10 @@ func (this *Listener) Listen() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
events.On(events.EventQuit, func() {
|
||||||
|
logs.Println("LISTENER", "quit "+this.group.FullAddr())
|
||||||
|
_ = netListener.Close()
|
||||||
|
})
|
||||||
|
|
||||||
switch protocol {
|
switch protocol {
|
||||||
case serverconfigs.ProtocolHTTP, serverconfigs.ProtocolHTTP4, serverconfigs.ProtocolHTTP6:
|
case serverconfigs.ProtocolHTTP, serverconfigs.ProtocolHTTP4, serverconfigs.ProtocolHTTP6:
|
||||||
@@ -88,6 +93,13 @@ func (this *Listener) Listen() error {
|
|||||||
go func() {
|
go func() {
|
||||||
err := this.listener.Serve()
|
err := this.listener.Serve()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// 在这里屏蔽accept错误,防止在优雅关闭的时候有多余的提示
|
||||||
|
opErr, ok := err.(*net.OpError)
|
||||||
|
if ok && opErr.Op == "accept" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打印其他错误
|
||||||
logs.Error("LISTENER", err.Error())
|
logs.Error("LISTENER", err.Error())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
http2 "golang.org/x/net/http2"
|
http2 "golang.org/x/net/http2"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
@@ -15,6 +16,8 @@ type BaseListener struct {
|
|||||||
namedServers map[string]*NamedServer // 域名 => server
|
namedServers map[string]*NamedServer // 域名 => server
|
||||||
|
|
||||||
Group *serverconfigs.ServerGroup
|
Group *serverconfigs.ServerGroup
|
||||||
|
|
||||||
|
countActiveConnections int64 // 当前活跃的连接数
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
@@ -29,6 +32,11 @@ func (this *BaseListener) Reset() {
|
|||||||
this.namedServersLocker.Unlock()
|
this.namedServersLocker.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取当前活跃连接数
|
||||||
|
func (this *BaseListener) CountActiveListeners() int {
|
||||||
|
return types.Int(this.countActiveConnections)
|
||||||
|
}
|
||||||
|
|
||||||
// 构造TLS配置
|
// 构造TLS配置
|
||||||
func (this *BaseListener) buildTLSConfig() *tls.Config {
|
func (this *BaseListener) buildTLSConfig() *tls.Config {
|
||||||
return &tls.Config{
|
return &tls.Config{
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -34,7 +35,15 @@ func (this *HTTPListener) Serve() error {
|
|||||||
this.httpServer = &http.Server{
|
this.httpServer = &http.Server{
|
||||||
Addr: this.addr,
|
Addr: this.addr,
|
||||||
Handler: handler,
|
Handler: handler,
|
||||||
IdleTimeout: 2 * time.Minute,
|
IdleTimeout: 2 * time.Minute, // TODO IdleTimeout可以设置
|
||||||
|
ConnState: func(conn net.Conn, state http.ConnState) {
|
||||||
|
switch state {
|
||||||
|
case http.StateNew:
|
||||||
|
atomic.AddInt64(&this.countActiveConnections, 1)
|
||||||
|
case http.StateClosed:
|
||||||
|
atomic.AddInt64(&this.countActiveConnections, -1)
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
this.httpServer.SetKeepAlivesEnabled(true)
|
this.httpServer.SetKeepAlivesEnabled(true)
|
||||||
|
|
||||||
|
|||||||
@@ -15,4 +15,7 @@ type ListenerInterface interface {
|
|||||||
|
|
||||||
// 重载配置
|
// 重载配置
|
||||||
Reload(serverGroup *serverconfigs.ServerGroup)
|
Reload(serverGroup *serverconfigs.ServerGroup)
|
||||||
|
|
||||||
|
// 获取当前活跃的连接数
|
||||||
|
CountActiveListeners() int
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,6 +93,18 @@ func (this *ListenerManager) Start(node *nodeconfigs.NodeConfig) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取总的活跃连接数
|
||||||
|
func (this *ListenerManager) TotalActiveConnections() int {
|
||||||
|
this.locker.Lock()
|
||||||
|
defer this.locker.Unlock()
|
||||||
|
|
||||||
|
total := 0
|
||||||
|
for _, listener := range this.listenersMap {
|
||||||
|
total += listener.listener.CountActiveListeners()
|
||||||
|
}
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
|
||||||
// 返回更加友好格式的地址
|
// 返回更加友好格式的地址
|
||||||
func (this *ListenerManager) prettyAddress(addr string) string {
|
func (this *ListenerManager) prettyAddress(addr string) string {
|
||||||
u, err := url.Parse(addr)
|
u, err := url.Parse(addr)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/logs"
|
"github.com/TeaOSLab/EdgeNode/internal/logs"
|
||||||
"net"
|
"net"
|
||||||
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TCPListener struct {
|
type TCPListener struct {
|
||||||
@@ -25,10 +26,16 @@ func (this *TCPListener) Serve() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
err = this.handleConn(conn)
|
|
||||||
if err != nil {
|
atomic.AddInt64(&this.countActiveConnections, 1)
|
||||||
logs.Error("TCP_LISTENER", err.Error())
|
|
||||||
}
|
go func(conn net.Conn) {
|
||||||
|
err = this.handleConn(conn)
|
||||||
|
if err != nil {
|
||||||
|
logs.Error("TCP_LISTENER", err.Error())
|
||||||
|
}
|
||||||
|
atomic.AddInt64(&this.countActiveConnections, -1)
|
||||||
|
}(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ type UDPListener struct {
|
|||||||
|
|
||||||
func (this *UDPListener) Serve() error {
|
func (this *UDPListener) Serve() error {
|
||||||
// TODO
|
// TODO
|
||||||
|
// TODO 注意管理 CountActiveConnections
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ type UnixListener struct {
|
|||||||
|
|
||||||
func (this *UnixListener) Serve() error {
|
func (this *UnixListener) Serve() error {
|
||||||
// TODO
|
// TODO
|
||||||
|
// TODO 注意管理 CountActiveConnections
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeNode/internal/apps"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/caches"
|
"github.com/TeaOSLab/EdgeNode/internal/caches"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/configs"
|
"github.com/TeaOSLab/EdgeNode/internal/configs"
|
||||||
|
"github.com/TeaOSLab/EdgeNode/internal/events"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/logs"
|
"github.com/TeaOSLab/EdgeNode/internal/logs"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/rpc"
|
"github.com/TeaOSLab/EdgeNode/internal/rpc"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/utils"
|
"github.com/TeaOSLab/EdgeNode/internal/utils"
|
||||||
@@ -16,7 +18,9 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"os/signal"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -49,6 +53,9 @@ func (this *Node) Test() error {
|
|||||||
|
|
||||||
// 启动
|
// 启动
|
||||||
func (this *Node) Start() {
|
func (this *Node) Start() {
|
||||||
|
// 处理信号
|
||||||
|
this.listenSignals()
|
||||||
|
|
||||||
// 本地Sock
|
// 本地Sock
|
||||||
err := this.listenSock()
|
err := this.listenSock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -92,12 +99,46 @@ func (this *Node) Start() {
|
|||||||
err = sharedListenerManager.Start(nodeConfig)
|
err = sharedListenerManager.Start(nodeConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logs.Error("NODE", "start failed: "+err.Error())
|
logs.Error("NODE", "start failed: "+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写入PID
|
||||||
|
err = apps.WritePid()
|
||||||
|
if err != nil {
|
||||||
|
logs.Error("NODE", "write pid failed: "+err.Error())
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// hold住进程
|
// hold住进程
|
||||||
select {}
|
select {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理信号
|
||||||
|
func (this *Node) listenSignals() {
|
||||||
|
signals := make(chan os.Signal)
|
||||||
|
signal.Notify(signals, syscall.SIGQUIT)
|
||||||
|
go func() {
|
||||||
|
for s := range signals {
|
||||||
|
switch s {
|
||||||
|
case syscall.SIGQUIT:
|
||||||
|
events.Notify(events.EventQuit)
|
||||||
|
|
||||||
|
// 监控连接数,如果连接数为0,则退出进程
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
countActiveConnections := sharedListenerManager.TotalActiveConnections()
|
||||||
|
if countActiveConnections <= 0 {
|
||||||
|
os.Exit(0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
// 读取API配置
|
// 读取API配置
|
||||||
func (this *Node) syncConfig(isFirstTime bool) error {
|
func (this *Node) syncConfig(isFirstTime bool) error {
|
||||||
// 检查api.yaml是否存在
|
// 检查api.yaml是否存在
|
||||||
@@ -180,6 +221,10 @@ func (this *Node) syncConfig(isFirstTime bool) error {
|
|||||||
func (this *Node) startSyncTimer() {
|
func (this *Node) startSyncTimer() {
|
||||||
// TODO 这个时间间隔可以自行设置
|
// TODO 这个时间间隔可以自行设置
|
||||||
ticker := time.NewTicker(60 * time.Second)
|
ticker := time.NewTicker(60 * time.Second)
|
||||||
|
events.On(events.EventQuit, func() {
|
||||||
|
logs.Println("NODE", "quit sync timer")
|
||||||
|
ticker.Stop()
|
||||||
|
})
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@@ -272,6 +317,10 @@ func (this *Node) listenSock() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
events.On(events.EventQuit, func() {
|
||||||
|
logs.Println("NODE", "quit unix sock")
|
||||||
|
_ = listener.Close()
|
||||||
|
})
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
|
teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
|
||||||
|
"github.com/TeaOSLab/EdgeNode/internal/events"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/logs"
|
"github.com/TeaOSLab/EdgeNode/internal/logs"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/rpc"
|
"github.com/TeaOSLab/EdgeNode/internal/rpc"
|
||||||
"github.com/iwind/TeaGo/lists"
|
"github.com/iwind/TeaGo/lists"
|
||||||
@@ -35,6 +36,12 @@ func (this *NodeStatusExecutor) Listen() {
|
|||||||
|
|
||||||
// TODO 这个时间间隔可以配置
|
// TODO 这个时间间隔可以配置
|
||||||
ticker := time.NewTicker(30 * time.Second)
|
ticker := time.NewTicker(30 * time.Second)
|
||||||
|
|
||||||
|
events.On(events.EventQuit, func() {
|
||||||
|
logs.Println("NODE_STATUS", "quit executor")
|
||||||
|
ticker.Stop()
|
||||||
|
})
|
||||||
|
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
this.isFirstTime = false
|
this.isFirstTime = false
|
||||||
this.update()
|
this.update()
|
||||||
@@ -48,6 +55,8 @@ func (this *NodeStatusExecutor) update() {
|
|||||||
|
|
||||||
status := &nodeconfigs.NodeStatus{}
|
status := &nodeconfigs.NodeStatus{}
|
||||||
status.BuildVersion = teaconst.Version
|
status.BuildVersion = teaconst.Version
|
||||||
|
status.OS = runtime.GOOS
|
||||||
|
status.Arch = runtime.GOARCH
|
||||||
status.ConfigVersion = sharedNodeConfig.Version
|
status.ConfigVersion = sharedNodeConfig.Version
|
||||||
status.IsActive = true
|
status.IsActive = true
|
||||||
|
|
||||||
|
|||||||
@@ -122,6 +122,13 @@ func (this *RPCClient) ClusterContext(clusterId string, clusterSecret string) co
|
|||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 关闭连接
|
||||||
|
func (this *RPCClient) Close() {
|
||||||
|
for _, conn := range this.conns {
|
||||||
|
_ = conn.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 随机选择一个连接
|
// 随机选择一个连接
|
||||||
func (this *RPCClient) pickConn() *grpc.ClientConn {
|
func (this *RPCClient) pickConn() *grpc.ClientConn {
|
||||||
if len(this.conns) == 0 {
|
if len(this.conns) == 0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user