美文网首页蜂窝儿童未来教育
解决Nginx负载均衡的Session共享问题

解决Nginx负载均衡的Session共享问题

作者: DollarB | 来源:发表于2017-03-30 04:39 被阅读252次

    目前来说,蜂窝的产品基本上都是基于微信公众平台进行开发。为了可以快速开发,我使用了PHP的CodeIgniter框架配合EasyWeChat。

    CodeIgniter和EasyWeChat 是什么?

    CodeIgniter 是一个小巧但功能强大的 PHP 框架,作为一个简单而“优雅”的工具包,它可以为开发者们建立功能完善的 Web 应用程序。
    传送门:CodeIgniter

    EasyWeChat 是一个开源的微信非官方 SDK。
    传送门:EasyWeChat

    而微信公众平台的开发,最基础的一个模块就是通过OAuth模块获取用户信息进而实现相关的业务逻辑。

    什么是OAuth?

    OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。

    OAuth的授权流程
    OAuth的授权流程

    步骤解释:
    (A)用户打开客户端以后,客户端要求用户给予授权。
    (B)用户同意给予客户端授权。
    (C)客户端使用上一步获得的授权,向认证服务器申请令牌。
    (D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
    (E)客户端使用令牌,向资源服务器申请获取资源。
    (F)资源服务器确认令牌无误,同意向客户端开放资源。

    摘自:RFC 6749

    而通过以上的授权流程之后,都会用Session 来保持会话,维持用户的状态并跟踪他们的行为。但是在这里就遇到了一个问题:“在微信内置浏览器跳转的时候Session丢失”。

    一个bug我改了两天

    1. 从框架入手

    我的第一反应肯定就是CodeIgniter的框架问题,因为CodeIgniter的Session类并不使用PHP本身的session,而是使用自己的Session类。

    CodeIgniter的Sessions 是怎样工作的?

    当页面载入后,Session类就会检查用户的cookie中是否存在有效的session数据。如果session数据不存在(或者已经过期),那么就会创建一个新的session并把他保存在cookie中。如果session数据存在,那么他的信息就会被更新,同时cookie也会被同时更新。每次更新都会重新生成session_id的值。

    根据文档的提示去检查了下Cookie,发现并不是所有的页面的自定义 session 数据都会丢失。也就是说在页面跳转的过程中保存在cookie中的session数据在某些页面会丢失,并且不是在固定的某个页面丢失!

    烦躁
    2. Session过期?

    在修改了Session 相关的参数后,这个假设很快就被排除。

    3. 使用xdebug跟踪全部业务逻辑

    在排除了框架以及一些简单配置可能造成的影响之后,我开始使用xdebug跟踪全部业务逻辑,期待能找到session的丢失规律。

    其实到这里,本应该就找到了问题。但是由于自己的大意,我并没有注意到某些细节的变化,完全陷入了参数对不对以及在哪丢失的细节中去,反复思考到底为什么?

    之后在google的过程中,Segmentfault上的一个问答给了我一些思路:
    传送门:PHP 实现多台服务器共用SESSION方案?

    看了这篇文章之后,突然恍然大悟。也就联想到了之前在朗玛(我之前工作的一个公司)的培训。在朗玛工作的时候,最基本的处理都会把session存在memcache中。

    恍然大悟

    由于使用了nginx做负载均衡,这样同样一个页面会被分配到不同的服务器上,此时如果session不同步的话,就会出现问题。

    蜂窝目前的系统架构

    由于目前蜂窝的产品并没有这么大的访问请求,所以就还没有到利用缓存技术改善系统性能的阶段。基于此,我使用了CodeIgniter框架自带的解决方案:“将 Session 数据存入数据库。”

    哎,真的被自己蠢哭了!

    相关文章

      网友评论

      本文标题:解决Nginx负载均衡的Session共享问题

      本文链接:https://www.haomeiwen.com/subject/xlzsottx.html