2016-06-03 09:09:14 +08:00
package command
2013-12-04 15:22:26 +08:00
import (
2019-04-30 11:22:19 +08:00
"fmt"
2021-09-13 13:47:52 +08:00
"github.com/chrislusf/seaweedfs/weed/pb"
2021-03-30 16:25:28 +08:00
"github.com/chrislusf/seaweedfs/weed/util/grace"
2021-07-31 17:00:01 +08:00
"net/http"
2013-12-04 15:22:26 +08:00
"os"
"strings"
"time"
2014-10-27 02:34:55 +08:00
2020-10-29 15:24:16 +08:00
stats_collect "github.com/chrislusf/seaweedfs/weed/stats"
2016-06-03 09:09:14 +08:00
"github.com/chrislusf/seaweedfs/weed/glog"
2018-10-11 15:05:54 +08:00
"github.com/chrislusf/seaweedfs/weed/util"
2013-12-04 15:22:26 +08:00
)
2014-05-08 01:17:06 +08:00
type ServerOptions struct {
2019-06-18 05:51:47 +08:00
cpuprofile * string
2021-03-30 16:25:28 +08:00
memprofile * string
2021-07-31 17:00:01 +08:00
debug * bool
2021-08-01 00:18:41 +08:00
debugPort * int
2019-06-18 05:51:47 +08:00
v VolumeServerOptions
2014-05-08 01:17:06 +08:00
}
2014-03-31 11:57:25 +08:00
var (
2020-05-18 13:44:20 +08:00
serverOptions ServerOptions
masterOptions MasterOptions
filerOptions FilerOptions
s3Options S3Options
2021-02-01 14:16:52 +08:00
webdavOptions WebDavOption
2020-05-18 13:44:20 +08:00
msgBrokerOptions MessageBrokerOptions
2014-03-31 11:57:25 +08:00
)
2013-12-04 15:22:26 +08:00
func init ( ) {
cmdServer . Run = runServer // break init cycle
}
var cmdServer = & Command {
2020-06-13 13:06:21 +08:00
UsageLine : "server -dir=/tmp -volume.max=5 -ip=server_name" ,
2019-04-24 15:25:20 +08:00
Short : "start a master server, a volume server, and optionally a filer and a S3 gateway" ,
2014-11-29 08:34:03 +08:00
Long : ` start both a volume server to provide storage spaces
2013-12-04 15:22:26 +08:00
and a master server to provide volume = > location mapping service and sequence number of file ids
2014-11-29 08:34:03 +08:00
2013-12-04 15:22:26 +08:00
This is provided as a convenient way to start both volume server and master server .
2019-04-24 15:25:20 +08:00
The servers acts exactly the same as starting them separately .
So other volume servers can connect to this master server also .
2014-04-26 13:09:42 +08:00
2019-04-24 15:25:20 +08:00
Optionally , a filer server can be started .
Also optionally , a S3 gateway can be started .
2019-04-24 15:18:01 +08:00
2013-12-04 15:22:26 +08:00
` ,
}
var (
2021-03-24 08:27:57 +08:00
serverIp = cmdServer . Flag . String ( "ip" , util . DetectedHostAddress ( ) , "ip or server name, also used as identifier" )
2021-03-13 07:32:51 +08:00
serverBindIp = cmdServer . Flag . String ( "ip.bind" , "" , "ip address to bind to" )
2019-06-24 06:30:16 +08:00
serverTimeout = cmdServer . Flag . Int ( "idleTimeout" , 30 , "connection idle seconds" )
serverDataCenter = cmdServer . Flag . String ( "dataCenter" , "" , "current volume server's data center name" )
serverRack = cmdServer . Flag . String ( "rack" , "" , "current volume server's rack name" )
serverWhiteListOption = cmdServer . Flag . String ( "whiteList" , "" , "comma separated Ip addresses having write permission. No limit if empty." )
serverDisableHttp = cmdServer . Flag . Bool ( "disableHttp" , false , "disable http requests, only gRPC operations are allowed." )
volumeDataFolders = cmdServer . Flag . String ( "dir" , os . TempDir ( ) , "directories to store data files. dir[,dir]..." )
2020-06-29 05:34:21 +08:00
volumeMaxDataVolumeCounts = cmdServer . Flag . String ( "volume.max" , "8" , "maximum numbers of volumes, count[,count]... If set to zero, the limit will be auto configured." )
2021-04-27 10:37:24 +08:00
volumeMinFreeSpacePercent = cmdServer . Flag . String ( "volume.minFreeSpacePercent" , "1" , "minimum free disk space (default to 1%). Low disk space will mark all volumes as ReadOnly (deprecated, use minFreeSpace instead)." )
volumeMinFreeSpace = cmdServer . Flag . String ( "volume.minFreeSpace" , "" , "min free disk space (value<=100 as percentage like 1, other as human readable bytes, like 10GiB). Low disk space will mark all volumes as ReadOnly." )
2020-09-25 00:55:02 +08:00
serverMetricsHttpPort = cmdServer . Flag . Int ( "metricsPort" , 0 , "Prometheus metrics listen port" )
2020-06-05 23:18:15 +08:00
2020-06-05 01:52:01 +08:00
// pulseSeconds = cmdServer.Flag.Int("pulseSeconds", 5, "number of seconds between heartbeats")
2021-01-07 18:35:47 +08:00
isStartingMasterServer = cmdServer . Flag . Bool ( "master" , true , "whether to start master server" )
2020-10-29 15:24:16 +08:00
isStartingVolumeServer = cmdServer . Flag . Bool ( "volume" , true , "whether to start volume server" )
isStartingFiler = cmdServer . Flag . Bool ( "filer" , false , "whether to start filer" )
isStartingS3 = cmdServer . Flag . Bool ( "s3" , false , "whether to start S3 gateway" )
2021-02-01 14:16:52 +08:00
isStartingWebDav = cmdServer . Flag . Bool ( "webdav" , false , "whether to start WebDAV gateway" )
2020-10-29 15:24:16 +08:00
isStartingMsgBroker = cmdServer . Flag . Bool ( "msgBroker" , false , "whether to start message broker" )
2013-12-04 15:22:26 +08:00
2016-08-06 05:45:48 +08:00
serverWhiteList [ ] string
2020-06-11 04:10:10 +08:00
False = false
2013-12-04 15:22:26 +08:00
)
2014-03-31 11:57:25 +08:00
func init ( ) {
2014-11-29 08:34:03 +08:00
serverOptions . cpuprofile = cmdServer . Flag . String ( "cpuprofile" , "" , "cpu profile output file" )
2021-03-30 16:25:28 +08:00
serverOptions . memprofile = cmdServer . Flag . String ( "memprofile" , "" , "memory profile output file" )
2021-08-01 00:18:41 +08:00
serverOptions . debug = cmdServer . Flag . Bool ( "debug" , false , "serves runtime profiling data, e.g., http://localhost:6060/debug/pprof/goroutine?debug=2" )
serverOptions . debugPort = cmdServer . Flag . Int ( "debug.port" , 6060 , "http port for debugging" )
2019-06-23 18:08:27 +08:00
masterOptions . port = cmdServer . Flag . Int ( "master.port" , 9333 , "master server http listen port" )
2021-09-21 05:05:59 +08:00
masterOptions . portGrpc = cmdServer . Flag . Int ( "master.port.grpc" , 0 , "master server grpc listen port" )
2019-06-23 18:08:27 +08:00
masterOptions . metaFolder = cmdServer . Flag . String ( "master.dir" , "" , "data directory to store meta data, default to same as -dir specified" )
masterOptions . peers = cmdServer . Flag . String ( "master.peers" , "" , "all master nodes in comma separated ip:masterPort list" )
masterOptions . volumeSizeLimitMB = cmdServer . Flag . Uint ( "master.volumeSizeLimitMB" , 30 * 1000 , "Master stops directing writes to oversized volumes." )
masterOptions . volumePreallocate = cmdServer . Flag . Bool ( "master.volumePreallocate" , false , "Preallocate disk space for volumes." )
2021-08-14 17:54:13 +08:00
masterOptions . defaultReplication = cmdServer . Flag . String ( "master.defaultReplication" , "" , "Default replication type if not specified." )
2019-06-23 18:08:27 +08:00
masterOptions . garbageThreshold = cmdServer . Flag . Float64 ( "garbageThreshold" , 0.3 , "threshold to vacuum and reclaim spaces" )
2019-06-24 06:30:16 +08:00
masterOptions . metricsAddress = cmdServer . Flag . String ( "metrics.address" , "" , "Prometheus gateway address" )
masterOptions . metricsIntervalSec = cmdServer . Flag . Int ( "metrics.intervalSeconds" , 15 , "Prometheus push interval in seconds" )
2020-10-04 04:56:38 +08:00
masterOptions . raftResumeState = cmdServer . Flag . Bool ( "resumeState" , false , "resume previous state on start master server" )
2019-06-23 18:08:27 +08:00
2014-05-13 15:03:10 +08:00
filerOptions . collection = cmdServer . Flag . String ( "filer.collection" , "" , "all data will be stored in this collection" )
filerOptions . port = cmdServer . Flag . Int ( "filer.port" , 8888 , "filer server http listen port" )
2021-09-21 05:05:59 +08:00
filerOptions . portGrpc = cmdServer . Flag . Int ( "filer.port.grpc" , 0 , "filer server grpc listen port" )
2017-05-28 11:14:22 +08:00
filerOptions . publicPort = cmdServer . Flag . Int ( "filer.port.public" , 0 , "filer server public http listen port" )
2020-10-01 00:32:00 +08:00
filerOptions . defaultReplicaPlacement = cmdServer . Flag . String ( "filer.defaultReplicaPlacement" , "" , "default replication type. If not specified, use master setting." )
2015-04-14 14:38:46 +08:00
filerOptions . disableDirListing = cmdServer . Flag . Bool ( "filer.disableDirListing" , false , "turn off directory listing" )
2021-04-01 17:21:59 +08:00
filerOptions . maxMB = cmdServer . Flag . Int ( "filer.maxMB" , 4 , "split files larger than the limit" )
2018-07-08 17:11:36 +08:00
filerOptions . dirListingLimit = cmdServer . Flag . Int ( "filer.dirListLimit" , 1000 , "limit sub dir listing size" )
2020-03-10 13:31:14 +08:00
filerOptions . cipher = cmdServer . Flag . Bool ( "filer.encryptVolumeData" , false , "encrypt data on volume servers" )
2021-01-11 15:14:46 +08:00
filerOptions . saveToFilerLimit = cmdServer . Flag . Int ( "filer.saveToFilerLimit" , 0 , "Small files smaller than this limit can be cached in filer store." )
2021-03-30 17:10:50 +08:00
filerOptions . concurrentUploadLimitMB = cmdServer . Flag . Int ( "filer.concurrentUploadLimitMB" , 64 , "limit total concurrent upload size" )
2018-10-11 15:04:31 +08:00
serverOptions . v . port = cmdServer . Flag . Int ( "volume.port" , 8080 , "volume server http listen port" )
2021-09-21 05:05:59 +08:00
serverOptions . v . portGrpc = cmdServer . Flag . Int ( "volume.port.grpc" , 0 , "volume server grpc listen port" )
2018-10-11 15:04:31 +08:00
serverOptions . v . publicPort = cmdServer . Flag . Int ( "volume.port.public" , 0 , "volume server public port" )
2019-04-10 00:42:06 +08:00
serverOptions . v . indexType = cmdServer . Flag . String ( "volume.index" , "memory" , "Choose [memory|leveldb|leveldbMedium|leveldbLarge] mode for memory~performance balance." )
2021-02-22 18:03:12 +08:00
serverOptions . v . diskType = cmdServer . Flag . String ( "volume.disk" , "" , "[hdd|ssd|<tag>] hard drive or solid state drive or any tag" )
2020-07-10 10:08:36 +08:00
serverOptions . v . fixJpgOrientation = cmdServer . Flag . Bool ( "volume.images.fix.orientation" , false , "Adjust jpg orientation when uploading." )
2021-07-04 06:55:56 +08:00
serverOptions . v . readMode = cmdServer . Flag . String ( "volume.readMode" , "proxy" , "[local|proxy|redirect] how to deal with non-local volume: 'not found|read in remote node|redirect volume location'." )
2019-05-04 08:22:39 +08:00
serverOptions . v . compactionMBPerSecond = cmdServer . Flag . Int ( "volume.compactionMBps" , 0 , "limit compaction speed in mega bytes per second" )
2020-10-30 06:46:26 +08:00
serverOptions . v . fileSizeLimitMB = cmdServer . Flag . Int ( "volume.fileSizeLimitMB" , 256 , "limit file size to avoid out of memory" )
2021-03-30 17:10:50 +08:00
serverOptions . v . concurrentUploadLimitMB = cmdServer . Flag . Int ( "volume.concurrentUploadLimitMB" , 64 , "limit total concurrent upload size" )
2021-08-09 14:25:16 +08:00
serverOptions . v . concurrentDownloadLimitMB = cmdServer . Flag . Int ( "volume.concurrentDownloadLimitMB" , 64 , "limit total concurrent download size" )
2018-10-11 15:04:31 +08:00
serverOptions . v . publicUrl = cmdServer . Flag . String ( "volume.publicUrl" , "" , "publicly accessible address" )
2020-09-12 19:05:33 +08:00
serverOptions . v . preStopSeconds = cmdServer . Flag . Int ( "volume.preStopSeconds" , 10 , "number of seconds between stop send heartbeats and stop volume server" )
2020-09-22 10:43:10 +08:00
serverOptions . v . pprof = cmdServer . Flag . Bool ( "volume.pprof" , false , "enable pprof http handlers. precludes --memprofile and --cpuprofile" )
2020-11-27 19:17:10 +08:00
serverOptions . v . idxFolder = cmdServer . Flag . String ( "volume.dir.idx" , "" , "directory to store .idx files" )
2021-03-08 06:45:36 +08:00
serverOptions . v . enableTcp = cmdServer . Flag . Bool ( "volume.tcp" , false , "<exprimental> enable tcp port" )
2018-10-11 15:04:31 +08:00
2019-04-24 15:18:01 +08:00
s3Options . port = cmdServer . Flag . Int ( "s3.port" , 8333 , "s3 server http listen port" )
2020-10-22 14:23:00 +08:00
s3Options . domainName = cmdServer . Flag . String ( "s3.domainName" , "" , "suffix of the host name in comma separated list, {bucket}.{domainName}" )
2019-04-24 15:18:01 +08:00
s3Options . tlsPrivateKey = cmdServer . Flag . String ( "s3.key.file" , "" , "path to the TLS private key file" )
s3Options . tlsCertificate = cmdServer . Flag . String ( "s3.cert.file" , "" , "path to the TLS certificate file" )
2020-02-10 06:31:51 +08:00
s3Options . config = cmdServer . Flag . String ( "s3.config" , "" , "path to the config file" )
2021-12-07 21:20:52 +08:00
s3Options . auditLogConfig = cmdServer . Flag . String ( "s3.auditLogConfig" , "" , "path to the audit log config file" )
2021-09-27 13:34:14 +08:00
s3Options . allowEmptyFolder = cmdServer . Flag . Bool ( "s3.allowEmptyFolder" , true , "allow empty folders" )
2019-04-24 15:18:01 +08:00
2021-02-01 14:16:52 +08:00
webdavOptions . port = cmdServer . Flag . Int ( "webdav.port" , 7333 , "webdav server http listen port" )
webdavOptions . collection = cmdServer . Flag . String ( "webdav.collection" , "" , "collection to create the files" )
2021-02-19 04:15:09 +08:00
webdavOptions . replication = cmdServer . Flag . String ( "webdav.replication" , "" , "replication to create the files" )
2021-02-22 18:03:12 +08:00
webdavOptions . disk = cmdServer . Flag . String ( "webdav.disk" , "" , "[hdd|ssd|<tag>] hard drive or solid state drive or any tag" )
2021-02-01 14:16:52 +08:00
webdavOptions . tlsPrivateKey = cmdServer . Flag . String ( "webdav.key.file" , "" , "path to the TLS private key file" )
webdavOptions . tlsCertificate = cmdServer . Flag . String ( "webdav.cert.file" , "" , "path to the TLS certificate file" )
webdavOptions . cacheDir = cmdServer . Flag . String ( "webdav.cacheDir" , os . TempDir ( ) , "local cache directory for file chunks" )
webdavOptions . cacheSizeMB = cmdServer . Flag . Int64 ( "webdav.cacheCapacityMB" , 1000 , "local cache capacity in MB" )
2019-04-24 15:18:01 +08:00
2020-05-18 13:44:20 +08:00
msgBrokerOptions . port = cmdServer . Flag . Int ( "msgBroker.port" , 17777 , "broker gRPC listen port" )
2014-03-31 11:57:25 +08:00
}
2013-12-04 15:22:26 +08:00
func runServer ( cmd * Command , args [ ] string ) bool {
2019-02-19 04:11:52 +08:00
2021-07-31 17:00:01 +08:00
if * serverOptions . debug {
2021-08-01 00:18:41 +08:00
go http . ListenAndServe ( fmt . Sprintf ( ":%d" , * serverOptions . debugPort ) , nil )
2021-07-31 17:00:01 +08:00
}
2019-06-05 16:30:24 +08:00
util . LoadConfiguration ( "security" , false )
util . LoadConfiguration ( "master" , false )
2019-02-19 04:11:52 +08:00
2021-03-30 16:25:28 +08:00
grace . SetupProfiling ( * serverOptions . cpuprofile , * serverOptions . memprofile )
2014-03-31 11:57:25 +08:00
2019-04-24 15:18:01 +08:00
if * isStartingS3 {
* isStartingFiler = true
}
2021-02-01 14:16:52 +08:00
if * isStartingWebDav {
* isStartingFiler = true
}
2020-05-18 13:44:20 +08:00
if * isStartingMsgBroker {
* isStartingFiler = true
}
2019-04-24 15:18:01 +08:00
2021-10-04 17:51:26 +08:00
if * isStartingMasterServer {
_ , peerList := checkPeers ( * serverIp , * masterOptions . port , * masterOptions . portGrpc , * masterOptions . peers )
peers := strings . Join ( pb . ToAddressStrings ( peerList ) , "," )
masterOptions . peers = & peers
}
2020-09-25 00:55:02 +08:00
// ip address
2019-06-23 18:08:27 +08:00
masterOptions . ip = serverIp
masterOptions . ipBind = serverBindIp
2021-10-04 18:27:10 +08:00
filerOptions . masters = pb . ServerAddresses ( * masterOptions . peers ) . ToAddresses ( )
2020-04-22 05:21:06 +08:00
filerOptions . ip = serverIp
filerOptions . bindIp = serverBindIp
2018-10-11 15:04:31 +08:00
serverOptions . v . ip = serverIp
serverOptions . v . bindIp = serverBindIp
2021-10-04 18:27:10 +08:00
serverOptions . v . masters = pb . ServerAddresses ( * masterOptions . peers ) . ToAddresses ( )
2018-10-11 15:04:31 +08:00
serverOptions . v . idleConnectionTimeout = serverTimeout
serverOptions . v . dataCenter = serverDataCenter
serverOptions . v . rack = serverRack
2020-05-18 13:44:20 +08:00
msgBrokerOptions . ip = serverIp
2019-06-23 18:11:21 +08:00
2020-06-05 01:52:01 +08:00
// serverOptions.v.pulseSeconds = pulseSeconds
// masterOptions.pulseSeconds = pulseSeconds
2014-03-31 11:57:25 +08:00
2019-06-23 18:08:27 +08:00
masterOptions . whiteList = serverWhiteListOption
2018-07-09 17:22:48 +08:00
filerOptions . dataCenter = serverDataCenter
2020-10-21 08:41:39 +08:00
filerOptions . rack = serverRack
2019-03-22 07:00:46 +08:00
filerOptions . disableHttp = serverDisableHttp
2019-06-23 18:08:27 +08:00
masterOptions . disableHttp = serverDisableHttp
2018-07-09 17:22:48 +08:00
2021-09-13 13:47:52 +08:00
filerAddress := string ( pb . NewServerAddress ( * serverIp , * filerOptions . port , * filerOptions . portGrpc ) )
2019-04-24 15:18:01 +08:00
s3Options . filer = & filerAddress
2021-02-01 14:16:52 +08:00
webdavOptions . filer = & filerAddress
2020-05-18 13:44:20 +08:00
msgBrokerOptions . filer = & filerAddress
2019-04-24 15:18:01 +08:00
2020-09-25 01:21:23 +08:00
go stats_collect . StartMetricsServer ( * serverMetricsHttpPort )
2013-12-04 15:22:26 +08:00
folders := strings . Split ( * volumeDataFolders , "," )
2019-06-23 18:08:27 +08:00
if * masterOptions . volumeSizeLimitMB > util . VolumeSizeLimitGB * 1000 {
2017-07-17 12:40:47 +08:00
glog . Fatalf ( "masterVolumeSizeLimitMB should be less than 30000" )
}
2019-06-23 18:08:27 +08:00
if * masterOptions . metaFolder == "" {
* masterOptions . metaFolder = folders [ 0 ]
2014-03-31 11:57:25 +08:00
}
2020-07-17 13:50:14 +08:00
if err := util . TestFolderWritable ( util . ResolvePath ( * masterOptions . metaFolder ) ) ; err != nil {
2019-06-23 18:08:27 +08:00
glog . Fatalf ( "Check Meta Folder (-mdir=\"%s\") Writable: %s" , * masterOptions . metaFolder , err )
2014-03-31 11:57:25 +08:00
}
2019-06-23 18:08:27 +08:00
filerOptions . defaultLevelDbDirectory = masterOptions . metaFolder
2014-03-31 11:57:25 +08:00
2016-08-06 05:45:48 +08:00
if * serverWhiteListOption != "" {
serverWhiteList = strings . Split ( * serverWhiteListOption , "," )
2013-12-04 15:22:26 +08:00
}
2014-03-31 11:57:25 +08:00
if * isStartingFiler {
go func ( ) {
2016-07-21 14:45:55 +08:00
time . Sleep ( 1 * time . Second )
2017-05-28 11:14:22 +08:00
2018-10-11 14:19:54 +08:00
filerOptions . startFiler ( )
2017-05-28 11:14:22 +08:00
2014-03-31 11:57:25 +08:00
} ( )
}
2014-03-31 02:28:04 +08:00
2019-04-24 15:18:01 +08:00
if * isStartingS3 {
go func ( ) {
time . Sleep ( 2 * time . Second )
s3Options . startS3Server ( )
} ( )
}
2021-02-01 14:16:52 +08:00
if * isStartingWebDav {
go func ( ) {
time . Sleep ( 2 * time . Second )
webdavOptions . startWebDav ( )
} ( )
}
2020-05-18 13:44:20 +08:00
if * isStartingMsgBroker {
go func ( ) {
time . Sleep ( 2 * time . Second )
msgBrokerOptions . startQueueServer ( )
} ( )
}
2019-07-28 16:55:05 +08:00
// start volume server
2020-10-29 15:24:16 +08:00
if * isStartingVolumeServer {
2021-05-28 19:19:24 +08:00
minFreeSpaces := util . MustParseMinFreeSpace ( * volumeMinFreeSpace , * volumeMinFreeSpacePercent )
2021-04-27 10:37:24 +08:00
go serverOptions . v . startVolumeServer ( * volumeDataFolders , * volumeMaxDataVolumeCounts , * serverWhiteListOption , minFreeSpaces )
2019-07-28 16:55:05 +08:00
}
2014-05-13 15:03:10 +08:00
2021-01-07 18:35:47 +08:00
if * isStartingMasterServer {
go startMaster ( masterOptions , serverWhiteList )
}
select { }
2013-12-04 15:22:26 +08:00
}