- 浏览: 174658 次
- 性别:
- 来自: 北京
最新评论
-
chainhou:
sunshineman 写道maven 编译不过啊,连不上ec ...
jetty的下载,编译,安装等 -
sunshineman:
maven 编译不过啊,连不上eclipse的proxy
jetty的下载,编译,安装等
最近有个朋友问我:
答:内存中。又问:
答:(当时没看过这块的代码),说由于每个应用对应一个Session管理,此处应该有类似于数组之类的东西,将该应用的session管理起来,当该应用移除或者某些sesion过期时可以准确的删除掉。最近看了下代码,对比下源码,发现回复的还行,没有特别大的出入。
我们的应用中一般都会用到session,那这个session在应用服务器内部到底是怎么保存到处理的呢?
当我们请求一个应用时,如果页面中用到了session,此时的创建session的调用链如下:
以上调用链的部分关键代码:
在setId时,同时在Manager中将相应的session保存了下来。此处对于session的保存使用的是ConcurrentHashMap,在创建后将其添加到map中,session过期后将其移除。
而在停止一个应用时,相应的remove session的调用链如下:
其中执行remove的代码如下:
引用
tomcat的session存在哪里?
答:内存中。又问:
引用
那既然都保存在内存中,要清除过期的sesion时,又怎么能区分是哪个应用的session而不会清除错误?
答:(当时没看过这块的代码),说由于每个应用对应一个Session管理,此处应该有类似于数组之类的东西,将该应用的session管理起来,当该应用移除或者某些sesion过期时可以准确的删除掉。最近看了下代码,对比下源码,发现回复的还行,没有特别大的出入。
我们的应用中一般都会用到session,那这个session在应用服务器内部到底是怎么保存到处理的呢?
当我们请求一个应用时,如果页面中用到了session,此时的创建session的调用链如下:
Daemon Thread [http-bio-8090-exec-1] (Suspended (breakpoint at line 145 in SessionIdGenerator)) owns: SocketWrapper<E> (id=234) SessionIdGenerator.generateSessionId() line: 145 StandardManager(ManagerBase).generateSessionId() line: 807 StandardManager(ManagerBase).createSession(String) line: 653 Request.doGetSession(boolean) line: 2892 Request.getSession(boolean) line: 2315 RequestFacade.getSession(boolean) line: 898 RequestFacade.getSession() line: 910 PageContextImpl._initialize(Servlet, ServletRequest, ServletResponse, String, boolean, int, boolean) line: 146 PageContextImpl.initialize(Servlet, ServletRequest, ServletResponse, String, boolean, int, boolean) line: 125 JspFactoryImpl.internalGetPageContext(Servlet, ServletRequest, ServletResponse, String, boolean, int, boolean) line: 112 JspFactoryImpl.getPageContext(Servlet, ServletRequest, ServletResponse, String, boolean, int, boolean) line: 65 index.jsp line: not available index_jsp(HttpJspBase).service(HttpServletRequest, HttpServletResponse) line: 70 index_jsp(HttpServlet).service(ServletRequest, ServletResponse) line: 728 JspServletWrapper.service(HttpServletRequest, HttpServletResponse, boolean) line: 432 JspServlet.serviceJspFile(HttpServletRequest, HttpServletResponse, String, boolean) line: 390 JspServlet.service(HttpServletRequest, HttpServletResponse) line: 334 JspServlet(HttpServlet).service(ServletRequest, ServletResponse) line: 728 ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 305 ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 210 StandardWrapperValve.invoke(Request, Response) line: 222 StandardContextValve.invoke(Request, Response) line: 123 NonLoginAuthenticator(AuthenticatorBase).invoke(Request, Response) line: 472 StandardHostValve.invoke(Request, Response) line: 171 ErrorReportValve.invoke(Request, Response) line: 99 AccessLogValve.invoke(Request, Response) line: 936 StandardEngineValve.invoke(Request, Response) line: 118 CoyoteAdapter.service(Request, Response) line: 408 Http11Processor(AbstractHttp11Processor<S>).process(SocketWrapper<S>) line: 1009 Http11Protocol$Http11ConnectionHandler(AbstractProtocol$AbstractConnectionHandler<S,P>).process(SocketWrapper<S>, SocketStatus) line: 589 JIoEndpoint$SocketProcessor.run() line: 310 ThreadPoolExecutor$Worker.runTask(Runnable) line: 895 ThreadPoolExecutor$Worker.run() line: 918 TaskThread(Thread).run() line: 662
以上调用链的部分关键代码:
/** * Construct and return a new session object, based on the default * settings specified by this Manager's properties. The session * id specified will be used as the session id. * If a new session cannot be created for any reason, return * <code>null</code>. * * @param sessionId The session id which should be used to create the * new session; if <code>null</code>, a new session id will be * generated * @exception IllegalStateException if a new session cannot be * instantiated for any reason */ @Override public Session createSession(String sessionId) { if ((maxActiveSessions >= 0) && (getActiveSessions() >= maxActiveSessions)) { rejectedSessions++; throw new TooManyActiveSessionsException( sm.getString("managerBase.createSession.ise"), maxActiveSessions); } // Recycle or create a Session instance Session session = createEmptySession(); // Initialize the properties of the new session and return it session.setNew(true); session.setValid(true); session.setCreationTime(System.currentTimeMillis()); session.setMaxInactiveInterval(this.maxInactiveInterval); String id = sessionId; if (id == null) { id = generateSessionId(); //此处生成sessionID } session.setId(id); sessionCounter++; SessionTiming timing = new SessionTiming(session.getCreationTime(), 0); synchronized (sessionCreationTiming) { sessionCreationTiming.add(timing); sessionCreationTiming.poll(); } return (session); } public void setId(String id, boolean notify) { if ((this.id != null) && (manager != null)) manager.remove(this); this.id = id; if (manager != null) manager.add(this); //注意此处 if (notify) { tellNew(); } }
在setId时,同时在Manager中将相应的session保存了下来。此处对于session的保存使用的是ConcurrentHashMap,在创建后将其添加到map中,session过期后将其移除。
/** * Add this Session to the set of active Sessions for this Manager. * * @param session Session to be added */ @Override public void add(Session session) { sessions.put(session.getIdInternal(), session); int size = getActiveSessions(); //此处应该可以使用AtomicInteger替换掉。 if( size > maxActive ) { synchronized(maxActiveUpdateLock) { if( size > maxActive ) { maxActive = size; } } } }
而在停止一个应用时,相应的remove session的调用链如下:
Daemon Thread [http-bio-8090-exec-2] (Suspended (breakpoint at line 733 in ManagerBase)) owns: StandardSession (id=340) owns: StandardManager (id=326) owns: StandardContext (id=327) owns: SocketWrapper<E> (id=341) StandardManager(ManagerBase).remove(Session, boolean) line: 733 StandardSession.expire(boolean) line: 840 StandardManager.doUnload() line: 463 StandardManager.unload() line: 353 StandardManager.stopInternal() line: 518 StandardManager(LifecycleBase).stop() line: 232 StandardContext.stopInternal() line: 5569 StandardContext(LifecycleBase).stop() line: 232 HTMLManagerServlet(ManagerServlet).stop(PrintWriter, ContextName, StringManager) line: 1306 HTMLManagerServlet.stop(ContextName, StringManager) line: 733 HTMLManagerServlet.doPost(HttpServletRequest, HttpServletResponse) line: 221 HTMLManagerServlet(HttpServlet).service(HttpServletRequest, HttpServletResponse) line: 647 HTMLManagerServlet(HttpServlet).service(ServletRequest, ServletResponse) line: 728 ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 305 ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 210 CsrfPreventionFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 213 ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 243 ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 210 SetCharacterEncodingFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 108 ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 243 ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 210 StandardWrapperValve.invoke(Request, Response) line: 222 StandardContextValve.invoke(Request, Response) line: 123 BasicAuthenticator(AuthenticatorBase).invoke(Request, Response) line: 581 StandardHostValve.invoke(Request, Response) line: 171 ErrorReportValve.invoke(Request, Response) line: 99 AccessLogValve.invoke(Request, Response) line: 936 StandardEngineValve.invoke(Request, Response) line: 118 CoyoteAdapter.service(Request, Response) line: 408 Http11Processor(AbstractHttp11Processor<S>).process(SocketWrapper<S>) line: 1009 Http11Protocol$Http11ConnectionHandler(AbstractProtocol$AbstractConnectionHandler<S,P>).process(SocketWrapper<S>, SocketStatus) line: 589 JIoEndpoint$SocketProcessor.run() line: 310 ThreadPoolExecutor$Worker.runTask(Runnable) line: 895 ThreadPoolExecutor$Worker.run() line: 918 TaskThread(Thread).run() line: 662
其中执行remove的代码如下:
/** * Perform the internal processing required to invalidate this session, * without triggering an exception if the session has already expired. * * @param notify Should we notify listeners about the demise of * this session? */ public void expire(boolean notify) { // Check to see if expire is in progress or has previously been called if (expiring || !isValid) return; synchronized (this) { // Check again, now we are inside the sync so this code only runs once // Double check locking - expiring and isValid need to be volatile if (expiring || !isValid) return; if (manager == null) return; ... //省略部分代码 } ... //省略部分代码 if (ACTIVITY_CHECK) { accessCount.set(0); } setValid(false); // Remove this session from our manager's active sessions manager.remove(this, true); } StandardManager中的remove方法: /** * Remove this Session from the active Sessions for this Manager. * * @param session Session to be removed * @param update Should the expiration statistics be updated */ @Override public void remove(Session session, boolean update) { // If the session has expired - as opposed to just being removed from // the manager because it is being persisted - update the expired stats if (update) { long timeNow = System.currentTimeMillis(); int timeAlive = (int) (timeNow - session.getCreationTimeInternal())/1000; updateSessionMaxAliveTime(timeAlive); expiredSessions.incrementAndGet(); SessionTiming timing = new SessionTiming(timeNow, timeAlive); synchronized (sessionExpirationTiming) { sessionExpirationTiming.add(timing); sessionExpirationTiming.poll(); } } if (session.getIdInternal() != null) { sessions.remove(session.getIdInternal()); //注意此处,即为上面保存session的concurrentHashMap } }
发表评论
-
Tomcat官方文档中文版
2017-02-13 17:15 1139在写微信公众号『Tomcat那些事儿』的时候,有不少读者看过 ... -
Cannot add or update a child row: a foreign key constraint fails
2014-03-24 14:49 9753最近在做应用服务器的CTS测试时发现这样一个问题,跑测试用例过 ... -
JAXB annotation说明及其使用
2013-06-14 14:59 3192最近学习REST,,由于jersey的demo中用到了JAXB ... -
获取当前用户所有java进程及jps命令的实现
2013-05-21 17:24 10046我们在开发中经常会遇 ... -
resource-ref与resource-env-ref的区别
2013-01-21 17:28 3467最近工作中处理一个对于资源引用的问题,主要问题是在reso ...
相关推荐
在Web开发中,Session管理是确保用户状态跟踪的重要机制之一。Tomcat作为一款广泛使用的Java应用服务器及Servlet容器,提供了多种方式来设定Session的有效时长。这有助于开发者根据具体业务需求灵活调整Session的...
综上所述,"Tomcat Redis Session"是一种在分布式环境中保证用户会话一致性的解决方案,通过集成Redis和Nginx,有效地解决了Web应用集群中的Session管理难题。在实际部署中,还需要考虑系统整体架构、性能优化和运维...
【标题】:“Tomcat-Redis-Session管理”的实践指南 在Web应用开发中,Session管理是关键的一环,用于在用户浏览器与服务器之间保持状态。传统的Session存储方式是将数据存放在服务器内存中,但随着高并发访问和...
Tomcat_Session 的持久...Tomcat 提供了 StandardManager 和 PersistentManager 两个实现类来管理 Session,其中 PersistentManager 能够把 Session 对象保存到 Session Store 中,提供了更为灵活的 Session 管理功能。
在Tomcat中集成memcached作为Session管理器,可以将Session数据分布在网络中的多个节点上,实现Session复制和高可用性。 为了在Tomcat中使用memcached进行Session管理,你需要以下关键的依赖jar包: 1. **...
在`Tomcat`中,我们可以通过`Tomcat Redis Session Manager`来实现与Redis的集成。这个组件允许我们将Tomcat的session数据存储在Redis中,使得所有服务器都能访问到这些数据。在提供的压缩包文件中,`jedis-2.1.0....
7. `memcached-session-manager-tc8-1.8.3.jar`:这个是针对Tomcat 8版本的session管理器实现,确保与Tomcat 8的兼容性。 8. `minlog-1.2.jar`:这是一个简单的日志库,可能用于在处理session共享时记录和调试信息。...
标题中的“tomcat8专用session管理包.rar”指的是一个针对Tomcat 8的特定session管理解决方案,这个压缩包包含了在使用Nginx作为反向代理服务器,并与Redis结合实现负载均衡场景下,确保Tomcat应用间session数据共享...
Tomcat中的Session管理** 在单台Tomcat服务器上,Session信息默认存储在服务器的内存中。然而,当部署多个Tomcat实例时,由于每个实例都有自己的Session存储,导致Session无法跨实例共享,用户在切换服务器时可能会...
综上所述,实现Tomcat集群session共享主要涉及Tomcat的session管理机制、Redis的集成以及相应的配置和优化。通过合理配置,可以确保在高并发环境下提供无缝的用户体验,同时提升系统的可扩展性和可靠性。
Tomcat作为最常用的Java Servlet容器,其Session管理能力直接影响到应用的性能和可扩展性。本教程将详细介绍如何利用Tomcat 8或9以及Redis实现Session共享,支持Redis集群,以提高系统的可伸缩性和数据一致性。 ...
综上所述,"tomcat-redis-session-manager包集合"为使用Tomcat8和JDK1.8的开发者提供了便捷的手段,通过集成Redis来增强session管理,提升应用在分布式环境下的性能和可靠性。正确配置和使用这个工具可以显著改善...
`SimpleTcpCluster` 是一个基于 TCP 的集群实现,而 `DeltaManager` 是用于处理 Session 数据更新的管理器。主要配置包括: - `tcpListenAddress`:指定接收复制数据的 IP 地址,例如 `192.168.1.55`。 - `...
5. **示例代码**:可能包含如何在Tomcat的web.xml配置文件中添加和配置这个session管理器的示例。 集成这个模块到Tomcat中,开发者需要: 1. 将jar文件放入Tomcat的lib目录,使服务器能加载到这个组件。 2. 在web....
2. **安装Redis-Session-Manager**: 在`Tomcat7`中,我们需要一个能够与Redis通信的Session管理器。可以通过`Spring Session`或者`JedisSessionRepositoryFilter`来实现。这里以`JedisSessionRepositoryFilter`为例...
6. **Cookie管理**:可以将session ID存储在cookie中,通过负载均衡器将请求路由到拥有相应session的服务器。这种方法简化了session的处理,但可能面临cookie篡改或跨站请求伪造(CSRF)攻击的风险。 在实际应用中...
总结来说,这个压缩包提供了一套完整的解决方案,包括了连接Redis的Jedis客户端、对象池管理、Tomcat的Session管理器以及配置文件,使得开发者可以轻松地在Tomcat集群中实现Session共享,提升系统的可扩展性和容错性...
总的来说,`tomcat-redis-session-manager`是应对分布式系统中session管理挑战的有效工具。它将Redis的强大功能引入Tomcat,实现了跨服务器的session共享,提高了应用的可扩展性和可靠性。正确配置和使用这个组件,...
在现代Web应用程序开发中,session管理是一个至关重要的环节,它涉及到用户会话的持久化和跨请求的数据共享。传统的session管理方式在高并发、分布式环境中可能会面临效率低下和数据一致性的问题。为了解决这些问题...
在多Tomcat环境下的session共享中,Shiro可以作为会话管理的工具,它支持自定义的session管理策略。 4. **共享Session的解决方案**: 为了实现session共享,我们可以利用Redis这样的内存数据存储系统。Redis具有...