java ответ остановки службы, но процесс все еще работает, как устранить проблему - PullRequest
0 голосов
/ 28 февраля 2020

1.Env:

  • os: CentOS Linux выпуск 7.6.1810 (Core)
  • веб-сервер: undertow v2.0.20.Final
  • springBootVersion: 2.1.5.RELEASE
  • java процесс обслуживания: oss
# undertow config: 
server:
  undertow:
    io-threads: 4
    worker-threads: 32
    buffer-size: 16384
    direct-buffers: true

2.Как возникла проблема, двусторонняя

  1. Продолжайте запрашивать разные ресурсы, такие как изображения или видео
  2. Многократно запрашивать один ресурс (без запроса кеша)

3. Производительность, связанная с проблемой:

при возникновении проблемы , jstack как это:

"XNIO-1 task-32" #69 prio=5 os_prio=0 tid=0x0000000001c8e800 nid=0x1e10 runnable [0x00007f0a20dc1000]
   java.lang.Thread.State: RUNNABLE
    at sun.nio.ch.PollArrayWrapper.poll0(Native Method)
    at sun.nio.ch.PollArrayWrapper.poll(PollArrayWrapper.java:115)
    at sun.nio.ch.PollSelectorImpl.doSelect(PollSelectorImpl.java:87)
    at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
    - locked <0x00000006cf91e858> (a sun.nio.ch.Util$3)
    - locked <0x00000006cf91e848> (a java.util.Collections$UnmodifiableSet)
    - locked <0x00000006cf91e5f0> (a sun.nio.ch.PollSelectorImpl)
    at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
    at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:101)
    at org.xnio.nio.SelectorUtils.await(SelectorUtils.java:46)
    at org.xnio.nio.NioSocketConduit.awaitWritable(NioSocketConduit.java:263)
    at org.xnio.conduits.AbstractSinkConduit.awaitWritable(AbstractSinkConduit.java:66)
    at io.undertow.conduits.ChunkedStreamSinkConduit.awaitWritable(ChunkedStreamSinkConduit.java:379)
    at org.xnio.conduits.ConduitStreamSinkChannel.awaitWritable(ConduitStreamSinkChannel.java:134)
    at io.undertow.channels.DetachableStreamSinkChannel.awaitWritable(DetachableStreamSinkChannel.java:87)
    at io.undertow.server.HttpServerExchange$WriteDispatchChannel.awaitWritable(HttpServerExchange.java:2039)
    at io.undertow.servlet.spec.ServletOutputStreamImpl.writeBufferBlocking(ServletOutputStreamImpl.java:577)
    at io.undertow.servlet.spec.ServletOutputStreamImpl.write(ServletOutputStreamImpl.java:150)
    at org.springframework.security.web.util.OnCommittedResponseWrapper$SaveContextServletOutputStream.write(OnCommittedResponseWrapper.java:639)
    at org.springframework.util.StreamUtils.copy(StreamUtils.java:143)
    at com.berry.oss.service.impl.ObjectServiceImpl.handlerResponse(ObjectServiceImpl.java:732)
    at com.berry.oss.service.impl.ObjectServiceImpl.getObject(ObjectServiceImpl.java:336)
    at com.berry.oss.service.impl.ObjectServiceImpl$$FastClassBySpringCGLIB$$6c092705.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:684)
    at com.berry.oss.service.impl.ObjectServiceImpl$$EnhancerBySpringCGLIB$$1b34ff28.getObject(<generated>)
    at com.berry.oss.api.ObjectController.getObject(ObjectController.java:165)
    at com.berry.oss.api.ObjectController$$FastClassBySpringCGLIB$$bbd00513.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
    at com.berry.oss.aop.StatisticsAspect.getObjectStatistics(StatisticsAspect.java:39)
    at sun.reflect.GeneratedMethodAccessor108.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    ...

netstat как это:

[root@localhost backend]# netstat -nalt |grep 8077
tcp6       0      0 :::8077                 :::*                    LISTEN     
tcp6       1 174696 192.168.2.195:8077      172.16.1.10:49588       CLOSE_WAIT 
tcp6       1 188280 192.168.2.195:8077      172.16.1.10:49576       CLOSE_WAIT 
tcp6       1 235768 192.168.2.195:8077      172.16.1.10:49544       CLOSE_WAIT 
tcp6       1 213280 192.168.2.195:8077      172.16.1.10:44406       CLOSE_WAIT 
tcp6       1 184320 192.168.2.195:8077      172.16.1.10:49560       CLOSE_WAIT 
tcp6       1 192752 192.168.2.195:8077      172.16.1.10:49562       CLOSE_WAIT 
tcp6       1 201440 192.168.2.195:8077      172.16.1.10:46424       CLOSE_WAIT 
tcp6       1 144840 192.168.2.195:8077      172.16.1.10:46426       CLOSE_WAIT 
tcp6       1 189432 192.168.2.195:8077      172.16.1.10:46576       CLOSE_WAIT 
tcp6       1 290664 192.168.2.195:8077      172.16.1.10:49556       CLOSE_WAIT 
tcp6       1 212472 192.168.2.195:8077      172.16.1.10:49558       CLOSE_WAIT 
tcp6       1 248416 192.168.2.195:8077      172.16.1.10:44410       CLOSE_WAIT 
tcp6       1 202464 192.168.2.195:8077      172.16.1.10:49582       CLOSE_WAIT 
tcp6       1 235512 192.168.2.195:8077      172.16.1.10:44374       CLOSE_WAIT 
tcp6       1 268432 192.168.2.195:8077      172.16.1.10:49568       CLOSE_WAIT 
tcp6       1 214984 192.168.2.195:8077      172.16.1.10:49532       CLOSE_WAIT 
tcp6       1 299904 192.168.2.195:8077      172.16.1.10:49552       CLOSE_WAIT 
tcp6       1 310040 192.168.2.195:8077      172.16.1.10:49566       CLOSE_WAIT 
tcp6       1 333080 192.168.2.195:8077      172.16.1.10:49540       CLOSE_WAIT 
tcp6       1 213536 192.168.2.195:8077      172.16.1.10:44380       CLOSE_WAIT 
tcp6       1 339000 192.168.2.195:8077      172.16.1.10:49584       CLOSE_WAIT 
tcp6       1 289768 192.168.2.195:8077      172.16.1.10:49546       CLOSE_WAIT 
tcp6       1 315280 192.168.2.195:8077      172.16.1.10:49538       CLOSE_WAIT 
tcp6       1 398752 192.168.2.195:8077      172.16.1.10:49530       CLOSE_WAIT 
tcp6       1 243304 192.168.2.195:8077      172.16.1.10:49574       CLOSE_WAIT 
tcp6       1 182616 192.168.2.195:8077      172.16.1.10:44414       CLOSE_WAIT 
tcp6       1 326352 192.168.2.195:8077      172.16.1.10:49572       CLOSE_WAIT 
tcp6       0      0 192.168.2.195:8077      172.16.1.10:49590       ESTABLISHED
tcp6       1 245776 192.168.2.195:8077      172.16.1.10:49580       CLOSE_WAIT 
tcp6       1 267920 192.168.2.195:8077      172.16.1.10:44412       CLOSE_WAIT 
tcp6       1 191432 192.168.2.195:8077      172.16.1.10:49550       CLOSE_WAIT 
tcp6       1 229208 192.168.2.195:8077      172.16.1.10:44404       CLOSE_WAIT 
tcp6       1 207360 192.168.2.195:8077      172.16.1.10:44408       CLOSE_WAIT 
[root@localhost backend]# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
CLOSE_WAIT 38
ESTABLISHED 101
FIN_WAIT2 1
TIME_WAIT 16

Многие соединения остаются в состоянии CLOSE_WAIT, соединение CLOSE_WAIT не будет освобождено, пока не будет выполнено активное уничтожение. ..

Я попытался

  1. Достигнут ли максимально допустимый размер кэша сокета? Я использую команду cat /proc/sys/net/ipv4/tcp_wmem, чтобы получить максимальное значение: 4194304 (4M), поскольку мы можем видеть, что значение Send-Q состояния соединения CLOSE_WAIT никогда не достигает этого!
  2. Почему netstat существует так много CLOSE_WAIT соединений где-то отдыхать забыл закрыть? Я проверил процесс Java (oss), нашел метод ключа ( код github ):
private void handlerResponse(String bucket, String objectPath, HttpServletResponse response, WebRequest request, ObjectInfo objectInfo, Boolean download) throws IOException {
        ObjectResource object = null;
        try {
            if (download != null && download) {
                object = dataService.getObject(bucket, objectInfo.getFileId());
                if (object == null || object.getInputStream() == null) {
                    throw new XmlResponseException(new NotFound());
                }
                response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
                StreamUtils.copy(object.getInputStream(), response.getOutputStream());
                response.flushBuffer();
                return;
            }

            long lastModified = objectInfo.getUpdateTime().getTime();
            String eTag = "\"" + DigestUtils.md5DigestAsHex(objectPath.getBytes()) + "\"";
            if (request.checkNotModified(eTag, lastModified)) {
                response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
            } else {
                object = dataService.getObject(bucket, objectInfo.getFileId());
                if (object == null) {
                    throw new XmlResponseException(new NotFound());
                }
                String contentType = StringUtils.getContentType(object.getFileName());
                response.setContentType(contentType);
                response.setHeader(HttpHeaders.ETAG, eTag);
                ZonedDateTime expiresDate = ZonedDateTime.now().with(LocalTime.MAX);
                String expires = expiresDate.format(DateTimeFormatter.RFC_1123_DATE_TIME);
                response.setHeader(HttpHeaders.EXPIRES, expires);
                StreamUtils.copy(object.getInputStream(), response.getOutputStream());
                response.flushBuffer();
            }
        } catch (Exception e) {
            logger.error("Exception catch, msg:{}", e.getMessage());
        } finally {
            if (object != null && object.getInputStream() != null) {
                object.getInputStream().close();
            }
            response.getOutputStream().close();
        }
    }

подтверждается, что ресурс закрыт !!

Ошибка Undertow? Утечка соединения? Никогда не знаешь ....

Нужна твоя помощь

Мой код неверен? Как найти проблему?

Спасибо

...