On Sun, 2020-10-11 at 22:16 +0530, Arunan Sugunakumar wrote:
> Hi,
> 
> We have used httpcore-NIO to implement a non-blocking server and with
> a recent JAVA upgrade, we are finding a high CPU usage in our
> servers. While we debugged, we found out that when we close the HTTPS
> connection on the server-side, the WRITE event is getting
> fired continuously and the connection close is unsuccessful.
> 
> To explain the code, we have extended DefaultNHttpConnectionBase with
> our own ServerConnection, and inside close() we simply just call the
> close() method of the NHttpConnectionBase[1]. If we look at the code
> below, the close method sets the status as CLOSING and after that
> either sets the WRITE event in the session or tries to close the
> session (SSLIOSession in our case).
> 
> @Override
> public void close() throws IOException {
>     if (this.status != ACTIVE) {
>         return;
>     }
>     this.status = CLOSING;
>     if (this.outbuf.hasData()) {
>         this.session.setEvent(EventMask.WRITE);
>     } else {
>         this.session.close();
>         this.status = CLOSED;
>     }
> }
> 
> Inside SSLIOSession close(), the updateEventMask() [2] is called. 
> @Override
> public synchronized void close() {
>     if (this.status >= CLOSING) {
>         return;
>     }
>     this.status = CLOSING;
>     if (this.session.getSocketTimeout() == 0) {
>         this.session.setSocketTimeout(1000);
>     }
>     try {
>         updateEventMask();
>     } catch (final CancelledKeyException ex) {
>         shutdown();
>     }
> }
> 
> Inside updateEventMask() method, we get the HandshakeStatus from the
> JAVA SSLEngine, and set a new Mask based on the status.
> switch (this.sslEngine.getHandshakeStatus()) {
> case NEED_WRAP:
>     newMask = EventMask.READ_WRITE;
>     break;
> case NEED_UNWRAP:
>     newMask = EventMask.READ;
>     break;
> case NOT_HANDSHAKING:
>     newMask = this.appEventMask;
>     break;
> case NEED_TASK:
>     break;
> case FINISHED:
>     break;
> }
> Before JDK upgrade, when outbound is closed, we used to get the
> status as NEED_UNWRAP which sets the newMask as READ mask which
> closes the connection in our server perfectly. 
> But with a recent JDK commit[3], the new status is returned as
> NOT_HANDSHAKING.
> Since mask is not set to READ because of the NOT_HANDSHAKING status,
> WRITE event is continuously getting fired which makes the Server
> connection close unsuccessful. 
> When the close is called multiple times for multiple connections, we
> could observe that CPU usage increased continuosly and reached 100
> percent and stays there continuously.
> When I look at the stack trace, the execution flow was completely
> inside the httpcore-nio component, which made our attempt to clear
> the Event from the server implementation, unsuccessful.
> 
> 
> Earlier we were using Httpcore-NIO version 4.3.3. With this issue, we
> tried upgrading to 4.4.13. But still the issue exists. 

I have seen no evidence supporting that. Please upgrade to 4.4.13.

Oleg



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to