braft

package module
v0.0.0-...-f98774e Latest Latest
Warning

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

Go to latest
Published: Nov 21, 2024 License: MIT Imports: 47 Imported by: 0

README

An easy to use a customizable library to make your Go application Distributed, Highly available, Fault Tolerant etc... using Hashicorp's Raft library which implements the Raft Consensus Algorithm. Original fork from ksrichard/easyraft

Features

  • Configure and start a fully functional Raft node by writing ~10 lines of code
  • Automatic Node discovery (nodes are discovering each other using Discovery method)
    1. Built-in discovery methods:
      1. Static Discovery (having a fixed list of node addresses)
      2. mDNS Discovery for local network node discovery
      3. Kubernetes discovery
  • Cloud Native because of kubernetes discovery and easy to load balance features
  • Automatic forward to leader - you can contact any node to perform operations; everything will be forwarded to the actual leader node
  • Node monitoring/removal - the nodes are monitoring each other and if there are some failures, then the offline nodes get removed automatically from the cluster
  • Simplified state machine - there is an already implemented generic state machine which handles the basic operations and routes requests to State Machine Services (see Examples)
  • All layers are customizable - you can select or implement your own State Machine Service, Message Serializer and Discovery Method
  • gRPC transport layer - the internal communications are done through gRPC based communication, if needed you can add your own services

Note: snapshots are not supported at the moment, will be handled at later point Note: at the moment the communication between nodes is insecure, I recommend not exposing that port

Get Started

You can create a simple BRaft Node with local mDNS discovery, an in-memory Map service and MsgPack as serializer(this is the only one built-in at the moment)

package main

import (
	"log"

	"github.com/bingoohuang/ngg/braft"
)

func main() {
	node, err := braft.NewNode()
	if err != nil {
		log.Fatalf("failed to new node, error: %v", err)
	}
	if err := node.Start(); err != nil {
		log.Fatalf("failed to start node, error: %v", err)
	}
}
  1. use mDNS discovery: braft on multiple nodes.
  2. use static discovery: BRAFT_DISCOVERY="192.168.126.16,192.168.126.18,192.168.126.182" braft on multiple nodes.

env VARIABLES

NAME ACRONYM USAGE DEFAULT EXAMPLE
GOLOG_STDOUT N/A print log on stdout false export GOLOG_STDOUT=true
BRAFT_DISCOVERY BDI discovery configuration mdns export BRAFT_DISCOVERY="mdns:_braft._tcp"

export BRAFT_DISCOVERY="static:192.168.1.1,192.168.1.2,192.168.1.3"

export BRAFT_DISCOVERY="k8s"

BRAFT_IP BIP specify the IP first host IP export BRAFT_IP=192.168.1.1
BRAFT_IF BIF specify the IF name N/A export BRAFT_IF=eth0
BRAFT_RESTART_MIN N/A specify restart min wait if no leader 90s export BRAFT_RESTART_MIN=30s
BRAFT_LEADER_STEADY N/A specify the delay time after leader changing 60s export BRAFT_LEADER_STEADY=30s
BRAFT_RPORT BRP specify the raft port 15000 export BRAFT_RPORT=15000
BRAFT_DPORT BDP specify the discovery port $BRAFT_RPORT + 1 export BRAFT_DPORT=15001
BRAFT_HPORT BHP specify the http port $DRAFT_DPORT + 1 export BRAFT_HPORT=15002
BRAFT_SLEEP BSL random sleep to startup raft cluster 10ms-15s export BRAFT_SLEEP=100ms-3s
MDNS_SERVICE MDS mDNS Service name (e.g. _http._tcp.) _braft._tcp,_windows export MDS=_braft._tcp,_windows
K8S_NAMESPACE K8N k8s namespace (empty) export K8S_NAMESPACE=prod
K8S_LABELS K8L service labels (empty) export K8S_LABELS=svc=braft
K8S_PORTNAME K8P container tcp port name (empty) export K8S_PORTNAME=http
K8S_SLEEP N/A k8s discovery sleep before start 15-30s export K8S_SLEEP=30-50s
DISABLE_GRPC_REFLECTION DGR disable grpc reflection off export DISABLE_GRPC_REFLECTION=off

demo

use static discovery

At localhost:

  1. BRAFT_RESTART_MIN=10s BRAFT_LEADER_STEADY=10s BRAFT_RPORT=15000 BRAFT_DISCOVERY="127.0.0.1:15000,127.0.0.1:16000,127.0.0.1:17000" braft
  2. BRAFT_RESTART_MIN=10s BRAFT_LEADER_STEADY=10s BRAFT_RPORT=16000 BRAFT_DISCOVERY="127.0.0.1:15000,127.0.0.1:16000,127.0.0.1:17000" braft
  3. BRAFT_RESTART_MIN=10s BRAFT_LEADER_STEADY=10s BRAFT_RPORT=17000 BRAFT_DISCOVERY="127.0.0.1:15000,127.0.0.1:16000,127.0.0.1:17000" braft

At 3-different hosts:

  1. BRAFT_RPORT=15000 BRAFT_DISCOVERY="host1,host2,host3" braft

use mDNS discovery

  1. braft
  2. braft (same)
  3. braft (same)

use k8s discovery

  1. K8S_SLEEP=50-80s K8N=footstone BDI=k8s K8L=svc=braft ./braft

example /raft http rest api result

$ gurl :15002/raft
{
  "currentLeader": false,
  "discovery": "mdns://_braft._tcp,_demo",
  "leaderAddr": "192.168.6.240:16000",
  "leaderID": "hKJJRLsyZ1UxVmdwM1lWcEdmNTdWSGRmMjVQbTM5b1OoSG9zdG5hbWWvYmluZ29vZGVNQlAubGFuoklQrTE5Mi4xNjguNi4yNDCkU3FpZKxJaWZmdjJ1akIwVWw",
  "nodeNum": 2,
  "nodes": [
    {
      "serverID": "hKJJRLsyZ1UxUnQ3SWJXdG5lN1l5VlhuQ0QwSnVZYVKoSG9zdG5hbWWvYmluZ29vZGVNQlAubGFuoklQrTE5Mi4xNjguNi4yNDCkU3FpZKw2WlZBZ0ZiMnh6aDc",
      "buildTime": "2024-05-15T09:41:41+0800",
      "duration": "59.048655379s",
      "address": "192.168.6.240:15000",
      "raftState": "Follower",
      "leader": "192.168.6.240:16000",
      "appVersion": "1.0.0",
      "startTime": "2024-05-15T09:42:16.594002+08:00",
      "goVersion": "go1.22.3_darwin/amd64",
      "gitCommit": "master-18f39a8@2024-04-25T14:20:29+08:00",
      "discoveryNodes": ["192.168.6.240:15000", "192.168.6.240:16000"],
      "addr": ["192.168.6.240:15000"],
      "raftID": {
        "id": "2gU1Rt7IbWtne7YyVXnCD0JuYaR",
        "hostname": "bingoodeMBP.lan",
        "ip": "192.168.6.240",
        "sqid": "6ZVAgFb2xzh7"
      },
      "raftLogSum": 0,
      "pid": 82043,
      "rss": 33443840,
      "pcpu": 1,
      "rport": 15000,
      "dport": 15001,
      "hport": 15002
    },
    {
      "serverID": "hKJJRLsyZ1UxVmdwM1lWcEdmNTdWSGRmMjVQbTM5b1OoSG9zdG5hbWWvYmluZ29vZGVNQlAubGFuoklQrTE5Mi4xNjguNi4yNDCkU3FpZKxJaWZmdjJ1akIwVWw",
      "buildTime": "2024-05-15T09:41:41+0800",
      "duration": "28.132773032s",
      "address": "192.168.6.240:16000",
      "raftState": "Leader",
      "leader": "192.168.6.240:16000",
      "appVersion": "1.0.0",
      "startTime": "2024-05-15T09:42:47.519663+08:00",
      "goVersion": "go1.22.3_darwin/amd64",
      "gitCommit": "master-18f39a8@2024-04-25T14:20:29+08:00",
      "discoveryNodes": ["192.168.6.240:16000"],
      "addr": ["192.168.6.240:16000"],
      "raftID": {
        "id": "2gU1Vgp3YVpGf57VHdf25Pm39oS",
        "hostname": "bingoodeMBP.lan",
        "ip": "192.168.6.240",
        "sqid": "Iiffv2ujB0Ul"
      },
      "raftLogSum": 0,
      "pid": 82453,
      "rss": 33402880,
      "pcpu": 1.2,
      "rport": 16000,
      "dport": 16001,
      "hport": 16002
    }
  ],
  "raftServers": [
    {
      "suffrage": 0,
      "id": "hKJJRLsyZ1UxUnQ3SWJXdG5lN1l5VlhuQ0QwSnVZYVKoSG9zdG5hbWWvYmluZ29vZGVNQlAubGFuoklQrTE5Mi4xNjguNi4yNDCkU3FpZKw2WlZBZ0ZiMnh6aDc",
      "address": "192.168.6.240:15000"
    },
    {
      "suffrage": 0,
      "id": "hKJJRLsyZ1UxVmdwM1lWcEdmNTdWSGRmMjVQbTM5b1OoSG9zdG5hbWWvYmluZ29vZGVNQlAubGFuoklQrTE5Mi4xNjguNi4yNDCkU3FpZKxJaWZmdjJ1akIwVWw",
      "address": "192.168.6.240:16000"
    }
  ]
}
# gurl :30010/raft
GET /raft? HTTP/1.1
Host: localhost:30010
Accept: application/json
Accept-Encoding: gzip, deflate
Content-Type: application/json
User-Agent: gurl/0.1.0


HTTP/1.1 200 OK
Date: Fri, 11 Feb 2022 03:58:50 GMT
Content-Type: application/json; charset=utf-8

{
  "CurrentLeader": false,
  "Discovery": "k8s://ns=footstone-common/labels=svc=braft/portName=",
  "Leader": "10.42.6.90:15000",
  "NodeNum": 3,
  "Nodes": [
    {
      "Leader": "10.42.6.90:15000",
      "ServerID": "hqJJRLsyNHdtNGh1WXJaS0dmS3VBdW80OHRaeHVWTUWlUnBvcnTNOpilRHBvcnTNOpmlSHBvcnTNOpqoSG9zdG5hbWW1YnJhZnQtZDliZmY0YjliLWt6ZGhxoklQkaoxMC40Mi42Ljky",
      "Address": "10.42.6.92:15000",
      "RaftState": "Follower",
      "RaftID": {
        "ID": "24wm4huYrZKGfKuAuo48tZxuVME",
        "Rport": 15000,
        "Dport": 15001,
        "Hport": 15002,
        "Hostname": "braft-d9bff4b9b-kzdhq",
        "IP": [
          "10.42.6.92"
        ]
      },
      "DiscoveryNodes": [
        "10.42.6.92",
        "10.42.6.90",
        "10.42.6.91"
      ],
      "StartTime": "2022-02-11T11:23:53.950293142+08:00",
      "Duration": "34m56.054300649s",
      "Rss": 57172,
      "RaftLogSum": 0,
      "Pid": 12,
      "GitCommit": "e4d9145@2022-02-11T10:50:34+08:00",
      "BuildTime": "2022-02-11T11:23:12+0800",
      "GoVersion": "go1.17.5_linux/amd64",
      "AppVersion": "1.0.0",
      "Pcpu": 2.7027028
    },
    {
      "Leader": "10.42.6.90:15000",
      "ServerID": "hqJJRLsyNHdtM2VKSEp5WGQ4RWYydDRHT0NWMmpXWE6lUnBvcnTNOpilRHBvcnTNOpmlSHBvcnTNOpqoSG9zdG5hbWW1YnJhZnQtZDliZmY0YjliLXhqYjJjoklQkaoxMC40Mi42Ljkx",
      "Address": "10.42.6.91:15000",
      "RaftState": "Follower",
      "RaftID": {
        "ID": "24wm3eJHJyXd8Ef2t4GOCV2jWXN",
        "Rport": 15000,
        "Dport": 15001,
        "Hport": 15002,
        "Hostname": "braft-d9bff4b9b-xjb2c",
        "IP": [
          "10.42.6.91"
        ]
      },
      "DiscoveryNodes": [
        "10.42.6.92",
        "10.42.6.90",
        "10.42.6.91"
      ],
      "StartTime": "2022-02-11T11:23:45.672142228+08:00",
      "Duration": "35m4.353394194s",
      "Rss": 58504,
      "RaftLogSum": 0,
      "Pid": 12,
      "GitCommit": "e4d9145@2022-02-11T10:50:34+08:00",
      "BuildTime": "2022-02-11T11:23:12+0800",
      "GoVersion": "go1.17.5_linux/amd64",
      "AppVersion": "1.0.0",
      "Pcpu": 2.739726
    },
    {
      "Leader": "10.42.6.90:15000",
      "ServerID": "hqJJRLsyNHdtMmdDV2lDbmI2SjRINFFydWxSeHZhZFSlUnBvcnTNOpilRHBvcnTNOpmlSHBvcnTNOpqoSG9zdG5hbWW1YnJhZnQtZDliZmY0YjliLWxxdnpuoklQkaoxMC40Mi42Ljkw",
      "Address": "10.42.6.90:15000",
      "RaftState": "Leader",
      "RaftID": {
        "ID": "24wm2gCWiCnb6J4H4QrulRxvadT",
        "Rport": 15000,
        "Dport": 15001,
        "Hport": 15002,
        "Hostname": "braft-d9bff4b9b-lqvzn",
        "IP": [
          "10.42.6.90"
        ]
      },
      "DiscoveryNodes": [
        "10.42.6.92",
        "10.42.6.90",
        "10.42.6.91"
      ],
      "StartTime": "2022-02-11T11:23:37.367006837+08:00",
      "Duration": "35m12.673937071s",
      "Rss": 57216,
      "RaftLogSum": 0,
      "Pid": 12,
      "GitCommit": "e4d9145@2022-02-11T10:50:34+08:00",
      "BuildTime": "2022-02-11T11:23:12+0800",
      "GoVersion": "go1.17.5_linux/amd64",
      "AppVersion": "1.0.0",
      "Pcpu": 2.631579
    }
  ]
}
# gurl http://a.b.c/rig-braft-service/raft
GET /rig-braft-service/raft? HTTP/1.1
Host: beta.isignet.cn:36131
Accept: application/json
Accept-Encoding: gzip, deflate
Content-Type: application/json
Gurl-Date: Wed, 16 Feb 2022 03:22:20 GMT
User-Agent: gurl/1.0.0


HTTP/1.1 200 OK
Server: nginx/1.19.2
Date: Wed, 16 Feb 2022 03:22:22 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Vary: Accept-Encoding
Content-Encoding: gzip

{
  "CurrentLeader": true,
  "Discovery": "static://rig-braft-service-0.rig-braft-service,rig-braft-service-1.rig-braft-service,rig-braft-service-2.rig-braft-service",
  "Leader": "10.42.6.198:11469",
  "NodeNum": 3,
  "Nodes": [
    {
      "Leader": "10.42.6.198:11469",
      "ServerID": "hqJJRLsyNUFyZDFqclp2Qmt5bnBWRUI5aGNRS2ZIZGelUnBvcnTNLM2lRHBvcnTNLM6lSHBvcnTNLM-oSG9zdG5hbWWzcmlnLWJyYWZ0LXNlcnZpY2UtMqJJUJGrMTAuNDIuNi4xOTg",
      "Address": "10.42.6.198:11469",
      "RaftState": "Leader",
      "RaftID": {
        "ID": "25Ard1jrZvBkynpVEB9hcQKfHdg",
        "Rport": 11469,
        "Dport": 11470,
        "Hport": 11471,
        "Hostname": "rig-braft-service-2",
        "IP": [
          "10.42.6.198"
        ]
      },
      "DiscoveryNodes": [
        "rig-braft-service-0.rig-braft-service",
        "rig-braft-service-1.rig-braft-service",
        "rig-braft-service-2.rig-braft-service"
      ],
      "StartTime": "2022-02-16T11:06:55.5760445+08:00",
      "Duration": "15m27.069639007s",
      "Rss": 49672,
      "RaftLogSum": 0,
      "Pid": 12,
      "GitCommit": "ca3ff05@2022-02-16T11:03:28+08:00",
      "BuildTime": "2022-02-16T11:05:56+0800",
      "GoVersion": "go1.17.5_linux/amd64",
      "AppVersion": "1.2.0",
      "Pcpu": 2.3118222
    },
    {
      "Leader": "10.42.6.198:11469",
      "ServerID": "hqJJRLsyNUFyZGRuS1R3bDNDREdMUXpRU3h2U1EzekWlUnBvcnTNLM2lRHBvcnTNLM6lSHBvcnTNLM-oSG9zdG5hbWWzcmlnLWJyYWZ0LXNlcnZpY2UtMaJJUJGrMTAuNDIuNi4xOTk",
      "Address": "10.42.6.199:11469",
      "RaftState": "Follower",
      "RaftID": {
        "ID": "25ArddnKTwl3CDGLQzQSxvSQ3zE",
        "Rport": 11469,
        "Dport": 11470,
        "Hport": 11471,
        "Hostname": "rig-braft-service-1",
        "IP": [
          "10.42.6.199"
        ]
      },
      "DiscoveryNodes": [
        "rig-braft-service-0.rig-braft-service",
        "rig-braft-service-1.rig-braft-service",
        "rig-braft-service-2.rig-braft-service"
      ],
      "StartTime": "2022-02-16T11:07:00.867960857+08:00",
      "Duration": "15m21.77895389s",
      "Rss": 46216,
      "RaftLogSum": 0,
      "Pid": 12,
      "GitCommit": "ca3ff05@2022-02-16T11:03:28+08:00",
      "BuildTime": "2022-02-16T11:05:56+0800",
      "GoVersion": "go1.17.5_linux/amd64",
      "AppVersion": "1.2.0",
      "Pcpu": 1.1629363
    },
    {
      "Leader": "10.42.6.198:11469",
      "ServerID": "hqJJRLsyNUFyaUsyTXhNbDNjTjlIMUJ6MUY4TEZDZTClUnBvcnTNLM2lRHBvcnTNLM6lSHBvcnTNLM-oSG9zdG5hbWWzcmlnLWJyYWZ0LXNlcnZpY2UtMKJJUJGrMTAuNDIuMi4yMTA",
      "Address": "10.42.2.210:11469",
      "RaftState": "Follower",
      "RaftID": {
        "ID": "25AriK2MxMl3cN9H1Bz1F8LFCe0",
        "Rport": 11469,
        "Dport": 11470,
        "Hport": 11471,
        "Hostname": "rig-braft-service-0",
        "IP": [
          "10.42.2.210"
        ]
      },
      "DiscoveryNodes": [
        "rig-braft-service-0.rig-braft-service",
        "rig-braft-service-1.rig-braft-service",
        "rig-braft-service-2.rig-braft-service"
      ],
      "StartTime": "2022-02-16T11:07:37.501965271+08:00",
      "Duration": "14m45.146689237s",
      "Rss": 43672,
      "RaftLogSum": 0,
      "Pid": 13,
      "GitCommit": "ca3ff05@2022-02-16T11:03:28+08:00",
      "BuildTime": "2022-02-16T11:05:56+0800",
      "GoVersion": "go1.17.5_linux/amd64",
      "AppVersion": "1.2.0",
      "Pcpu": 1.5182345
    }
  ]
}

grpcui

  1. check the env DISABLE_GRPC_REFLECTION is not enabled.
  2. install grpcui
  3. grpcui -plaintext localhost:15000

image

本机 static 双节点测试

  1. BRAFT_DISCOVERY=192.168.6.240:15001,192.168.6.240:16001 BRAFT_RPORT=15000 braft
  2. BRAFT_DISCOVERY=192.168.6.240:15001,192.168.6.240:16001 BRAFT_RPORT=16000 braft
  3. gurl :15002/raft
{
  "currentLeader": true,
  "discovery": "static://192.168.6.240:15001,192.168.6.240:16001",
  "leaderAddr": "192.168.6.240:15000",
  "leaderID": "hKJJRLsyZ1hEdW1ISDlDZzFiU29JdWZ0RTJ5SEhraWOoSG9zdG5hbWWvYmluZ29vZGVNQlAubGFuoklQrTE5Mi4xNjguNi4yNDCkU3FpZKw2WlZBZ0ZiMnh6aDc",
  "memberList": [
    {
      "addr": "192.168.6.240",
      "name": "hKJJRLsyZ1hEdW1ISDlDZzFiU29JdWZ0RTJ5SEhraWOoSG9zdG5hbWWvYmluZ29vZGVNQlAubGFuoklQrTE5Mi4xNjguNi4yNDCkU3FpZKw2WlZBZ0ZiMnh6aDc:15000",
      "port": 15001
    },
    {
      "addr": "192.168.6.240",
      "name": "hKJJRLsyZ1hEdzZxc1FlR3RDcEFoZkd1VmVmczc0VGWoSG9zdG5hbWWvYmluZ29vZGVNQlAubGFuoklQrTE5Mi4xNjguNi4yNDCkU3FpZKxJaWZmdjJ1akIwVWw:16000",
      "port": 16001
    }
  ],
  "nodeNum": 2,
  "nodes": [
    {
      "serverID": "hKJJRLsyZ1hEdW1ISDlDZzFiU29JdWZ0RTJ5SEhraWOoSG9zdG5hbWWvYmluZ29vZGVNQlAubGFuoklQrTE5Mi4xNjguNi4yNDCkU3FpZKw2WlZBZ0ZiMnh6aDc",
      "buildTime": "2024-05-16T12:53:58+0800",
      "duration": "27.754114093s",
      "address": "192.168.6.240:15000",
      "raftState": "Leader",
      "leader": "192.168.6.240:15000",
      "appVersion": "1.0.0",
      "startTime": "2024-05-16T12:54:13.278255+08:00",
      "goVersion": "go1.22.3_darwin/amd64",
      "gitCommit": "master-e97f6f2@2024-05-16T09:05:54+08:00",
      "discoveryNodes": ["192.168.6.240:15001", "192.168.6.240:16001"],
      "addr": ["192.168.6.240:15000"],
      "raftID": {
        "id": "2gXDumHH9Cg1bSoIuftE2yHHkic",
        "hostname": "bingoodeMBP.lan",
        "ip": "192.168.6.240",
        "sqid": "6ZVAgFb2xzh7"
      },
      "raftLogSum": 0,
      "pid": 19026,
      "rss": 31629312,
      "pcpu": 0.3,
      "raftPort": 15000,
      "discoveryPort": 15001,
      "httpPort": 15002
    },
    {
      "serverID": "hKJJRLsyZ1hEdzZxc1FlR3RDcEFoZkd1VmVmczc0VGWoSG9zdG5hbWWvYmluZ29vZGVNQlAubGFuoklQrTE5Mi4xNjguNi4yNDCkU3FpZKxJaWZmdjJ1akIwVWw",
      "buildTime": "2024-05-16T12:53:58+0800",
      "duration": "16.927061744s",
      "address": "192.168.6.240:16000",
      "raftState": "Follower",
      "leader": "192.168.6.240:15000",
      "appVersion": "1.0.0",
      "startTime": "2024-05-16T12:54:24.114572+08:00",
      "goVersion": "go1.22.3_darwin/amd64",
      "gitCommit": "master-e97f6f2@2024-05-16T09:05:54+08:00",
      "discoveryNodes": ["192.168.6.240:15001", "192.168.6.240:16001"],
      "addr": ["192.168.6.240:16000"],
      "raftID": {
        "id": "2gXDw6qsQeGtCpAhfGuVefs74Te",
        "hostname": "bingoodeMBP.lan",
        "ip": "192.168.6.240",
        "sqid": "Iiffv2ujB0Ul"
      },
      "raftLogSum": 0,
      "pid": 19162,
      "rss": 30310400,
      "pcpu": 0.2,
      "raftPort": 16000,
      "discoveryPort": 16001,
      "httpPort": 16002
    }
  ],
  "raftServers": [
    {
      "suffrage": 0,
      "id": "hKJJRLsyZ1hEdW1ISDlDZzFiU29JdWZ0RTJ5SEhraWOoSG9zdG5hbWWvYmluZ29vZGVNQlAubGFuoklQrTE5Mi4xNjguNi4yNDCkU3FpZKw2WlZBZ0ZiMnh6aDc",
      "address": "192.168.6.240:15000"
    },
    {
      "suffrage": 0,
      "id": "hKJJRLsyZ1hEdzZxc1FlR3RDcEFoZkd1VmVmczc0VGWoSG9zdG5hbWWvYmluZ29vZGVNQlAubGFuoklQrTE5Mi4xNjguNi4yNDCkU3FpZKxJaWZmdjJ1akIwVWw",
      "address": "192.168.6.240:16000"
    }
  ]
}

Documentation

Overview

Package braft 提供了 raft 更加方便的集成 API 胶水代码。

Index

Constants

This section is empty.

Variables

View Source
var (
	// DefaultMdnsService 默认 Mdns 服务名称
	DefaultMdnsService string
	// DefaultK8sNamespace 默认 k8s 命名空间名称
	DefaultK8sNamespace string
	// DefaultK8sPortName 默认 k8s 端口名称
	DefaultK8sPortName string
	// DefaultK8sServiceLabels 默认 i8s 服务标签
	DefaultK8sServiceLabels map[string]string
	// DefaultDiscovery 默认发现策略
	DefaultDiscovery string
	// EnvIP IP 值
	EnvIP string
	// EnvRport Raft 端口值
	EnvRport int
	// EnvDport Discovery 端口值
	EnvDport int
	// EnvHport HTTP 端口值
	EnvHport int
	// DefaultStaticPeers 静态端点列表
	DefaultStaticPeers []string
)
View Source
var ErrNoLeader = errors.New("no leader found")

Functions

func CheckTCP

func CheckTCP(ipPort string) bool

func CreateDiscovery

func CreateDiscovery(discoveryMethod string, dport int) discovery.Discovery

CreateDiscovery creates a new discovery from the given discovery method.

func GetPeerDetails

func GetPeerDetails(addr string, timeout time.Duration) (*proto.GetDetailsResponse, error)

GetPeerDetails returns the remote peer details.

func GetRaftClient

func GetRaftClient(addr string, timeout time.Duration) (ctx context.Context, deferFn func(), client proto.RaftClient, err error)

GetRaftClient returns the raft client with timeout context.

func Setup

func Setup()

Setup 初始化设置客户端

Types

type ClientGrpcServices

type ClientGrpcServices struct {
	proto.UnimplementedRaftServer
	Node *Node
}

ClientGrpcServices is the client of grpc services.

func NewClientGrpcService

func NewClientGrpcService(node *Node) *ClientGrpcServices

NewClientGrpcService creates a new ClientGrpcService.

func (*ClientGrpcServices) ApplyLog

ApplyLog responses the request.

func (*ClientGrpcServices) GetDetails

GetDetails returns the node details.

type Config

type Config struct {
	TypeRegister    *marshal.TypeRegister
	DataDir         string
	Discovery       discovery.Discovery
	Services        []fsm.Service
	LeaderChange    NodeStateChanger
	BizData         func() any
	HTTPConfigFns   []HTTPConfigFn
	EnableHTTP      bool
	GrpcDialOptions []grpc.DialOption

	// Rport Raft 监听端口值
	Rport int
	// Dport Discovery 端口值
	Dport int
	// Hport HTTP 端口值
	Hport int
	// Raft ServiceID
	ServerID string
	// ShutdownExit 集群停止时,直接退出,方便 systemctl 重启
	ShutdownExit bool
	// ShutdownExitCode 退出时的编码
	ShutdownExitCode int

	// HostIP 当前主机的IP
	HostIP string
}

Config is the configuration of the node.

type ConfigFn

type ConfigFn func(*Config)

ConfigFn is the function option pattern for the NodeConfig.

func WithBizData

func WithBizData(s func() any) ConfigFn

WithBizData specifies the biz data of current node for the node for /raft api .

func WithDataDir

func WithDataDir(s string) ConfigFn

WithDataDir specifies the data directory.

func WithDiscovery

func WithDiscovery(s discovery.Discovery) ConfigFn

WithDiscovery specifies the discovery method of raft cluster nodes.

func WithDiscoveryPort

func WithDiscoveryPort(port int) ConfigFn

WithDiscoveryPort specifies the discovery port.

func WithEnableHTTP

func WithEnableHTTP(v bool) ConfigFn

WithEnableHTTP specifies whether to enable the http service.

func WithGrpcDialOptions

func WithGrpcDialOptions(options ...grpc.DialOption) ConfigFn

WithGrpcDialOptions specifies the grpc options.

func WithHTTPFns

func WithHTTPFns(s ...HTTPConfigFn) ConfigFn

WithHTTPFns specifies the http service.

func WithHostIP

func WithHostIP(v string) ConfigFn

func WithHttpPort

func WithHttpPort(port int) ConfigFn

WithHttpPort specifies the http port.

func WithLeaderChange

func WithLeaderChange(s NodeStateChanger) ConfigFn

WithLeaderChange specifies the leader change callback.

func WithRaftPort

func WithRaftPort(port int) ConfigFn

WithRaftPort specifies the raft port.

func WithServerID

func WithServerID(serverID string) ConfigFn

WithServerID specifies the RaftID.

func WithServices

func WithServices(s ...fsm.Service) ConfigFn

WithServices specifies the services for the FSM.

func WithShutdownExitCode

func WithShutdownExitCode(shutdownExit bool, shutdownExitCode int) ConfigFn

WithShutdownExitCode specifies the program should exit or not when the raft cluster shutdown.

func WithTypeRegister

func WithTypeRegister(s *marshal.TypeRegister) ConfigFn

WithTypeRegister specifies the serializer.TypeRegister of the raft log messages.

type DistributeOption

type DistributeOption struct {
	Key string // http /distribute/:key
}

type DistributeOptionFunc

type DistributeOptionFunc func(*DistributeOption)

func WithKey

func WithKey(key string) DistributeOptionFunc

type HTTPConfig

type HTTPConfig struct {
	Handlers []pathHalder
	EnableKv bool
}

HTTPConfig is configuration for HTTP service.

type HTTPConfigFn

type HTTPConfigFn func(*HTTPConfig)

HTTPConfigFn is function options for HTTPConfig.

func WithEnableKV

func WithEnableKV(b bool) HTTPConfigFn

WithEnableKV enables or disables KV service on HTTP.

func WithHandler

func WithHandler(method, path string, handler HandlerFunc) HTTPConfigFn

WithHandler defines the http handler.

type HandlerFunc

type HandlerFunc func(ctx *gin.Context, n *Node)

HandlerFunc defines the handler used by gin middleware as return value.

type Node

type Node struct {
	StartTime time.Time

	Raft       *raft.Raft
	GrpcServer *grpc.Server

	Conf *Config

	TransportManager *transport.Manager

	ID string

	RaftID RaftID

	GrpcListen net.Listener

	DistributeCache sync.Map // map[string]fsm.Distributable
	// contains filtered or unexported fields
}

Node is the raft cluster node.

func NewNode

func NewNode(fns ...ConfigFn) (*Node, error)

NewNode returns an BRaft node.

func (*Node) ApplyOnLeader

func (n *Node) ApplyOnLeader(payload []byte, timeout time.Duration) (any, error)

ApplyOnLeader apply a payload on the leader node.

func (*Node) DiscoveryName

func (n *Node) DiscoveryName() string

DiscoveryName returns the name of discovery.

func (*Node) Distribute

func (n *Node) Distribute(bean fsm.Distributable, fns ...DistributeOptionFunc) (any, error)

Distribute distributes the given bean to all the nodes in the cluster.

func (*Node) GetDistribute

func (n *Node) GetDistribute(key string, result any) (nodeID string, err error)

func (*Node) GetRaftNodes

func (n *Node) GetRaftNodes(raftServers []raft.Server) (nodes []RaftNode)

GetRaftNodes return the raft nodes information.

func (*Node) GetRaftNodesInfo

func (n *Node) GetRaftNodesInfo() (nodes []RaftNode)

GetRaftNodesInfo return the raft nodes information.

func (*Node) GetRaftServers

func (n *Node) GetRaftServers() []raft.Server

GetRaftServers 获得 Raft 节点服务器列表.

func (*Node) IsLeader

func (n *Node) IsLeader() bool

IsLeader tells whether the current node is the leader.

func (*Node) Leader

func (n *Node) Leader() (*RaftID, error)

func (*Node) NotifyJoin

func (n *Node) NotifyJoin(node *memberlist.Node)

NotifyJoin triggered when a new Node has been joined to the cluster (discovery only) and capable of joining the Node to the raft cluster

func (*Node) NotifyLeave

func (n *Node) NotifyLeave(node *memberlist.Node)

NotifyLeave triggered when a Node becomes unavailable after a period of time it will remove the unavailable Node from the Raft cluster

func (*Node) NotifyUpdate

func (n *Node) NotifyUpdate(node *memberlist.Node)

NotifyUpdate responses the update of raft cluster member.

func (*Node) RaftApply

func (n *Node) RaftApply(request any, timeout time.Duration) (any, error)

RaftApply is used to apply any new logs to the raft cluster this method will do automatic forwarding to the Leader Node

func (*Node) RegisterServeKV

func (n *Node) RegisterServeKV(r gin.IRoutes, path string)

RegisterServeKV register kv service for the gin route.

func (*Node) ServeDistribute

func (n *Node) ServeDistribute(ctx *gin.Context)

func (*Node) ServeKV

func (n *Node) ServeKV(ctx *gin.Context)

ServeKV services the kv set/get http api.

func (*Node) ServeRaft

func (n *Node) ServeRaft(ctx *gin.Context)

ServeRaft services the raft http api.

func (*Node) ShortNodeIds

func (n *Node) ShortNodeIds() (nodeIds []string)

ShortNodeIds returns a sorted list of short node IDs in the current raft cluster.

func (*Node) Start

func (n *Node) Start() (err error)

Start starts the Node and returns a channel that indicates, that the node has been stopped properly

func (*Node) Stop

func (n *Node) Stop()

Stop stops the node and notifies on a stopped channel returned in Start.

type NodeStateChanger

type NodeStateChanger func(n *Node, nodeState raft.RaftState)

NodeStateChanger defines the leader change callback func prototype.

type NotifyEvent

type NotifyEvent struct {
	*memberlist.Node
	NotifyType
}

NotifyEvent 通知事件

type NotifyType

type NotifyType int

NotifyType 定义通知类型

const (

	// NotifyJoin 通知加入 Raft 集群
	NotifyJoin NotifyType
	// NotifyLeave 通知离开 Raft 集群
	NotifyLeave
	// NotifyUpdate 通知更新 Raft 集群
	NotifyUpdate
)

func (NotifyType) String

func (t NotifyType) String() string

type RaftID

type RaftID struct {
	ID         string `json:"id,omitempty"`
	Hostname   string `json:"hostname,omitempty"`
	IP         string `json:"ip,omitempty"`
	Sqid       string `json:"sqid,omitempty"` // {RaftPort, Dport, Hport}
	ServerID   string `json:"serverID,omitempty"`
	ServerAddr string `json:"serverAddr,omitempty"`
}

RaftID is the structure of node ID.

func ParseRaftID

func ParseRaftID(s string) (rid RaftID)

ParseRaftID parses the coded raft ID string a RaftID structure.

func UnmarshRaftID

func UnmarshRaftID(serverID string) (*RaftID, error)

func (RaftID) NodeID

func (i RaftID) NodeID() string

type RaftNode

type RaftNode struct {
	ServerID  string `json:"serverID"`
	BuildTime string `json:"buildTime"`
	Duration  string `json:"duration"`

	Address    string `json:"address"`
	RaftState  string `json:"raftState"`
	Leader     string `json:"leader"`
	AppVersion string `json:"appVersion"`
	StartTime  string `json:"startTime"`
	Error      string `json:"error,omitempty"`
	GoVersion  string `json:"goVersion"`

	GitCommit      string   `json:"gitCommit"`
	DiscoveryNodes []string `json:"discoveryNodes"`

	Addr []string `json:"addr"`

	BizData json.RawMessage `json:"bizData,omitempty"`

	RaftID RaftID `json:"raftID"`

	RaftLogSum uint64 `json:"raftLogSum"`
	Pid        uint64 `json:"pid"`

	Rss  uint64  `json:"rss"`
	Pcpu float32 `json:"pcpu"`

	RaftPort      int `json:"raftPort"`
	DiscoveryPort int `json:"discoveryPort"`
	HttpPort      int `json:"httpPort"`

	NodeIds []string `json:"nodeIds"`
}

RaftNode is a node info of raft cluster.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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