Cloud Foundry中gorouter对StickySession的支持

Cloud Foundry中gorouter对StickySession的支持

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

        Cloud Foundry作为业界出众的PaaS平台,在应用的可扩展性方面做得很优秀。

        详细来讲,在一个应用须要横向伸展的时候,Cloud Foundry能够轻松地帮助用户做好伸展工作,也就是创建出一个应用的多个实例,多个实例地位相等,多个实例共同为用户服务,多个实例共同分担訪问压力。

        大致来说,能够觉得是共同分担訪问压力,可是也不是针对全部该应用的訪问,都进行均衡,分发到不同的应用实例处。譬如:当Cloud Foundry的訪问用户訪问应用时,第一次的訪问,gorouter会将请求分发到应用的某个实例处,可是假设该用户之后的訪问都是有状态的,不希望之后的訪问会被分发到该应用的其它实例处。针对以上这样的情况,Cloud Foundry提供了自己的解决方式,使用StickySession的方式,保证请求依然分发给指定的应用实例。

        本文即分析Cloud Foundry中gorouter关于StickySession的实现方式。

        该部分内容须要对gorouter有一定的了解,能够參见笔者之前的博文:Cloud Foundry中gorouter源代码分析

        关于StickySession的信息,gorouter所做的工作,主要分为两个部分:怎样给HTTP请求加入�StickySession、怎样通过StickySession辨别应用的详细实例。

怎样给HTTP请求加入�StickySession

        

        在分析这个问题的时候,首先我们须要提出还有一个问题:什么情况下须要给HTTP请求加入�StickySession?

        首先,来看这种一个方法setupStickySession的go语言实现:

func (h *RequestHandler) setupStickySession(endpointResponse *http.Response, endpoint *route.Endpoint) {
        needSticky := false
        for _, v := range endpointResponse.Cookies() {
                if v.Name == StickyCookieKey {
                        needSticky = true
                        break
                }
        }

        if needSticky && endpoint.PrivateInstanceId != "" {
                cookie := &http.Cookie{
                        Name:  VcapCookieId,
                        Value: endpoint.PrivateInstanceId,
                        Path:  "/",
                }

                http.SetCookie(h.response, cookie)
        }
}
      

       紧接着,查看setupStickySession方法何时被调用的代码:

func (h *RequestHandler) HandleHttpRequest(transport *http.Transport, endpoint *route.Endpoint) (*http.Response, error) {
        h.transport = transport

        h.setupRequest(endpoint)
        h.setupConnection()

        endpointResponse, err := transport.RoundTrip(h.request)
        if err != nil {
                return endpointResponse, err
        }

        h.forwardResponseHeaders(endpointResponse)

        h.setupStickySession(endpointResponse, endpoint)

        return endpointResponse, err
}

        在setupStickySession方法中,能够看到:首先进入一个循环语句块中,当endpointResponse中的cookies中有名为StickyCookieKey的话,将needSticky字段置为true,跳出循环。这里也就回答了什么时候须要给HTTP请求加入�StickySession的问题。关于StickyCookieKey的值,能够先看一下gorouter的设置:

const (
        VcapCookieId    = "__VCAP_ID__"
        StickyCookieKey = "JSESSIONID"
)

        能够看到StickyCookieKey的值为JSESSIONID,而JSESSIONID是Tomcat对session id的称呼,在其它容器中就不一定叫JSESSIONID了。因此,假设平台运维者自己定义了一种容器的buildpack,而这个容器中对于session id的称呼不为JSESSIONID的话,那么Sticky Session在gorouter中将不能被实现,除非将这部分内容自行进行改写,或者改动该容器对session id的称呼。

       紧接着在setupStickySession中,通过一个推断,来给response创建一个cookie,创建的cookie有Name字段,Value字段以及Path字段。最后通过http.SetCookie(h.response, cookie)来实现对response的设置加入�cookie。

       读完setupStickySession方法的实现,如今进入调用该方法的HandleHttpRequest方法,该方法的主要工作是:将haproxy代理来的请求,转发给详细对应的DEA上的应用实例,最后构建该请求的response信息,并返回该响应信息。在返回response响应信息的之前,gorouter为该response信息设置了StickySession。

        以上便是怎样给HTTP请求加入�StickySession,下面分析怎样通过StickySession辨别应用的详细实例。

怎样通过StickySession辨别应用的详细实例

        
        当一个请求到达gorouter的时候,gorouter须要首先辨别该请求中是否带有StickySession的信息,假设有的话,,gorouter分析该请求中的对应信息,终于得到指定应用实例的信息,并将请求转发到该指定应用实例。详细实现代码例如以下:
func (p *proxy) lookup(request *http.Request) (*route.Endpoint, bool) {
        uri := route.Uri(hostWithoutPort(request))

        // Try choosing a backend using sticky session
        if _, err := request.Cookie(StickyCookieKey); err == nil {
                if sticky, err := request.Cookie(VcapCookieId); err == nil {
                        routeEndpoint, ok := p.registry.LookupByPrivateInstanceId(uri, sticky.Value)
                        if ok {
                                return routeEndpoint, ok
                        }
                }
        }

        // Choose backend using host alone
        return p.registry.Lookup(uri)
}

        从源代码中能够看到,首先从请求中提取出uri,随后分析请求中是否带有StickyCookieKey,也就是JSESSIONID,若有的话,继续分析是否带有VcapCookieID,也就是__VCAP_ID__,若有的话,那说明是gorouter支持的StickySession,从sticky中找出value属性相应的值,也就是应用PrivateInstanceID,通过该ID寻找出详细相应的是应用的哪个实例,最后返回该应用实例的详细信息,当然包含终于该实例的IP:PORT。假设以上这些StickyCookieKey或者VcapCookieID不存在的话,也就是说该请求不支持StickySession,那么将直接通过uri,寻找某一个应用实例来为该请求服务。

        以上便是Cloud Foundry中gorouter对StickySession的支持与实现。


转载请注明出处。

这篇文档很多其它出于我本人的理解,肯定在一些地方存在不足和错误。希望本文可以对接触Cloud Foundry v2中gorouter实现StickySession的人有些帮助,假设你对这方面感兴趣,并有更好的想法和建议,也请联系我。

我的邮箱:shlallen@zju.edu.cn


新浪微博:
@莲子弗如清

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/118949.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 阿里iconfont使用方法

    阿里iconfont使用方法阿里巴巴iconfont的使用方式分为两种:本地使用线上引用iconfont-阿里巴巴矢量图标库0.前期准备使用时先到网站上选中需要使用的图标添加至项目1.本地使用1.下载项目至本地2.解压到项目中3.在页面中引入样式<!DOCTYPEhtml><htmllang=”en”><head> <metacharset=”UTF-8″> <metaname=”viewport”content=”width=dev

    2022年10月29日
  • 用js来实现那些数据结构16(图02-图的遍历)

    上一篇文章我们简单介绍了一下什么是图,以及用JS来实现一个可以添加顶点和边的图。按照惯例,任何数据结构都不可或缺的一个point就是遍历。也就是获取到数据结构中的所有元素。那么图当然也不例外。这篇文章

  • 小米手机MIUI安装Google服务框架和Google Play的教程[通俗易懂]

    GooglePlay上的APP普遍比国内应用商店的要干净得多,权限要求更少,这也是促使很多人使用GooglePlay的原因。步骤如下:1、打开小米应用商店,搜索“谷歌安装器”,拉到最下面,“去豌豆荚搜索”image2、找到谷歌安装器3.0image3、开始安装Google服务框架和GooglePlayimage整个过程无需SS,在国内网络即可完成。最后,连上SS,登录GooglePlay,开始下载干净的app吧,少年。…

  • 显示为弹出窗口是什么意思(电脑总是弹出广告)

    今天很伤心啊,刚到学校的教室打开电脑准备链接校园网,谁知给我弹出个快快赶紧的把我的指甲刀那来,谁都不要拦我~~~~~~~~~~~~~~~~~~~~~~~~不说废话啦,讲操作了~~~~~~~~~~~~~~~~~~~啦啦~~~~~~~~~~~lala~~~~~首先在菜单栏里搜“默认应用设置”会出现这个点进去找到http然后点击,进去就会有个强烈推荐,点击进去就好。希…

  • MODIS数据介绍及下载

    MODIS数据介绍及下载MODIS数据简介中分辨率成像光谱仪(MODerate-resolutionImagingSpectroradiometer)-MODIS是Terra和Aqua卫星上搭载的主要传感器之一。MODIS标准数据产品根据内容的不同分为0级、1级数据产品,在1B级数据产品之后,划分2-4级数据产品,包括:陆地标准数据产品、大气标准数据产品和海洋标准数据产品等三种主要标准数据产品类型,总计分解为44种标准数据产品类型。数据产品的详细介绍参考博文。官网下载数据数据产品投影MODIS数据采用正弦投影(Sin

  • source insight 3.5的注册码「建议收藏」

    source insight 3.5的注册码「建议收藏」
    sourceinsight3.5的注册码:SI3US-719473-71478

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号