Nginx使用proxy_pass反向代理时Tomcat Session 对象丢失的解决办法
来源:xjh 编辑:xjh 2025-06-23
Nginx作为一个强大的Web服务器,有很强的功能。Nginx+Tomcat是Java Web动静分离的很好模型。但是,今天在配置过程中,遇到了一个问题,就是无法登录,从Session获取的随机验证码为null。由于之前在配置Tomcat的过程中,网站没有遇到过类似的问题,所以我很快确定了是由于配置了Nginx服务器引起session对象丢失。
原始错误:
String rand=(String)session.getAttribute("rand"):
java.lang.NullPointerException:Cannot invoke"String.equals(0bject)"because "rand” is null
那么,我们如何在Nginx中配置,以避免这样的事情呢?答案是通过修改Nginx配置文件来解决。
解决方法:修改 proxy_cookie_path 配置
Cookie及Session原理:
浏览器第一次请求,会发送一个cookie,但没有携带session相关的信息,Tomcat收到这个浏览器的请求之后,会查看cookie中是否包含了session信息,没有的话会在JVM中的session容器中创建一个session对象,并有一个唯一对应的sessionId,服务器处理完请求,返回响应给浏览器时,会将这个新创建的sessionId以及对应的session对象存入cookie中发给浏览器,浏览器收到该cookie之后存储在浏览器缓存中,至此第一次请求响应完毕。
以后浏览器每次发请求都会携带此cookie到Tomcat服务器,cookie是以(name:value)键值对形式存在,即携带的是sessionId,以及对应的session对象。Tomcat收到这样的cookie之后会拿到sessionId与session容器中存储的session对象进行对比,一致的话就不会新创建session对象表示这个session有效,会采用现存的session对象进行操作。否则session已经过期,需要创建新的session对象重复上述操作,处理完响应还是会将此cookie发送给浏览器(若浏览器存在一样的cookie就是覆盖操作)。
前面由于是单台Tomcat,不会有session丢失的情况。但若存在nginx服务器,浏览器则先发送cookie给nginx,再由nginx转交到各个Tomcat,这里的原理与上述一致,不同的是由nginx负载均衡之后,服务器可能发生改变,但由于各个Tomcat服务器JVM中session容器不共享,所以每次切换浏览器,都会发生session不一致情况,也即原来的session丢失了(Tomcat发现sessionId不一致会认为浏览器发送的session已经过期,会新创建session进行覆盖)。
参考:
https://blog.csdn.net/weixin_34087301/article/details/91982227
https://blog.csdn.net/yakson/article/details/46683285
https://blog.csdn.net/weixin_44864347/article/details/115314407
https://www.cnblogs.com/qvennnnn/p/6245676.html
https://blog.51cto.com/weimouren/1845102
https://blog.csdn.net/godaa/article/details/122716255