Domanda

Quando si sviluppa un'applicazione che consuma un webservice esterni Ho generato i sorgenti dal WSDL-url e poi creato un client:

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

Dal momento che la creazione di questa delega richiede un certo tempo ho impostato il cliente come un attributo della mia classe di servizio.

Ma io sono preoccupato che il client non è thread-safe e questo webservice è molto utilizzato nella domanda da thread concorrenti (webapp). Non riesco a trovare alcuna documentazione su questo.

Per precauzione ho iniziato a utilizzare un pool di oggetti di clienti sapone invece di un condiviso.

Si tratta di una precauzione inutile? Qual è la migliore pratica quando si scrive client XFire?

Ho il sospetto che un qualche tipo di problema di concorrenza con xfire da quando ho regolarmente, sotto carico elevato, ottengo le discussioni bloccata e come conseguenza di questo l'applicazione si blocca. Ecco una discarica filo parziali:

"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)

Il dump filo contiene un sacco di discussioni bloccate che assomigliano a questo.

È stato utile?

Soluzione

Credo che come si ottiene un sacco di fili bloccati, il cliente è in realtà thread-safe come dati oggetto non è danneggiato :). Ma sono d'accordo che non è gestisce la concorrenza in senso buono.

1) Un'osservazione è che il blocco finale sembra essere in esecuzione JAXB e non in XFire. Che cosa succede se si prova utilizzando l'implementazione JAXB diversa, come JaxMe ?

2) Anche il metodo getJAXBContext in JaxbType è sincronizzato. E molto probabilmente perché i thread accedono alla stessa istanza JaxbType possono essere bloccate.

Guardando quel metodo mi sarebbe effettivamente spostato la sincronizzazione nel metodo dopo contesto presense è controllato:

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

Ciò permetterà ai clienti che hanno già JAXBContext inizializzato per saltare costoso sincronizzazione.

Il mio suggerimento è o provare che fissa il codice di te e fare un test o inviare un bug a XFire o fare entrambe le cose:.)

Altri suggerimenti

Dipende dalla versione di Xfire che si sta utilizzando, come hanno fissato alcuni problemi di sicurezza thread nella versione 1.2.5. È possibile controllare il bug sollevato in http://jira.codehaus.org/browse/XFIRE-886 , e vedere più dettagli sulla note di rilascio a hxxp: //xfire.codehaus.org/XFire+1.2.5+Release+Notes

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top