在tomcat 6.0中从jar文件读取静态资源时如何减少linux上打开文件句柄的数量?
在我们的应用程序中,我们从位于 WEB-INF/lib 的 jar 文件中读取静态资源(即 JavaScript 文件)。碰巧服务器因打开文件过多
异常而停止工作。 我发现(使用lsof
),jar 文件被打开了几次,并且当我重新加载页面时,打开次数会随着页面 JavaScript 文件的数量而增加。 我尝试了以下几件事,但没有得到积极的结果:
- URLConnection setDefaultUSeCache(false)
- URLConnection setUSeCache(false)
- context.xml cachingAllowed="false"
我还可以尝试其他方法吗?
In our application we read static resources (i.e. JavaScript files) from a jar file located in WEB-INF/lib. It happens that the server quits working with too many open files
exception.
I found out (using lsof
), that the jar file is opened several times, and the number increases when I reload a page by the number of JavaScript files of the page.
I tried a couple the following things without positive result:
- URLConnection setDefaultUSeCache(false)
- URLConnection setUSeCache(false)
- context.xml cachingAllowed="false"
Is there something else I could try?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在 Tomcat 服务器中,每个传入请求都使用一个 TCP 套接字,并且该套接字消耗进程可用的总文件描述符中的一个文件描述符。文件描述符(FD)是进程打开文件时创建的句柄。每个进程可以使用一定数量的 FD,这通常是操作系统级别的设置。
如果每页加载很多 JS 脚本文件,那么每个 JS 请求在处理时都会消耗一个 FD。
随着进入服务器的请求数量增加,您可能会遇到打开许多套接字的情况,从而耗尽 FD,并收到“Too Many Open Files”错误。
检查#cat /proc/sys/fs/file-max的值,看看你的Tomcat在服务器上可以打开多少个FD。
理想情况下应该是 65535。请参阅此处了解如何增加此限制
http://tech-torch.blogspot.com/2009/07/linux-ubuntu-tomcat-too-many-open-files.html
另一个建议是您是否可以减少JS 调用次数,通过将 JS 文件合并为一个。
In Tomcat server, each incoming request uses a TCP socket and this socket consumes one file descriptor from the total available for the process. The file fescriptor (FD) is a handle created by a process when the file is opened. Each process can use a set limit of FDs and this is usually an OS level setting.
If you have many JS script files being loaded per page, then each JS request will consume one FD while it is being processed.
As the number of requests coming into the server increase, you can face a situation where there are many sockets open and thus you run out of FDs and you get the "Too Many Open Files" error.
Check the value of
# cat /proc/sys/fs/file-max
to see how many FDs can be opened by your Tomcat on the server.Ideally should be 65535. See here on how to increase this limit
http://tech-torch.blogspot.com/2009/07/linux-ubuntu-tomcat-too-many-open-files.html
Another suggestion is if you can reduce the number of JS calls, by combining the JS files into one.
稍微介绍一下细节,但听起来您正在使用 Stream 加载资源,因此您正在创建的代码很可能也在方法调用中匿名创建对象(我见过的示例中非常常见的做法)并且我我知道这会导致 Windows 上的文件锁定问题,所以我确信它会使描述符在 Unix 上挂起。确保你有一个 try 块,并且完成后可以在 finally 块中调用 close() 。静态代码分析工具通常会捕获这种情况。
然而,您没有提到我们正在讨论的文件句柄的数量。通常,网络连接将是您的罪魁祸首,并且通常您希望增加限制。
A little light on detail, but it sounds like you're loading the resources with a Stream, so chances are your code is creating also creates the object anonymously in a method call (a very common practice in examples I've seen) and I know that causes file locking issues on Windows, so I'm sure it keeps descriptors hanging about on Unixes. Make sure you have a try block and you can call close() in the finally block when you're done. Static code analysis tools will usually catch this condition.
You don't mention the number of file handles we're talking about however. Usually, network connections will be your culprit, and usually you want to increase the limit.
按照您的建议,输入流在 finally 块中关闭。我还查看了 URLConnection,但似乎没有 close() 或 disconnect 方法。
在我看来,这些文件在一段时间后就被删除了。
打开的文件由 lsof 列出,如果我重新加载页面,打开的文件句柄就会上升。但几分钟后,它们又下降了。
在用户流量较高的情况下,打开的文件句柄已经大于每个进程的最大值 2048。所以释放打开的文件句柄已经太晚了。
The inputstream is closed in the finally block as you suggest. I looked also at URLConnection, but it seems that there is no close() or disconnect method.
It seems to me that the files were claused after a certain period of time.
The open files are listed by lsof and if I reload the page open file handles go up. But after a couple of minutes they go down again.
In case of high user traffic the open file handle were greater than the max of 2048 per process already. So the freeing of open file handles is to late then.
如果编写了一个打开文件 URL 连接的小测试程序。它只调用 getLastModified() 并且这已经打开了一个文件句柄。
之后我关闭输入流,这种效果就消失了。
所以我得出的结论是,即使连接后没有读取流,我也必须关闭 URLConnection.inputStream 。
If wrote a tiny test program that opens a URLconnection to a file. It only calls getLastModified() and this opens a file handle already.
Afterwards I close the input stream and this effect dissappears.
So I come to the conclusion that I have to close the URLConnection.inputStream even if the stream is not read after the connection.