简体   繁体   English

泽西岛-来自资源的大规模延迟呼叫服务方法

[英]Jersey - Massive Latency Calling Service Method From Resource

I have a Jersey REST service with a resource class that calls methods on a service class. 我有一个提供资源类的Jersey REST服务,该资源类调用服务类上的方法。 During testing we've noticed a latency between the time the resource method's "Entering" log statement and the service's. 在测试过程中,我们注意到资源方法的“ Entering”日志语句与服务之间存在延迟。 This latency can be as much as 5 minutes although normally it's in the 2 minute range. 此延迟可能长达5分钟,尽管通常在2分钟范围内。 Once in awhile, the latency is minimal (milliseconds). 偶尔,延迟是最小的(毫秒)。

Here's what our classes look like: 这是我们的类的样子:

Resource 资源资源

@Stateless
@Path("/provision")
public class ProvisionResource
{
    private final Logger logger = LoggerFactory.getLogger(ProvisionResource.class);

    @EJB
    private ProvisionService provisionService;

    @GET
    @Produces(MediaType.APPLICATION_XML)
    @Path("/subscriber")
    public SubscriberAccount querySubscriberAccount(
            @QueryParam("accountNum") String accountNum)
    {
        logger.debug("Entering querySubscriberAccount()");

        final SubscriberAccount account;

        try
        {
            account = provisionService.querySubscriber(accountNum);    
        }
        catch (IllegalArgumentException ex)
        {
            logger.error("Illegal argument while executing query for subscriber account",
                    ex);

            throw new WebApplicationException(Response.Status.BAD_REQUEST);
        }
        catch (Exception ex)
        {
            logger.error("Unexpected exception while executing query for subscriber account",
                    ex);

            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
        }

        logger.debug("Exiting querySubscriberAccount()");

        return account;
    }    
}

Service: 服务:

@Singleton
public class ProvisionService
{
    private final Logger logger = LoggerFactory.getLogger(ProvisionService.class);

    public SubscriberAccount querySubscriber(final String accountNum) throws IllegalArgumentException, Exception
    {
        logger.debug("Entering querySubscriber()");

        if (null == accountNum)
        {
            throw new IllegalArgumentException("The argument {accountNum} must not be NULL");
        }

        SubscriberAccount subscriberAccount = null;

        try
        {
            // do stuff to get subscriber account
        }
        catch (Exception ex)
        {
            throw new Exception("Caught exception querying {accountNum}=["
                    + accountNum + "]", ex);
        }
        finally
        {
            logger.debug("Exiting querySubscriber()");
        }

        return subscriberAccount;
    }

Here's some samples from our logs showing the timestamps of when we enter the methods. 这是日志中的一些示例,显示了输入方法的时间戳。

2012 Feb 07 15:31:06,303 MST [http-thread-pool-80(1)] DEBUG my.package.ProvisionResource - Entering querySubscriberAccount() 
2012 Feb 07 15:31:06,304 MST [http-thread-pool-80(1)] DEBUG my.package.ProvisionService - Entering querySubscriber()

2012 Feb 07 15:35:06,359 MST [http-thread-pool-80(1)] DEBUG my.package.ProvisionResource - Entering querySubscriberAccount()
2012 Feb 07 15:40:33,395 MST [http-thread-pool-80(1)] DEBUG my.package.ProvisionService - Entering querySubscriber()

2012 Feb 07 15:34:06,345 MST [http-thread-pool-80(2)] DEBUG my.package.ProvisionResource - Entering querySubscriberAccount()
2012 Feb 07 15:37:24,372 MST [http-thread-pool-80(2)] DEBUG my.package.ProvisionService - Entering querySubscriber()

2012 Feb 07 15:33:06,332 MST [http-thread-pool-80(4)] DEBUG my.package.ProvisionResource - Entering querySubscriberAccount()
2012 Feb 07 15:34:15,349 MST [http-thread-pool-80(4)] DEBUG my.package.ProvisionService - Entering querySubscriber()

2012 Feb 07 15:37:24,371 MST [http-thread-pool-80(4)] DEBUG my.package.ProvisionResource - Entering querySubscriberAccount()
2012 Feb 07 15:40:36,004 MST [http-thread-pool-80(4)] DEBUG my.package.ProvisionService - Entering querySubscriber()

2012 Feb 07 15:32:06,317 MST [http-thread-pool-80(5)] DEBUG my.package.ProvisionResource - Entering querySubscriberAccount()
2012 Feb 07 15:34:15,325 MST [http-thread-pool-80(5)] DEBUG my.package.ProvisionService - Entering querySubscriber()

2012 Feb 07 15:36:06,373 MST [http-thread-pool-80(5)] DEBUG my.package.ProvisionResource - Entering querySubscriberAccount()
2012 Feb 07 15:40:34,956 MST [http-thread-pool-80(5)] DEBUG my.package.ProvisionService - Entering querySubscriber()

As you can see, the first one called the querySubscriber method in the service almost immediately after entering the resource's querySubscriberAccount. 如您所见,第一个在输入资源的querySubscriberAccount之后几乎立即在服务中调用了querySubscriber方法。 However, subsequent calls to the webservice take ~1 to 5 minutes. 但是,随后对Web服务的调用大约需要1到5分钟。 There's really nothing happening in the resource that would hold up processing/calling the service. 资源中实际上没有任何事情可以阻止处理/调用服务。

The webservice is deployed on a Linux server in Glassfish 3.1.1. 该Web服务部署在Glassfish 3.1.1中的Linux服务器上。

Has anyone seen anything like this before?? 有人看过类似的东西吗? Any suggestions on what's going on? 有什么建议吗?

EDIT 编辑

Just a little more information... 只是更多信息...

The domain into which the web service war is deployed has 4 applications deployed in it: Web Service War部署到的域中部署了4个应用程序:

  • the Jersey webservice war which is having issues 发生问题的泽西岛网络服务大战
  • an ear which uses a client to the Jersey webservice 使用Jersey网络服务的客户端的耳朵
  • a servlet war used to test connections etc. used by the ear (including the Jersey webservice) 用于测试耳朵使用的连接等的servlet战争(包括Jersey网络服务)
  • another servlet war which does not use the webservice 另一个不使用Web服务的Servlet之战

When we disabled the ear and "other" war file (only the Jersey war and the test servlet were enabled), the latency issue goes away. 当我们禁用耳朵和“其他” war文件(仅启用Jersey战争和测试servlet)时,延迟问题就消失了。 We re-enabled the war and ear and things still continued to respond in a timely manner. 我们重新启用了战争和行动,一切仍然继续及时作出反应。 When we redeployed Jersey webservice war (made some logging changes), the latency problem immediately came back. 当我们重新部署Jersey Webservice战争(进行了一些日志更改)时,延迟问题立即出现。

Thread dump can be used to find out what code (including stack traces) is running and the current moment inside Java process. 线程转储可用于找出正在运行的代码(包括堆栈跟踪)以及Java进程中的当前时刻。 jps tool will help in get getting PID of the required JVM instance. jps工具将帮助获取所需的JVM实例的PID。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM