Httpclient的会话保持引起的线程安全问题

这两天线上出现一个问题,通过httpclient来抓取页面,服务端在页面渲染的时候出现了串号现象。

首先看下代码,controller中代码如下:

request.getSession().setAttribute("sid", id);

vm页面再通过$!request.session.getAttribute("sid")获取参数值,这代码很常见,看起来单线程和多线程并发都不会有问题,因为每个用户的session都不同。但为什么httpclient请求时就有问题呢?

客户端(浏览器)在第一次和服务端建立连接后,服务端会创建一个session,响应的时候会和其他cookie信息保存到客户端,客户端发起下一次请求时,服务端会根据带上来的cookie信息(JSessionId)来决定是否要创建新session,如果存在就会共用之前的session。

而httpclient对象在创建后就相当于打开了一个浏览器,多个线程并发时,分别通过这个httpclient对象和服务器端建立了多个连接,但由于使用的是同一个httpclient对象,如果这个对象已经和服务端建立过连接,就会分配一个sessionid,并保存到cookie中,后面其他线程再通过这个httpclient对象和服务的建立连接时,服务端就会根据sessionid识别成同一个session。

看到这里相信大家都明白了开头说的串号现象背后的原因吧,线程安全要保持高度警惕,尽量使用线程变量(在当前线程中创建并生效的变量),而减少使用全局变量(多线程公用的变量),当出现多生产者时,全局变量就容易出问题,一旦出问题就是很诡异,不易重现的问题,测试一般难以发现。

你可能感兴趣的:(软件开发)