代码之家  ›  专栏  ›  技术社区  ›  Mads Mobæk

Glassfish在从imageservlet提供多个blob图像时挂起

  •  1
  • Mads Mobæk  · 技术社区  · 15 年前

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

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

    这映射到一个imageservlet,它:


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

    @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 */
    }
    

    问题

    alt text

    有些图像总是挂起直到超时(15秒)。如上面的firebug所示)。服务器是Glassfish v2.1(集成在Netbeans 6.7.1中)。一开始超时是30秒,所以我开始在Glassfish中设置不同的超时值来缩小问题范围。其中一个超时是HttpService->Keep Alive->Timeout,我将它(作为唯一的一个)设置为15秒。重新启动GF后,firebug会在15秒后报告超时。而不是默认的30。因为我在GF中设置了不同的超时,我很确定问题与保持活力有关。以下是我在此选项卡中的其他设置:

    alt text

    这是与NetBeans捆绑的版本的现成配置,除了更改超时值之外,我什么也没做。我的问题是:这是由于Glassfish中的错误设置,还是我的ImageServlet或其他代码的问题造成的?

    1 回复  |  直到 5 年前
        1
  •  0
  •   Andrey Adamovich    15 年前

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

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

    2) 另一个想法是尝试在每个请求上检索EJB实例。当然,这不是一个完美的解决方案,但它可能会使您避免一些可能存在的锁定问题。如果有帮助的话,您可以在后面引入一个ejb池。但无论如何,我建议你走第一条路,去了解更多的信息。