0

HTTP를 통해 서버 측에 액세스하는 Java 클라이언트를 사용하여 새 데이터 페이지를 여러 번로드하는 몇 가지 작은 요청을 작성했습니다. 모든 비 UI 처리를 처리하는 스레드 풀을 유지하므로 백그라운드 클라이언트 측 작업과 서버에 연결하려는 모든 작업이 처리됩니다. 몇 가지 성능 문제를 조사해 봤는데 가능한 한 우리의 스레드 풀을 설정했는지 확신 할 수 없습니다. 현재 우리는 코어 풀 크기가 8 인 ThreadPoolExecutor를 사용하며 작업 대기열에 LinkedBlockingQueue를 사용하므로 최대 풀 크기는 무시됩니다. 의심의 여지가 없다는 간단한 모든 상황 에서이 특정 일을 대답하지만, 거기에 어떤 모범 사례가 있습니다. 그 순간 내 생각은Java RIA 클라이언트 응용 프로그램 용 스레드 풀을 구성하는 가장 좋은 방법

입니다. 1) LinkedBlockingQueue 대신 SynchronousQueue를 사용하여 풀을 최대 풀 크기로 확장 할 수 있습니다. 2) 최대 풀 크기를 무제한으로 설정하겠습니다.

기본적으로 현재 나의 두려움은 서버 측의 간헐적 인 성능 문제로 인해 관련없는 클라이언트 측 처리가 스레드 풀 크기의 상한으로 인해 중단되는 것입니다. 이를 경계하는 내 두려움은 클라이언트에서 이러한 스레드를 관리하는 데 추가 히트이며 아마도 2 가지 악 중 더 나은 것일 수 있습니다.

제안, 권장 사항 또는 유용한 참조 사항이 있으십니까? 건배, 로빈

바운드 형식의 큐를 만들 수 있지만 거부 작업을 (그리고 어쩌면 서버 (응용 프로그램에 의존!) 바쁜 사용자 통보) 큐가 일정한 크기에 도달 할 때하지 왜
+0

SynchronousQueue는 블로킹 대기열입니다 (하나에서 다른 것으로 전환하겠다고 말했을 때) – Joel

+0

ta, 나는 이것을 LinkedBlockingQueue (queueSize == corePoolSize 일 때 요청 대기) 및 SynchronousQueue (새 스레드를 poolSize Robin

답변

1

대기열 크기를 제한하는 것이 더 좋을 것 같습니다. 대기열에 많은 요청이있을 때 응용 프로그램이 올바르게 작동합니까? (모든 작업이 오랫동안 대기 할 수 있는지, 더 중요한지 다른 사람에게)? 대기중인 작업이 남아 있고 사용자가 응용 프로그램을 종료하면 어떻게됩니까? 대기열이 매우 커지는 경우 사용자가 문제를 완전히 숨길 정도로 서버가 갑자기 중단 될 가능성이 있습니까?

사용자 인터페이스를 업데이트하고 큐를 매우 작게 유지해야하는 요청에 대해 하나의 큐를 생성한다고 말하고 싶습니다. 이 대기열이 너무 커지면 사용자에게 알리십시오.

실제 배경 작업의 경우 대기열이 길지만 무한대가 아닌 별도의 풀을 유지하십시오. 이것이 커지거나 사용자가 종료하기를 원하지만 작업이 남아있을 때이 풀에 대한 정상적인 동작을 정의하십시오.

+0

이것은 내가 지금 한 일에 가깝고 내가 앞으로 나아갈 수있는 것입니다. 이 책의 세부 사항을 기반으로하는 제한된 스레드 풀을 구성했습니다. http://www.javaconcurrencyinpractice.com/. 그리고 무제한 큐. 주로 개별 클라이언트의 서버 기능을 제한하려고하므로 풀 크기를 조정할 수도 있지만 클라이언트에서도 적절한 응답을 유지하려고합니다. 이상적으로는 2 개의 threadpools에 대한 제안을 구현할 것이므로이 책의 제안에 따르면 특정 풀의 작업 대기열이 이상적으로 균질이어야한다고 언급했습니다. 감사 – Robin

0

? 그런 다음이 이벤트를 기록하고 백업을 위해 서버 측에서 어떤 일이 발생했는지 확인할 수 있습니다. 또한 여러 원격 서버에 연결하지 않는 한 풀에 두 개 이상의 스레드가있는 것은 아닙니다. 이는 앱과 앱의 기능 및 앱의 사용자에게 달려 있습니다.

제한되지 않은 풀은 일반적으로 정상적으로 성능이 저하되지 않으므로 일반적으로 위험합니다. 문제를 기록하고, 경고를 제기하고, 대기중인 추가 작업을 방지하고, 문제가있을 경우 서버 측 규모를 조정하여 문제를 다시 방지하십시오.

+0

대기열이 특정 크기에 도달하면 작업을 거부하면 대기열이 제한됩니다. –

1

일반적으로 네트워크 대기 시간은 클라이언트 쪽에서 메모리 할당이나 스레드 관리와 관련하여 발생할 수있는 모든 것보다 훨씬 더 쉽습니다. 따라서 일반적으로 성능 병 목에 부딪히는 경우 가장 먼저 네트워킹 링크를 살펴보십시오.

서버가 단순히 클라이언트의 요청을 따라갈 수 없다는 것이 문제라면 클라이언트 측의 스레드를 부딪히지 않아도 문제가 해결되지는 않습니다. 기다리는 더 많은 스레드에 대한 응답 (관리하는 연결 수의 증가로 인해 부하를 증가시킴으로써 서버 측 문제를 악화시킬 수도 있음)

JDK의 동시 대기열은 모두 높은 성능을 발휘합니다. 선택은 실제로 사용 의미론으로 귀결됩니다. 논 블로킹 배관이있는 경우 논 블로킹 대기열을 사용하는 것이 더 자연 스럽습니다. 그렇지 않으면 블로킹 큐를 사용하는 것이 더 합리적입니다. 항상 Integer.MAX_VALUE를 제한으로 지정할 수 있습니다. FIFO 처리가 요구 사항이 아닌 경우 상당한 성능 저하를 초래할 수있는 공정한 주문을 지정하지 않았는지 확인하십시오.

1

alphazero에 따르면 병목 현상이있는 경우 사용하는 접근 방식에 관계없이 클라이언트 측 대기 작업 수가 계속 증가 할 것입니다.

실제 질문은 병목 현상을 어떻게 처리 할 것인가입니다. 아니면 사용자가 병목 현상에 대처할 수있는 방법을 올바르게 설정해야합니다.

제한되지 않은 큐를 사용하는 경우 병목 현상이 발생했다는 피드백을받지 못합니다. 그리고 일부 응용 프로그램에서는 괜찮습니다. 사용자가 비동기 작업을 시작한 경우 백 로그를보고 할 필요가 없습니다 (최종적으로 지워진다 고 가정). 그러나 사용자가 다음 클라이언트 측 태스크를 수행하기 전에 응답을 기다려야하는 경우 이는 매우 나쁩니다.

제한된 대기열에 LinkedBlockingQueue.offer()을 사용하면 대기열이 가득 찼다는 응답을 즉시 받게되며 특정 애플리케이션 기능을 사용 중지하거나 대화 상자를 표시하는 등의 조치를 취할 수 있습니다. 그러나 이는 특히 여러 곳에서 요청을 제출할 수있는 경우 더 많은 작업이 필요합니다. 만약 당신이 이미 그것을 가지고 있지 않다면, 당신은 일반적인 행동을 제공하기 위해 서버 큐를 통해 GUI 인식 계층을 생성 할 것을 제안합니다.

당연히 이벤트 스레드에서 LinkedBlockingQueue.put()을 호출 할 수는 없습니다 (매달아 진 클라이언트가 마음에 들지 않는 한).