2013-11-04 36 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但其中一人正在等待的连接持久性存储,那么你的数据源没有连接池。
相关问题