2025-10-03 19:55:20 +08:00
|
|
|
|
// Package service 提供微服务管理功能
|
|
|
|
|
// 包括服务启动、注册、网关代理等核心功能
|
2025-03-29 15:02:49 +08:00
|
|
|
|
package service
|
|
|
|
|
|
|
|
|
|
import (
|
2025-03-30 13:23:46 +08:00
|
|
|
|
"context"
|
2025-03-29 15:02:49 +08:00
|
|
|
|
"log"
|
|
|
|
|
"net"
|
|
|
|
|
"os"
|
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
|
|
|
|
|
2025-03-30 13:23:46 +08:00
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
|
|
gwRuntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
|
|
|
|
|
2025-03-29 15:02:49 +08:00
|
|
|
|
"git.apinb.com/bsm-sdk/core/conf"
|
|
|
|
|
"git.apinb.com/bsm-sdk/core/env"
|
2025-09-27 00:20:36 +08:00
|
|
|
|
"git.apinb.com/bsm-sdk/core/printer"
|
2025-03-29 15:02:49 +08:00
|
|
|
|
"git.apinb.com/bsm-sdk/core/vars"
|
|
|
|
|
clientv3 "go.etcd.io/etcd/client/v3"
|
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type (
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// RegisterFn 定义服务注册函数类型
|
2025-03-29 15:02:49 +08:00
|
|
|
|
RegisterFn func(*grpc.Server)
|
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// Service 微服务实例
|
2025-03-29 15:02:49 +08:00
|
|
|
|
Service struct {
|
2025-10-03 19:55:20 +08:00
|
|
|
|
GrpcSrv *grpc.Server // gRPC服务器实例
|
|
|
|
|
Opts *Options // 服务配置选项
|
2025-03-29 15:02:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// Options 服务配置选项
|
2025-03-29 15:02:49 +08:00
|
|
|
|
Options struct {
|
2025-10-03 19:55:20 +08:00
|
|
|
|
Addr string // 服务监听地址
|
|
|
|
|
EtcdClient *clientv3.Client // Etcd客户端
|
|
|
|
|
MsConf *conf.MicroServiceConf // 微服务配置
|
|
|
|
|
GatewayConf *conf.GatewayConf // 网关配置
|
|
|
|
|
GatewayCtx context.Context // 网关上下文
|
|
|
|
|
GatewayMux *gwRuntime.ServeMux // 网关多路复用器
|
2025-03-29 15:02:49 +08:00
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// New 创建新的服务实例
|
|
|
|
|
// srv: gRPC服务器实例
|
|
|
|
|
// opts: 服务配置选项
|
2025-03-29 15:02:49 +08:00
|
|
|
|
func New(srv *grpc.Server, opts *Options) *Service {
|
|
|
|
|
return &Service{GrpcSrv: srv, Opts: opts}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// Addr 将IP和端口格式化为host:port格式
|
|
|
|
|
// ip: IP地址
|
|
|
|
|
// port: 端口号
|
2025-03-29 15:02:49 +08:00
|
|
|
|
func Addr(ip string, port int) string {
|
|
|
|
|
return net.JoinHostPort(ip, strconv.Itoa(port))
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// Start 启动服务
|
|
|
|
|
// 包括etcd注册、gRPC服务启动、HTTP网关启动
|
2025-03-29 15:02:49 +08:00
|
|
|
|
func (s *Service) Start() {
|
2025-09-27 00:20:36 +08:00
|
|
|
|
printer.Info("[BSM - %s] Service Starting ...", vars.ServiceKey)
|
2025-03-29 15:02:49 +08:00
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// 注册到etcd
|
2025-03-30 13:23:46 +08:00
|
|
|
|
if s.Opts.MsConf != nil && s.Opts.MsConf.Enable {
|
2025-03-29 15:02:49 +08:00
|
|
|
|
if s.Opts.EtcdClient == nil {
|
2025-09-27 00:20:36 +08:00
|
|
|
|
printer.Error("[BSM Register] Etcd Client is nil.")
|
2025-03-29 15:02:49 +08:00
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
2025-09-27 00:20:36 +08:00
|
|
|
|
printer.Info("[BSM - %s] Registering Service to Etcd ...", vars.ServiceKey)
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// 获取gRPC方法用于网关/路由发现
|
2025-03-29 15:02:49 +08:00
|
|
|
|
methods := FoundGrpcMethods(s.GrpcSrv)
|
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// 设置路由键
|
2025-03-29 15:02:49 +08:00
|
|
|
|
routerKey := vars.ServiceRootPrefix + "Router/" + env.Runtime.Workspace + "/" + strings.ToLower(vars.ServiceKey) + "/" + s.Opts.Addr
|
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// 使用租约注册到etcd
|
2025-03-29 15:02:49 +08:00
|
|
|
|
register, err := RegisterService(s.Opts.EtcdClient, routerKey, methods, vars.ServiceLease)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Panicf("[ERROR] %s Service Register:%s \n", vars.ServiceKey, err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
anonKey := vars.ServiceRootPrefix + "Router/" + env.Runtime.Workspace + "/"
|
|
|
|
|
|
2025-03-30 13:23:46 +08:00
|
|
|
|
register.SetAnonymous(anonKey, s.Opts.MsConf.Anonymous)
|
2025-03-29 15:02:49 +08:00
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// 服务注册租约监听
|
2025-03-29 15:02:49 +08:00
|
|
|
|
go register.ListenLeaseRespChan()
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// 启动gRPC服务
|
2025-03-29 15:02:49 +08:00
|
|
|
|
tcpListen, err := net.Listen("tcp", s.Opts.Addr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-30 13:23:46 +08:00
|
|
|
|
go func() {
|
|
|
|
|
if err := s.GrpcSrv.Serve(tcpListen); err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
}()
|
2025-09-27 00:20:36 +08:00
|
|
|
|
printer.Success("[BSM - %s] Grpc %s Runing Success !", vars.ServiceKey, s.Opts.Addr)
|
2025-03-30 13:23:46 +08:00
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// 启动HTTP网关
|
2025-03-30 13:23:46 +08:00
|
|
|
|
if s.Opts.GatewayConf != nil && s.Opts.GatewayConf.Enable {
|
|
|
|
|
addr := Addr("0.0.0.0", s.Opts.GatewayConf.Port)
|
|
|
|
|
go s.Gateway(s.Opts.Addr, addr)
|
|
|
|
|
|
2025-09-27 00:20:36 +08:00
|
|
|
|
printer.Success("[BSM - %s] Http %s Runing Success!", vars.ServiceKey, addr)
|
2025-03-29 15:02:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// 阻塞主线程
|
2025-03-30 13:23:46 +08:00
|
|
|
|
select {}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// Gateway 启动HTTP网关服务
|
|
|
|
|
// grpcAddr: gRPC服务地址
|
|
|
|
|
// httpAddr: HTTP服务地址
|
2025-03-30 13:23:46 +08:00
|
|
|
|
func (s *Service) Gateway(grpcAddr string, httpAddr string) {
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// 定义上下文
|
2025-03-30 13:23:46 +08:00
|
|
|
|
_, cancel := context.WithCancel(s.Opts.GatewayCtx)
|
|
|
|
|
defer cancel()
|
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// 启动HTTP服务,不因HTTP启动失败而导致panic
|
2025-09-27 00:41:27 +08:00
|
|
|
|
if err := http.ListenAndServe(httpAddr, s.Opts.GatewayMux); err != nil {
|
|
|
|
|
printer.Error("[BSM - %s] Http Serve Error: %v", vars.ServiceKey, err)
|
|
|
|
|
}
|
2025-03-29 15:02:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// Use 执行初始化函数
|
|
|
|
|
// initFunc: 初始化函数
|
2025-09-23 12:41:31 +08:00
|
|
|
|
func (s *Service) Use(initFunc func() error) {
|
|
|
|
|
err := (initFunc)()
|
|
|
|
|
if err != nil {
|
2025-09-27 00:20:36 +08:00
|
|
|
|
printer.Error(err.Error())
|
2025-09-23 12:41:31 +08:00
|
|
|
|
panic(err)
|
2025-09-23 12:37:00 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// Stop 优雅停止服务
|
2025-03-29 15:02:49 +08:00
|
|
|
|
func (s *Service) Stop() {
|
|
|
|
|
s.GrpcSrv.GracefulStop()
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-03 19:55:20 +08:00
|
|
|
|
// FoundGrpcMethods 发现gRPC服务中的所有方法
|
|
|
|
|
// s: gRPC服务器实例
|
|
|
|
|
// 返回: 方法名列表
|
2025-03-29 15:02:49 +08:00
|
|
|
|
func FoundGrpcMethods(s *grpc.Server) []string {
|
|
|
|
|
var mothods []string
|
|
|
|
|
for key, srv := range s.GetServiceInfo() {
|
|
|
|
|
srvName := strings.Split(key, ".")[1]
|
|
|
|
|
for _, mn := range srv.Methods {
|
|
|
|
|
mothods = append(mothods, srvName+"."+mn.Name)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return mothods
|
|
|
|
|
}
|