golang利用beego的session存储实现session共享与微服务及负载均衡

前段时间要做游戏的管理后台,讲真一个游戏的后台管理真心不比任何一个管理系统要少,主要还是运营提的需求比较多。为了以后的扩展跟维护就想把游戏管理后台的业务拆开来,做成微服务。
服务器的类型有(这里只说与web有关的服务器):中心服务器、web网关服务器、web静态服务器、web服务器、服务中心(这里不仅仅给web服务器提供业务)、数据服务器。服务中心跟数据服务器在微服务的思路上没多大的用,这里只记录一下微服务的思路。所有的服务器之间用tcp协议通信用protobuf来进行数据通信(protobuf可以使用不同的语言即可以在服务端各个服务间使用也可以用于客户端的数据通信),用命令来区分服务器之间的业务。
1.服务分类型、都要向中心服务注册,中心服务在一个服务上线及下线时会通知与之有关的服务器;
2.web网关服务与web服务及web静太服务通信都通过中心服务,先发往中心服务,再由中心服务器转发给有关的服务;
3.web网关服务需跟中心要所有的web服务,把web服务以map[string][]*grpcmodel.ModelRegReqServerType的形式存放;ModelRegReqServerType里主要是服务名字、代理的url、服务地址、及权重;
4.web网关服务再把代理的信息通过中心服发送到所有的web服务;

web网关服务:通过map的key来区分代理url对就的服务器,多加一个/(对根路径)的代理处理(要放在最后进行匹配处理)及404等状态的处理;
启动服务:
    err := http.ListenAndServe(g.gwsCfg.Addr, g.reverseProxy())
g.reverseProxy方法是负责反向代理的;会在header里添加两个信息一个记录代理本服务器的url,一个记录静太服务器的代理地址;代码如下:
    director := func(req *http.Request) {
        //处理找不到页面报错的问题
        defer func() {
            if err := recover(); err != nil {
                utils.NewLogger().Errorln(err)
            }
        }()

        req_url := req.URL.Path
        proxy_url := "/"
        proxy_server := g.getProxy(proxy_url)

        req_url_splits := strings.Split(req_url, "/")
        if len(req_url_splits) > 1 && req_url_splits[1] != "" {
            first_url := req_url_splits[1]
            if _, ok := g.proxyUrls[proxy_url]; ok {
                proxy_server = g.getProxy(proxy_url)
            }
        }

        if proxy_server == nil {
            return
        }

        newUrl, err := url.Parse(fmt.Sprintf("http://%s%s", proxy_server.Addr, strings.Replace(req.URL.Path, proxy_url, "", 1)))
        utils.NewLogger().Infof("proxy_url is %s and proxy_server is %v\n", proxy_url, proxy_server)
        if err != nil {
            utils.NewLogger().Errorln(err)
            return
        }
        //req里设置被代理服务器的前置url
        //设置web服务被代理的基础路径
        //暂时思路是在代理的服务器上使用request的header里设置一个信息来作为一个被代理的路径
        req.Header.Add(define.Gate_String_Web_Proxy, proxy_url)
        if g.staticProxyUrl != "" {
            req.Header.Add(define.Gate_String_Web_Static_Resource_Proxy, g.staticProxyUrl)
        }
        req.URL = newUrl
    }
    return &httputil.ReverseProxy{Director: director}

getProxy方法是通过权重算出在一组同样的服务器里是要选择那个服务器进行连接(也可以根据服务器的cpu与内存的占比来决定)。

web服务器方面,因为关于服务器还有许多其他的配置我用的是直接自己写配置文件后用代码进行设置beego的配置;代码如下:
    //设定基础的配置
    if len(d.WebConfig.WebWiew) > 0 {
        beego.BConfig.WebConfig.ViewsPath = d.WebConfig.WebWiew
    }
    //自己的静态文件配置地址
    if len(d.WebConfig.WebStaticPath) > 0 {
        beego.SetStaticPath(d.WebConfig.WebStaticUrl, d.WebConfig.WebStaticPath)
    }
    beego.BConfig.WebConfig.Session.SessionOn = true
    //如果想让session共享把所有的SessionProvider与SessionProviderConfig配置为一个地方,前提是在同一台服务器上
    //内存方式实现不了共享
    if len(d.WebConfig.SessionProvider) > 0 {
        beego.BConfig.WebConfig.Session.SessionProvider = d.WebConfig.SessionProvider
    }
    if len(d.WebConfig.SessionProviderConfig) > 0 {
        beego.BConfig.WebConfig.Session.SessionProviderConfig = d.WebConfig.SessionProviderConfig
        if d.WebConfig.SessionProvider != "memory" {
            //把要存储session的结构体进行序列化存储
            d.webEngine.RegSessionGobStruct()
        }
    }

    if len(d.WebConfig.RunMode) > 0 {
        beego.BConfig.RunMode = d.WebConfig.RunMode
    }

    //日志设定
    beego.SetLogger("file", fmt.Sprintf(`{"filename":"./log/%s.log"}`, d.LogCfg.DeviceName))

    //启动
    beego.Run(d.WebConfig.Addr)

配置文件的配置内容:
    webView=webrec/managent/view
    //webStaticPath文件夹是没有文件的
    webStaticPath=webrec/managent/view/static
    webStaticUrl=/rec
    webUploadDir=webrec/staticresource/view/useshow
    runMode=dev
    proxyUrl=/managent
    //sessionProvider=file
    //sessionProviderConfig=sessiontmp
    sessionProvider=redis
    sessionProviderConfig=127.0.0.1:6379

web网关主要解决的是反向代理的问题,web服务器主要用beego的框架解决session共享的问题,beego的内存存储不支持session共享,如果想在单台服务器实现微服务可以装个redis也可以使用beego的文件存储。

备案号:豫ICP备14002392号-2