活动会话太多

时间:2013-05-27 03:49:09

标签: jsf session jboss cdi

我在JBoss 6上使用JSF 2.我做了一个示例应用程序,它使用JSF作为View,EJB用于逻辑,JPA用于Persistence。 JSF中的bean具有RequestScoped。 EJB是无状态的:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:c="http://java.sun.com/jsp/jstl/core">
    <h:head>
        <title>Long HDi</title>
    </h:head>
    <h:body>
        <c:forEach var="tweet" items="#{tweets.getAll}">
            <p>
                #{tweet.content}<br />
            </p>
        </c:forEach>
    </h:body>
</html>

豆:

@Named("tweets")
@RequestScoped
public class Tweets implements Serializable {
    @EJB
    private TweetServiceLocal tweetService;
    private List<Tweet> tweets;

    public List<Tweet> getGetAll() {
        return tweetService.findAllSortedByTimeDesc();
    }
}

EJB:

@Stateless
public class TweetService implements TweetServiceLocal {

    @PersistenceContext(unitName = "LongHDi-ejbPU")
    private EntityManager em;

    @Override
    public Tweet create(final String content, final Date postTime) throws ContentTooLargeException {
        if (content.length() > 480)
            throw new ContentTooLargeException("Content must have less than 480 charaters!");
        else {
            try {
                Tweet tweet = new Tweet();
                tweet.setContent(content);
                tweet.setPostTime(postTime);
                em.persist(tweet);
                return tweet;
            } catch (Exception e) {
                return null;
            }
        }
    }

    @Override
    public java.util.List<Tweet> findAllSortedByTimeDesc() {
        return em.createNamedQuery("Tweet.findAllSortedByTimeDesc").getResultList();
    }

}

当我向它发送几百个请求时,JBoss 6服务器抛出了这个异常:

JBWEB000065: HTTP Status 500 - JBWEB000209: Session creation failed due to too many active sessions

JBWEB000309: type JBWEB000066: Exception report

JBWEB000068: message JBWEB000209: Session creation failed due to too many active sessions

JBWEB000069: description JBWEB000145: The server encountered an internal error that prevented it from fulfilling this request.

JBWEB000070: exception

javax.servlet.ServletException: JBWEB000209: Session creation failed due to too many active sessions
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)
JBWEB000071: root cause

java.lang.IllegalStateException: JBWEB000209: Session creation failed due to too many active sessions
    org.apache.catalina.session.StandardManager.createSession(StandardManager.java:297)
    org.apache.catalina.connector.Request.doGetSession(Request.java:2651)
    org.apache.catalina.connector.Request.getSession(Request.java:2357)
    org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:790)
    com.sun.faces.context.ExternalContextImpl.getSession(ExternalContextImpl.java:157)
    com.sun.faces.application.view.FaceletViewHandlingStrategy.getSession(FaceletViewHandlingStrategy.java:494)
    com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:400)
    com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:124)
    javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:286)
    com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
    com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)

我的问题是:为什么服务器会创建太多会话?我使用了RequestScope和Stateless bean,他们怎么会在会话中结束?我该怎么做才能克服这种情况?如果我只使用servlet和JSP,当请求太多时,服务器会变慢,但至少它不会像这样停止。

1 个答案:

答案 0 :(得分:3)

  

为什么服务器会创建太多会话?

因为您向它发送了几百个请求,并且服务器显然已配置为创建最多X个会话。


  

我使用了RequestScope和Stateless bean,他们怎么会在会话中结束?

他们没有。 JSF视图状态确实如此。将JSF状态保存方法设置为server(默认设置)时,JSF会将视图状态存储在HTTP会话中。


  

我能做些什么来克服这种情况?

通过client中的此上下文参数将JSF状态保存方法设置为web.xml

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>

这样,JSF视图状态将以序列化形式存储在JSF表单的javax.faces.ViewState隐藏输入字段中,而不是存储在HTTP会话中。

或者,在使用Mojarra 2.1.19或更高版本时,只需将transient的{​​{1}}属性设置为<f:view>,即可在每个视图的基础上关闭JSF状态保存。

true

(你可以在<f:view transient="true"> / <f:view>周围包裹<h:head>;这也是JSF隐含做的事情 - 它代表<h:body>组件)

另见: