从图像服务器提供多个blob图像时,Glassfish会挂起

时间:2009-11-30 03:28:43

标签: java mysql servlets jpa glassfish

在我的JSP / HTML文件中,我使用以下servlet从MySQL数据库中获取blob-images。

<img src="/image?id=1" />

图像servlet

这映射到一个imageservlet,其中:
- 获取无状态会话bean注入
- 使用session-bean根据传入servlet的id查找产品 - 将此图像作为响应流式传输

public class Image extends HttpServlet {

    @EJB
    private ProductLocal productBean;

    protected void processRequest(HttpServletRequest request, 
        HttpServletResponse response) throws ServletException, IOException {
    long id = 0;
    Product product = null;

    String possibleID = request.getParameter("id");
    if(possibleID == null){
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    // Try to parse id
    try{
        id = Long.parseLong(possibleID);
        product = productBean.getById(id);
        if(product == null) throw new NullPointerException("Product not found");
    } catch(NumberFormatException e){
        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
        return;
    } catch(NullPointerException e){
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    // Serve image
    byte[] image = product.getImage();
    response.setContentType(product.getImageContentType());
    response.setContentLength(image.length);
    ServletOutputStream output = response.getOutputStream();

    for(int i = 0; i < image.length; i++){
        output.write(image[i]);
    }
    output.flush();
    output.close();
} 
}

的ProductBean:

@Stateless
public class ProductBean implements ProductLocal {

    @PersistenceContext(unitName="xxx")
    private EntityManager em;

    public Product getById(long id) {
        return em.find(Product.class, id);
    }

}

产品(实体bean)

@Entity
public class Product implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Lob
    private byte[] image;

    private String imageContentType;

    /* getters and setters */
}

问题

当迭代产品页面时,例如15,servlet被调用15次,因此得到相同的结果(尽管ID上的顺序不同):

alt text  

有些图像一直挂起,直到它们超时(15秒,如上面的萤火虫所示)。服务器是Glassfish v2.1(集成在Netbeans 6.7.1中)。首先超时是30秒,所以我开始在Glassfish中设置不同的超时值来缩小问题范围。其中一个超时是HttpService - &gt;保持活力 - &gt;超时,我坐着(作为唯一一个)到15秒。重新启动GF后,firebug现在会在15秒后报告超时。而不是默认的30.由于我在GF中添加了不同的超时,我很确定这个问题与Keep-Alive有关。以下是此选项卡中的其余设置:

alt text

这是与NetBeans捆绑在一起的版本的开箱即用配置,除了更改超时值之外我没有做任何事情。我的问题:这是由于Glassfish中的错误设置,还是我的ImageServlet或其他代码的问题引起的?

1 个答案:

答案 0 :(得分:0)

这可能与以下事实有关:在Servlet中检索的EJB实例以某种方式锁定其他线程向同一个servlet发出请求。我有几点建议:

1)要知道你应该采取线程转储的确切答案,然后你会看到哪个线程阻止了其他线程或者线程正忙着做什么。

2)另一个想法是尝试在每个请求上检索EJB实例。当然,这不是完美的解决方案,但也许它可以帮助您解决一些锁定问题。如果它有帮助,那么您可以在后面引入一个EJB池。但无论如何,我建议第一条路可以获得有关正在发生的事情的更多信息。