go-common/app/admin/main/cache/http/cache.go
2019-04-22 18:49:16 +08:00

215 lines
5.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package http
import (
"encoding/json"
"net"
"strconv"
"strings"
"go-common/app/admin/main/cache/model"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
yaml "gopkg.in/yaml.v2"
)
// @params ClustersReq
// @router get /x/admin/cache/clusters
// @response ClustersResp
func clusters(ctx *bm.Context) {
req := new(model.ClusterReq)
if err := ctx.Bind(req); err != nil {
return
}
req.Cookie = ctx.Request.Header.Get("Cookie")
ctx.JSON(srv.Clusters(ctx, req))
}
// @params AddClusterReq
// @router post /x/admin/cache/cluster/add
// @response EmpResp
func addCluster(ctx *bm.Context) {
req := new(model.AddClusterReq)
if err := ctx.Bind(req); err != nil {
return
}
ctx.JSON(srv.AddCluster(ctx, req))
}
// @params delClusterReq
// @router post /x/admin/cache/cluster/del
// @response EmpResp
func delCluster(ctx *bm.Context) {
req := new(model.DelClusterReq)
if err := ctx.Bind(req); err != nil {
return
}
ctx.JSON(srv.DelCluster(ctx, req))
}
// @params ClusterReq
// @router get /x/admin/cache/cluster
// @response []Cluster
func cluster(ctx *bm.Context) {
req := new(model.ClusterReq)
if err := ctx.Bind(req); err != nil {
return
}
if req.AppID != "" {
resp, err := srv.Cluster(ctx, req)
if err != nil {
ctx.JSON(nil, err)
return
}
ctx.JSON(&model.ClusterResp{Clusters: resp}, nil)
} else {
req.Cookie = ctx.Request.Header.Get("Cookie")
ctx.JSON(srv.Clusters(ctx, req))
}
}
// @params ClusterDtlReq
// @router get /x/admin/cache/cluster/detail
// @response ClusterDtlResp
func clusterDtl(ctx *bm.Context) {
req := new(model.ClusterDtlReq)
if err := ctx.Bind(req); err != nil {
return
}
ctx.JSON(srv.ClusterDtl(ctx, req))
}
// @params ModifyClusterReq
// @router post /x/admin/cache/cluster/modify
// @response EmpResp
func modifyCluster(ctx *bm.Context) {
req := new(model.ModifyClusterReq)
if err := ctx.Bind(req); err != nil {
return
}
ctx.JSON(srv.ModifyCluster(ctx, req))
}
func toml(ctx *bm.Context) {
req := new(model.ClusterReq)
if err := ctx.Bind(req); err != nil {
return
}
resp, err := srv.Toml(ctx, req)
if err != nil {
ctx.Status(500)
return
}
ctx.Writer.Write(resp)
}
// @params addFromYml
// @router post /x/admin/cache/cluster/from/yml
// @response EmpResp
func addFromYml(ctx *bm.Context) {
req := new(model.ClusterFromYml)
if err := ctx.Bind(req); err != nil {
ctx.JSONMap(map[string]interface{}{
"message": "参数有问题app_id,zone,tw_yml",
}, ecode.RequestErr)
return
}
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"`
}
type node struct {
Addr string `json:"addr"`
Weigth int64 `json:"weight"`
Alias string `json:"alias"`
}
confs := make(map[string]server)
err := yaml.Unmarshal([]byte(req.TwYml), &confs)
if err != nil {
ctx.JSONMap(map[string]interface{}{
"message": "解析twemproxy.yml文件失败",
}, ecode.RequestErr)
return
}
mcPort := 11211
rdPort := 26379
for name, conf := range confs {
ctp := "memcache"
if conf.Redis {
ctp = "redis"
}
if conf.Hash != "fnv1a_64" {
ctx.JSONMap(map[string]interface{}{
"message": "不支持除了fnv1a_64之外的hash方法",
}, ecode.RequestErr)
return
}
addr := "0.0.0.0:"
_, port, err := net.SplitHostPort(conf.Listen)
if err == nil {
addr = addr + port
} else {
if conf.Redis {
addr = addr + strconv.Itoa(rdPort)
rdPort++
} else {
addr = addr + strconv.Itoa(mcPort)
mcPort++
}
}
clst := &model.AddClusterReq{
Type: ctp,
AppID: req.AppID,
Zone: req.Zone,
HashMethod: "fnv1a_64",
HashDistribution: "ketama",
HashTag: "",
Name: name,
DailTimeout: 1000,
ReadTimeout: 1000,
WriteTimeout: 1000,
NodeConn: 2,
PingFailLimit: 3,
PingAutoEject: true,
ListenProto: "tcp",
ListenAddr: addr,
}
if _, err := srv.AddCluster(ctx, clst); err != nil {
ctx.JSONMap(map[string]interface{}{
"message": "添加cluster失败:" + name + " " + err.Error(),
}, ecode.RequestErr)
return
}
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]})
}
ns, _ := json.Marshal(nodes)
cn := &model.ModifyClusterReq{
Name: name,
Action: 1,
Nodes: string(ns),
}
if _, err := srv.ModifyCluster(ctx, cn); err != nil {
ctx.JSONMap(map[string]interface{}{
"message": "添加cluster node失败:" + name + " " + err.Error(),
}, ecode.RequestErr)
return
}
}
}