170 lines
4.3 KiB
Go
170 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
var (
|
|
infile string
|
|
appname string
|
|
host string
|
|
)
|
|
var usage = func() {
|
|
fmt.Fprintf(os.Stderr, "Usage of cache admin import conf tool:\n")
|
|
flag.PrintDefaults()
|
|
}
|
|
|
|
func main() {
|
|
flag.StringVar(&appname, "app", "", "server app name")
|
|
flag.StringVar(&host, "h", "http://sven.bilibili.co", "sven host")
|
|
flag.StringVar(&infile, "in", "twemproxy.yml", "server yml file")
|
|
flag.Usage = usage
|
|
flag.Parse()
|
|
if appname == "" {
|
|
panic("app name cannot be nil")
|
|
}
|
|
b, err := ioutil.ReadFile(infile)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
confs := make(map[string]server)
|
|
err = yaml.Unmarshal(b, &confs)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// one service can't use 5168 memcaches at the same time.
|
|
redisPort := 26379
|
|
mcPort := 21211
|
|
|
|
for name, conf := range confs {
|
|
var (
|
|
addr string
|
|
cacheType string
|
|
)
|
|
|
|
if conf.Redis {
|
|
addr = fmt.Sprintf("0.0.0.0:%d", redisPort)
|
|
cacheType = "redis"
|
|
redisPort++
|
|
} else {
|
|
addr = fmt.Sprintf("0.0.0.0:%d", mcPort)
|
|
cacheType = "memcache"
|
|
mcPort++
|
|
}
|
|
|
|
addCluster(appname, name, addr, cacheType, conf.AutoEjectHosts, conf.ServerFailureLimit)
|
|
var nodes []*node
|
|
for _, n := range conf.Servers {
|
|
ss := strings.Split(n, " ")
|
|
idx := strings.LastIndex(ss[0], ":")
|
|
weight, _ := strconv.ParseInt(ss[0][idx+1:], 10, 64)
|
|
nodes = append(nodes, &node{Addr: ss[0][:idx], Weigth: weight, Alias: ss[1]})
|
|
}
|
|
addNode(name, nodes)
|
|
}
|
|
}
|
|
|
|
type server struct {
|
|
AutoEjectHosts bool `yaml:"auto_eject_hosts"`
|
|
Backlog int `yaml:"backlog"`
|
|
Distribution string `yaml:"distribution"`
|
|
Hash string `yaml:"hash"`
|
|
Listen string `yaml:"listen"`
|
|
Preconnect bool `yaml:"preconnect"`
|
|
Timeout int `yaml:"timeout"`
|
|
Redis bool `yaml:"redis"`
|
|
ServerConnections int `yaml:"server_connections"`
|
|
ServerFailureLimit int `yaml:"server_failure_limit"`
|
|
ServerRetryTimeout int `yaml:"server_retry_timeout"`
|
|
Servers []string `yaml:"servers"`
|
|
}
|
|
|
|
const (
|
|
readTimeout = "1000"
|
|
writeTimeout = "1000"
|
|
conn = "20"
|
|
dialTimeout = "100"
|
|
proto = "tcp"
|
|
)
|
|
|
|
var (
|
|
addCluURL = "%s/x/admin/cache/cluster/add"
|
|
addNodeURL = "%s/x/admin/cache/cluster/node/modify"
|
|
)
|
|
|
|
func addCluster(app, cluster, addr, tp string, reject bool, fail int) {
|
|
params := url.Values{}
|
|
params.Add("dail_timeout", dialTimeout)
|
|
params.Add("ping_fail_limit", strconv.FormatInt(int64(fail), 10))
|
|
params.Add("ping_auto_reject", strconv.FormatBool(reject))
|
|
params.Add("hash_distribution", "ketama")
|
|
params.Add("read_timeout", readTimeout)
|
|
params.Add("write_timeout", writeTimeout)
|
|
params.Add("node_conn", conn)
|
|
params.Add("type", tp)
|
|
params.Add("app_id", app)
|
|
params.Add("name", cluster)
|
|
params.Add("hash_method", "fnv1a_64")
|
|
params.Add("listen_proto", proto)
|
|
params.Add("listen_addr", addr)
|
|
url := fmt.Sprintf(addCluURL, host)
|
|
req, err := http.NewRequest("POST", url, strings.NewReader(params.Encode()))
|
|
if err != nil {
|
|
fmt.Printf("add cluster req err %v", err)
|
|
return
|
|
}
|
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
fmt.Println("add cluster err", err)
|
|
return
|
|
}
|
|
defer resp.Body.Close()
|
|
bs, err := ioutil.ReadAll(resp.Body)
|
|
fmt.Printf("add cluster req %v resp %v err %v\n", params.Encode(), string(bs), err)
|
|
}
|
|
|
|
type node struct {
|
|
Addr string `json:"addr"`
|
|
Weigth int64 `json:"weight"`
|
|
Alias string `json:"alias"`
|
|
}
|
|
|
|
func addNode(name string, nodes []*node) {
|
|
params := url.Values{}
|
|
bs, err := json.Marshal(nodes)
|
|
if err != nil {
|
|
fmt.Println("node marshal err", err)
|
|
return
|
|
}
|
|
params.Add("action", "1")
|
|
params.Add("name", name)
|
|
params.Add("nodes", string(bs))
|
|
url := fmt.Sprintf(addNodeURL, host)
|
|
req, err := http.NewRequest("POST", url, strings.NewReader(params.Encode()))
|
|
if err != nil {
|
|
fmt.Printf("add node req err %v", err)
|
|
return
|
|
}
|
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
fmt.Println("add node err", err)
|
|
return
|
|
}
|
|
defer resp.Body.Close()
|
|
bs, err = ioutil.ReadAll(resp.Body)
|
|
fmt.Printf("add node req %v resp %v err %v\n", params.Encode(), string(bs), err)
|
|
}
|