- 论坛徽章:
- 0
|
各位好:
最近上线了一个bs的网页系统,前台通过网页查询后台oracle中的一些业务数据,运行过程中出了一个非常奇怪的问题,应该所有做bs系统中包含jsp验证码的大侠们都应该碰到过,希望大家帮帮忙,抽几分钟帮忙看看(可能您已经完成,正在上线的系统也存在该问题哦),拉兄弟一把,拉兄弟一把 。
问题描述:
由于在该网页中提供了一些特殊的查询接口:struts中的一些method,为防止别人直接使用恶意程序批量查询,中间也就添加了一个jsp图片验证码的程序(我看网上的验证码程序似乎都是这个模样的),可是确出现了一个问题:平时系统运行都正常,验证码也能正常显示,验证逻辑也正常工作,可是经过长期的分析、测试发现在访问该验证码jsp页面在并发量特别大的时候,在正式的系统(linux 企业4+jdk1.4+weblogic812)的环境下 的 /tmp 目录中会生成一些 imageioxxxx.tmp的文件(xxxx为linux系统自己生成的数值编号),而使用 linux的lsof命令可以查询到这些文件句柄被linux系统占用,未释放,可是linux系统对文件句柄的个数有控制,由于系统访问量特别大,导致这个数值一直在涨,于是乎weblogic系统平均半个月要重新启动一次(已经确定不是什么jdbc连接池泄漏之类的问题了),导致客户意见非常大。
该现象有以下几个特点:
1、访问量特别大时候出现 linux的 /tmp 生成不释放文件句柄的 imageioxxx.tmp 临时文件。
2、在某些linux机器上,同样的程序导致CPU涨得比较快(比如,从IE中直接访问 该页面 http://网站url/bug.jsp ,在 linux的top 命令中,就立马可以看到cpu瞬间冲到99%让后又落下来),在有些机器又没有该现象。
3、具体在代码中,JPEG的图片方式比PNG的方式更容易发生 /tmp 目录生成不释放文件句柄的 imageioxxx.tmp 临时文件。
4、这些 imageioxxx.tmp 文件,从服务器ftp下载回来后,直接重新命名为 imageioxxx.jpg,即可看到,就是验证码的图片。
验证码的jsp代码如下:
<%@ page contentType="image/jpeg" import="java.awt.*,
java.awt.image.*,java.util.*,javax.imageio.ImageIO,javax.servlet.http.*,java.io.OutputStream" %>
<%!
long serialVersionUID = -3938318741402322164L;
Color getRandColor(int fc,int bc){
Random random = new Random();
if(fc>255) fc=255;
if(bc>255) bc=255;
int r=fc+random.nextInt(bc-fc);
int g=fc+random.nextInt(bc-fc);
int b=fc+random.nextInt(bc-fc);
return new Color(r,g,b);
}
private final void drawNoise(Graphics graphics, int lineNumber) {
graphics.setColor(getRandColor(20, 250));
int pointX1, pointY1, pointX2, pointY2;
for (int i = 0; i < lineNumber; i++) {
pointX1 = 1 + (int) (Math.random() * 70);
pointY1 = 1 + (int) (Math.random() * 20);
pointX2 = 1 + (int) (Math.random() * 70);
pointY2 = 1 + (int) (Math.random() * 20);
graphics.drawLine(pointX1, pointY1, pointX2, pointY2);
}
}
%>
<%
String charsLong = "23456789abcdefghjklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ";
String charsShort = "0123456789";
String chars = charsShort;
try {
int charsLength = chars.length();
response.setHeader("ragma", "No-cache"
response.setHeader("Cache-Control", "no-cache"
response.setDateHeader("Expires", 0);
out.clear();
int width = 70, height = 20;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
Random random = new Random();
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height);
g.setFont(new Font("Times New Roman", Font.ITALIC, height));
g.setColor(getRandColor(160, 200));
for (int i = 0; i < 2; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x, y, x + xl, y + yl);
}
StringBuffer sRand = new StringBuffer();
String[] fontNames = { "Times New Roman", "Arial", "Book antiqua", "" };
for (int i = 0; i < 4; i++) {
g.setFont(new Font(fontNames[random.nextInt(3)], Font.ITALIC, height));
char rand = chars.charAt(random.nextInt(charsLength));
sRand.append(rand);
g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
g.drawString(String.valueOf(rand), 16 * i + random.nextInt(6) + 3, height - random.nextInt(4));
}
g.setColor(getRandColor(160, 200));
drawNoise(g,;
for (int i = 0; i < 2; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(width);
int yl = random.nextInt(width);
g.drawLine(x, y, x + xl, y + yl);
}
request.getSession().setAttribute("Login_Image_Code", sRand.toString());
g.dispose();
try {
Thread.sleep(100);
} catch (Exception ex) {
}
OutputStream os = response.getOutputStream();
//这里修改为PNG,出现 imageioxxxx.tmp 文件的几率小了很多,JPEG则在并发访问的时候,非常容易生成。注视掉该句,图片自然无法在网页显示,并发时,生成imageioxxxx.tmp的现象也随之消失。
ImageIO.write(image, "NG", os);
os.flush();
os.close();
out.clear();
out.close();
} catch (Exception ex) {
}
%>
附件中也传上了,各位大侠,在你们的linux系统下把这个 验证码的文件放到任何一个 web服务器的目录中,然后通过ie http://您的网络url地址/bug.jsp 就可以看到该验证码生成了,然后按住F5狂刷页面,看看 linux的CPU,看看linux /tmp目录中有没有生成 imageioxxx.tmp的临时文件。
拉兄弟一把,拉兄弟一把,已经被客户训斥得快不行了,网上的验证码几乎都是青一色的使用 ImageIO.write(....) 最后完成动态图片在网页上的显示,难道只有我碰到了该问题?。 |
-
-
bug.rar
1.31 KB, 下载次数: 90
jsp在该论坛中不能直接上传,rar了一下
|