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.

177 lines
5.3 KiB

6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
4 years ago
  1. package weed_server
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "os"
  7. "sync"
  8. "time"
  9. "github.com/chrislusf/seaweedfs/weed/stats"
  10. "google.golang.org/grpc"
  11. "github.com/chrislusf/seaweedfs/weed/util/grace"
  12. "github.com/chrislusf/seaweedfs/weed/operation"
  13. "github.com/chrislusf/seaweedfs/weed/pb"
  14. "github.com/chrislusf/seaweedfs/weed/pb/master_pb"
  15. "github.com/chrislusf/seaweedfs/weed/util"
  16. "github.com/chrislusf/seaweedfs/weed/filer"
  17. _ "github.com/chrislusf/seaweedfs/weed/filer/cassandra"
  18. _ "github.com/chrislusf/seaweedfs/weed/filer/elastic/v7"
  19. _ "github.com/chrislusf/seaweedfs/weed/filer/etcd"
  20. _ "github.com/chrislusf/seaweedfs/weed/filer/leveldb"
  21. _ "github.com/chrislusf/seaweedfs/weed/filer/leveldb2"
  22. _ "github.com/chrislusf/seaweedfs/weed/filer/mongodb"
  23. _ "github.com/chrislusf/seaweedfs/weed/filer/mysql"
  24. _ "github.com/chrislusf/seaweedfs/weed/filer/postgres"
  25. _ "github.com/chrislusf/seaweedfs/weed/filer/redis"
  26. _ "github.com/chrislusf/seaweedfs/weed/filer/redis2"
  27. "github.com/chrislusf/seaweedfs/weed/glog"
  28. "github.com/chrislusf/seaweedfs/weed/notification"
  29. _ "github.com/chrislusf/seaweedfs/weed/notification/aws_sqs"
  30. _ "github.com/chrislusf/seaweedfs/weed/notification/gocdk_pub_sub"
  31. _ "github.com/chrislusf/seaweedfs/weed/notification/google_pub_sub"
  32. _ "github.com/chrislusf/seaweedfs/weed/notification/kafka"
  33. _ "github.com/chrislusf/seaweedfs/weed/notification/log"
  34. "github.com/chrislusf/seaweedfs/weed/security"
  35. )
  36. type FilerOption struct {
  37. Masters []string
  38. Collection string
  39. DefaultReplication string
  40. DisableDirListing bool
  41. MaxMB int
  42. DirListingLimit int
  43. DataCenter string
  44. Rack string
  45. DefaultLevelDbDir string
  46. DisableHttp bool
  47. Host string
  48. Port uint32
  49. recursiveDelete bool
  50. Cipher bool
  51. Filers []string
  52. }
  53. type FilerServer struct {
  54. option *FilerOption
  55. secret security.SigningKey
  56. filer *filer.Filer
  57. grpcDialOption grpc.DialOption
  58. // metrics read from the master
  59. metricsAddress string
  60. metricsIntervalSec int
  61. // notifying clients
  62. listenersLock sync.Mutex
  63. listenersCond *sync.Cond
  64. brokers map[string]map[string]bool
  65. brokersLock sync.Mutex
  66. }
  67. func NewFilerServer(defaultMux, readonlyMux *http.ServeMux, option *FilerOption) (fs *FilerServer, err error) {
  68. fs = &FilerServer{
  69. option: option,
  70. grpcDialOption: security.LoadClientTLS(util.GetViper(), "grpc.filer"),
  71. brokers: make(map[string]map[string]bool),
  72. }
  73. fs.listenersCond = sync.NewCond(&fs.listenersLock)
  74. if len(option.Masters) == 0 {
  75. glog.Fatal("master list is required!")
  76. }
  77. fs.filer = filer.NewFiler(option.Masters, fs.grpcDialOption, option.Host, option.Port, option.Collection, option.DefaultReplication, option.DataCenter, func() {
  78. fs.listenersCond.Broadcast()
  79. })
  80. fs.filer.Cipher = option.Cipher
  81. fs.checkWithMaster()
  82. go stats.LoopPushingMetric("filer", stats.SourceName(fs.option.Port), fs.metricsAddress, fs.metricsIntervalSec)
  83. go fs.filer.KeepConnectedToMaster()
  84. v := util.GetViper()
  85. if !util.LoadConfiguration("filer", false) {
  86. v.Set("leveldb2.enabled", true)
  87. v.Set("leveldb2.dir", option.DefaultLevelDbDir)
  88. _, err := os.Stat(option.DefaultLevelDbDir)
  89. if os.IsNotExist(err) {
  90. os.MkdirAll(option.DefaultLevelDbDir, 0755)
  91. }
  92. glog.V(0).Infof("default to create filer store dir in %s", option.DefaultLevelDbDir)
  93. }
  94. util.LoadConfiguration("notification", false)
  95. fs.option.recursiveDelete = v.GetBool("filer.options.recursive_delete")
  96. v.SetDefault("filer.options.buckets_folder", "/buckets")
  97. fs.filer.DirBucketsPath = v.GetString("filer.options.buckets_folder")
  98. // TODO deprecated, will be be removed after 2020-12-31
  99. // replaced by https://github.com/chrislusf/seaweedfs/wiki/Path-Specific-Configuration
  100. fs.filer.FsyncBuckets = v.GetStringSlice("filer.options.buckets_fsync")
  101. fs.filer.LoadConfiguration(v)
  102. notification.LoadConfiguration(v, "notification.")
  103. handleStaticResources(defaultMux)
  104. if !option.DisableHttp {
  105. defaultMux.HandleFunc("/", fs.filerHandler)
  106. }
  107. if defaultMux != readonlyMux {
  108. handleStaticResources(readonlyMux)
  109. readonlyMux.HandleFunc("/", fs.readonlyFilerHandler)
  110. }
  111. fs.filer.AggregateFromPeers(fmt.Sprintf("%s:%d", option.Host, option.Port), option.Filers)
  112. fs.filer.LoadBuckets()
  113. fs.filer.LoadFilerConf()
  114. grace.OnInterrupt(func() {
  115. fs.filer.Shutdown()
  116. })
  117. return fs, nil
  118. }
  119. func (fs *FilerServer) checkWithMaster() {
  120. for _, master := range fs.option.Masters {
  121. _, err := pb.ParseFilerGrpcAddress(master)
  122. if err != nil {
  123. glog.Fatalf("invalid master address %s: %v", master, err)
  124. }
  125. }
  126. isConnected := false
  127. for !isConnected {
  128. for _, master := range fs.option.Masters {
  129. readErr := operation.WithMasterServerClient(master, fs.grpcDialOption, func(masterClient master_pb.SeaweedClient) error {
  130. resp, err := masterClient.GetMasterConfiguration(context.Background(), &master_pb.GetMasterConfigurationRequest{})
  131. if err != nil {
  132. return fmt.Errorf("get master %s configuration: %v", master, err)
  133. }
  134. fs.metricsAddress, fs.metricsIntervalSec = resp.MetricsAddress, int(resp.MetricsIntervalSeconds)
  135. if fs.option.DefaultReplication == "" {
  136. fs.option.DefaultReplication = resp.DefaultReplication
  137. }
  138. return nil
  139. })
  140. if readErr == nil {
  141. isConnected = true
  142. } else {
  143. time.Sleep(7 * time.Second)
  144. }
  145. }
  146. }
  147. }