2018-05-24raft實現代碼

1.go語言實現raft分發(fā)原理
main.go 文件代碼如下

package main

import (
    "sync"
    "math/rand"
    "fmt"
    "time"
    "go/ast"
)

// 設置節(jié)點的個數為3
const raftCount  =3
// 聲明leader
type AppendEntiresArgs struct {
    Term int// 第幾任領導
    leaderId  int//設置領導編號
}
// 創(chuàng)建一個領導對象
var args   =AppendEntiresArgs{0,-1}
// 聲明節(jié)點類型
type Raft struct {
    // 線程鎖
    mu  sync.Mutex
    // 節(jié)點編號
    me int
    //當前領導期數
    currentTerm int
    // 為哪個節(jié)點投票
    votedFor int
    //當前節(jié)點的狀態(tài)
    state int// 0 跟隨者 1候選人 2就是領導
    // 厚厚一天發(fā)送消息時間
    lastMessageTime  int64
    // 節(jié)點間發(fā)送消息的通道
    message  chan bool
    // 選舉通道
    eclectCh chan bool
    // 心跳信號通道
    heartBeat chan bool
    // 返回心跳信號
    heartBeatRe chan  bool
    // 超時時間
    timeout  int

    // 設置當前節(jié)點的領導
  currentLeader int
}
// 產生隨機值
func  randRange(min,max int64)int64  {
    return  rand.Int63n(max-min)+min
}
// 打印當前時間
func printTime()  {
    fmt.Printf("%s",time.Now().String())
}

// 獲取當前時間的ms
func millisecond()int64  {
    return  time.Now().UnixNano()/int64(time.Millisecond)
}

func  main()  {
    // 創(chuàng)建三個節(jié)點
    for i:=0;i<raftCount ;i++  {
        // 創(chuàng)建三個raft
        Make(i)

    }
    for{

    }
}
// 通過make函數創(chuàng)建raft節(jié)點的對象
func Make(me int)*Raft  {
    rf :=&Raft{}
    rf.me = me
    rf.votedFor = -1
    rf.state = 0
    rf.timeout =0
    rf.currentLeader = -1
    rf.setTerm(0)
    // 創(chuàng)建通道對象
    rf.eclectCh = make(chan bool)
    rf.message = make(chan  bool)
    rf.heartBeat = make(chan bool)
    rf.heartBeatRe = make(chan bool)
    rand.Seed(time.Now().UnixNano())

    go rf.sendLeaderHeartBeat()
    go rf.election()

    return rf
}
// 創(chuàng)建raft對象的方法
func  (rf *Raft) setTerm(term int)  {
    rf.currentTerm = term
}
// 設置節(jié)點發(fā)送心跳信號的方法
func (rf *Raft)sendLeaderHeartBeat()  {
}
//設置節(jié)點投票的方法
func (rf *Raft)election ()  {
    // 設置標簽
    var result bool
    for  {
        // 設置超時時間
        timeout := randRange(150,300)
        // 設置每個節(jié)點的時間
        rf.lastMessageTime = millisecond()
        select {
        // 延遲等待
        case <-time.After(time.Duration(timeout)*time.Millisecond):
            fmt.Println(rf.state)// 打印當前節(jié)點的狀態(tài)
        }
        result= false
        for !result{
            // 選擇誰作為leader
            result = rf.election_one_round(&args)
        }
    }
}
// 選擇誰為leader
func (rf *Raft)election_one_round(args *AppendEntiresArgs)bool  {
    var  timeout int64
    var done int
    // 是否開始心跳信號的產生
    var  triggerHeartbeat bool
    last := millisecond()
    timeout = 100
    // 信號變量標簽
    success :=false
    // 修改raft節(jié)點的狀態(tài)為candidate候選人狀態(tài)
    rf.mu.Lock()
    rf.becomeCandidate()
    rf.mu.Unlock()

    fmt.Println("start electing leader")
    for  {
        for i:=0;i<raftCount ;i++  {
            if i!= rf.me {
                //拉選票
             printTime()
             go func() {
                 if args.leaderId <0 {
                    // 設置此節(jié)點開始選舉
                    rf.eclectCh <- true
                 }
             }()
            }
        }
        // 設置投票數量
        done =0
        triggerHeartbeat = false
        for i:=0;i<raftCount-1 ;i++  {
            // 計算一下投票的數量
            //raftCount-1 把自己去掉
            select {
            case ok:= <-rf.eclectCh:
                if ok {
                    done ++
                    success = done>raftCount/2
                    if success && !triggerHeartbeat {
                        // 選舉成功了
                        triggerHeartbeat = true
                        rf.mu.Lock()
                        rf.brcomeLeader()
                        rf.mu.Unlock()
                        // 由leader向其他節(jié)點發(fā)送心跳信號
                        rf.heartBeat <- true
                        fmt.Println("leader發(fā)送心跳信號")
                    }
                }
            }
        }
        if(timeout+last <millisecond()||(done>raftCount/2 || rf.currentLeader>-1)) {
            break
        }else {
            select {
            // 延時操作
            case <-time.After(time.Duration(10)*time.Millisecond):      
            }
        }
    }
    return success
}
func(rf *Raft) becomeCandidate()  {
    rf.state  = 1
    rf.setTerm(rf.currentTerm +1)
    rf.votedFor = rf.me
    rf.currentLeader = -1
}
func (rf *Raft)brcomeLeader()  {
    rf.state = 2
    rf.currentLeader = rf.me
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容