
저는 Java에서 Vert.x를 사용하는 서버에서 작업하고 있으며 Ubuntu 12.04를 실행하는 전용 서버에서 실행할 때 일부 성능 문제를 발견했습니다.
서버는 들어오는 HTTP 요청을 선택하고, HMAC를 사용하여 일부 인증을 수행하고, 요청 본문을 구문 분석하고, 일부 텍스트 처리를 수행하고, UDP를 통해 데이터를 다른 서버로 보냅니다. 디스크 I/O가 없으며 상대적으로 적은 양의 메모리 사용량만 있습니다(스왑에 가까운 곳은 없음). Grinder 및 AWS 인스턴스를 사용하여 서버에 대해 로드 테스트를 수행하고 있지만 잘 구성된 서버를 사용하더라도 초당 10,000개 이상의 요청을 얻을 수 없습니다.
내가 보고 있는 것은 서버 시스템의 한 코어가 대부분 커널에 절대적으로 고정되어 있고 다른 코어의 활용도는 ~20-25%에 불과하다는 것입니다. 내 가정은 들어오는 TCP 연결을 수신하는 데 CPU가 소비되고 있다는 것입니다. JMX는 대부분의 시간을 io.netty.channel.nio.NioEventLoop.select()에 보고하는데, 이는 커널을 기다리는 시간을 계산하는 것으로 가정하고 strace는 futex() 및 epoll_wait()에 소요된 많은 시간을 보여줍니다. 서버의 처리량을 높이기 위해 커널 설정을 사용해 보았지만 성공하지 못했습니다.
프로파일러 실행:
원래 URL:https://i.stack.imgur.com/6wIZA.png
CPU 사용량:
원래 URL:https://i.stack.imgur.com/9mM5u.png
이를 돕기 위해 커널 수준에서 무엇을 조정할 수 있는지 궁금합니다. 나는 TCP 버퍼 크기를 조작하고, 파일 핸들을 늘리고, TCP 기능을 끄는 등의 작업을 시도했지만 소용이 없었습니다. 이 서버 OS는 실제로 Xen에서 실행되고 있으며, 유일한 상주라는 점에서 '전용'입니다.
답변1
귀하의 응용 프로그램과 응용 프로그램이 사용하는 라이브러리를 면밀히 조사하겠습니다. Linux 커널에 관한 한 JVM 스레드는 최소한 Sun/Oracle JVM 구현을 사용하여 Linux(경량 프로세스)에서 기본 스레드로 구현됩니다.
JVM은 많은 스레드를 포함하는 단일 프로세스입니다. 스핀업되는 각 스레드는 사용 가능한 모든 코어에서 실행될 수 있습니다. Linux의 단일 프로세스에는 여러 스레드가 있을 수 있습니다.
또한 다음 리소스를 살펴볼 수도 있습니다.