firemelon

package
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 29, 2024 License: LGPL-3.0 Imports: 19 Imported by: 0

README

如何实现业务自定义框架

业务自定义框架是指根据业务特性基于 watermelon 实现自定义注册/发现字段信息
本文我们以一个定时任务系统的角度来设计基础框架

  1. 复制整个根目录下 watermelon.go 文件到业务代码中,例如本示例的 firemelon.go(当然记得修改包名)

  2. 声明业务自定义的 NodeMeta(注册信息) 与 ResolveMeta(发现信息)

自定义注册信息

需要实现

interface[T any] {
    // 框架需要
    WithMeta(register.NodeMeta) T
    // watermelon自带的etcd注册器需要
    RegisterKey() string
	Value() string
}

register.NodeMeta 为框架能获取的一些关于节点的基本信息,用户可以根据需要自行通过 WithMeta 方法 merge 进 NodeMeta 中
WithMeta(register.NodeMeta) T 在框架调用服务前时被调用, watermelon.registry.Append(s.CustomInfo.WithMeta(metaData))

假设我们当前场景需要按照组织及系统来划分不同的微服务,同时我们又要通过地区属性(region)来隔离不同网络环境下的服务,且希望每个服务拥有自己的一个权重属性用来做负载均衡逻辑
那么我们的 NodeMeta 设计如下

type NodeMeta struct {
	OrgID        string
	System       string
	Region       string
	Weight       int32
	RegisterTime int64
	register.NodeMeta
}

通过实现 WithMeta(register.NodeMeta) T 方法拿到框架提供给我们的一些服务基本信息

func (n NodeMeta) WithMeta(meta register.NodeMeta) NodeMeta {
	n.NodeMeta = meta
	return n
}

通过实现 RegisterKey() stringValue() string 两个方法来告诉 etcd 注册器我们需要写入 etcd 的 key 和 value


func init() {
	// 首先设置etcd key前缀,该前缀主要用来与其他共用etcd的业务进行隔离,其次可以方便的通过该前缀获取所有与之相关的服务注册信息
	infra.RegisterETCDRegisterPrefixKey("/gophercron/registry")
}

func (n NodeMeta) RegisterKey() string {
	// 实际写入时框架会在我们生成的key前面加上 etcdkeyprefix,这里我们只需要生成业务相关的key即可
	return fmt.Sprintf("%s/%s/%s/node/%s:%d", n.OrgID, n.System, n.ServiceName, n.Host, n.Port)
}

func (n NodeMeta) Value() string {
	n.RegisterTime = time.Now().Unix()

	raw, _ := json.Marshal(n)
	return string(raw)
}

当我们在设计 etcd key 时,是需要考虑到我们的节点如何被 resolver 发现,示例中我们设计的 key 为

{组织 ID}/{系统名称}/{服务名称}/node/IP:端口

其中组织 ID 可以方便的使我们系统成为多租户系统,比如公司内部不同的部门进行隔离
这样在我们定时任务中心需要发现某一系统的 agent 时,就可以使用

etcdctl get {etcd-prefix-key}/{组织ID}/{系统名称} --prefix

实现代码见 service.meta.go 中的 NodeMeta

自定义发现信息

需要实现

interface {
    FullServiceName(srvName string) string
}

返回服务发现时需要用到的 target,该 taget 不包含 scheme

实现代码见 client.meta.go 中的 ResolveMeta

  1. 实现 server 与 client 的 options 配置方法
func (s *Server[T]) WithSystem(ns string) infra.Option[NodeMeta] {
	return func(s *infra.SrvInfo[NodeMeta]) {
		s.CustomInfo.System = ns
	}
}

func (s *Server[T]) WithOrg(org string) infra.Option[NodeMeta] {
	return func(s *infra.SrvInfo[NodeMeta]) {
		s.CustomInfo.OrgID = org
	}
}

至此完成了业务框架的自定义封装

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultAllowFunc

func DefaultAllowFunc(query url.Values, attr NodeMeta, addr *resolver.Address) bool

func MustSetupEtcdRegister

func MustSetupEtcdRegister() register.ServiceRegister[NodeMeta]

func MustSetupEtcdResolver

func MustSetupEtcdResolver() wresolver.Resolver

func RegisterETCDRegisterPrefixKey

func RegisterETCDRegisterPrefixKey(prefix string)

RegisterETCDRegisterPrefixKey a function to change default register(etcd) prefix key

func RegisterEtcdClient

func RegisterEtcdClient(etcdConfig clientv3.Config) error

ResolveEtcdClient a function to register etcd client to watermelon global

func RegisterRegionProxy

func RegisterRegionProxy(region, proxy string)

RegisterRegionProxy set region's proxy endpoint

func ResolveEtcdClient

func ResolveEtcdClient() *clientv3.Client

ResolveEtcdClient a function to get registed etcd client

func ResolveProxy

func ResolveProxy(region string) string

ResolveProxy return region's proxy, if it exist

Types

type ClientConn

type ClientConn[T infra.ClientServiceNameGenerator] func(serviceName string, opts ...infra.ClientOptions[T]) (*grpc.ClientConn, error)

ClientConn is a function to create grpc client connection

func NewClientConn

func NewClientConn() ClientConn[ResolveMeta]

NewClientConn is a function to create a cc instance

func (*ClientConn[T]) WithDialTimeout

func (c *ClientConn[T]) WithDialTimeout(t time.Duration) infra.ClientOptions[T]

func (*ClientConn[T]) WithGrpcDialOptions

func (c *ClientConn[T]) WithGrpcDialOptions(opts ...grpc.DialOption) infra.ClientOptions[T]

func (*ClientConn[T]) WithOrg

func (*ClientConn[T]) WithOrg(id string) infra.ClientOptions[ResolveMeta]

func (*ClientConn[T]) WithRegion

func (*ClientConn[T]) WithRegion(region string) infra.ClientOptions[ResolveMeta]

func (*ClientConn[T]) WithServiceResolver

func (c *ClientConn[T]) WithServiceResolver(r resolver.Resolver) infra.ClientOptions[T]

func (*ClientConn[T]) WithSystem

func (*ClientConn[T]) WithSystem(ns string) infra.ClientOptions[ResolveMeta]

type NodeMeta

type NodeMeta struct {
	OrgID        string
	System       string
	Region       string
	Weight       int32
	RegisterTime int64
	register.NodeMeta
}

register node meta

func (NodeMeta) Equal

func (n NodeMeta) Equal(b any) bool

func (NodeMeta) RegisterKey

func (n NodeMeta) RegisterKey() string

func (NodeMeta) Value

func (n NodeMeta) Value() string

func (NodeMeta) WithMeta

func (n NodeMeta) WithMeta(meta register.NodeMeta) NodeMeta

type ResolveMeta

type ResolveMeta struct {
	OrgID  string
	Region string
	System string
}

resolver service meta

func (ResolveMeta) FullServiceName

func (r ResolveMeta) FullServiceName(srvName string) string

func (ResolveMeta) ProxyMetadata

func (r ResolveMeta) ProxyMetadata() metadata.MD

type Server

type Server[T interface {
	WithMeta(register.NodeMeta) T
}] func(register func(srv *grpc.Server), opts ...infra.Option[T]) *infra.Srv[T]

Server is a function to build grpc service

func NewServer

func NewServer() Server[NodeMeta]

NewServer is a function to create a server instance

func (*Server[T]) WithAddress

func (*Server[T]) WithAddress(addr []infra.Address) infra.Option[T]

func (*Server[T]) WithGrpcServerOptions

func (s *Server[T]) WithGrpcServerOptions(opts ...grpc.ServerOption) infra.Option[T]

func (*Server[T]) WithHttpServer

func (*Server[T]) WithHttpServer(srv *http.Server) infra.Option[T]

func (*Server[T]) WithOrg

func (s *Server[T]) WithOrg(org string) infra.Option[NodeMeta]

func (*Server[T]) WithRegion

func (s *Server[T]) WithRegion(region string) infra.Option[NodeMeta]

customized options

func (*Server[T]) WithServiceRegister

func (*Server[T]) WithServiceRegister(r register.ServiceRegister[NodeMeta]) infra.Option[NodeMeta]

copy infra options

func (*Server[T]) WithSystem

func (s *Server[T]) WithSystem(ns string) infra.Option[NodeMeta]

func (*Server[T]) WithWeight

func (s *Server[T]) WithWeight(weight int32) infra.Option[NodeMeta]

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL