程序设计有缺陷如session能不能共享
一。分布式Session的几种实现方式
1基于数据库的Session共享
2基于NFS共享文件系统
3基于memcached 的session,如何保证 memcached 本身的高可用性?
4 基于resin/tomcat web容器本身的session复制机制
5 基于TT/Redis 或 jbosscache 进行 session 共享。
6 基于cookie 进行session共享
或者是:
一、Session Replication 方式管理 (即session复制)
简介:将一台机器上的Session数据广播复制到集群中其余机器上
使用场景:机器较少,网络流量较小
优点:实现简单、配置较少、当网络中有机器Down掉时不影响用户访问
缺点:广播式复制到其余机器有一定廷时,带来一定网络开销
二、Session Sticky 方式管理
简介:即粘性Session、当用户访问集群中某台机器后,强制指定后续所有请求均落到此机器上
使用场景:机器数适中、对稳定性要求不是非常苛刻
优点:实现简单、配置方便、没有额外网络开销
缺点:网络中有机器Down掉时、用户Session会丢失、容易造成单点故障
三、缓存集中式管理
简介:将Session存入分布式缓存集群中的某台机器上,当用户访问不同节点时先从缓存中拿Session信息
使用场景:集群中机器数多、网络环境复杂
优点:可靠性好
缺点:实现复杂、稳定性依赖于缓存的稳定性、Session信息放入缓存时要有合理的策略写入
二。Session和Cookie的区别和联系以及Session的实现原理
1、session保存在服务器,客户端不知道其中的信息;cookie保存在客户端,服务器能够知道其中的信息。
2、session中保存的是对象,cookie中保存的是字符串。
3、session不能区分路径,同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到。而cookie中如果设置了路径参数,那么同一个网站中不同路径下的cookie互相是访问不到的。
4、session需要借助cookie才能正常<nobr oncontextmenu="return false;"
onmousemove="kwM(3);" id="key3" onmouseover="kwE(event,3, this);"
style="COLOR: #6600ff; BORDER-BOTTOM: 0px dotted; BACKGROUND-COLOR:
transparent; TEXT-DECORATION: underline" onclick="return kwC();"
onmouseout="kwL(event, this);"
target="_blank">工作</nobr>。如果客户端完全禁止cookie,session将失效。
http是无状态的协议,客户每次读取web页面时,服务器都打开新的会话,而且服务器也不会自动维护客户的上下文信息,那么要怎么才能实现网上商店中的
购物车呢,session就是一种保存上下文信息的机制,它是针对每一个用户的,变量的值保存在服务器端,通过SessionID来区分不同的客
户,session是以cookie或URL重写为基础的,默认使用cookie来实现,系统会创造一个名为JSESSIONID的输出cookie,我
们叫做session cookie,以区别persistent
cookies,也就是我们通常所说的cookie,注意session
cookie是存储于浏览器内存中的,并不是写到硬盘上的,这也就是我们刚才看到的JSESSIONID,我们通常情是看不到JSESSIONID的,但
是当我们把浏览器的cookie禁止后,web服务器会采用URL重写的方式传递Sessionid,我们就可以在地址栏看到
sessionid=KWJHUG6JJM65HS2K6之类的字符串。
明白了原理,我们就可以很容易的分辨出persistent cookies和session
cookie的区别了,网上那些关于两者安全性的讨论也就一目了然了,session cookie针对某一次会话而言,会话结束session
cookie也就随着消失了,而persistent
cookie只是存在于客户端硬盘上的一段文本(通常是加密的),而且可能会遭到cookie欺骗以及针对cookie的跨站脚本攻击,自然不如
session cookie安全了。
通常session
cookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的sessionid,这样我们信息共享的目的就达不到
了,此时我们可以先把sessionid保存在persistent
cookie中,然后在新窗口中读出来,就可以得到上一个窗口SessionID了,这样通过session cookie和persistent
cookie的结合我们就实现了跨窗口的session tracking(会话跟踪)。
在一些web开发的书中,往往只是简单的把Session和cookie作为两种并列的http传送信息的方式,session
cookies位于服务器端,persistent
cookie位于客户端,可是session又是以cookie为基础的,明白的两者之间的联系和区别,我们就不难选择合适的技术来开发web
service了。
总之:
一、cookie机制和session机制的区别
具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。
同时我们也看到,由于在服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上还有其他选择。
二、会话cookie和持久cookie的区别
如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。
如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。
存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。
三、如何利用实现自动登录
当用户在某个网站注册后,就会收到一个惟一用户ID的cookie。客户后来重新连接时,这个用户ID会自动返回,服务器对它进行检查,确定它是否为注册用户且选择了自动登录,从而使用户无需给出明确的用户名和密码,就可以访问服务器上的资源。
四、如何根据用户的爱好定制站点
网站可以使用cookie记录用户的意愿。对于简单的设置,网站可以直接将页面的设置存储在cookie中完成定制。然而对于更复杂的定制,网站只需仅将一个惟一的标识符发送给用户,由服务器端的数据库存储每个标识符对应的页面设置。
五、cookie的发送
1创建Cookie对象
2设置最大时效
3将Cookie放入到HTTP响应报头
如果你创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie:存储在浏览器的内存中,用户退出浏览器之后被删除。如
果你希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该
cookie。
发送cookie需要使用HttpServletResponse的addCookie方法,将cookie插入到一个 Set-Cookie
HTTP请求报头中。由于这个方法并不修改任何之前指定的Set-Cookie报头,而是创建新的报头,因此我们将这个方法称为是addCookie,而
非setCookie。同样要记住响应报头必须在任何文档内容发送到客户端之前设置。
六、cookie的读取
1调用requestgetCookie
要获取有浏览器发送来的cookie,需要调用HttpServletRequest的getCookies方法,这个调用返回Cookie对象的数组,对应由HTTP请求中Cookie报头输入的值。
2对数组进行循环,调用每个cookie的getName方法,直到找到感兴趣的cookie为止
cookie与你的主机(域)相关,而非你的servlet或JSP页面。因而,尽管你的servlet可能只发送了单个cookie,你也可能会得到许多不相关的cookie。
例如:
String cookieName = “userID”;
Cookie cookies[] = requestgetCookies();
if (cookies!=null){
for(int i=0;i
Cookie
cookie = cookies[i];
if (cookieNameequals(cookiegetName())){
doSomethingWith(cookiegetValue());
}
}
}
七、如何使用cookie检测初访者
A调用HttpServletRequestgetCookies()获取Cookie数组
B在循环中检索指定名字的cookie是否存在以及对应的值是否正确
C如果是则退出循环并设置区别标识
D根据区别标识判断用户是否为初访者从而进行不同的操作
八、使用cookie检测初访者的常见错误
不能仅仅因为cookie数组中不存在在特定的数据项就认为用户是个初访者。如果cookie数组为null,客户可能是一个初访者,也可能是由于用户将cookie删除或禁用造成的结果。
但是,如果数组非null,也不过是显示客户曾经到过你的网站或域,并不能说明他们曾经访问过你的servlet。其它servlet、JSP页面以及
非Java Web应用都可以设置cookie,依据路径的设置,其中的任何cookie都有可能返回给用户的浏览器。
正确的做法是判断cookie数组是否为空且是否存在指定的Cookie对象且值正确。
九、使用cookie属性的注意问题
属性是从服务器发送到浏览器的报头的一部分;但它们不属于由浏览器返回给服务器的报头。
因此除了名称和值之外,cookie属性只适用于从服务器输出到客户端的cookie;服务器端来自于浏览器的cookie并没有设置这些属性。
因而不要期望通过requestgetCookies得到的cookie中可以使用这个属性。这意味着,你不能仅仅通过设置cookie的最大时效,
发出它,在随后的输入数组中查找适当的cookie,读取它的值,修改它并将它存回Cookie,从而实现不断改变的cookie值。
十、如何使用cookie记录各个用户的访问计数
1获取cookie数组中专门用于统计用户访问次数的cookie的值
2将值转换成int型
3将值加1并用原来的名称重新创建一个Cookie对象
4重新设置最大时效
5将新的cookie输出
十一、session在不同环境下的不同含义
session,中文经常翻译为会话,其本来的含义是指有始有终的一系列动作/消息,比如打电话是从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个session。
然而当session一词与网络协议相关联时,它又往往隐含了“面向连接”和/或“保持状态”这样两个含义。
session在Web开发环境下的语义又有了新的扩展,它的含义是指一类用来在客户端与服务器端之间保持状态的解决方案。有时候Session也用来指这种解决方案的存储结构。
十二、session的机制
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
但程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否包含了一个session标识-称为session
id,如果已经包含一个session id则说明以前已经为此客户创建过session,服务器就按照session
id把这个session检索出来使用(如果检索不到,可能会新建一个,这种情况可能出现在服务端已经删除了该用户对应的session对象,但用户人为
地在请求的URL后面附加上一个JSESSION的参数)。
如果客户请求不包含session id,则为此客户创建一个session并且生成一个与此session相关联的session id,这个session id将在本次响应中返回给客户端保存。
十三、保存session id的几种方式
A.保存session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。
B.
由于cookie可以被人为的禁止,必须有其它的机制以便在cookie被禁止时仍然能够把session
id传递回服务器,经常采用的一种技术叫做URL重写,就是把session
id附加在URL路径的后面,附加的方式也有两种,一种是作为URL路径的附加信息,另一种是作为查询字符串附加在URL后面。网络在整个交互过程中始终
保持状态,就必须在每个客户端可能请求的路径后面都包含这个session
id。
C.另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。
十四、session什么时候被创建
一个常见的错误是以为session在有客户端访问时就被创建,然而事实是直到某server端程序(如Servlet)调用HttpServletRequestgetSession(true)这样的语句时才会被创建。
十五、session何时被删除
session在下列情况下被删除:
A.程序调用HttpSessioninvalidate()
B.距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间
C.服务器进程被停止
再次注意关闭浏览器只会使存储在客户端浏览器内存中的session cookie失效,不会使服务器端的session对象失效。
试试bboss sesion共享方案,简单又实用,跨容器,采用mongodb存储会话信息,安全可靠,不会丢失session,支持属性增量更新,支持tomcat,jetty,
<Manager className="dejavakaffeewebmsmMemcachedBackupSessionManager"
memcachedNodes="n1:host1yourdomaincom:11211,n2:host2yourdomaincom:11211"
sticky="false"
sessionBackupAsync="false"
lockingMode="uriPattern:/path1|/path2"
requestUriIgnorePattern="\(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="dejavakaffeewebmsmJavaSerializationTranscoderFactory"
/>
如你还有别的问题,可另外向我求助,还有不懂的地方,请继续追问。
系统bug问题。系统bug是nginx系统出现了问题导致nginx配置不共享session后端,等待官方修复即可。Nginx是一款轻量级的Web服务器反向代理服务器及电子邮件代理服务器,在BSDlike协议下发行。
一、术语session
在我的经验里,session这个词被滥用的程度大概仅次于transaction,更加有趣的是transaction与session在某些语境下的含义是相同的。
session,中文经常翻译为会话,其本来的含义是指有始有终的一系列动作/消息,比如打电话时从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个session。有时候我们可以看到这样的话"在一个浏览器会话期间,",这里的会话一词用的就是其本义,是指从一个浏览器窗口打开到关闭这个期间①。最混乱的是"用户(客户端)在一次会话期间"这样一句话,它可能指用户的一系列动作(一般情况下是同某个具体目的相关的一系列动作,比如从登录到选购商品到结账登出这样一个网上购物的过程,有时候也被称为一个transaction),然而有时候也可能仅仅是指一次连接,也有可能是指含义①,其中的差别只能靠上下文来推断②。
然而当session一词与网络协议相关联时,它又往往隐含了"面向连接"和/或"保持状态"这样两个含义,"面向连接"指的是在通信双方在通信之前要先建立一个通信的渠道,比如打电话,直到对方接了电话通信才能开始,与此相对的是写信,在你把信发出去的时候你并不能确认对方的地址是否正确,通信渠道不一定能建立,但对发信人来说,通信已经开始了。"保持状态"则是指通信的一方能够把一系列的消息关联起来,使得消息之间可以互相依赖,比如一个服务员能够认出再次光临的老顾客并且记得上次这个顾客还欠店里一块钱。这一类的例子有"一个TCP session"或者"一个POP3 session"③。
而到了web服务器蓬勃发展的时代,session在web开发语境下的语义又有了新的扩展,它的含义是指一类用来在客户端与服务器之间保持状态的解决方案④。有时候session也用来指这种解决方案的存储结构,如"把xxx保存在session里"⑤。由于各种用于web开发的语言在一定程度上都提供了对这种解决方案的支持,所以在某种特定语言的语境下,session也被用来指代该语言的解决方案,比如经常把Java里提供的javaxservlethttpHttpSession简称为session⑥。
鉴于这种混乱已不可改变,本文中session一词的运用也会根据上下文有不同的含义,请大家注意分辨。
在本文中,使用中文"浏览器会话期间"来表达含义①,使用"session机制"来表达含义④,使用"session"表达含义⑤,使用具体的"HttpSession"来表达含义⑥
二、HTTP协议与状态保持
HTTP协议本身是无状态的,这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器请求下载某些文件,无论是客户端还是服务器都没有必要纪录彼此过去的行为,每一次请求之间都是独立的,好比一个顾客和一个自动售货机或者一个普通的(非会员制)大卖场之间的关系一样。
然而聪明(或者贪心?)的人们很快发现如果能够提供一些按需生成的动态信息会使web变得更加有用,就像给有线电视加上点播功能一样。这种需求一方面迫使HTML逐步添加了表单、脚本、DOM等客户端行为,另一方面在服务器端则出现了CGI规范以响应客户端的动态请求,作为传输载体的HTTP协议也添加了文件上载、cookie这些特性。其中cookie的作用就是为了解决HTTP协议无状态的缺陷所作出的努力。至于后来出现的session机制则是又一种在客户端与服务器之间保持状态的解决方案。
让我们用几个例子来描述一下cookie和session机制之间的区别与联系。笔者曾经常去的一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微乎其微,这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案:
1、该店的店员很厉害,能记住每位顾客的消费数量,只要顾客一走进咖啡店,店员就知道该怎么对待了。这种做法就是协议本身支持状态。
2、发给顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。
3、发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次消费时,如果顾客出示该卡片,则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。
由于HTTP协议是无状态的,而出于种种考虑也不希望使之成为有状态的,因此,后面两种方案就成为现实的选择。具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。
三、理解cookie机制
cookie机制的基本原理就如上面的例子一样简单,但是还有几个问题需要解决:"会员卡"如何分发;"会员卡"的内容;以及客户如何使用"会员卡"。
正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。然而纯粹的客户端脚本如JavaScript或者VBScript也可以生成cookie。
而cookie的使用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器。意思是麦当劳的会员卡只能在麦当劳的店里出示,如果某家分店还发行了自己的会员卡,那么进这家店的时候除了要出示麦当劳的会员卡,还要出示这家店的会员卡。
cookie的内容主要包括:名字,值,过期时间,路径和域。
其中域可以指定某一个域比如googlecom,相当于总店招牌,比如宝洁公司,也可以指定一个域下的具体某台机器比如wwwgooglecom或者frooglegooglecom,可以用飘柔来做比。
路径就是跟在域名后面的URL路径,比如/或者/foo等等,可以用某飘柔专柜做比。
路径与域合在一起就构成了cookie的作用范围。
如果不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。
存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存里的cookie,不同的浏览器有不同的处理方式。对于IE,在一个打开的窗口上按Ctrl-N(或者从文件菜单)打开的窗口可以与原窗口共享,而使用其他方式新开的IE进程则不能共享已经打开的窗口的内存cookie;对于Mozilla Firefox08,所有的进程和标签页都可以共享同样的cookie。一般来说是用javascript的windowopen打开的窗口会与原窗口共享内存cookie 。浏览器对于会话cookie的这种只认cookie不认人的处理方式经常给采用session机制的web应用程序开发者造成很大的困扰。
下面就是一个goolge设置cookie的响应头的例子
HTTP/11 302 Found
Location: http://wwwgooglecom/intl/zh-CN/
Set-Cookie: PREF=ID=0565f77e132de138:NW=1:TM=1098082649:LM=1098082649:S=KaeaCFPo49RiA_d8; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=googlecom
Content-Type: text/html
实现同一Tomcat下两个WEB应用之间通过session 共享数据。
查看tomcat 关于 HTTP Connector 中有个emptySessionPath 其解释如下:
If set to true, all paths for session cookies will be set to / This can be useful for portlet specification implementations If not specified, this attribute is set to false
A side effect to setting this to true, is that if Tomcat creates a new session it will attempt to use the cookie session id if supplied by the client
设置为true 发现没有用,在网上搜了一下方法,基本是这样的:
由于每个WEB应用程序都有一个唯一的一个ServletContext 实例对象,自己下面的所有的servlet 共享此ServletContext,利用ServletContext 中的setAttribute() 方法把Session 传递过去,然后在另外一个WEB程序中拿到session实例。
1、修改Tomcat---conf----serverxml文件
把
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true" xmlNamespaceAware="false" x mlValidation="false"></Host>
修改为:
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true" xmlNamespaceAware="false" x mlValidation="false">
<Context path="/Project_A" reloadable="false" crossContext="true"></Context>
<Context path="/Project_B" reloadable="false" crossContext="true"></Context>
</Host>
注意 crossContext 属性:
crossContext: Set to true if you want calls within this application to ServletContextgetContext() to successfully return a request dispatcher for other web applications running on this virtual host Set to false (the default) in security conscious environments, to make getContext() always return null
0条评论