当前位置: 首页 > 知识库问答 >
问题:

在并发环境中的EhacececkReentantReadWriteLock

单于皓轩
2023-03-14

我在带有ehacache2.1.0库的Webphere 7. x的生产环境中有一个问题,web容器的线程都在等待咨询或插入缓存中。

这是所有webcontainer线程挂起时的转储:

NULL
3XMTHREADINFO      "WebContainer : 11" J9VMThread:0x00000000C7C10300, j9thread_t:0x0000010043913FB0, java/lang/Thread:0x00000000507623F0, state:P, prio=5
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:182)
java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:822) < 2 >
java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.lock(ReentrantReadWriteLock.java:907)
net.sf.ehcache.store.compound.Segment.put(Segment.java:402)
net.sf.ehcache.store.compound.CompoundStore.put(CompoundStore.java:132)
net.sf.ehcache.Cache.putInternal(Cache.java:1247) < 2 >
org.springframework.cache.ehcache.EhCacheCache.put(EhCacheCache.java:70)
xxx.yyy.fac.security.userdetails.GaiaLdapAuthoritiesPopulator.putElementCache(GaiaLdapAuthoritiesPopulator.java:466) < 4 >
xxx.yyy.dgtp.gaiafrontend.core.filters.preauth.GaiaGrantedAuthoritiesWebAuthenticationDetails.buildDetails(GaiaGrantedAuthoritiesWebAuthenticationDetails.java:32) < 1 >
org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter.doAuthenticate(AbstractPreAuthenticatedProcessingFilter.java:114) < 1 >
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:184) < 1 >
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) < 1 >
com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:190)
com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:125)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:322)
xxx.yyy.dgtp.gaiafrontend.core.web.filters.JsonDeserializerFilter.doFilterChain(JsonDeserializerFilter.java:109) < 1 >
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
xxx.yyy.dgtp.gaiafrontend.core.filters.userinfo.UserInfoFilter.followWithTheRequestChain(UserInfoFilter.java:106) < 1 >
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
xxx.yyy.dgtp.gaia.commons.web.filters.RequestResponseWrapperFilter.doFilter(RequestResponseWrapperFilter.java:69)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:83)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
xxx.yyy.dgtp.gaiafrontend.core.web.filters.ResponseHeadersFilter.doFilter(ResponseHeadersFilter.java:55)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:184) < 1 >
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) < 1 >
com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:190)
com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:125)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:190)
com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:125) < 1 >
com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:908)
com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:939) < 1 >
com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:181)
com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3994)
com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:276)
com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:945)
com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1592)
com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:191)
com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:453) < 3 >
com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:214) < 1 >
com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:175)
com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
com.ibm.io.async.AsyncChannelFuture$1.run(AsyncChannelFuture.java:205)
com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1660)     

我在ehache上使用Spring作为抽象层,以编程方式获取/放入缓存的代码没有什么特别的。

缓存的配置如下:

    @Bean
    public EhCacheManagerFactoryBean cacheFactoryBean() {

        EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
        ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("gaia-cache-ldap.xml"));
        return ehCacheManagerFactoryBean;

    }

    @Bean
    public CacheManager cacheManagerLdap() {
        CacheManager cacheManager = new EhCacheCacheManager(cacheFactoryBean().getObject());
        return cacheManager;

    }

可以访问缓存的代码:

 private void getMemberOfRecursive(String group, ConcurrentMap<String, String> groupsCollector) {

        if (group != null) {
            if (existInCache(group)) {
                log.debug("Group: {} exist in cache. No query executing", group);
                groupsCollector.put(group, group);
                Set<String> groups = (Set<String>) getElementCache(group).get();
                for (String newGroup : groups) {
                    getMemberOfRecursive(newGroup, groupsCollector);
                }
            } else {
                String cn = getCnFromDn(group);
                String filter = MessageFormat.format(getFilterGroupRecursive(), cn);
                String baseDN = group.substring(group.indexOf(",") + 1);
                groupsCollector.put(group, group);

                log.debug("Executing recursive  query with baseDN: {} " +
                        " and filter {}: ", baseDN, filter);
                Set<String> groups =
                        getLdapTemplate().searchForSingleAttributeValues(
                                baseDN, filter, new String[]{}, getRetrievesAttributes());
                putElementCache(group, groups);
                for (String newGroup : groups) {
                    getMemberOfRecursive(newGroup, groupsCollector);
                }
            }

        }

ehache配置文件:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false"    monitoring="autodetect"       dynamicConfig="true">
    <diskStore path="java.io.tmpdir" />
    <defaultCache maxElementsInMemory="3000" eternal="false" timeToIdleSeconds="1200"
                  timeToLiveSeconds="1200" overflowToDisk="true" maxElementsOnDisk="10000"
                  diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
                  memoryStoreEvictionPolicy="LRU"/>
    <cache name="groupsldap" maxElementsInMemory="3000" eternal="true" overflowToDisk="false"
           memoryStoreEvictionPolicy="LRU"/>

</ehcache>

共有1个答案

柳逸春
2023-03-14

最后,有可能重现生产错误。这个错误似乎与至少存在于活动目录组用户中的交叉组有关。上周在没有启用缓存的情况下,这个错误也被跳过,为了能够更仔细地分析它,观察到有堆栈溢出错误,在这种情况下,它导致ldap连接池在线程处于等待状态时耗尽。

一旦发现这是由于这个问题,并且包含了消除以前访问的组的修复程序,这一次在本地测试中使用缓存进行了复制,我们必须用与生产中检测到的行为类似的行为使web容器的线程池饱和。

 类似资料:
  • 主要内容:流行的Java编辑器在这篇文章中主要介绍Java编程语言设置环境,以下是设置环境的方法说明。 Java SE可以从Java官方网站免费获得。可以根据您的操作系统下载一个版本。 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 以在Windows系统上为例,按照说明下载Java并运行在您的机器上安装Ja

  • 我有一个长期的项目,是使用与redis和一个问题,已经开始,我相信只有升级到sidkiq 3。 问题是,如果不先启动redis服务器,我就无法运行正在开发的rails(4.1.4)应用程序。我在启动rails服务器时遇到的错误与我在没有首先启动redis的情况下运行bundle exec sidekiq时遇到的错误相同。在没有运行redis的情况下运行我的rails应用程序以前从来都不是问题,即使

  • 主要内容:下载Erlang,Erlang安装,Erlang配置,在流行IDE上安装插件现在在开始使用 Erlang 编程工作之前,需要确保在你的系统上运行 Erlang 全功能版本。 本节将学习在 Windows 10机器上安装 Erlang 及后续的 Erlang 开发环境配置。 确保在继续安装前系统满足以下要求 系统要求 内存 2 GB RAM (推荐) 硬盘空间 没有最低要求,最好是有足够的硬盘空间来存储应用程序就可以了满足 Erlang 的应用要求了    操作系统版本 E

  • 当项目逐渐变大,webpack 的编译时间会变长,可以通过参数让编译的输出内容带有进度和颜色。 $ webpack --progress --colors 如果不想每次修改模块后都重新编译,那么可以启动监听模式。开启监听模式后,没有变化的模块会在编译后缓存到内存中,而不会每次都被重新编译,所以监听模式的整体速度是很快的。 $ webpack --progress --colors --watch

  • Termux 支持的开发环境很强,可以完美的运行 C、Python、Java、PHP、Ruby等开发环境,建议读者朋友们选择自己需要的开发环境折腾。 编辑器 写代码前总得折腾一下编辑器,毕竟磨刀不误砍柴工嘛。Termux 支持多种编辑器,完全可以满足日常使用需求。 Emacs 据说Emacs是神的编辑器,国光我这种小菜鸡还不会使用哎,但是 Termux 官方已经封装好了 Emacs了,我们安装起来

  • 你可以使用原生的Node.js开发环境来开发Electron应用。 为了打造一个Electron桌面程序的开发环境,你只需要安装好的Node.js、npm、一个顺手的代码编辑器以及对你的操作系统命令行客户端的基本了解。 Developer Environment Electron development is essentially Node.js development. To turn you