问题背景: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天,没出现堆积未确认消息的问题了。