|
@@ -7,8 +7,10 @@ import (
|
|
|
"net"
|
|
|
"os"
|
|
|
"os/signal"
|
|
|
+ "runtime"
|
|
|
"strings"
|
|
|
"sync"
|
|
|
+ "sync/atomic"
|
|
|
"syscall"
|
|
|
"time"
|
|
|
|
|
@@ -18,23 +20,29 @@ import (
|
|
|
"git.nspix.com/golang/micro/log"
|
|
|
"git.nspix.com/golang/micro/registry"
|
|
|
"git.nspix.com/golang/micro/utils/docker"
|
|
|
+ "git.nspix.com/golang/micro/utils/metric"
|
|
|
"git.nspix.com/golang/micro/utils/net/ip"
|
|
|
"git.nspix.com/golang/micro/utils/unsafestr"
|
|
|
)
|
|
|
|
|
|
+var (
|
|
|
+ upMetricProcessFlag int32
|
|
|
+)
|
|
|
+
|
|
|
type Service struct {
|
|
|
- opts *Options
|
|
|
- ctx context.Context
|
|
|
- cancelFunc context.CancelFunc
|
|
|
- registry registry.Registry
|
|
|
- node *registry.ServiceNode
|
|
|
- listener net.Listener
|
|
|
- gateway *gateway.Gateway
|
|
|
- wg sync.WaitGroup
|
|
|
- httpSvr *http.Server
|
|
|
- rpcSvr *rpc.Server
|
|
|
- upTime time.Time
|
|
|
- client *Client
|
|
|
+ opts *Options
|
|
|
+ ctx context.Context
|
|
|
+ cancelFunc context.CancelFunc
|
|
|
+ registry registry.Registry
|
|
|
+ node *registry.ServiceNode
|
|
|
+ listener net.Listener
|
|
|
+ gateway *gateway.Gateway
|
|
|
+ wg sync.WaitGroup
|
|
|
+ httpSvr *http.Server
|
|
|
+ rpcSvr *rpc.Server
|
|
|
+ upTime time.Time
|
|
|
+ client *Client
|
|
|
+ environment string
|
|
|
}
|
|
|
|
|
|
func (svr *Service) wrapSync(f func()) {
|
|
@@ -47,25 +55,63 @@ func (svr *Service) wrapSync(f func()) {
|
|
|
|
|
|
func (svr *Service) eventLoop() {
|
|
|
var (
|
|
|
- err error
|
|
|
- ticker *time.Ticker
|
|
|
+ err error
|
|
|
+ registryTicker *time.Ticker
|
|
|
+ upMetricTicker *time.Ticker
|
|
|
)
|
|
|
- ticker = time.NewTicker(time.Second * 10)
|
|
|
- defer ticker.Stop()
|
|
|
+ registryTicker = time.NewTicker(time.Second * 20)
|
|
|
+ upMetricTicker = time.NewTicker(time.Second * 5)
|
|
|
+ defer func() {
|
|
|
+ registryTicker.Stop()
|
|
|
+ }()
|
|
|
for {
|
|
|
select {
|
|
|
- case <-ticker.C:
|
|
|
+ case <-registryTicker.C:
|
|
|
if !svr.opts.DisableRegister {
|
|
|
if err = svr.registry.Register(svr.node); err != nil {
|
|
|
log.Warnf("registry service %s error: %s", svr.opts.Name, err.Error())
|
|
|
}
|
|
|
}
|
|
|
+ case <-upMetricTicker.C:
|
|
|
+ if svr.opts.TSDBUrl != "" {
|
|
|
+ if atomic.CompareAndSwapInt32(&upMetricProcessFlag, 0, 1) {
|
|
|
+ go svr.upMetrics()
|
|
|
+ }
|
|
|
+ }
|
|
|
case <-svr.ctx.Done():
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func (svr *Service) upMetrics() {
|
|
|
+ ms := make(metric.Values, 0)
|
|
|
+ tags := make(map[string]string)
|
|
|
+ tags["host"] = ip.InternalIP()
|
|
|
+ tags["name"] = svr.opts.ShortName()
|
|
|
+ tags["version"] = svr.opts.Version
|
|
|
+ memStats := &runtime.MemStats{}
|
|
|
+ runtime.ReadMemStats(memStats)
|
|
|
+ ms = append(ms, metric.New("sys.go.goroutine", float64(runtime.NumGoroutine())).SetTags(tags))
|
|
|
+ ms = append(ms, metric.New("sys.go.ccall", float64(runtime.NumCgoCall())).SetTags(tags))
|
|
|
+ ms = append(ms, metric.New("sys.go.cpus", float64(runtime.NumCPU())).SetTags(tags))
|
|
|
+ ms = append(ms, metric.New("sys.go.gc", float64(memStats.NumGC)).SetTags(tags))
|
|
|
+ ms = append(ms, metric.New("sys.go.next_gc", float64(memStats.NextGC)).SetTags(tags))
|
|
|
+ ms = append(ms, metric.New("sys.go.heap_alloc", float64(memStats.HeapAlloc)).SetTags(tags))
|
|
|
+ ms = append(ms, metric.New("sys.go.heap_inuse", float64(memStats.HeapInuse)).SetTags(tags))
|
|
|
+ ms = append(ms, metric.New("sys.go.memory_allow", float64(memStats.Alloc)).SetTags(tags))
|
|
|
+ ms = append(ms, metric.New("sys.go.memory_frees", float64(memStats.Frees)).SetTags(tags))
|
|
|
+
|
|
|
+ if svr.opts.MetricCallback != nil {
|
|
|
+ vs := svr.opts.MetricCallback()
|
|
|
+ for _, v := range vs {
|
|
|
+ v.SetTags(tags)
|
|
|
+ ms = append(ms, v)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ metric.Push(svr.ctx, svr.opts.TSDBUrl, ms)
|
|
|
+}
|
|
|
+
|
|
|
func (svr *Service) Handle(method string, cb HandleFunc, opts ...HandleOption) {
|
|
|
opt := &HandleOptions{HttpMethod: "POST"}
|
|
|
for _, f := range opts {
|
|
@@ -117,13 +163,18 @@ func (svr *Service) Node() *registry.ServiceNode {
|
|
|
return svr.node
|
|
|
}
|
|
|
|
|
|
-func (svr *Service) generateInstance() {
|
|
|
+func (svr *Service) Environment() string {
|
|
|
+ return svr.environment
|
|
|
+}
|
|
|
+
|
|
|
+func (svr *Service) instance() *registry.ServiceNode {
|
|
|
var (
|
|
|
err error
|
|
|
id string
|
|
|
dockerID string
|
|
|
tcpAddr *net.TCPAddr
|
|
|
ipLocal string
|
|
|
+ node *registry.ServiceNode
|
|
|
)
|
|
|
if id, err = docker.SelfContainerID(); err != nil {
|
|
|
//生成唯一ID
|
|
@@ -133,8 +184,9 @@ func (svr *Service) generateInstance() {
|
|
|
id = hex.EncodeToString(e5.Sum(nil))
|
|
|
} else {
|
|
|
dockerID = id
|
|
|
+ svr.environment = EnvironmentDocker
|
|
|
}
|
|
|
- svr.node = ®istry.ServiceNode{
|
|
|
+ node = ®istry.ServiceNode{
|
|
|
ID: id,
|
|
|
Name: svr.opts.Name,
|
|
|
Version: svr.opts.Version,
|
|
@@ -146,21 +198,22 @@ func (svr *Service) generateInstance() {
|
|
|
} else {
|
|
|
ipLocal = svr.opts.Address
|
|
|
}
|
|
|
- svr.node.Address = ipLocal
|
|
|
+ node.Address = ipLocal
|
|
|
if svr.listener != nil {
|
|
|
if tcpAddr, err = net.ResolveTCPAddr("tcp", svr.listener.Addr().String()); err == nil {
|
|
|
- svr.node.Port = tcpAddr.Port
|
|
|
+ node.Port = tcpAddr.Port
|
|
|
}
|
|
|
} else {
|
|
|
- svr.node.Port = svr.opts.Port
|
|
|
+ node.Port = svr.opts.Port
|
|
|
}
|
|
|
- svr.node.Metadata["docker-id"] = dockerID
|
|
|
+ node.Metadata["docker-id"] = dockerID
|
|
|
if svr.opts.EnableHttp {
|
|
|
- svr.node.Metadata["enable-http"] = "true"
|
|
|
+ node.Metadata["enable-http"] = "true"
|
|
|
}
|
|
|
if svr.opts.EnableRPC {
|
|
|
- svr.node.Metadata["enable-rpc"] = "true"
|
|
|
+ node.Metadata["enable-rpc"] = "true"
|
|
|
}
|
|
|
+ return node
|
|
|
}
|
|
|
|
|
|
func (svr *Service) startHttpServe() (err error) {
|
|
@@ -240,7 +293,7 @@ func (svr *Service) prepare() (err error) {
|
|
|
err = svr.startRpcServe()
|
|
|
}
|
|
|
}
|
|
|
- svr.generateInstance()
|
|
|
+ svr.node = svr.instance()
|
|
|
svr.wrapSync(func() {
|
|
|
svr.eventLoop()
|
|
|
})
|
|
@@ -304,12 +357,13 @@ func New(opts ...Option) *Service {
|
|
|
opt(o)
|
|
|
}
|
|
|
svr := &Service{
|
|
|
- opts: o,
|
|
|
- upTime: time.Now(),
|
|
|
- httpSvr: http.New(),
|
|
|
- rpcSvr: rpc.NewServer(),
|
|
|
- registry: o.registry,
|
|
|
- client: NewClient(o.registry),
|
|
|
+ opts: o,
|
|
|
+ upTime: time.Now(),
|
|
|
+ httpSvr: http.New(),
|
|
|
+ rpcSvr: rpc.NewServer(),
|
|
|
+ registry: o.registry,
|
|
|
+ client: NewClient(o.registry),
|
|
|
+ environment: EnvironmentHost,
|
|
|
}
|
|
|
svr.ctx, svr.cancelFunc = context.WithCancel(o.Context)
|
|
|
return svr
|