一次线程挂起的问题排查-socketRead0

1,138 阅读1分钟

问题背景:rabbitMq有大量未ack的消息

排查过程:我们是在处理完消息后,再向rabbitMq确认消息。消费消息逻辑有try/catch 保护,肯定能走到确认逻辑块。反复研究代码,未发现不能ack的漏洞。之后想着去看线程堆栈,发现了异常,有消息线程挂起了。

看到这里,就能说明现象了。消费者线程调用一直hang在socketRead0的本地方法。我们看一下原先代码合优化后的代码

原先代码:

    public static void image2RGBBmp(URL url, String destPath) {
        try {
            BufferedImage sourceImg = ImageIO.read(url);
            int h = sourceImg.getHeight(), w = sourceImg.getWidth();
            int[] pixel = new int[w * h];
            PixelGrabber pixelGrabber = new PixelGrabber(sourceImg, 0, 0, w, h, pixel, 0, w);
            pixelGrabber.grabPixels();

            MemoryImageSource m = new MemoryImageSource(w, h, pixel, 0, w);
            Image image = Toolkit.getDefaultToolkit().createImage(m);
            BufferedImage buff = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
            buff.createGraphics().drawImage(image, 0, 0, null);
            ImageIO.write(buff, "bmp", new File(destPath));
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

优化后代码:

public static void image2RGBBmp(String imageUrl, String destPath) {
        BufferedInputStream in = null;
        try {
            URL url = new URL(imageUrl);
            URLConnection connection = url.openConnection();
            connection.setReadTimeout(3000);//设置读取超时时间
            connection.setConnectTimeout(3000);//设置连接超时时间
            connection.connect();
            in = new BufferedInputStream(connection.getInputStream());

            BufferedImage sourceImg = ImageIO.read(in);
            int h = sourceImg.getHeight(), w = sourceImg.getWidth();
            int[] pixel = new int[w * h];
            PixelGrabber pixelGrabber = new PixelGrabber(sourceImg, 0, 0, w, h, pixel, 0, w);
            pixelGrabber.grabPixels();

            MemoryImageSource m = new MemoryImageSource(w, h, pixel, 0, w);
            Image image = Toolkit.getDefaultToolkit().createImage(m);
            BufferedImage buff = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
            buff.createGraphics().drawImage(image, 0, 0, null);
            ImageIO.write(buff, "bmp", new File(destPath));
        } catch (InterruptedException | IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

发布后观察了2天,没出现堆积未确认消息的问题了。