【问题标题】:Glassfish hangs when serving multiple blob-images from an imageservlet从 imageservlet 提供多个 blob 图像时,Glassfish 挂起
【发布时间】:2010-12-21 12:31:48
【问题描述】:

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

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

图像小服务程序

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

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);
    }

}

产品(实体豆)

@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 上的顺序不同):

有些图像总是挂起,直到超时(上面的萤火虫显示 15 秒)。服务器是 Glassfish v2.1(集成在 Netbeans 6.7.1 中)。起初超时是 30 秒,所以我开始在 Glassfish 中设置不同的超时值来缩小问题的范围。其中一个超时是 HttpService -> Keep Alive -> Timeout,我只坐了 15 秒(作为唯一一个)。重启 GF 后,firebug 现在会在 15 秒后报告超时。而不是默认的 30。由于我在 GF 中设置了不同的超时,我很确定问题与 Keep-Alive 有关。这是我在此选项卡中的其余设置:

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

【问题讨论】:

  • 知道这是不久前的事了,但您在这方面取得了进展吗,我们遇到了一个我们认为相关的问题

标签: java mysql servlets jpa glassfish


【解决方案1】:

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

1) 要知道确切的答案,您应该进行线程转储,然后您将看到哪个线程正在阻止其他线程或哪些线程正忙着做。

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

【讨论】:

  • 在每个请求中(在 doGet 中)获取 bean 似乎并没有什么不同。我试图进行线程转储,但以前从未这样做过。我正在使用 OSX,并按照 Glassfish 手册的建议尝试了“kill -3 ”,但 domain1/logs 中没有出现任何内容。我成功地从 NetBeans 运行了分析器,但我不确定要查找什么。等待的线程是一堆计时器,以及“MySQL 取消请求”
  • 看看锁。如果您可以附上几张来自分析器的图片,可能会更容易说些什么。
猜你喜欢
  • 2018-02-16
  • 1970-01-01
  • 2013-04-12
  • 1970-01-01
  • 2020-07-17
  • 1970-01-01
  • 1970-01-01
  • 2020-01-14
  • 2022-12-14
相关资源
最近更新 更多