문제

외부 웹 서비스를 소비하는 응용 프로그램을 개발할 때 WSDL-URL에서 소스를 생성 한 다음 클라이언트를 만들었습니다.

GeoIPServiceClient service = new GeoIPServiceClient();
GeoIPServiceSoap geoIPClient = service.getGeoIPServiceSoap();

이 프록시를 생성하는 데 시간이 걸리므로 클라이언트를 서비스 클래스에서 속성으로 설정했습니다.

그러나 클라이언트가 스레드 안전하지 않으며이 웹 서비스는 동시 스레드 (WebApp)에 의해 응용 프로그램에 많이 사용됩니다. 이것에 대한 문서를 찾을 수 없습니다.

예방책으로 나는 공유 된 비누 클라이언트 대신 비누 클라이언트의 객체 풀을 사용하기 시작했습니다.

이것이 불필요한 예방 조치입니까? XFIRE 클라이언트를 작성할 때 가장 모범 사례는 무엇입니까?

나는 정기적으로, 높은 하중에서 차단 된 스레드를 얻기 때문에 Xfire의 어떤 종류의 동시성 문제가 의심되고, 결과적으로 응용 프로그램 충돌이 발생합니다. 부분 스레드 덤프는 다음과 같습니다.

"http-xx.xx.xx.xx-80-17" daemon prio=10 tid=0x00007f560d437000 nid=0x66cb waiting for monitor entry [0x00000000412b8000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Injector.java:174)
    - waiting to lock <0x00007f561d44e1c0> (a com.sun.xml.bind.v2.runtime.reflect.opt.Injector)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Injector.java:85)
    at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:87)
    at com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:165)
    at com.sun.xml.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.java:253)
    at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor$CompositeTransducedAccessorImpl.<init>(TransducedAccessor.java:231)
    at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor.get(TransducedAccessor.java:173)
    at com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty.<init>(SingleElementLeafProperty.java:83)
    at sun.reflect.GeneratedConstructorAccessor165.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.sun.xml.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:124)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:171)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:481)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:315)
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:139)
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:117)
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:188)
    at sun.reflect.GeneratedMethodAccessor176.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:128)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:277)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:372)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:337)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:244)
    at org.codehaus.xfire.jaxb2.JaxbType.getJAXBContext(JaxbType.java:306)
    - locked <0x00007f565b3aee60> (a org.codehaus.xfire.jaxb2.JaxbType)
    at org.codehaus.xfire.jaxb2.JaxbType.writeObject(JaxbType.java:230)
    at org.codehaus.xfire.aegis.AegisBindingProvider.writeParameter(AegisBindingProvider.java:229)
    at org.codehaus.xfire.service.binding.AbstractBinding.writeParameter(AbstractBinding.java:273)
    at org.codehaus.xfire.service.binding.WrappedBinding.writeMessage(WrappedBinding.java:90)
    at org.codehaus.xfire.soap.SoapSerializer.writeMessage(SoapSerializer.java:80)
    at org.codehaus.xfire.transport.http.HttpChannel.writeWithoutAttachments(HttpChannel.java:56)
    at org.codehaus.xfire.transport.http.OutMessageRequestEntity.writeRequest(OutMessageRequestEntity.java:51)
    at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
    at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
    at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
    at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
    at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
    at org.codehaus.xfire.transport.http.CommonsHttpMessageSender.send(CommonsHttpMessageSender.java:369)
    at org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:123)
    at org.codehaus.xfire.transport.http.HttpChannel.send(HttpChannel.java:48)
    at org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:26)
    at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
    at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:79)
    at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:114)
    at org.codehaus.xfire.client.Client.invoke(Client.java:336)
    at org.codehaus.xfire.client.XFireProxy.handleRequest(XFireProxy.java:77)
    at org.codehaus.xfire.client.XFireProxy.invoke(XFireProxy.java:57)
    at $Proxy143.getMyMethod(Unknown Source)

스레드 덤프에는 이와 같이 보이는 많은 차단 스레드가 포함되어 있습니다.

도움이 되었습니까?

해결책

많은 차단 된 스레드를 얻을 때 객체 데이터가 손상되지 않기 때문에 클라이언트는 실제로 스레드 안전입니다 :). 그러나 나는 그것이 동시성을 좋은 방법으로 처리하지 않는다는 데 동의합니다.

1) 한 가지 관찰은 최종 잠금이 Xfire가 아닌 JAXB 구현에있는 것으로 보인다는 것입니다. 다른 JAXB 구현과 같은 다른 JAXB 구현을 사용하려면 어떻게해야합니까? Jaxme?

2) 메소드 getJaxBContext in jaxbtype 동기화됩니다. 그리고 스레드가 동일한 jaxbtype 인스턴스에 액세스하기 때문에 차단 될 수 있습니다.

그 방법을 살펴보면 실제로 컨텍스트 프리젠즈를 확인한 후 동기화를 메소드로 옮겼습니다.

if (context == null) {
    synchronized (this)  {
         ...

이를 통해 이미 JAXBCONTEXT가 초기화 된 클라이언트가 고가의 동기화를 건너 뛸 수 있습니다.

내 제안은 코드를 직접 수정하고 테스트하거나 XFIRE에 버그를 제출하거나 둘 다 수행하는 것입니다. :).

다른 팁

버전 1.2.5의 스레드 안전 문제가 거의 고정되어 있으므로 사용중인 XFIRE 버전에 따라 다릅니다. 제기 된 버그를 확인할 수 있습니다 http://jira.codehaus.org/browse/xfire-886 hxxp : //xfire.codehaus.org/xfire+1.2.5+ release+notes의 릴리스 노트에 대한 자세한 내용을 참조하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top