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.

192 lines
6.0 KiB

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