Loading...
Spring Framework Reference Documentation 7.0.2의 Performance의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
Performance와 관련해서는 만능 해결책이 없습니다. 메시지의 크기와 양, 애플리케이션 메서드가 blocking이 필요한 작업을 수행하는지 여부, 그리고 네트워크 속도 및 기타 문제와 같은 외부 요인 등 많은 요소가 영향을 미칩니다. 이 섹션의 목표는 사용 가능한 설정 옵션에 대한 개요와 함께 스케일링을 어떻게 고려할지에 대한 몇 가지 생각을 제공하는 것입니다.
Messaging 애플리케이션에서는 메시지가 스레드 풀에 의해 지원되는 채널을 통해 비동기적으로 실행됩니다. 이러한 애플리케이션을 설정하려면 채널과 메시지 흐름에 대한 충분한 지식이 필요합니다.
따라서 Flow of Messages를 검토하는 것이 권장됩니다.
가장 먼저 시작할 수 있는 곳은 clientInboundChannel과 clientOutboundChannel을
지원하는 스레드 풀을 설정하는 것입니다. 기본적으로 둘 다 사용 가능한 프로세서
수의 두 배로 설정됩니다.
Annotated 메서드에서의 메시지 처리(handling)가 주로 CPU-bound인 경우,
clientInboundChannel의 스레드 수는 프로세서 수에 가깝게 유지해야 합니다. 수행하는 작업이
더 IO-bound이고 데이터베이스나 기타 외부 시스템에서 blocking되거나 기다려야 한다면,
스레드 풀 크기를 늘려야 할 가능성이 큽니다.
ThreadPoolExecutor에는 core thread pool size,<br>max thread pool size, 그리고 사용 가능한 스레드가 없는 task를 저장하기 위한<br>queue의 capacity라는 세 가지 중요한 속성이 있습니다.<br>흔히 혼동되는 점은 core pool size(예: 10)와 max pool size(예: 20)를<br>설정하면 10개에서 20개 사이의 스레드를 가진 스레드 풀이<br>생성된다고 생각하는 것입니다.<br>실제로는 capacity가 기본값인 Integer.MAX_VALUE로 유지되면,<br>추가 task는 모두 queue에 쌓이기 때문에 스레드 풀은 core pool size를<br>넘어 증가하지 않습니다.<br>이러한 속성이 어떻게 동작하는지와 다양한 큐잉 전략을 이해하려면<br>ThreadPoolExecutor의 javadoc을 참고하십시오. |
clientOutboundChannel 측면에서는 WebSocket
클라이언트로 메시지를 보내는 것이 전부입니다. Client가 빠른 네트워크 상에 있다면 스레드 수는
사용 가능한 프로세서 수에 가깝게 유지해야 합니다.
느리거나 낮은 대역폭 상에 있다면, 메시지를 소비하는 데 더 오래 걸리고 스레드 풀에 부담을 줍니다. 따라서 스레드 풀 크기를 늘리는 것이 필요해집니다.
clientInboundChannel의 워크로드는 애플리케이션이 수행하는 작업을 기반으로 하므로 예측이
가능하지만, "clientOutboundChannel"을 어떻게 설정할지는 애플리케이션의 통제를
벗어난 요인들에 기반하므로 더 어렵습니다. 이러한 이유로 메시지 전송과 관련된 두 가지 추가
프로퍼티가 있습니다: sendTimeLimit
과 sendBufferSizeLimit입니다.
이러한 메서드를 사용하여 클라이언트로 메시지를 보낼 때 send가 허용되는 시간과 버퍼할 수 있는 데이터의 양을 설정할 수 있습니다.
일반적인 개념은 어느 시점에서든 하나의 스레드만 클라이언트로 send하는 데 사용할 수 있다는 것입니다. 그동안의 추가 메시지는 모두 버퍼되며, 이러한 프로퍼티를 사용하여 메시지 send가 허용되는 시간과 그 사이에 버퍼될 수 있는 데이터의 양을 결정할 수 있습니다.
중요한 추가 세부 사항은 javadoc과 XML 스키마 문서를 참고하십시오.
다음 예는 가능한 설정을 보여줍니다:
1@Configuration 2@EnableWebSocketMessageBroker 3public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer { 4 5 @Override 6 public void configureWebSocketTransport(WebSocketTransportRegistration registration) { 7 registration.setSendTimeLimit(15 * 1000).setSendBufferSizeLimit(512 * 1024); 8 } 9 10 // ... 11 12}
1@Configuration 2@EnableWebSocketMessageBroker 3class WebSocketConfiguration : WebSocketMessageBrokerConfigurer { 4 5 override fun configureWebSocketTransport(registration: WebSocketTransportRegistration) { 6 registration.setSendTimeLimit(15 * 1000).setSendBufferSizeLimit(512 * 1024) 7 } 8 9 // ... 10}
1<beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns:websocket="http://www.springframework.org/schema/websocket" 4 xsi:schemaLocation=" 5 http://www.springframework.org/schema/beans 6 https://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/websocket 8 https://www.springframework.org/schema/websocket/spring-websocket.xsd"> 9 10 <websocket:message-broker> 11 <websocket:transport send-timeout="15000" send-buffer-size="524288" /> 12 <!-- ... --> 13 </websocket:message-broker> 14 15</beans>
또한 앞에서 보여준 WebSocket transport 설정을 사용하여 들어오는 STOMP 메시지에 대해 허용되는 최대 크기를 설정할 수 있습니다. 이론적으로 WebSocket 메시지는 거의 무제한의 크기를 가질 수 있습니다. 실제로 WebSocket 서버는 예를 들어 Tomcat에서는 8K, Jetty에서는 64K와 같은 제한을 둡니다.
이러한 이유로
stomp-js/stompjs와 같은 STOMP 클라이언트는 더 큰
STOMP 메시지를 16K 경계에서 분할하여 여러 WebSocket 메시지로 전송하며,
이는 서버가 이를 버퍼하고 재조립해야 함을 의미합니다.
Spring의 STOMP-over-WebSocket 지원은 이를 수행하므로, 애플리케이션은 WebSocket 서버별 message size와 관계없이 STOMP 메시지의 최대 크기를 설정할 수 있습니다. WebSocket 메시지 크기는 최소한 16K WebSocket 메시지를 전달할 수 있도록 보장하기 위해 필요한 경우 자동으로 조정된다는 점을 기억해야 합니다.
다음 예는 가능한 설정 중 하나를 보여줍니다:
1@Configuration 2@EnableWebSocketMessageBroker 3public class MessageSizeLimitWebSocketConfiguration implements WebSocketMessageBrokerConfigurer { 4 5 @Override 6 public void configureWebSocketTransport(WebSocketTransportRegistration registration) { 7 registration.setMessageSizeLimit(128 * 1024); 8 } 9 10 // ... 11 12}
1@Configuration 2@EnableWebSocketMessageBroker 3class MessageSizeLimitWebSocketConfiguration : WebSocketMessageBrokerConfigurer { 4 5 override fun configureWebSocketTransport(registration: WebSocketTransportRegistration) { 6 registration.setMessageSizeLimit(128 * 1024) 7 } 8 9 // ... 10}
1<beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns:websocket="http://www.springframework.org/schema/websocket" 4 xsi:schemaLocation=" 5 http://www.springframework.org/schema/beans 6 https://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/websocket 8 https://www.springframework.org/schema/websocket/spring-websocket.xsd"> 9 10 <websocket:message-broker> 11 <websocket:transport message-size="131072" /> 12 <!-- ... --> 13 </websocket:message-broker> 14 15</beans>
스케일링과 관련된 중요한 포인트는 여러 애플리케이션 인스턴스를 사용하는 것입니다. 현재 simple broker로는 그렇게 할 수 없습니다.
그러나 RabbitMQ와 같은 full-featured broker를 사용할 때는 각 애플리케이션 인스턴스가 브로커에 연결되며, 하나의 애플리케이션 인스턴스에서 broadcast된 메시지는 브로커를 통해 다른 모든 애플리케이션 인스턴스에 연결된 WebSocket 클라이언트로 broadcast될 수 있습니다.
WebSocket Scope
Monitoring