JIRA initial GET on a JSP performs very slowly causing slow page loads

XMLWordPrintable

    • Type: Bug
    • Resolution: Tracked Elsewhere
    • Priority: Low
    • None
    • Affects Version/s: 6.4.8, 6.4.9
    • Component/s: None
    • 6.04

      Summary

      When opening pages in JIRA such as the dashboard or issues, the initial GET on the Dashboard.jspa or the issue can take considerable periods of time, for example greater than 10s.

      When there is a change in the Crowd directory (for example, logging in, synchronisation and so on), the Add-on Manager (UPM) clears the agent count cache. As a result of this when code references this cache it must be rebuilt each time. This can cause significant performance problems in JIRA as the construction of pages references Service Desk code to determine which URLs should be added.

      Steps to Reproduce

      1. Setup a large instance with JIRA Service Desk and a large number of users.
      2. Load a page.
      3. Make a change to a user in Crowd (such as logging in).
      4. Reload the page.

      Expected Results

      The page loads quickly.

      Actual Results

      Page loads, such as GET on a issue or dashboard can take greater than 10s.

      Fix

      Upgrading the Add-on Manager (UPM) to 2.18.5 or higher will resolve this problem. This can be done by browsing to the Manage Add-ons page and selecting upgrade.

      Verification

      Taking thread dumps as per Generate a Thread Dump during periods of slow responsiveness in JIRA will display threads similar to the ones below. An easy way to parse them to find if this is a problem can be searching for the following:

      grep -c GlobalPermissionUserCountCacheImpl.resetAll *
      thread_dump_20150831_01.txt:2
      thread_dump_20150831_02.txt:11
      thread_dump_20150831_03.txt:12
      thread_dump_20150831_04.txt:2
      thread_dump_20150831_05.txt:11
      thread_dump_20150831_06.txt:2
      thread_dump_20150831_07.txt:3
      thread_dump_20150831_08.txt:8
      

      A higher number of threads consistently can indicate this is a problem. The thread dumps:

      "TP-Processor52" #4660 daemon prio=5 os_prio=0 tid=0x66944000 nid=0x3775 waiting on condition [0x5e72b000]
         java.lang.Thread.State: WAITING (parking)
      	at sun.misc.Unsafe.park(Native Method)
      	- parking to wait for  <0x80c2ac50> (a java.util.concurrent.locks.ReentrantReadWriteLock$FairSync)
      	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
      	at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
      	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
      	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
      	at java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.lock(ReentrantReadWriteLock.java:943)
      	at com.atlassian.cache.memory.DelegatingCache$DelegatingLoadingCache.removeAll(DelegatingCache.java:360)
      	at com.atlassian.upm.license.role.jira.GlobalPermissionUserCountCacheImpl.resetAll(GlobalPermissionUserCountCacheImpl.java:58)
      	at com.atlassian.upm.license.role.jira.JiraRoleBasedLicenseService.handleEventForUnidentifiedGlobalPermission(JiraRoleBasedLicenseService.java:201)
      	at com.atlassian.upm.license.role.jira.JiraRoleBasedLicenseService.onCrowdDirectoryEvent(JiraRoleBasedLicenseService.java:140)
      	at sun.reflect.GeneratedMethodAccessor370.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:483)
      	at com.atlassian.event.internal.SingleParameterMethodListenerInvoker.invoke(SingleParameterMethodListenerInvoker.java:36)
      	at com.atlassian.event.internal.AsynchronousAbleEventDispatcher$1$1.run(AsynchronousAbleEventDispatcher.java:48)
      	at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:253)
      	at com.atlassian.event.internal.AsynchronousAbleEventDispatcher.dispatch(AsynchronousAbleEventDispatcher.java:107)
      	at com.atlassian.event.internal.EventPublisherImpl.invokeListeners(EventPublisherImpl.java:160)
      	at com.atlassian.event.internal.EventPublisherImpl.publish(EventPublisherImpl.java:79)
      	at com.atlassian.crowd.manager.directory.DirectoryManagerGeneric.storeUserAttributes(DirectoryManagerGeneric.java:412)
      	at com.atlassian.crowd.manager.application.ApplicationServiceGeneric.storeUserAttributes(ApplicationServiceGeneric.java:759)
      	at com.atlassian.crowd.embedded.core.CrowdServiceImpl.setUserAttribute(CrowdServiceImpl.java:403)
      	at com.atlassian.crowd.embedded.core.CrowdServiceImpl.setUserAttribute(CrowdServiceImpl.java:391)
      	at com.atlassian.crowd.embedded.core.DelegatingCrowdService.setUserAttribute(DelegatingCrowdService.java:105)
      	at com.atlassian.crowd.embedded.core.FilteredCrowdServiceImpl.setUserAttribute(FilteredCrowdServiceImpl.java:51)
      	at com.atlassian.jira.security.login.LoginStoreImpl.setLong(LoginStoreImpl.java:137)
      	at com.atlassian.jira.security.login.LoginStoreImpl.recordLoginAttempt(LoginStoreImpl.java:78)
      	at com.atlassian.jira.security.login.LoginManagerImpl.recordLoginAttempt(LoginManagerImpl.java:359)
      	at com.atlassian.jira.security.login.LoginManagerImpl.onLoginAttempt(LoginManagerImpl.java:237)
      	at com.atlassian.jira.security.login.JiraElevatedSecurityGuard.onFailedLoginAttempt(JiraElevatedSecurityGuard.java:30)
      	at com.atlassian.seraph.auth.DefaultAuthenticator.getUserFromBasicAuthentication(DefaultAuthenticator.java:526)
      	at com.atlassian.crowd.integration.seraph.v25.CrowdAuthenticator.isAuthenticated(CrowdAuthenticator.java:254)
      	at com.atlassian.crowd.integration.seraph.v25.CrowdAuthenticator.getUser(CrowdAuthenticator.java:356)
      	at com.atlassian.jira.security.login.SSOSeraphAuthenticator.getUser(SSOSeraphAuthenticator.java:70)
      	at com.atlassian.seraph.filter.SecurityFilter.doFilter(SecurityFilter.java:136)
      	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      

      With the flow on effect of

      "TP-Processor29" #504 daemon prio=5 os_prio=0 tid=0x62a4ac00 nid=0x1fa7 waiting on condition [0x6f383000]
         java.lang.Thread.State: WAITING (parking)
      	at sun.misc.Unsafe.park(Native Method)
      	- parking to wait for  <0x96a8ee60> (a com.google.common.util.concurrent.AbstractFuture$Sync)
      	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
      	at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
      	at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
      	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
      	at com.google.common.util.concurrent.AbstractFuture$Sync.get(AbstractFuture.java:317)
      	at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:111)
      	at com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly(Uninterruptibles.java:132)
      	at com.google.common.cache.LocalCache$LoadingValueReference.waitForValue(LocalCache.java:3591)
      	at com.google.common.cache.LocalCache$Segment.waitForLoadingValue(LocalCache.java:2333)
      	at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2320)
      	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2228)
      	at com.google.common.cache.LocalCache.get(LocalCache.java:3970)
      	at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3974)
      	at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4834)
      	at com.atlassian.cache.memory.DelegatingCache$DelegatingLoadingCache.get(DelegatingCache.java:316)
      	at com.atlassian.upm.license.role.jira.GlobalPermissionUserCountCacheImpl.getUserCount(GlobalPermissionUserCountCacheImpl.java:70)
      	at com.atlassian.upm.license.role.jira.JiraLicensingRole.getRoleCount(JiraLicensingRole.java:65)
      	at com.atlassian.upm.license.internal.impl.role.RoleBasedLicenseServiceProxyImpl.getLicensingRoleForPlugin(RoleBasedLicenseServiceProxyImpl.java:65)
      	at com.atlassian.upm.license.internal.impl.role.RoleBasedLicensingPluginServiceImpl.getLicensingRoleForPlugin(RoleBasedLicensingPluginServiceImpl.java:89)
      	at com.atlassian.upm.license.internal.impl.role.RoleBasedLicensingPluginServiceImpl.getLicensingRoleForPluginKey(RoleBasedLicensingPluginServiceImpl.java:79)
      	at com.atlassian.upm.license.internal.impl.PluginLicenseManagerImpl.withRole(PluginLicenseManagerImpl.java:106)
      	at com.atlassian.upm.license.internal.impl.PluginLicenseManagerImpl.getCurrentUserCountInLicenseRole(PluginLicenseManagerImpl.java:83)
      	at sun.reflect.GeneratedMethodAccessor793.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:483)
      	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
      	at org.springframework.osgi.service.importer.support.internal.aop.ServiceInvoker.doInvoke(ServiceInvoker.java:58)
      	at org.springframework.osgi.service.importer.support.internal.aop.ServiceInvoker.invoke(ServiceInvoker.java:62)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
      	at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
      	at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
      	at org.springframework.osgi.service.util.internal.aop.ServiceTCCLInterceptor.invokeUnprivileged(ServiceTCCLInterceptor.java:56)
      	at org.springframework.osgi.service.util.internal.aop.ServiceTCCLInterceptor.invoke(ServiceTCCLInterceptor.java:39)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
      	at org.springframework.osgi.service.importer.support.LocalBundleContextAdvice.invoke(LocalBundleContextAdvice.java:59)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
      	at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
      	at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
      	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
      	at com.sun.proxy.$Proxy5076.getCurrentUserCountInLicenseRole(Unknown Source)
      	at com.atlassian.servicedesk.internal.permission.group.ServiceDeskAgentLicenseLimitManagerImpl.getTotalAgentCount(ServiceDeskAgentLicenseLimitManagerImpl.java:165)
      	at com.atlassian.servicedesk.internal.conditions.AdminAgentNeededConditionCheckerImpl.com$atlassian$servicedesk$internal$conditions$AdminAgentNeededConditionCheckerImpl$$agentExists(AdminAgentNeededConditionCheckerImpl.scala:25)
      	at com.atlassian.servicedesk.internal.conditions.AdminAgentNeededConditionCheckerImpl$$anonfun$shouldDisplay$1.apply(AdminAgentNeededConditionCheckerImpl.scala:20)
      	at com.atlassian.servicedesk.internal.conditions.AdminAgentNeededConditionCheckerImpl$$anonfun$shouldDisplay$1.apply(AdminAgentNeededConditionCheckerImpl.scala:20)
      	at com.atlassian.servicedesk.internal.user.SDUserFactoryImpl.checkPermission(SDUserFactoryImpl.scala:134)
      	at com.atlassian.servicedesk.internal.conditions.AdminAgentNeededConditionCheckerImpl.shouldDisplay(AdminAgentNeededConditionCheckerImpl.scala:19)
      	at com.atlassian.servicedesk.internal.condition.UrlReadingAdminAgentNeededCondition.addToUrl(UrlReadingAdminAgentNeededCondition.java:30)
      	at com.atlassian.plugin.webresource.condition.DecoratingUrlReadingCondition.addToUrl(DecoratingUrlReadingCondition.java:31)
      	at com.atlassian.plugin.webresource.WebResourceModuleDescriptor.addToUrl(WebResourceModuleDescriptor.java:207)
      

            Assignee:
            Unassigned
            Reporter:
            Dave C
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: