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.

173 lines
5.2 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
4 years ago
4 years ago
5 years ago
5 years ago
4 years ago
4 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. "google.golang.org/grpc"
  10. "github.com/chrislusf/seaweedfs/weed/util/grace"
  11. "github.com/chrislusf/seaweedfs/weed/operation"
  12. "github.com/chrislusf/seaweedfs/weed/pb"
  13. "github.com/chrislusf/seaweedfs/weed/pb/master_pb"
  14. "github.com/chrislusf/seaweedfs/weed/stats"
  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. DefaultLevelDbDir string
  45. DisableHttp bool
  46. Host string
  47. Port uint32
  48. recursiveDelete bool
  49. Cipher bool
  50. Filers []string
  51. }
  52. type FilerServer struct {
  53. option *FilerOption
  54. secret security.SigningKey
  55. filer *filer.Filer
  56. grpcDialOption grpc.DialOption
  57. // metrics read from the master
  58. metricsAddress string
  59. metricsIntervalSec int
  60. // notifying clients
  61. listenersLock sync.Mutex
  62. listenersCond *sync.Cond
  63. brokers map[string]map[string]bool
  64. brokersLock sync.Mutex
  65. }
  66. func NewFilerServer(defaultMux, readonlyMux *http.ServeMux, option *FilerOption) (fs *FilerServer, err error) {
  67. fs = &FilerServer{
  68. option: option,
  69. grpcDialOption: security.LoadClientTLS(util.GetViper(), "grpc.filer"),
  70. brokers: make(map[string]map[string]bool),
  71. }
  72. fs.listenersCond = sync.NewCond(&fs.listenersLock)
  73. if len(option.Masters) == 0 {
  74. glog.Fatal("master list is required!")
  75. }
  76. fs.filer = filer.NewFiler(option.Masters, fs.grpcDialOption, option.Host, option.Port, option.Collection, option.DefaultReplication, func() {
  77. fs.listenersCond.Broadcast()
  78. })
  79. fs.filer.Cipher = option.Cipher
  80. fs.maybeStartMetrics()
  81. go fs.filer.KeepConnectedToMaster()
  82. v := util.GetViper()
  83. if !util.LoadConfiguration("filer", false) {
  84. v.Set("leveldb2.enabled", true)
  85. v.Set("leveldb2.dir", option.DefaultLevelDbDir)
  86. _, err := os.Stat(option.DefaultLevelDbDir)
  87. if os.IsNotExist(err) {
  88. os.MkdirAll(option.DefaultLevelDbDir, 0755)
  89. }
  90. glog.V(0).Infof("default to create filer store dir in %s", option.DefaultLevelDbDir)
  91. }
  92. util.LoadConfiguration("notification", false)
  93. fs.option.recursiveDelete = v.GetBool("filer.options.recursive_delete")
  94. v.SetDefault("filer.options.buckets_folder", "/buckets")
  95. fs.filer.DirBucketsPath = v.GetString("filer.options.buckets_folder")
  96. fs.filer.FsyncBuckets = v.GetStringSlice("filer.options.buckets_fsync")
  97. fs.filer.LoadConfiguration(v)
  98. notification.LoadConfiguration(v, "notification.")
  99. handleStaticResources(defaultMux)
  100. if !option.DisableHttp {
  101. defaultMux.HandleFunc("/", fs.filerHandler)
  102. }
  103. if defaultMux != readonlyMux {
  104. readonlyMux.HandleFunc("/", fs.readonlyFilerHandler)
  105. }
  106. fs.filer.AggregateFromPeers(fmt.Sprintf("%s:%d", option.Host, option.Port), option.Filers)
  107. fs.filer.LoadBuckets()
  108. grace.OnInterrupt(func() {
  109. fs.filer.Shutdown()
  110. })
  111. return fs, nil
  112. }
  113. func (fs *FilerServer) maybeStartMetrics() {
  114. for _, master := range fs.option.Masters {
  115. _, err := pb.ParseFilerGrpcAddress(master)
  116. if err != nil {
  117. glog.Fatalf("invalid master address %s: %v", master, err)
  118. }
  119. }
  120. isConnected := false
  121. var readErr error
  122. for !isConnected {
  123. for _, master := range fs.option.Masters {
  124. fs.metricsAddress, fs.metricsIntervalSec, readErr = readFilerConfiguration(fs.grpcDialOption, master)
  125. if readErr == nil {
  126. isConnected = true
  127. } else {
  128. time.Sleep(7 * time.Second)
  129. }
  130. }
  131. }
  132. go stats.LoopPushingMetric("filer", stats.SourceName(fs.option.Port), stats.FilerGather, fs.metricsAddress, fs.metricsIntervalSec)
  133. }
  134. func readFilerConfiguration(grpcDialOption grpc.DialOption, masterAddress string) (metricsAddress string, metricsIntervalSec int, err error) {
  135. err = operation.WithMasterServerClient(masterAddress, grpcDialOption, func(masterClient master_pb.SeaweedClient) error {
  136. resp, err := masterClient.GetMasterConfiguration(context.Background(), &master_pb.GetMasterConfigurationRequest{})
  137. if err != nil {
  138. return fmt.Errorf("get master %s configuration: %v", masterAddress, err)
  139. }
  140. metricsAddress, metricsIntervalSec = resp.MetricsAddress, int(resp.MetricsIntervalSeconds)
  141. return nil
  142. })
  143. return
  144. }