You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
4.1 KiB

7 years ago
  1. package weed_server
  2. import (
  3. "fmt"
  4. "net"
  5. "time"
  6. "github.com/chrislusf/seaweedfs/weed/security"
  7. "github.com/spf13/viper"
  8. "google.golang.org/grpc"
  9. "github.com/chrislusf/seaweedfs/weed/glog"
  10. "github.com/chrislusf/seaweedfs/weed/pb/master_pb"
  11. "github.com/chrislusf/seaweedfs/weed/util"
  12. "golang.org/x/net/context"
  13. )
  14. func (vs *VolumeServer) GetMaster() string {
  15. return vs.currentMaster
  16. }
  17. func (vs *VolumeServer) heartbeat() {
  18. glog.V(0).Infof("Volume server start with masters: %v", vs.MasterNodes)
  19. vs.store.SetDataCenter(vs.dataCenter)
  20. vs.store.SetRack(vs.rack)
  21. grpcDialOption := security.LoadClientTLS(viper.Sub("grpc"), "volume")
  22. var err error
  23. var newLeader string
  24. for {
  25. for _, master := range vs.MasterNodes {
  26. if newLeader != "" {
  27. master = newLeader
  28. }
  29. masterGrpcAddress, parseErr := util.ParseServerToGrpcAddress(master)
  30. if parseErr != nil {
  31. glog.V(0).Infof("failed to parse master grpc %v: %v", masterGrpcAddress, parseErr)
  32. continue
  33. }
  34. newLeader, err = vs.doHeartbeat(context.Background(), master, masterGrpcAddress, grpcDialOption, time.Duration(vs.pulseSeconds)*time.Second)
  35. if err != nil {
  36. glog.V(0).Infof("heartbeat error: %v", err)
  37. time.Sleep(time.Duration(vs.pulseSeconds) * time.Second)
  38. newLeader = ""
  39. }
  40. }
  41. }
  42. }
  43. func (vs *VolumeServer) doHeartbeat(ctx context.Context, masterNode, masterGrpcAddress string, grpcDialOption grpc.DialOption, sleepInterval time.Duration) (newLeader string, err error) {
  44. grpcConection, err := util.GrpcDial(ctx, masterGrpcAddress, grpcDialOption)
  45. if err != nil {
  46. return "", fmt.Errorf("fail to dial %s : %v", masterNode, err)
  47. }
  48. defer grpcConection.Close()
  49. client := master_pb.NewSeaweedClient(grpcConection)
  50. stream, err := client.SendHeartbeat(ctx)
  51. if err != nil {
  52. glog.V(0).Infof("SendHeartbeat to %s: %v", masterNode, err)
  53. return "", err
  54. }
  55. glog.V(0).Infof("Heartbeat to: %v", masterNode)
  56. vs.currentMaster = masterNode
  57. vs.store.Client = stream
  58. defer func() { vs.store.Client = nil }()
  59. doneChan := make(chan error, 1)
  60. go func() {
  61. for {
  62. in, err := stream.Recv()
  63. if err != nil {
  64. doneChan <- err
  65. return
  66. }
  67. if in.GetVolumeSizeLimit() != 0 {
  68. vs.store.SetVolumeSizeLimit(in.GetVolumeSizeLimit())
  69. }
  70. if in.GetLeader() != "" && masterNode != in.GetLeader() && !isSameIP(in.GetLeader(), masterNode) {
  71. glog.V(0).Infof("Volume Server found a new master newLeader: %v instead of %v", in.GetLeader(), masterNode)
  72. newLeader = in.GetLeader()
  73. doneChan <- nil
  74. return
  75. }
  76. }
  77. }()
  78. if err = stream.Send(vs.store.CollectHeartbeat()); err != nil {
  79. glog.V(0).Infof("Volume Server Failed to talk with master %s: %v", masterNode, err)
  80. return "", err
  81. }
  82. tickChan := time.Tick(sleepInterval)
  83. for {
  84. select {
  85. case volumeMessage := <-vs.store.NewVolumesChan:
  86. deltaBeat := &master_pb.Heartbeat{
  87. NewVolumes: []*master_pb.VolumeShortInformationMessage{
  88. &volumeMessage,
  89. },
  90. }
  91. glog.V(1).Infof("volume server %s:%d adds volume %d", vs.store.Ip, vs.store.Port, volumeMessage.Id)
  92. if err = stream.Send(deltaBeat); err != nil {
  93. glog.V(0).Infof("Volume Server Failed to update to master %s: %v", masterNode, err)
  94. return "", err
  95. }
  96. case volumeMessage := <-vs.store.DeletedVolumesChan:
  97. deltaBeat := &master_pb.Heartbeat{
  98. DeletedVolumes: []*master_pb.VolumeShortInformationMessage{
  99. &volumeMessage,
  100. },
  101. }
  102. glog.V(1).Infof("volume server %s:%d deletes volume %d", vs.store.Ip, vs.store.Port, volumeMessage.Id)
  103. if err = stream.Send(deltaBeat); err != nil {
  104. glog.V(0).Infof("Volume Server Failed to update to master %s: %v", masterNode, err)
  105. return "", err
  106. }
  107. case <-tickChan:
  108. glog.V(4).Infof("volume server %s:%d heartbeat", vs.store.Ip, vs.store.Port)
  109. if err = stream.Send(vs.store.CollectHeartbeat()); err != nil {
  110. glog.V(0).Infof("Volume Server Failed to talk with master %s: %v", masterNode, err)
  111. return "", err
  112. }
  113. case err = <-doneChan:
  114. return
  115. }
  116. }
  117. }
  118. func isSameIP(ip string, host string) bool {
  119. ips, err := net.LookupIP(host)
  120. if err != nil {
  121. return false
  122. }
  123. for _, t := range ips {
  124. if ip == t.String() {
  125. return true
  126. }
  127. }
  128. return false
  129. }