hprose / hprose-java

Hprose is a cross-language RPC. This project is Hprose 2.0 for Java
MIT License
550 stars 187 forks source link

关于内存溢出的疑问 #57

Closed liuwenpeng1 closed 4 years ago

liuwenpeng1 commented 4 years ago

hprose-java的server,用的版本是2.0.38.服务在运行一段时间之后就会出现内存溢出的异常,服务器openfile过多,不知道是哪里配置的不对。

Exception in thread "Thread-11" java.lang.OutOfMemoryError: Direct buffer memory
    at java.nio.Bits.reserveMemory(Bits.java:695)
    at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
    at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
    at hprose.io.ByteBufferStream$ByteBufferPool.allocate(ByteBufferStream.java:64)
    at hprose.io.ByteBufferStream$ByteBufferPool.access$200(ByteBufferStream.java:31)
    at hprose.io.ByteBufferStream.allocate(ByteBufferStream.java:107)
    at hprose.net.Connection.receive(Connection.java:138)
    at hprose.net.Reactor.dispatch(Reactor.java:100)
    at hprose.net.Reactor.run(Reactor.java:49)
Exception in thread "Thread-10" java.lang.OutOfMemoryError: Direct buffer memory
    at java.nio.Bits.reserveMemory(Bits.java:695)
    at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
    at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
    at hprose.io.ByteBufferStream$ByteBufferPool.allocate(ByteBufferStream.java:64)
    at hprose.io.ByteBufferStream$ByteBufferPool.access$200(ByteBufferStream.java:31)
    at hprose.io.ByteBufferStream.allocate(ByteBufferStream.java:107)
    at hprose.net.Connection.receive(Connection.java:138)
    at hprose.net.Reactor.dispatch(Reactor.java:100)
    at hprose.net.Reactor.run(Reactor.java:49)
Exception in thread "Thread-12" java.lang.OutOfMemoryError: Direct buffer memory
    at java.nio.Bits.reserveMemory(Bits.java:695)
    at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
    at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
    at hprose.io.ByteBufferStream$ByteBufferPool.allocate(ByteBufferStream.java:64)
    at hprose.io.ByteBufferStream$ByteBufferPool.access$200(ByteBufferStream.java:31)
    at hprose.io.ByteBufferStream.allocate(ByteBufferStream.java:107)
    at hprose.net.Connection.receive(Connection.java:138)
    at hprose.net.Reactor.dispatch(Reactor.java:100)
    at hprose.net.Reactor.run(Reactor.java:49)
Exception in thread "Thread-14" java.lang.OutOfMemoryError: Direct buffer memory
andot commented 4 years ago

我觉得可能是有非法的客户端请求导致的。请求头部的前4个字节是包体的大小,如果非法的客户端发送一个无效的请求,头部前4个字节所表示的包体的大小非常大,那么在分配内存时就会导致内存溢出。在 hprose 3.0 中,tcp 请求头部增加了一个crc32的校验,并且可以设置请求最大长度的限制,可以有效的防止这种非法请求。不过 java 版本暂未实现 hprose 3.0。

目前 hprose-java 2.0 的 tcp 服务最好是部署在内网,防止有非法的客户端来访问到它。如果部署在公网的话,最好用 hprose 的 http 服务。

liuwenpeng1 commented 4 years ago

我觉得可能是有非法的客户端请求导致的。请求头部的前4个字节是包体的大小,如果非法的客户端发送一个无效的请求,头部前4个字节所表示的包体的大小非常大,那么在分配内存时就会导致内存溢出。在 hprose 3.0 中,tcp 请求头部增加了一个crc32的校验,并且可以设置请求最大长度的限制,可以有效的防止这种非法请求。不过 java 版本暂未实现 hprose 3.0。

目前 hprose-java 2.0 的 tcp 服务最好是部署在内网,防止有非法的客户端来访问到它。如果部署在公网的话,最好用 hprose 的 http 服务。

感谢回复! 目前这边所有的RPC接口都有访问log,但是没有看到异常访问的log,所以也定位不了是否属于非法访问。 从异常的堆栈来分析也没有什么帮助。所以有没有什么办法可以帮我确定问题的。再次感谢~

andot commented 4 years ago

这个异常是在接收数据时产生的,因此,还到不了 log 的位置。

liuwenpeng1 commented 4 years ago

这个异常是在接收数据时产生的,因此,还到不了 log 的位置。

ok,我接下来会做好访问限制,添加ip白名单,来排除这方面的原因,以后也会陆续跟踪此问题。

最后期待3.0版本早日上线~

zhangruhong commented 4 years ago

@liuwenpeng1 请问你解决这个问题了吗?我这边也遇到这个问题了。非常规律,每隔三五天就出现一次,只能重启,看起来不是非法请求 @andot

liuwenpeng1 commented 4 years ago

请问你解决这个问题了吗?我这边也遇到这个问题了。非常规律,每隔三五天就出现一次,只能重启,看起来不是非法请求

我这边对服务器做了白名单,针对tcp端口的访问做了限制,目前看来没有在出现了,希望能帮到你