fix leadership transfer on leave suggestions (#11387)
* add suggestions * set isLeader to false when leadership transfer succeed
This commit is contained in:
parent
9e8e5e407e
commit
75f69a98a2
|
@ -1,3 +1,3 @@
|
||||||
```release-note:enhancement
|
```release-note:enhancement
|
||||||
try to transfer leadership to another server when leaving.
|
raft: Consul leaders will attempt to transfer leadership to another server as part of gracefully leaving the cluster.
|
||||||
```
|
```
|
||||||
|
|
|
@ -977,6 +977,22 @@ func (s *Server) Shutdown() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) attemptLeadershipTransfer() (success bool) {
|
||||||
|
leadershipTransferVersion := version.Must(version.NewVersion(LeaderTransferMinVersion))
|
||||||
|
|
||||||
|
ok, _ := ServersInDCMeetMinimumVersion(s, s.config.Datacenter, leadershipTransferVersion)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
future := s.raft.LeadershipTransfer()
|
||||||
|
if err := future.Error(); err != nil {
|
||||||
|
s.logger.Error("failed to transfer leadership, removing the server", "error", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Leave is used to prepare for a graceful shutdown of the server
|
// Leave is used to prepare for a graceful shutdown of the server
|
||||||
func (s *Server) Leave() error {
|
func (s *Server) Leave() error {
|
||||||
s.logger.Info("server starting leave")
|
s.logger.Info("server starting leave")
|
||||||
|
@ -996,24 +1012,9 @@ func (s *Server) Leave() error {
|
||||||
// removed for some reasonable period of time.
|
// removed for some reasonable period of time.
|
||||||
isLeader := s.IsLeader()
|
isLeader := s.IsLeader()
|
||||||
if isLeader && numPeers > 1 {
|
if isLeader && numPeers > 1 {
|
||||||
leadershipTransferVersion := version.Must(version.NewVersion(LeaderTransferMinVersion))
|
if s.attemptLeadershipTransfer() {
|
||||||
removeServer := false
|
|
||||||
if ok, _ := ServersInDCMeetMinimumVersion(s, s.config.Datacenter, leadershipTransferVersion); !ok {
|
|
||||||
// Transfer leadership to another node then leave the cluster
|
|
||||||
future := s.raft.LeadershipTransfer()
|
|
||||||
if err := future.Error(); err != nil {
|
|
||||||
s.logger.Error("failed to transfer leadership, removing the server", "error", err)
|
|
||||||
// leadership transfer failed, fallback to removing the server from raft
|
|
||||||
removeServer = true
|
|
||||||
} else {
|
|
||||||
// we are not leader anymore, continue the flow to leave as follower
|
|
||||||
isLeader = false
|
isLeader = false
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Leadership transfer is not available in the current version, fallback to removing the server from raft
|
|
||||||
removeServer = true
|
|
||||||
}
|
|
||||||
if removeServer {
|
|
||||||
future := s.raft.RemoveServer(raft.ServerID(s.config.NodeID), 0, 0)
|
future := s.raft.RemoveServer(raft.ServerID(s.config.NodeID), 0, 0)
|
||||||
if err := future.Error(); err != nil {
|
if err := future.Error(); err != nil {
|
||||||
s.logger.Error("failed to remove ourself as raft peer", "error", err)
|
s.logger.Error("failed to remove ourself as raft peer", "error", err)
|
||||||
|
|
Loading…
Reference in New Issue