go开源网络库nano(2)-集群和节点

前言

第一篇只要介绍了nano 库的一些概念,这篇主要讲解代码部分。因为这个库作者还是不断完善中,所以后续可能会有变动。作者已经在最初版本上加入了cluster,集群等概念。

结构

cluster集群

cluster 包含有多个nano节点
每个nano都提供一组不同的服务。
所有服务需求从客户端开始,并向前推进到适当的节点。

// cluster represents a nano cluster, which contains a bunch of nano nodes
// and each of them provide a group of different services. All services requests
// from client will send to gate firstly and be forwarded to appropriate node.
type cluster struct {
	// If cluster is not large enough, use slice is OK
	currentNode *Node
	rpcClient   *rpcClient

	mu      sync.RWMutex
	members []*Member
}

node 节点:

Node表示nano集群中的一个节点,该节点将包含一组服务。
所有服务都将注册到群集,消息将转发到节点
提供各自的服务

// Node represents a node in nano cluster, which will contains a group of services.
// All services will register to cluster and messages will be forwarded to the node
// which provides respective service
type Node struct {
	Options            // current node options
	ServiceAddr string // current server service address (RPC)

	cluster   *cluster
	handler   *LocalHandler
	server    *grpc.Server
	rpcClient *rpcClient

	mu       sync.RWMutex
	sessions map[int64]*session.Session
}

listen 函数 --启动一个node 并配置属性

定义

listen 是启动一个node的主要函数,设置监听端口,并且通过可变参数进行对node一下属性进行配置。

//Listen listens on the TCP network address addr and then calls Serve with handler to handle requests on incoming connections.
func Listen(addr string, opts …Option)
第二个参数是函数定义
type Option func(*cluster.Options)

//node.go
type Options struct {
    Pipeline       pipeline.Pipeline
    IsMaster       bool             //是否是master服务器
    AdvertiseAddr  string           //需要连接的ip和port
    RetryInterval  time.Duration
    ClientAddr     string
    Components     *component.Components         //注册服务
    Label          string
    IsWebsocket    bool              //是否websocket
    TSLCertificate string
    TSLKey         string
}

配置函数

func listen 通过参数进行配置,代理中也提供了配置函数

1. func WithMaster

WithMaster设置指示当前节点是否为主节点的选项

// options.go
func WithMaster() Option

// WithMaster sets the option to indicate whether the current node is master node
func WithMaster() Option {
	return func(opt *cluster.Options) {
		opt.IsMaster = true
	}
}
2. func WithComponents

设置功能组件

func WithComponents(components *component.Components) Option {
	return func(opt *cluster.Options) {
		opt.Components = components
	}
}
3. func WithAdvertiseAddr

设置AdvertiseAddr变量。其实是master node 的ip地址,端口和超时重连,用于连接master node。
master node 不用设置。

func WithAdvertiseAddr(addr string, retryInterval ...time.Duration) Option {
	return func(opt *cluster.Options) {
		opt.AdvertiseAddr = addr
		if len(retryInterval) > 0 {
			opt.RetryInterval = retryInterval[0]
		}
	}
}
4. func WithClientAddr

设置用于在群集成员之间建立连接的侦听地址。如果没有成员地址设置,将自动选择可用端口;如果没有可用端口,将panic (我理解的还不是很清楚这个函数)

func WithClientAddr(addr string) Option {
	return func(opt *cluster.Options) {
		opt.ClientAddr = addr
	}
}
5. func WithHeartbeatInterval

设置心跳时间

func WithHeartbeatInterval(d time.Duration) Option {
	return func(_ *cluster.Options) {
		env.Heartbeat = d
	}
}
6. func WithIsWebsocket

指示当前节点WebSocket是否已启用

func WithIsWebsocket(enableWs bool) Option {
	return func(opt *cluster.Options) {
		opt.IsWebsocket = enableWs
	}
}
7. func WithDebugMode

设置debug模式

func WithDebugMode() Option {
	return func(_ *cluster.Options) {
		env.Debug = true
	}
}
8. func WithSerializer

自定义应用程序序列化过程,它自动封送和解除封送处理程序

func WithSerializer(serializer serialize.Serializer) Option {
	return func(opt *cluster.Options) {
		env.Serializer = serializer
	}
}

listen函数实现

// interface.go
// Listen listens on the TCP network address addr
// and then calls Serve with handler to handle requests
// on incoming connections.
func Listen(addr string, opts ...Option) {
	if atomic.AddInt32(&running, 1) != 1 {
		log.Println("Nano has running")
		return
	}

	// application initialize
	app.name = strings.TrimLeft(filepath.Base(os.Args[0]), "/")
	app.startAt = time.Now()

	// environment initialize
	if wd, err := os.Getwd(); err != nil {
		panic(err)
	} else {
		env.Wd, _ = filepath.Abs(wd)
	}

	opt := cluster.Options{
		Components: &component.Components{},
	}
	for _, option := range opts {
		option(&opt)
	}

	// Use listen address as client address in non-cluster mode
	if !opt.IsMaster && opt.AdvertiseAddr == "" && opt.ClientAddr == "" {
		log.Println("The current server running in singleton mode")
		opt.ClientAddr = addr
	}

	// Set the retry interval to 3 secondes if doesn't set by user
	if opt.RetryInterval == 0 {
		opt.RetryInterval = time.Second * 3
	}

	node := &cluster.Node{
		Options:     opt,
		ServiceAddr: addr,
	}
	err := node.Startup()
	if err != nil {
		log.Fatalf("Node startup failed: %v", err)
	}
	runtime.CurrentNode = node

	if node.ClientAddr != "" {
		log.Println(fmt.Sprintf("Startup *Nano gate server* %s, client address: %v, service address: %s",
			app.name, node.ClientAddr, node.ServiceAddr))
	} else {
		log.Println(fmt.Sprintf("Startup *Nano backend server* %s, service address %s",
			app.name, node.ServiceAddr))
	}

	go scheduler.Sched()
	sg := make(chan os.Signal)
	signal.Notify(sg, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGTERM)

	select {
	case <-env.Die:
		log.Println("The app will shutdown in a few seconds")
	case s := <-sg:
		log.Println("Nano server got signal", s)
	}

	log.Println("Nano server is stopping...")

	node.Shutdown()
	runtime.CurrentNode = nil
	scheduler.Close()
	atomic.StoreInt32(&running, 0)
}

cluster关闭

// Shutdown send a signal to let 'nano' shutdown itself.
func Shutdown() {
	close(env.Die)
}

备注

这是一些基本的,还有其他的设置函数,比如重新设置日志系统,TSL加密等等,大家可以去看源码。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值