1. 문제
- 대시보드를 실시간으로 보여주는 기능을 구현합니다.
2. 조사
- 실시간 처리에는 다음과 같은 기술들이 있습니다.
- polling
- 클라이언트가 일정한 주기로 서버에 업데이트 요청을 보내는 방법이다.
- 지속적인 HTTP 요청이 발생하기 때문에 리소스 낭비가 발생한다.
- websoket
- 실시간 양방향 통신을 위한 스펙으로 서버와 브라우저가 지속적으로 연결된 TCP라인을 통해 실시간으로 데이터를 주고받을 수 있도록 하는 HTML5 사양이다.
- 연결지향 양방향 전이중 통신이 가능하며 채팅, 게임, 주식 차트 등에 사용된다.
- polling은 주기적으로 HTTP 요청을 수행하지만, websocket은 연결을 유지하여 서버와 클라이언트 간 양방향 통신이 가능하다.
- SSE(Server Sent Event)
- 이벤트가 [서버 -> 클라이언트] 방향으로만 흐르는 단방향 통신 채널이다.
- SSE는 클라이언트가 polling과 같이 주기적으로 http 요청을 보낼 필요없이 http 연결을 통해 서버에서 클라이언트로 데이터를 보낼 수 있다.
3. 해결방법
- 클라이언트에서 지속적인 요청없이 서버에서 응답을 하기 위해 SSE를 사용합니다.
- 비동기로 처리합니다.
4. 코드
@RestController
public class Publisher {
...
@GetMapping("/publisher")
public Flux<ServerSentEvent<Dto>> publish() {
return service.publish();
}
}
@Service
public class Publisher {
private static final Long refreshTime = 2L;
public Flux<ServerSentEvent<Dto>> publish() {
return Flux.interval(Duration.ofSeconds(refreshTime))
.map(sequence -> ServerSentEvent.<Dto> builder()
.id("/publish")
.event("dashboard")
.data(Dto)
.build());
}
}
5. 이슈
- 현재 event 발생이 없어도 Event를 계속 보냈습니다.
- 하지만, AWS에 배포 하고 모니터링을 해보니 서버에 너무 많은 과부하가 걸린다는 것을 알았습니다.
- Event 발생 시 새로운 대시보드를 보내는 방법을 고안중입니다.