123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- 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
- }
- }
- }
|