시세 화면이 초당 한 번씩 서버에 값을 물어보고 있었다. 동시 접속이 늘면서 서버가 그 요청량을 버티지 못했다.
Table of contents
Open Table of contents
초당 한 번씩 묻던 화면
화면 하나가 초당 한 번을 부르므로 접속자 수가 그대로 초당 요청 수가 된다. 값이 안 바뀐 시간에도 같은 양을 부른다.
새벽처럼 거의 아무것도 안 바뀌는 시간에도 부하가 동일했다. 요청량이 실제 변화량이 아니라 접속자 수에 묶여 있는 구조였다.
부하와 신선도가 반대로 간다
먼저 주기를 늘려 보는 것을 검토했는데 부하는 그만큼 줄지만 화면이 그만큼 늦게 갱신된다. 시세 화면에서 몇 초의 지연은 받아들이기 어려웠다.
주기를 조절하는 안에서는 부하와 신선도가 항상 반대로 움직이므로 둘 다 필요하면 구조를 바꾸는 수밖에 없다. 그래서 묻는 방식에서 밀어 주는 방식으로 갔다.
밀어 주는 구조와 재연결
연결을 열어 두고 값이 바뀔 때만 보내게 하니 안 바뀌는 시간에는 트래픽이 거의 없어졌다. 바뀌면 다음 주기를 기다리지 않고 바로 나간다.
연결을 오래 열어 두니 끊기는 경우가 생겨서 끊기면 간격을 늘려 가며 다시 붙게 했다. 끊긴 동안 놓친 값이 있으므로 다시 붙을 때 현재값을 한 번 받고 나서 스트림을 여는 순서로 잡았다.
중간 장비가 끊는 연결
앞단이 일정 시간 아무것도 안 오는 연결을 끊고 있었는데 값이 안 바뀌면 정말로 아무것도 안 간다. 그래서 주기적으로 빈 신호를 보내 연결이 살아 있음을 알렸다.
앞단의 버퍼링도 꺼야 했는데 켜져 있으면 모아서 내보내느라 실시간이 아니게 된다. 중간에 있는 장비들이 전부 이 구조를 전제로 설정돼 있어야 동작했다.
연결 수와 보내는 양
연결 수가 곧 부하가 되므로 지표로 세고 파일 서술자 상한도 확인했다. 상한이 목표 동시 접속보다 낮아서 올렸고 올리기 전에 연결당 메모리도 재 봤다.
보내는 양도 줄였는데 전체를 매번 보내던 것을 바뀐 항목만 보내고 필드 이름도 짧게 했다. 초당 수천 건이 나가는 자리에서는 한 건의 크기가 그대로 대역폭이 된다.
정리
- 주기적 조회는 요청량이 변화량이 아니라 접속자 수에 묶인다
- 주기를 늘리면 부하가 주는 대신 신선도가 준다
- 둘 다 필요하면 구조를 바꾼다
- 바뀔 때만 보내면 안 바뀌는 시간에 부하가 없다
- 끊기면 다시 붙고 현재값을 한 번 받은 뒤 스트림을 연다
- 중간 장비가 조용한 연결을 끊으므로 주기 신호를 보내고 버퍼링을 끈다
- 연결 수가 부하이므로 파일 서술자 상한을 확인한다
- 초당 수천 건이면 한 건의 크기가 그대로 대역폭이다