Skip to content

Improve performance of STOMP message header encoding [SPR-14901] #19467

@spring-projects-issues

Description

@spring-projects-issues

Christoph Dreis opened SPR-14901 and commented

Hey,

Problem

In recent loadtests I noticed quite some heap pressure coming from the encoding and escaping from STOMP headers that are sent to the client by our application. This is caused by mainly two things:

  • Escaping creates StringBuilder and String objects for every header and every of its values
  • Serializing the escaped header (and its values) requires to copy the bytes coming from StringCoding.safeTrim() every time.

Overall this creates around ~3-4GB of heap pressure in a 10 minute profile for us and is the TOP 1 reason for causing allocations right now. (I'd be happy to post a screenshot on Monday since I don't have it running on my laptop currently - if you need it).

Proposed solution

I thought a bit about a possible solution and came up with the idea to allow the StompEncoder (and StompDecoder) to be configured on the StompSubProtocolHandler. In the proposed solution this is done via a new StompWebSocketCodecRegistration object - consisting of both the encoder (and the decoder for consistency reasons). (I explicitly didn't call it a StompWebSocketCodec because it doesn't offer the actual decoding and encoding a real codec would offer.) In order to don't change too much contracts and allow a possible backport to 4.3.x I didn't create an interface for StompEncoder (and StompDecoder), but decided to go for encapsulating the header encoding via a new interface StompHeaderEncoder. Which in the end is the sole culprit for the allocations and thereby the interesting part.

With the proposed solution I am now able to specify a customized StompEncoder with a specialized version of a StompHeaderEncoder. In our case I would now write an implementation that makes use of a precompiled Map of headers and their byte representation, since we know them pretty much upfront. JMH microbenchmarks show a possible uplift of factor 20 with that sort of mechanism, but one could also think about a "trainable" header encoding.

Let me know what you think about the proposed solution. I'd be happy to adjust it according to your feedback.

Cheers,
Christoph


Affects: 4.3.4

Reference URL: #1236

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions