PHP多台服务器跨域SESSION共享

网站业务规模和访问量的逐步发展,原本由单台服务器、单个域名的迷你网站架构已经无法满足发展需要。

  此时我们可能会购买更多服务器,并且启用多个二级子域名以频道化的方式,根据业务功能将网站分布部署在独立的服务器上;或通过负载均衡技术
(如:DNS轮询、Radware、F5、LVS等)让多个频道共享一组服务器。

  OK,头脑中我们已经构思了这样的解决方案,不过进入深入开发后新的技术问题又随之而来:

  我们把网站程序分布部署到多台服务器上,而且独立为几个二级域名,由于Session受实现原理的局限(PHP中Session默认以文件的形
式保
存在本地服务器的硬盘),使得我们的网站用户不得不经常在几个频道间来回输入用户名、密码登入,导致用户体验大打折扣;另外,原本程序可以直接从用户
Session变量中读取的资料(如:昵称、积分、登入时间等),因为无法跨服务器同步更新Session变量,迫使开发人员必须实时读写数据库,从而增
加了数据库的负担。

  于是,解决网站跨服务器之间的Session共享方案需求变得迫切起来,最终催生了多种解决方案,下面列举4种较为可行的方案进行对比探讨:

  1. 基于NFS的Session共享

  NFS是Net FileSystem的简称,最早由Sun公司为解决Unix网络主机间的目录共享而研发。

  这个方案实现最为简单,无需做过多的二次开发,仅需将共享目录服务器mount到各频道服务器的本地session目录即可,缺点是NFS依托
于复 杂的安全机制和文件系统,因此并发效率不高,尤其对于session这类高并发读写的小文件,
会由于共享目录服务器的io-wait过高,最终拖累前端WEB应用程序的执行效率。

  2. 基于数据库的Session共享

  首选当然是大名鼎鼎的Mysql数据库,并且建议使用内存表Heap,提高session操作的读写效率。这个方案的实用性比较强,相信大家普
遍在
使用,它的缺点在于session的并发读写能力取决于Mysql数据库的性能,同时需要自己实现session淘汰逻辑,以便定时从数据表中更新、删除
session记录,当并发过高时容易出现表锁,虽然我们可以选择行级锁的表引擎,但不得不否认使用数据库存储Session还是有些杀鸡用牛刀的架势。

  3. 基于Cookie的Session共享

  这个方案我们可能比较陌生,但它在大型网站中还是比较普遍被使用。原理是将全站用户的Session信息加密、序列化后以Cookie的方式,
统一
种植在根域名下(如:.host.com),利用浏览器访问该根域名下的所有二级域名站点时,会传递与之域名对应的所有Cookie内容的特性,从而实现
用户的Cookie化Session 在多服务间的共享访问。

  这个方案的优点无需额外的服务器资源;缺点是由于受http协议头信心长度的限制,仅能够存储小部分的用户信息,同时Cookie化的
Session内容需要进行安全加解密(如:采用DES、RSA等进行明文加解密;再由MD5、SHA-1等算法进行防伪认证),另外它也会占用一定的带
宽资源,因为浏览器会在请求当前域名下任何资源时将本地Cookie附加在http头中传递到服务器。

  4. 基于Memcache的Session共享

  Memcache由于是一款基于Libevent多路异步I/O技术的内存共享系统,简单的Key +
Value数据存储模式使得代码逻辑小巧高效,因此在并发处理能力上占据了绝对优势,目前本人所经历的项目达到2000/秒
平均查询,并且服务器CPU消耗依然不到10%。

  另外值得一提的是Memcache的内存hash表所特有的Expires数据过期淘汰机制,正好和Session的过期机制不谋而合,降低了
过期Session数据删除的代码复杂度,对比“基于数据库的存储方案”,仅这块逻辑就给数据表产生巨大的查询压力。

  基于Memcache 的存储是这几个方案中推荐选用的!

  其它方案依然有其使用的场合,具体选用哪套需要开发人员的根据当前的服务器资源、网站并发压力等综合评估。

时间: 2024-10-11 00:36:34

PHP多台服务器跨域SESSION共享的相关文章

跨服务器之间的session共享

跨服务器之间的Session共享方案需求变得迫切起来,最终催生了多种解决方案,下面列举4种较为可行的方案进行对比探讨: 1. 基于NFS的Session共享 NFS是Net FileSystem的简称,最早由Sun公司为解决Unix网络主机间的目录共享而研发. 这个方案实现最为简单,无需做过多的二次开发,仅需将共享目录服务器mount到各频道服务器的 本地session目录即可,缺点是NFS依托于复杂的安全机制和文件系统,因此并发效率不高,尤其对于session这类高并发读写的小文件, 会由于共

Iframe跨域Session丢失的问题(大家是怎么解决的)

很久之前做的一个使用插件实现了图片批量上传,是通过IFrame加载上传面板的,使用google上传成功了就没怎么理了,最近同事测试时(使用的是360安全浏览器)老是出现上传不了图片的问题,然后换个浏览器上传就成功了. 于是, 今天就下载360安全浏览器测试一下,一调试,坑爹啊,我的session丢失了,网上查了一下,没解决, 最后只想到通过url传递参数的方法解决了.不知道大伙有没遇到过这样的问题,还有怎么解决的 Iframe跨域Session丢失的问题(大家是怎么解决的),布布扣,bubuko

Ajax跨域Session和跨域访问

一.关于ajax跨域请求,用jsonp老是不成功,虽然可以返回数据,但是error处报错.原因是返回的数据格式不是jsonp格式.但是用C#构造的请求却能够返回数据. 二.第三方的ajax请求肯定是不能获取得到你当前用户的session. 任务是这样的的,支付宝的页面返回notify页面(这个页面是异步访问的),而我的C#处理有一个处理模块,需要判断如果是已经登录则加积分之类的操作,结果老是获取不到session数据,可是明明登录了啊.这里的误区是,我们当前域肯定是已经登录了,可对于支付宝那边的

前后端分离 ajax 跨域 session 传值 (后端使用 node)

前端:ajax访问时要加上"xhrFields: {withCredentials: true}" ,实现session可以传递 后端:Access-Control-Allow-Credentials 设置为 true:同时 Access-Control-Allow-Origin 必须指定 url npm 安装 express.body-parser.express-session.svg-captcha 后台代码: 1 var express = require('express')

sso单点登录之跨域cookie共享 (跨域缓存共享)

使用cookie的两个属性 domain-域 通过设置这个属性可以使多个web服务器共享cookie.domain属性的默认值是创建cookie的服务器的主机名.不能将一个cookie的域设置成服务器所在的域之外的域. 举个例子: 让位于a.taotao.com的服务器能够读取b.taotao.com设置的cookie值.如果b.taotao.com的页面创建的cookie把 它的path属性设置为”/”,把domain属性设置成”.taotao.com”,那么所有位于b.taotao.com的

前端开发用nginx代理服务器解决服务器跨域问题及跨域访问https访问(mac系统下)

前端开发经常遇到一些服务器由于跨域造成访问不了的情况.以前BS模式,前后端都是一个人开发,跨域问题造成的开发阻碍不是很明显,但是现在前端框架欣欣向荣,很多时候变成了CS模式的开发,但浏览器天生的跨域限制,造成了开发,特别是对单独的前端开发人员(不太懂后台开发的人)造成一定开发障碍.还好有nodejs及其一系列前端自动化工具很好的解决了开发时的问题.但今天我要说的用nginx代理来解决这个问题.我觉得很简单!以下都是基于mac系统的操作!先看没有代理时,随便访问网上一个接口, http://web

基于Cesium1.26地图API下的GeoServer2.90服务器跨域设置

遇到的问题: 最近基于Cesium来做3D模型的地图开发,在访问自己发布的WMS服务之后,遇到了GeoServer跨域问题. 调用这个WMS服务的时候,浏览器(我用Chrome)开发者工具报错: 控制台提示如下: Font from origin 'http://xxxxxxxxxxxxx' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin'

java之初识服务器跨域获取数据

当一个项目膨大到无法进行整理时,而作为新负责维护的团队是非常苦恼的.对于想实现两个系统的数据访问,使用Ajax数据请求方式获取jsonp格式的数据 需要有前端jquery库文件. 前端代码通过jquery的处理方式如下: $.ajax({ type : "get", //jquey是不支持post方式跨域的 async:false, url : "http://192.168.0.113:8080/test/", //跨域请求的URL dataType : &quo

golang http服务器跨域问题解决

func main() { openHttpListen() } func openHttpListen() { http.HandleFunc("/", receiveClientRequest) fmt.Println("go server start running...") err := http.ListenAndServe(":9090", nil) if err != nil { log.Fatal("ListenAndS