CXF client在并发下的线程安全问题

这个是发生在上周周末的真实案例,因为cxf client 端线程安全导致的错误,总结出来希望其他使用cxf的兄弟注意。

首先描述一下背景,简单的说就是使用cxf作为web service的客户端,运行在weblogic上,连接外部的服务器。为了测试需要,开发了一个简单的模拟器模拟服务器端,准备在release之前跑稳定性测试。

结果出问题了,在排除掉一些干扰和诸如网络环境,设置等之后问题依旧,由于系统负责,包括ws的模拟器也是出了一个之前没有试过的方法,因此费了不少时间来查找问题。过程很枯燥,应该很多人经历过,在一个大的系统中找到一个小错误的出处,可以说是一门学问,技术耐心和运气都是需要的.....跳出这个过程,由于问题表现在web service的网络连接在这个异常上,在服务器端模拟器的日志中有大量的这种异常信息:

2009-07-24 19:23:22,898 DEBUG (                    :  ) (tomcat-exec-56) [Http11NioProcessor] - Error parsing HTTP request header
java.io.EOFException: Unexpected EOF read on the socket
         at org.apache.coyote.http11.InternalNioInputBuffer.readSocket(InternalNioInputBuffer.java:589)
         at org.apache.coyote.http11.InternalNioInputBuffer.parseRequestLine(InternalNioInputBuffer.java:425)
         at org.apache.coyote.http11.Http11NioProcessor.process(Http11NioProcessor.java:825)
         at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:719)
         at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:2080)
         at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
         at java.lang.Thread.run(Thread.java:619)
2009-07-24 19:23:22,898 DEBUG ( :  ) (tomcat-exec-56) [Http11NioProcessor] - Error parsing HTTP request header
java.io.EOFException: Unexpected EOF read on the socket
         at org.apache.coyote.http11.InternalNioInputBuffer.readSocket(InternalNioInputBuffer.java:589)
         at org.apache.coyote.http11.InternalNioInputBuffer.parseRequestLine(InternalNioInputBuffer.java:425)
         at org.apache.coyote.http11.Http11NioProcessor.process(Http11NioProcessor.java:825)
         at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:719)
         at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:2080)
         at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
         at java.lang.Thread.run(Thread.java:619)

而服务器端模拟器这次是我们第一次使用tomcat和coyote,因此怀疑是tomcat的问题,在再三追查代码无果的情况下,决定换一个服务器端模拟器来确认问题所在:到底是cxf的客户端的问题,还是服务器端模拟器。一个简单的模拟器写出来了,一个跳过所有业务逻辑直接调用cxf客户端实现代码的测试小程序写出来了,测试之后发现,问题依旧。于是将目光集中到cxf的客户端上。

在测试中发现这样一个规律,在上述服务器端的异常发生前,在客户端中总是会有规律的出现下面这个异常:

Jul 24, 2009 10:36:18 PM org.apache.cxf.phase.PhaseInterceptorChain doIntercept
INFO: Interceptor has thrown exception, unwinding now null
tps = 25
Exception in thread "Thread-41" 2009-07-24 22:36:19,925 149585 [Thread-41] (********Impl.java:459) ERROR junit.framework.Test  - Got an exception when invoking **** service:javax.xml.ws.WebServiceException: java.lang.NullPointerException
     (这里的信息是和业务相关的,不方便打出,总之和我们讨论的问题无关)
     at test.TestMci.execute(TestMci.java:84)
     at test.TestMci.access$1(TestMci.java:81)
     at test.TestMci$TestThread.run(TestMci.java:90)
     at java.lang.Thread.run(Thread.java:595)
Caused by: javax.xml.ws.WebServiceException: java.lang.NullPointerException
     at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:142)
     at $Proxy40.authorizeAndPurchase(Unknown Source)
     at *********************
      6 more
Caused by: java.lang.NullPointerException
     at org.apache.cxf.transport.http.HTTPConduit.prepare(HTTPConduit.java:483)
     at org.apache.cxf.interceptor.MessageSenderInterceptor.handleMessage(MessageSenderInterceptor.java:46)
     at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:226)
     at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:469)
     at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:299)
     at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:251)
     at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73)
     at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:124)
      8 more

看来问题是出现在这里了。

时间: 2024-10-21 19:50:12

CXF client在并发下的线程安全问题的相关文章

Spring-利用ThreadLocal解决线程安全问题

ThreadLocal是什么 ThreadLocal,顾名思义,它不是一个线程,而是线程的一个本地化对象.当工作于多线程中的对象使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程分配一个独立的变量副本.所以每一个线程都可以独立地改变自己的副本,而不会影响其他线程所对应的副本.从线程的角度看,这个变量就像是线程的本地变量,这也是类名中"Local"所要表达的意思. ThreadLocal的方法很简单,主要的就是4个方法 1234567891011 // 设

Servlet和JSP的线程安全问题

js|servlet|安全|问题 编写Servlet和JSP的时候,线程安全问题很容易被忽略,如果忽视了这个问题,你的程序就存在潜在的隐患. 1.Servlet的生命周期 Servlet的生命周期是由Web容器负责的,当客户端第一次请求Servlet时,容器负责初始化Servlet,也就是实例化这个Servlet类.以后这个实例就负责客户端的请求,一般不会再实例化其他Servlet类,也就是有多个线程在使用这个实例.Servlet之所以比CGI效率高就是因为Servlet是多线程的.如果该Ser

UNIX编程中错误输出的线程安全问题

系统调用失败原因分析 在 UNIX 编程中,我们会经常使用系统调用来完成期望的功能:而与此同时,我们也需要付出大段 的代码来检测.输出错误和其他意外情况. 以下是系统调用失败的可能原因: 系统可能出现资源短缺或者程序使用的资源可能超过系统为单个程序规定的上限.常见的情况有: 程序可能尝试分配大量内存,或者同时打开很多文件等. 程序执行操作时,可能会由于权限不足而被系统阻止.例如,程序可能会试图写一个只读的文件, 或者企图访问其他进程的内存空间. 传入系统调用的参数可能无效,原因可能是用户提供无效

HttpSession的线程安全问题及注意事项

HttpSession session = request.getSession(); List<Product> list = session.getAttribute("productCart"); myService.save(list); // 保存购物车数据到数据库 这个对象会被多次使用,也会被同一个用户的多个页面使用,所以他对于系统来说是线程不安全的. 比如用户在从产品列表里面选择产品,这面选择3种,他点了查看购物车 该用户还开了另一个页面,继续选择产品. 此时

在多线程中使用静态方法是否有线程安全问题

   类的成员分为两类,静态成员(static member)和实例成员(instance member).静态成员属于类,实例成员则属于对象,即类的实例.     简单讨论一下在一个类中使用静态字段(static field)和静态方法(static method)是否会有线程安全问题.      我们在知道, 静态字段(static field)和静态方法(static method)的调用是通过类来调用.静态方法不对特定的实例操作,只能访问静态成员.实例方法可对特定的实例操作,既能访问静态

java-Java 单例线程安全问题

问题描述 Java 单例线程安全问题 public class A { public final static A INSTANCE = new A(); private A(){} }这个类是不是线程安全的呢?单例能这样写吗? 解决方案 这种写法是线程安全的.但是在该类一开始被加载的时候INSTANCE = new A()就会被执行.具体参考陈皓的博客深入浅出单实例Singleton设计模式介绍得非常详细. 解决方案二: 如果单线程中初始化,多线程中应用就没问题. 解决方案三: 深入解析单例线

java初学者求教:关于线程安全问题

问题描述 java初学者求教:关于线程安全问题 List list = new ArrayList(); list = Collections.synchronizedList(list); 这时list是线程安全的,那么当我用增强for循环遍历list, 并且使用list的remove方法时,是不是就不安全了? 另外,如果list集合中存放的是一些带有图片的对象,比如dog public void paintTest(Graphisc g){ for(dog d:list){ g.drawIm

多线程-高手请进!!!---线程安全问题,怎么解决new String 问题

问题描述 高手请进!!!---线程安全问题,怎么解决new String 问题 场景是:一个订单号只能一个在付款,只能一个线程处理,不同的订单号支持并发处理 现在如果是new String("20140719140818");就有问题怎么解决 如果不是new出来的,什么情况会出现问题 public class Test { public static void main(String[] args) { new Thread(){ public void run(){ pay(&quo

单例模式与线程安全问题浅析

           最近看到到Struts1与Struts2的比较,说Struts1的控制器是单例的,线程不安全的:Struts2的多例的,不存在线程不安全的问题.之后又想到了之前自己用过的HttpHandler...这些类,好像单例的线程安全问题确实是随处可见的.但是只是知道这个是不安全的,也没有认真分析过.接下来就仔细分析下. 一,修改单例模式代码       首先我先写一段单例类的代码:          /** * @ClassName: Sigleton * @Description