diff --git a/.gitignore b/.gitignore index 4fd0fa5..f6d4081 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ .DS_Store /_vendor /.vendor -/bin/mouryou /log/ /vendor mouryou diff --git a/Gopkg.lock b/Gopkg.lock index 03741c8..583a410 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -32,17 +32,6 @@ revision = "cb03c542a4054f0f4d3dc13919d31c456bdb5c39" version = "v1.7.1" -[[projects]] - branch = "master" - digest = "1:2c584d8971881e9f9a7dd2e0a712e83cb5ded51c5173eef1615ce3f047dbded3" - name = "github.com/influxdata/platform" - packages = [ - "models", - "pkg/escape", - ] - pruneopts = "UT" - revision = "81c0e53c4a515668db7181b01f832d852f521109" - [[projects]] branch = "master" digest = "1:ec6d80e0622e6d95e40b76936f13d28dd5d88635968a7cc87bf4c737237e13e9" diff --git a/lib/apache/scoreboard.go b/lib/apache/scoreboard.go index fa2fa4d..a8917e0 100644 --- a/lib/apache/scoreboard.go +++ b/lib/apache/scoreboard.go @@ -2,6 +2,7 @@ package apache import ( "encoding/json" + "fmt" "io/ioutil" "net/http" ) @@ -10,19 +11,21 @@ func Scoreboard(host string) ([]byte, error) { var board []byte url := "http://" + host + ":8080" - request, err := http.NewRequest("GET", url, nil) if err != nil { + fmt.Println(err) return board, err } response, err := http.DefaultClient.Do(request) if err != nil { + fmt.Println(err) return board, err } body, err := ioutil.ReadAll(response.Body) if err != nil { + fmt.Println(err) return board, err } defer response.Body.Close() diff --git a/lib/engine/destination_setting.go b/lib/engine/destination_setting.go index 0b1e6e2..4dfe326 100644 --- a/lib/engine/destination_setting.go +++ b/lib/engine/destination_setting.go @@ -74,7 +74,7 @@ func DestinationSetting(config *models.Config) { // 起動処理が終わったので,起動処理中の台数を減少 mutex.Write(&booting, &bootMutex, b-1) // 起動処理が完了した後,config.Wait秒間は停止処理を発火しないようにwaitingを設定 - go timer.Set(&waiting, &waitMutex, config.Wait) + //go timer.Set(&waiting, &waitMutex, config.Wait) case "shutting down": // 停止処理を開始した // 停止処理中の台数を増加 mutex.Write(&shutting, &shutMutex, s+1) diff --git a/lib/engine/server_management.go b/lib/engine/server_management.go index 8db5f07..ed54e29 100644 --- a/lib/engine/server_management.go +++ b/lib/engine/server_management.go @@ -65,6 +65,10 @@ func bootUpVMs(config *models.Config, weight int, load string) { serverStates := monitor.GetServerStates() for i, serverState := range serverStates { + if config.Cluster.VirtualMachines[serverState.Name].Role == "pool" { + // poolサーバは無視 + continue + } if serverState.Info != "shutted down" { // 停止中のサーバ以外は無視 continue @@ -72,7 +76,7 @@ func bootUpVMs(config *models.Config, weight int, load string) { if serverState.Weight >= weight { // サーバの重さが必要な重み以上なら起動処理を任せてreturn - go bootUpVM(config, serverState, load) + go bootUpVMpool(config, serverState, load) mutex.Write(&futureTotalWeight, &futureTotalWeightMutex, futureTotalWeight+serverState.Weight) return } @@ -92,10 +96,145 @@ func bootUpVMs(config *models.Config, weight int, load string) { toBootUp = n } } - go bootUpVM(config, serverStates[toBootUp], load) + go bootUpVMpool(config, serverStates[toBootUp], load) mutex.Write(&futureTotalWeight, &futureTotalWeightMutex, futureTotalWeight+serverStates[toBootUp].Weight) } +func bootUpVMpool(config *models.Config, serverState monitor.ServerState, load string) { + var power monitor.PowerStruct + var pp monitor.PowerStruct + var pool monitor.ServerState + + // これから起動処理を発行することを通知 + power.Name = serverState.Name + power.Info = "booting up" + power.Load = load + serverState.Info = "booting up" + if monitor.PowerCh != nil { + monitor.PowerCh <- power + } + if monitor.StateCh != nil { + monitor.StateCh <- serverState + } + if config.DevelopLogLevel >= 1 { + place := logger.Place() + logger.Debug(place, serverState.Name+" is booting up") + } + + pool.Name = "" + /* + for _, status := range monitor.GetStates() { + if status.Info == "shutted down" && status.Name != st.Name { + pool.Name = status.Name + } + } + */ + // プールサーバ + for _, status := range monitor.GetServerStates() { + if status.Info == "shutted down" && config.Cluster.VirtualMachines[status.Name].Role == "pool" { + pool.Name = status.Name + } + } + if pool.Name != "" { + pool.Weight = 5 + pp.Name = pool.Name + pp.Info = "booting up" + pp.Load = load + pool.Info = "booting up" + if monitor.PowerCh != nil { + monitor.PowerCh <- pp + } + if monitor.StateCh != nil { + monitor.StateCh <- pool + } + if config.DevelopLogLevel >= 1 { + //logger.PrintPlace("BootUp " + pool.Name) + //fmt.Println("Pool " + pool.Name + " is booting up") + place := logger.Place() + logger.Debug(place, pool.Name+" is booting up") + } + pp.Info = config.Cluster.VirtualMachines[pool.Name].Bootup(config.Start) + pool.Info = "booted up" + if monitor.PowerCh != nil { + monitor.PowerCh <- pp + } + if monitor.StateCh != nil { + monitor.StateCh <- pool + } + if config.DevelopLogLevel >= 1 { + //logger.PrintPlace("BootUp " + pool.Name) + //fmt.Println("Pool " + pool.Name + " is booted up") + place := logger.Place() + logger.Debug(place, serverState.Name+" is booted up") + } + power.Info = config.Cluster.VirtualMachines[serverState.Name].Bootup(config.Sleep - config.Start) + } else { + // 起動処理を発行,完了後の返却値受け取り + power.Info = config.Cluster.VirtualMachines[serverState.Name].Bootup(config.Sleep) + } + + serverState.Info = power.Info + if monitor.PowerCh != nil { + monitor.PowerCh <- power + } + if monitor.StateCh != nil { + monitor.StateCh <- serverState + } + if config.DevelopLogLevel >= 1 { + place := logger.Place() + logger.Debug(place, serverState.Name+" is boot up") + } + + if pool.Name != "" { + //i := 10 + pp.Info = config.Cluster.VirtualMachines[pool.Name].Shutdown(config.Sleep + config.Stop) + /* + fmt.Println("## PoolChangeWeight") + for i > 1 { + fmt.Println("### PoolChangeWeight") + PoolFireChangeWeight(c, pool.Name, i) + fmt.Println(i) + time.Sleep(3 * time.Second) + i-- + } + */ + pp.Info = "shutting down" + pool.Info = pp.Info + if monitor.PowerCh != nil { + monitor.PowerCh <- pp + } + if monitor.StateCh != nil { + monitor.StateCh <- pool + } + if config.DevelopLogLevel >= 1 { + //fmt.Println("Pool " + pool.Name + " is shutting down") + place := logger.Place() + logger.Debug(place, pool.Name+" is shutting up") + } + + pp.Info = "shutted down" + pool.Info = pp.Info + if monitor.PowerCh != nil { + monitor.PowerCh <- pp + } + if monitor.StateCh != nil { + monitor.StateCh <- pool + } + if config.DevelopLogLevel >= 1 { + //fmt.Println("Pool " + pool.Name + " is shutted down") + place := logger.Place() + logger.Debug(place, pool.Name+" is shutted up") + } + + mutex.Write(&totalWeight, &totalWeightMutex, totalWeight-pool.Weight) + if config.DevelopLogLevel >= 1 { + fmt.Println(pool.Name + " going to shutdown") + } + } else { + mutex.Write(&totalWeight, &totalWeightMutex, totalWeight+serverState.Weight) + } +} + // bootUpVM は引数に 設定値用構造体 config, 起動するサーバの情報 serverState, 判断基準にした負荷量 load をとります. func bootUpVM(config *models.Config, serverState monitor.ServerState, load string) { var power monitor.PowerStruct diff --git a/lib/engine/throughput_base_load_determination.go b/lib/engine/throughput_base_load_determination.go index 410bea7..4e7f2f8 100644 --- a/lib/engine/throughput_base_load_determination.go +++ b/lib/engine/throughput_base_load_determination.go @@ -56,8 +56,17 @@ func throughputBase(config *models.Config) { // 動的閾値を用いる場合 if config.Cluster.LoadBalancer.UseThroughputDynamicThreshold { serverNum := len(config.Cluster.VirtualMachines) - changedThreshold, operatingUnitRatio := config.Cluster.LoadBalancer.ChangeThresholdOutInThroughputAlgorithm(working, booting, serverNum) - loggingThreshold(config, changedThreshold, operatingUnitRatio, working, booting, shutting) + //changedThreshold, operatingUnitRatio := config.Cluster.LoadBalancer.ChangeThresholdOutInThroughputAlgorithm(working, booting, serverNum) + changedThreshold_out := 0.0 + changedThreshold_in := 0.0 + if config.Cluster.LoadBalancer.UseThroughputBooting { + changedThreshold_out, changedThreshold_in = config.Cluster.LoadBalancer.ChangeThresholdOutInThroughputBooting(working, booting, serverNum) + } else { + changedThreshold_out, changedThreshold_in = config.Cluster.LoadBalancer.ChangeThresholdOutInThroughput(working, booting, serverNum) + } + loggingThreshold(config, changedThreshold_out, changedThreshold_in, working, booting, shutting) + config.Cluster.LoadBalancer.ThroughputScaleOutRatio = changedThreshold_out + config.Cluster.LoadBalancer.ThroughputScaleInRatio = changedThreshold_in } switch config.Cluster.LoadBalancer.ThroughputAlgorithm { case "MovingAverageV1.2": @@ -83,7 +92,7 @@ func throughputBase(config *models.Config) { } } -func loggingThreshold(config *models.Config, thresholdOut float64, operatingUnitRatio, work, boot, shut int) { +func loggingThreshold(config *models.Config, thresholdOut, changedThreshold_in float64, work, boot, shut int) { tags := []string{ "base_load:tp", "operation:throughput_base_load_determination", @@ -91,7 +100,7 @@ func loggingThreshold(config *models.Config, thresholdOut float64, operatingUnit } fields := []string{ fmt.Sprintf("threshold_out:%f", thresholdOut), - fmt.Sprintf("operating_unit_ratio:%d", operatingUnitRatio), + fmt.Sprintf("threshold_in:%f", changedThreshold_in), fmt.Sprintf("working:%d", work), fmt.Sprintf("booting:%d", boot), fmt.Sprintf("shutting:%d", shut), @@ -125,6 +134,8 @@ func judgeByMovingAverageForCluster(config *models.Config, bootedServersName []s tags := []string{"parameter:working_log", "operation:load_determination"} fields := []string{ fmt.Sprintf("moving_average:%f", movingAverage), + fmt.Sprintf("throughput_out:%f", config.Cluster.LoadBalancer.ThroughputScaleOutRatio), + fmt.Sprintf("throughput_in:%f", config.Cluster.LoadBalancer.ThroughputScaleInRatio), } logger.Record(tags, fields) databases.WriteValues(config.InfluxDBConnection, config, tags, fields) diff --git a/lib/models/config.go b/lib/models/config.go index aa30e68..e3cda37 100644 --- a/lib/models/config.go +++ b/lib/models/config.go @@ -21,8 +21,10 @@ type Config struct { // DevelopLogLevel>=3: 各サーバの負荷状況を全て出力 // DevelopLogLevel>=4: 詳細に DevelopLogLevel int `json:"develop_log_level"` - Timeout time.Duration `json:"timeout"` // 負荷取得がタイムアウトしたと判断するまでの時間 - Sleep time.Duration `json:"sleep"` // サーバの起動処理発行後、稼働し始めるまでの時間 + Timeout time.Duration `json:"timeout"` // 負荷取得がタイムアウトしたと判断するまでの時間 + Sleep time.Duration `json:"sleep"` // サーバの起動処理発行後、稼働し始めるまでの時間 + Start time.Duration `json:"start"` + Stop time.Duration `json:"stop"` Wait time.Duration `json:"wait"` // 起動処理発行後、停止処理を実行しない時間 RestorationTime time.Duration `json:"restoration_time"` // タイムアウトなどして重さを下げた後、復元するまでの時間 IsWeightChange bool `json:"is_weight_change"` // 重さを変更するか diff --git a/lib/models/load_balancer.go b/lib/models/load_balancer.go index a7f859b..30eb8b4 100644 --- a/lib/models/load_balancer.go +++ b/lib/models/load_balancer.go @@ -34,6 +34,9 @@ type LoadBalancer struct { ThroughputScaleOutTime int `json:"throughput_scale_out_time"` ThroughputScaleInTime int `json:"throughput_scale_in_time"` UseThroughputDynamicThreshold bool `json:"use_throughput_dynamic_threshold"` + UseThroughputBooting bool `json:"use_throughput_booting"` + ThroughputScaleOutRate float64 `json:"throughput_scale_out_rate"` + ThroughputScaleInRate float64 `json:"throughput_scale_in_rate"` ThroughputDynamicThreshold map[string][]int `json:"throughput_dynamic_threshold"` } @@ -136,6 +139,24 @@ func (lb LoadBalancer) ChangeThresholdOutInThroughputAlgorithm(working, booting, return 0.0, ocRate } +func (lb LoadBalancer) ChangeThresholdOutInThroughputBooting(working, booting, n int) (float64, float64) { + lb.ThroughputScaleOutRatio = float64((float64(working+booting) - lb.ThroughputScaleOutRate) / float64(working+booting)) + lb.ThroughputScaleInRatio = float64(float64(float64(working+booting)-1-lb.ThroughputScaleInRate) / float64(working+booting)) + if lb.ThroughputScaleInRatio < 0.0 { + lb.ThroughputScaleInRatio = 0.0 + } + return lb.ThroughputScaleOutRatio, lb.ThroughputScaleInRatio +} + +func (lb LoadBalancer) ChangeThresholdOutInThroughput(working, booting, n int) (float64, float64) { + lb.ThroughputScaleOutRatio = float64((float64(working) - lb.ThroughputScaleOutRate) / float64(working)) + lb.ThroughputScaleInRatio = float64(float64(float64(working)-1-lb.ThroughputScaleInRate) / float64(working)) + if lb.ThroughputScaleInRatio < 0.0 { + lb.ThroughputScaleInRatio = 0.0 + } + return lb.ThroughputScaleOutRatio, lb.ThroughputScaleInRatio +} + // ThHighInOperatingRatioAlgorithm は稼働率ベースのアルゴリズムで使われる高負荷判定(スケールアウト)の閾値です。 func (balancer LoadBalancer) ThHighInOperatingRatioAlgorithm(c *Config, w, n int) float64 { switch c.Cluster.LoadBalancer.OperatingRatioAlgorithm { diff --git a/lib/models/virtual_machine.go b/lib/models/virtual_machine.go index 505ad29..180f35a 100644 --- a/lib/models/virtual_machine.go +++ b/lib/models/virtual_machine.go @@ -20,6 +20,7 @@ type VirtualMachine struct { Weight int `json:"weight"` // 現在の重さ Hypervisor *HypervisorStruct `json:"-"` // ハイパーバイザ Vendor *VendorStruct `json:"-"` // ベンダー + Role string `json:"role"` } // ServerState はapache.Scoreboardから負荷状況を受け取り返却します。 diff --git a/log/.keep b/log/.keep deleted file mode 100644 index e69de29..0000000