0 Star 1 Fork 0

shallot/Go开发工具集

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
web.go 3.99 KB
一键复制 编辑 原始数据 按行查看 历史
shallot 提交于 2024-12-17 15:56 +08:00 . 添加gomicro精简的微服务框架。
package gomicro
import (
"context"
"net"
"net/http"
"os"
"os/signal"
"strings"
"syscall"
"time"
"github.com/google/uuid"
)
var (
DefaultVersion = "latest"
DefaultId = uuid.New().String()
DefaultRegisterTTL = 2 * time.Second
DefaultRegisterInterval = 1 * time.Second
)
type WebOptions struct {
Name string // [必填] 服务名称
Address string // [必填] 监听地址
Handler http.Handler // [必填] 路由处理
Registry *ConsulRegistry // [必填] 服务注册与发现
// 以下为可选项
Context context.Context
Metadata map[string]string
Version string // 服务版本号
Id string // 服务实例ID,默认生成UUID
RegisterInterval time.Duration // 注册间隔,大于0,默认2秒钟
RegisterTTL time.Duration // 默认1秒钟
}
type WebService struct {
srv *RegistryService
exit chan chan error
ex chan bool
opts WebOptions
}
func NewWebService(options WebOptions) *WebService {
if len(options.Name) == 0 {
DefaultLogger.Fatal(nil, "web.opts.name is empty")
}
if len(options.Address) == 0 {
DefaultLogger.Fatal(nil, "web.opts.address is empty")
}
if options.Handler == nil {
DefaultLogger.Fatal(nil, "web.opts.handler is empty")
}
if options.Registry == nil {
DefaultLogger.Fatal(nil, "web.opts.registry is empty")
}
if len(options.Version) == 0 {
options.Version = DefaultVersion
}
if len(options.Id) == 0 {
options.Id = DefaultId
}
if options.RegisterTTL <= 0 {
options.RegisterTTL = DefaultRegisterTTL
}
if options.RegisterInterval <= 0 {
options.RegisterInterval = DefaultRegisterInterval
}
if options.Context == nil {
options.Context = context.TODO()
}
s := &WebService{
opts: options,
ex: make(chan bool),
}
s.srv = s.genSrv()
return s
}
func (s *WebService) Run() error {
if err := s.start(); err != nil {
return err
}
if err := s.register(); err != nil {
return err
}
// start reg loop
go s.run()
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT)
select {
// wait on kill signal
case sig := <-ch:
DefaultLogger.Info("received signal %s", sig)
// wait on context cancel
case <-s.opts.Context.Done():
DefaultLogger.Info("received context shutdown")
}
// exit reg loop
close(s.ex)
if err := s.deregister(); err != nil {
return err
}
return s.stop()
}
func (s *WebService) genSrv() *RegistryService {
var (
host string
port string
err error
)
// default host:port
host, port, err = net.SplitHostPort(s.opts.Address)
if err != nil {
DefaultLogger.Fatal(err, "web.opts.address is invalid")
}
addr, err := extract(host)
if err != nil {
DefaultLogger.Fatal(err, "web.genSrv extract failed")
}
if strings.Count(addr, ":") > 0 {
addr = "[" + addr + "]"
}
return &RegistryService{
Name: s.opts.Name,
Version: s.opts.Version,
Nodes: []*RegistryNode{{
Id: s.opts.Id,
Address: net.JoinHostPort(addr, port),
Metadata: s.opts.Metadata,
}},
}
}
func (s *WebService) run() {
t := time.NewTicker(s.opts.RegisterInterval)
for {
select {
case <-t.C:
s.register()
case <-s.ex:
t.Stop()
return
}
}
}
func (s *WebService) register() error {
// attempt to register
regErr := s.opts.Registry.Register(s.srv, s.opts.RegisterTTL)
if regErr != nil {
return regErr
}
return nil
}
func (s *WebService) deregister() error {
return s.opts.Registry.Deregister(s.srv)
}
func (s *WebService) start() error {
listener, err := net.Listen("tcp", s.opts.Address)
if err != nil {
return err
}
s.opts.Address = listener.Addr().String()
httpSrv := &http.Server{}
httpSrv.Handler = s.opts.Handler
go httpSrv.Serve(listener)
s.exit = make(chan chan error, 1)
go func() {
ch := <-s.exit
ch <- listener.Close()
}()
DefaultLogger.Info("listening on %v", listener.Addr().String())
return nil
}
func (s *WebService) stop() error {
ch := make(chan error, 1)
s.exit <- ch
DefaultLogger.Info("stopping")
return <-ch
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/gxsshallot/gotool.git
git@gitee.com:gxsshallot/gotool.git
gxsshallot
gotool
Go开发工具集
d05a69787598

搜索帮助