2013-11-04 39 views
3

我有REST服務後續REST調用被阻止,直到前一個完成

@Path("/rest") 
@Component 
public class MyRestService 
{ 
    @Inject 
    private MyBean bean; 

    @GET 
    @Path("/do") 
    public String start() 
    { 
     this.logger.info("Before do " + Thread.currentThread().getId()); 
     String result = this.bean.do(); 
     this.logger.info("After do " + Thread.currentThread().getId()); 

     return result; 
    } 
} 

這就要求注入Spring的singleton bean的方法(有一些國家內)

@Service 
public class MyBean 
{ 
    public String do() 
    { 
     // do something big... 
    } 
} 

當我打電話」。 ../rest/do「,第一次調用如預期的那樣,但是如果我在另一個tab中調用同一個調用,則此調用將等待第一次完成以在同一線程中處理第二個調用。

如果我第二次調用爲「.../rest/do?async = true」,它不會等待並在新線程中處理第二個請求,但如果我將這兩個請求都作爲「.../rest/do ?async = true「 - 第二個等待第一個完成。

這種行爲的原因是什麼?它實際上是預期的嗎?

我的web.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    version="2.5"> 

    <welcome-file-list> 
     <welcome-file>index.html</welcome-file> 
    </welcome-file-list> 

    <display-name>My REst</display-name> 

    <!-- spring configuration by annotations --> 
    <context-param> 
     <param-name>contextClass</param-name> 
     <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> 
    </context-param> 

    <!-- spring configuration class --> 
    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>app.Config</param-value> 
    </context-param> 

    <!-- to return data according to extension --> 
    <context-param> 
     <param-name>resteasy.media.type.mappings</param-name> 
     <param-value>json : application/json, xml : application/xml</param-value> 
    </context-param> 

    <!-- this has to match with resteasy-servlet url-pattern --> 
    <context-param> 
     <param-name>resteasy.servlet.mapping.prefix</param-name> 
     <param-value>/rest</param-value> 
    </context-param> 

    <listener> 
     <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> 
    </listener> 

    <!-- resteasy spring connector (to use DI in rest-resources) --> 
    <listener> 
     <listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class> 
    </listener> 

    <servlet> 
     <servlet-name>resteasy-servlet</servlet-name> 
     <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> 
    </servlet> 

    <!-- this has to match with resteasy-servlet url-pattern --> 
    <servlet-mapping> 
     <servlet-name>resteasy-servlet</servlet-name> 
     <url-pattern>/rest/*</url-pattern> 
    </servlet-mapping> 

    <!-- Bind Jboss's TransactionManager (EntityManagerFactory) to JNDI --> 
    <persistence-unit-ref> 
     <persistence-unit-ref-name>persistence/ReferenceDataDS</persistence-unit-ref-name> 
     <persistence-unit-name>ReferenceDataDS</persistence-unit-name> 
    </persistence-unit-ref> 
</web-app> 
+3

您的servlet容器可以配置爲單線程。 – Taylor

+1

您向我們展示的內容中沒有任何內容可以說明發生此行爲的原因。 –

+1

這段代碼非常好,但是這裏的代碼並沒有以任何方式描述這種行爲。你正在使用一個Spring來描述某個地方的行爲,並且它僅僅使用這個代碼來實現請求定義。在你的容器或Spring中的某個地方是一個定義,它告訴它它是單線程還是接受多個請求或其他東西。閱讀servlet容器上的配置註釋並嘗試修改這些文本文件。 – SpacePrez

回答

1

可以解決運行在調試模式下你的應用服務器這個問題。用兩個不同的客戶端進行測試,例如Firefox,Chrome,IE,Opera,...等待答案暫停所有線程。

  • 如果您看到只有一個workerthread活動,那麼應用程序服務器的設置就是問題所在。
  • 如果您看到多個workerthreads活躍,但其中一人在等待一個信號,你有多個線程訪問同一資源的問題
  • 如果您有多個活動workerthreads但其中一人正在等待的連接持久性存儲,那麼你的數據源沒有連接池。
相關問題