์คํ๋ง ๋ถํธ ์ธ๋ํ ์ฐ
์ธํ ๋ฆฌ์ ์ด ๋๋ ์คํ๋ง ์ด๋์ ๋ผ์ด์ ๋ฅผ ํตํด ์คํ๋ง ๋ถํธ ํ๋ก์ ํธ๋ฅผ ๊ฐ๋จํ๊ฒ ์์ฑํ ์ ์๋ค. ์คํ๋ง ์ด๋์ ๋ผ์ด์ ๋ฅผ ํตํด ๋ง๋ค๊ณ ์ ํ๋ ํ๋ก์ ํธ์์ ํ์ํ ๋ชจ๋์ ์ฝ๊ฒ ์ ํํ ์ ์๊ฒ ์ง์ํ์ง๋ง ์ธ๋ถ์ ์ธ ๋ชจ๋์ ์ ํ์ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ์ ๋ง๋ค์ด์ง ํ๋ก์ ํธ๋ฅผ ์์ ํด์ผํ ํ์์ฑ์ด ์๊ธธ ์ ์๋ค. ์ํ์น ํฐ์บฃ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์ํ๋ ๊ธฐ๋ณธ ์ปจํ ์ด๋๋ก์จ ์ถฉ๋ถํ ์ ์ฆ๋ ๊ธฐ์ ์ด์ง๋ง ํ์ฌ ์กฐ์ง๊ณผ ๊ฐ์ด ์ผ๋ถ ์ค๋ฌด ํ๋ก์ ํธ์์๋ ์ธ๋ํ ์ฐ๋ฅผ ์ฌ์ฉํ๋ ํธ์ด๋ค.
build.gradleconfigurations.configureEach { exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat' } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-websocket' implementation 'org.springframework.boot:spring-boot-starter-undertow' }
์ ์์์์ spring-boot-starter-websocket ๋ชจ๋์ ์ํด spring-boot-starter-web์ ๋ช ์ํ ํ์๊ฐ ์๋ค.
WebSocketDeploymentInfo ๊ฒฝ๊ณ ๋ก๊ทธ ์์ ๊ธฐ
spring-boot-starter-websocket ๋ชจ๋์ ์ถ๊ฐํ๋ฉด ์๋์ฒ๋ผ WebSocketDeploymentInfo๊ฐ ์ค์ ๋์ง ์์ ๊ธฐ๋ณธ ๋ฒํผ ํ์ด ์ฌ์ฉ๋๋ค๋ ๊ฒฝ๊ณ ๋ก๊ทธ๊ฐ ์ถ๋ ฅ๋๋ค. ๋ก๊ทธ ๋ ๋ฒจ ์กฐ์ ์ ํตํด ๋ฌด์ํด๋ ๋์ง๋ง WebServerFactoryCustomizer๋ฅผ ํตํด์ WebSocketDeploymentInfo๊ฐ ๋ฑ๋ก๋๋๋ก ๊ตฌํํ ์ ์๋ค.
2023-03-16T21:49:43.249+09:00 WARN 35488 --- [main] io.undertow.websockets.jsr : UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used
UndertowWebsocketCustomizer@Component public class UndertowWebsocketCustomizer implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> { private final ServerProperties.Undertow undertow; public UndertowWebsocketCustomizer(final ServerProperties serverProperties) { this.undertow = serverProperties.getUndertow(); } @Override public void customize(UndertowServletWebServerFactory factory) { factory.addDeploymentInfoCustomizers(deploymentInfo -> { boolean direct = this.undertow.getDirectBuffers() != null && this.undertow.getDirectBuffers(); int bufferSize = this.undertow.getBufferSize() != null ? (int) this.undertow.getBufferSize().toBytes() : 1024; WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo(); webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(direct, bufferSize)); deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo); }); } }
HTTPS ํฌํธ๋ก ๋ฆฌ๋ค์ด๋ ํธ
์ด์ ๋ AWS ELB์ ๊ฐ์ ๋ก๋๋ฐธ๋ฐ์ ๋๋ ์์ง์์ค์ ๊ฐ์ ์น ์๋ฒ๋ค์ ํตํด์ ๋ฆฌ๋ฒ์ค ํ๋ก์๋ฅผ ๊ตฌ์ฑํ๋ฏ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ด HTTP/2๋ฅผ ์ง์ํ๋๋ก ๊ตฌ๋ํ์ง ์๋ ํธ์ด์ง๋ง TLS ์คํ๋ก๋๊ฐ ํ์ํ๋ค๋ฉด ์๋์ ๊ฐ์ด HTTP๋ก ์ฐ๊ฒฐ๋์์๋ HTTPS๋ก ์ฐ๊ฒฐ๋๋๋ก ๊ตฌ์ฑํ ์ ์๋ค.
UndertowHttp2Customizer@Component public class UndertowHttp2Customizer implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> { private final ServerProperties serverProperties; private final int httpPort; public UndertowHttp2Customizer(final ServerProperties serverProperties, final Environment environment) { this.serverProperties = serverProperties; this.httpPort = environment.getProperty("server.http-port", Integer.class, 8080); } @Override public void customize(UndertowServletWebServerFactory factory) { factory.addBuilderCustomizers(builder -> builder.addHttpListener(this.httpPort, "0.0.0.0")); factory.addDeploymentInfoCustomizers(deploymentInfo -> deploymentInfo.addSecurityConstraint( new SecurityConstraint() .addWebResourceCollection(new WebResourceCollection().addUrlPattern("/*")) .setTransportGuaranteeType(TransportGuaranteeType.CONFIDENTIAL) .setEmptyRoleSemantic(SecurityInfo.EmptyRoleSemantic.PERMIT)) .setConfidentialPortManager(exchange -> serverProperties.getPort())); } }