效能
在效能方面,沒有一勞永逸的解決方案。許多因素會影響效能,包括訊息的大小和數量,應用程式方法是否執行需要阻塞的工作,以及外部因素(如網路速度和其他問題)。本節的目標是概述可用的配置選項,並就如何推理擴充套件提供一些思考。
在訊息應用程式中,訊息透過由執行緒池支援的通道進行非同步執行。配置此類應用程式需要對通道和訊息流有充分的瞭解。因此,建議查閱訊息流。
顯而易見的起點是配置支援clientInboundChannel和clientOutboundChannel的執行緒池。預設情況下,兩者都配置為可用處理器數量的兩倍。
如果帶註解方法中的訊息處理主要是CPU密集型的,clientInboundChannel的執行緒數應保持接近處理器數量。如果它們所做的工作更多是IO密集型的,需要阻塞或等待資料庫或其他外部系統,則可能需要增加執行緒池大小。
|
一個常見的誤解是,配置核心池大小(例如,10)和最大池大小(例如,20)會產生一個包含10到20個執行緒的執行緒池。實際上,如果容量保持其預設值Integer.MAX_VALUE,執行緒池永遠不會超過核心池大小,因為所有額外的任務都會排隊。 請參閱 |
在clientOutboundChannel方面,主要是向WebSocket客戶端傳送訊息。如果客戶端在快速網路上,執行緒數應保持接近可用處理器數量。如果它們速度慢或頻寬低,它們消耗訊息的時間會更長,並對執行緒池造成負擔。因此,增加執行緒池大小變得必要。
雖然clientInboundChannel的工作負載是可能預測的——畢竟,它基於應用程式所做的事情——但如何配置"clientOutboundChannel"則更難,因為它基於應用程式無法控制的因素。因此,還有兩個額外屬性與訊息傳送相關:sendTimeLimit和sendBufferSizeLimit。您可以使用這些方法配置允許傳送操作花費的時間以及向客戶端傳送訊息時可以緩衝的資料量。
一般而言,在任何給定時間,只能使用單個執行緒向客戶端傳送訊息。同時,所有額外的訊息都會被緩衝,您可以使用這些屬性來決定允許傳送訊息花費多長時間以及在此期間可以緩衝多少資料。有關重要的附加詳細資訊,請參閱javadoc和XML schema文件。
以下示例顯示了一種可能的配置
-
Java
-
Kotlin
-
Xml
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
@Override
public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
registration.setSendTimeLimit(15 * 1000).setSendBufferSizeLimit(512 * 1024);
}
// ...
}
@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
override fun configureWebSocketTransport(registration: WebSocketTransportRegistration) {
registration.setSendTimeLimit(15 * 1000).setSendBufferSizeLimit(512 * 1024)
}
// ...
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/websocket
https://www.springframework.org/schema/websocket/spring-websocket.xsd">
<websocket:message-broker>
<websocket:transport send-timeout="15000" send-buffer-size="524288" />
<!-- ... -->
</websocket:message-broker>
</beans>
您還可以使用前面顯示的 WebSocket 傳輸配置來配置傳入 STOMP 訊息的最大允許大小。理論上,WebSocket 訊息的大小几乎沒有限制。實際上,WebSocket 伺服器會施加限制——例如,Tomcat 上為 8K,Jetty 上為 64K。因此,諸如 stomp-js/stompjs 等 STOMP 客戶端會將較大的 STOMP 訊息以 16K 為界拆分,並將其作為多個 WebSocket 訊息傳送,這需要伺服器進行緩衝和重新組裝。
Spring 對 STOMP-over-WebSocket 的支援可以做到這一點,因此應用程式可以配置 STOMP 訊息的最大大小,而無需考慮特定於 WebSocket 伺服器的訊息大小。請記住,WebSocket 訊息大小會在必要時自動調整,以確保它們至少可以承載 16K 的 WebSocket 訊息。
以下示例顯示了一種可能的配置
-
Java
-
Kotlin
-
Xml
@Configuration
@EnableWebSocketMessageBroker
public class MessageSizeLimitWebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
@Override
public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
registration.setMessageSizeLimit(128 * 1024);
}
// ...
}
@Configuration
@EnableWebSocketMessageBroker
class MessageSizeLimitWebSocketConfiguration : WebSocketMessageBrokerConfigurer {
override fun configureWebSocketTransport(registration: WebSocketTransportRegistration) {
registration.setMessageSizeLimit(128 * 1024)
}
// ...
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/websocket
https://www.springframework.org/schema/websocket/spring-websocket.xsd">
<websocket:message-broker>
<websocket:transport message-size="131072" />
<!-- ... -->
</websocket:message-broker>
</beans>
關於擴充套件的一個重要點涉及使用多個應用程式例項。目前,您無法使用簡單的代理實現這一點。但是,當您使用功能齊全的代理(如 RabbitMQ)時,每個應用程式例項都連線到代理,並且從一個應用程式例項廣播的訊息可以透過代理廣播到透過任何其他應用程式例項連線的 WebSocket 客戶端。