티스토리 뷰
반응형
WebSocket을 연결하면 단일 요청에 비해 연결 횟수가 줄어들어서 http에 비해서 빨라진다는 건 대부분 알고 있을 것이다.
그러면 얼마나 빨라지는지 우리 서비스에서 실험해봤다.
TTS edge function과 React를 웹소켓으로 연결했을 경우
Response from backend: {response: '안녕하세요! 만나서 정말 반가워요. 요즘 어떻게 지내고 계신가요?'}
useSpeechRecognition.js:126 tts2: 3860.410888671875 ms
useSpeechRecognition.js:163 Response from backend: {response: '알겠어요! 그럼 계속 이야기 나눠볼까요? 요즘 어떤 일들이 있으셨나요?'}
useSpeechRecognition.js:126 tts2: 3931.52294921875 ms
useSpeechRecognition.js:163 Response from backend: {response: '알겠어요! 그럼 계속 이야기 나눠볼까요? 요즘 어떤 일들이 있으셨나요?'}
useSpeechRecognition.js:126 tts2: 2121.7470703125 ms
useSpeechRecognition.js:163 Response from backend: {response: '안녕하세요! 만나서 반가워요. 요즘 어떻게 지내고 계신가요?'}
useSpeechRecognition.js:126 tts2: 2219.73095703125 ms
useSpeechRecognition.js:163 Response from backend: {response: '안녕하세요! 만나서 반가워요. 요즘 어떻게 지내고 계신가요?'}
useSpeechRecognition.js:126 tts2: 2648.985107421875 ms
useSpeechRecognition.js:163 Response from backend: {response: '안녕하세요! 만나서 반가워요. 요즘 어떻게 지내고 계신가요?'}
useSpeechRecognition.js:126 tts2: 2265.364990234375 ms
useSpeechRecognition.js:163 Response from backend: {response: '안녕하세요! 만나서 반가워요. 요즘 어떻게 지내고 계신가요?'}
useSpeechRecognition.js:126 tts2: 2642.868896484375 ms
useSpeechRecognition.js:163 Response from backend: {response: '안녕하세요! 만나서 반가워요. 요즘 어떻게 지내고 계신가요?'}
useSpeechRecognition.js:126 tts2: 2107.48779296875 ms
useSpeechRecognition.js:163 Response from backend: {response: '안녕하세요! 만나서 반가워요. 요즘 어떻게 지내고 계신가요?'}
useSpeechRecognition.js:126 tts2: 2421.31396484375 ms
useSpeechRecognition.js:163 Response from backend: {response: '안녕하세요! 만나서 반가워요. 요즘 어떻게 지내고 계신가요?'}
useSpeechRecognition.js:126 tts2: 2978.48193359375 ms
useSpeechRecognition.js:163 Response from backend: {response: '안녕하세요! 만나서 반가워요. 요즘 어떻게 지내고 계신가요?'}
useSpeechRecognition.js:126 tts2: 2775.327880859375 ms
useSpeechRecognition.js:163 Response from backend: {response: '안녕하세요! 만나서 반가워요. 요즘 어떻게 지내고 계신가요?'}
useSpeechRecognition.js:126 tts2: 3562.56591796875 ms
useSpeechRecognition.js:163 Response from backend: {response: '안녕하세요! 만나서 반가워요. 요즘 어떻게 지내고 계신가요?'}
useSpeechRecognition.js:126 tts2: 2402.093017578125 ms
useSpeechRecognition.js:163 Response from backend: {response: '안녕하세요! 만나서 반가워요. 요즘 어떻게 지내고 계신가요?'}
useSpeechRecognition.js:126 tts2: 2076.577880859375 ms
The average tts2 time is approximately 2715.32 ms.
지난번 2980ms보다는 확실히 빨라졌다.
Django 단일로 했을 때는 어차피 텍스트밖에 오고 가지 않아서 대략 2890ms 정도 됐었다.
그럼 두 개 다 웹소켓을 연결하면 어떨까?
WebSocket 3389 opened.
useSpeechRecognition.js:40 WebSocket 8000 opened.
useSpeechRecognition.js:45 Response from backend via WebSocket: {response: '안녕하세요! 다시 만나서 반가워요. 오늘 기분은 어떠신가요? 특별한 일은 없으셨나요?'}
useSpeechRecognition.js:125 tts2: 5410.5751953125 ms
useSpeechRecognition.js:45 Response from backend via WebSocket: {response: '안녕하세요! 다시 만나서 반가워요. 오늘 기분은 어떠신가요? 특별한 일은 없으셨나요?'}
useSpeechRecognition.js:125 tts2: 2839.68310546875 ms
useSpeechRecognition.js:45 Response from backend via WebSocket: {response: '안녕하세요! 다시 만나서 반가워요. 오늘 기분은 어떠신가요? 특별한 일은 없으셨나요?'}
useSpeechRecognition.js:125 tts2: 3465.69189453125 ms
useSpeechRecognition.js:45 Response from backend via WebSocket: {response: '안녕하세요! 다시 만나서 반가워요. 오늘 기분은 어떠신가요? 특별한 일은 없으셨나요?'}
useSpeechRecognition.js:125 tts2: 2960.12109375 ms
useSpeechRecognition.js:45 Response from backend via WebSocket: {response: '안녕하세요! 다시 만나서 반가워요. 오늘 기분은 어떠신가요? 특별한 일은 없으셨나요?'}
useSpeechRecognition.js:125 tts2: 3582.5810546875 ms
useSpeechRecognition.js:45 Response from backend via WebSocket: {response: '안녕하세요! 다시 만나서 반가워요. 오늘 기분은 어떠신가요? 특별한 일은 없으셨나요?'}
useSpeechRecognition.js:125 tts2: 3587.431884765625 ms
useSpeechRecognition.js:45 Response from backend via WebSocket: {response: '알겠어요! 그럼 대화를 마무리할게요. 오늘 이야기 나눠주셔서 정말 감사해요. 다음에 또 소중한 이야기 들려주세요!'}
useSpeechRecognition.js:125 tts2: 3244.60693359375 ms
useSpeechRecognition.js:45 Response from backend via WebSocket: {response: '알겠어요! 그럼 다시 시작해볼까요? 안녕하세요! 오늘 기분은 어떠신가요? 특별한 일은 없으셨나요?'}
useSpeechRecognition.js:125 tts2: 6323.248046875 ms
useSpeechRecognition.js:45 Response from backend via WebSocket: {response: '안녕하세요! 다시 만나서 반가워요. 오늘 기분은 어떠신가요? 특별한 일은 없으셨나요?'}
useSpeechRecognition.js:125 tts2: 3239.845947265625 ms
useSpeechRecognition.js:45 Response from backend via WebSocket: {response: '안녕하세요! 다시 만나서 반가워요. 오늘 기분은 어떠신가요? 특별한 일은 없으셨나요?'}
useSpeechRecognition.js:125 tts2: 3383.10888671875 ms
useSpeechRecognition.js:45 Response from backend via WebSocket: {response: '안녕하세요! 다시 만나서 반가워요. 오늘 기분은 어떠신가요? 특별한 일은 없으셨나요?'}
useSpeechRecognition.js:125 tts2: 3028.070068359375 ms
평균 TTS2 시간은 약 3733.18ms입니다.
놀랍게도 더 느려졌다.
이는 아마도 네트워크 방식의 차이이다.
1. 네트워크 대역폭 및 리소스 제한
- 두 개의 웹소켓 연결을 각각 다른 포트에서 실행할 경우, 동시에 두 개의 소켓을 관리하는 데 필요한 네트워크 대역폭과 리소스를 더 많이 소모할 수 있습니다.
- 특히 WebSocket은 실시간으로 양방향 통신을 유지하기 때문에, 연결이 두 개가 되면 추가적인 네트워크 리소스와 서버의 I/O 리소스가 소모될 수 있습니다.
- 서버에서 요청을 처리하는 동안 여러 포트로 데이터를 처리하다 보면 병목 현상이 발생할 수 있습니다. 이 경우, 처리 속도가 느려지는 이유가 될 수 있습니다.
2. 서버 성능 (Django vs Express)
- Express.js는 Node.js 환경에서 돌아가며, 비동기 I/O 모델을 잘 처리하는 특성이 있어, WebSocket을 관리하는 데 적합합니다.
- Django는 기본적으로 동기적으로 작동하는 웹 프레임워크이기 때문에 WebSocket을 잘 처리하려면 Channels나 Daphne와 같은 추가적인 비동기 처리 방법을 설정해야 합니다. 비동기 처리가 제대로 설정되지 않으면 여러 웹소켓을 동시에 처리할 때 성능 저하가 발생할 수 있습니다.
- Django Channels에서 비동기 코드가 제대로 최적화되지 않으면 서버가 요청을 처리하는 데 시간이 더 걸릴 수 있습니다.
3. WebSocket 핸들링 방식
- 두 개의 웹소켓을 동시에 사용할 경우 각 웹소켓이 각기 다른 포트에서 연결되고, 메시지를 처리하는 방식에 차이가 있을 수 있습니다. 예를 들어:
- 하나의 웹소켓이 비동기적으로 처리되고 다른 하나는 동기적으로 처리되거나, 서버에서 웹소켓 메시지를 받아서 처리하는 속도가 달라질 수 있습니다.
- 웹소켓 서버가 메시지를 처리하는 방식에서 지연이 발생할 수도 있습니다. 예를 들어, 두 웹소켓 서버에서 동일한 리소스를 공유하거나 같은 코드 흐름을 처리한다면, 하나의 서버에서 지연이 발생하면 다른 서버에도 영향을 미칠 수 있습니다.
4. 서버 사이드의 멀티스레딩/멀티프로세싱 이슈
- Django는 기본적으로 멀티스레드가 아니라 단일 스레드로 작동하기 때문에, 하나의 웹소켓 연결이 처리되는 동안 다른 연결에 영향을 미칠 수 있습니다. 여러 포트에서 동시에 웹소켓을 처리하면, 서버의 스레드나 프로세스가 처리할 수 있는 요청의 수가 제한될 수 있습니다.
- uvicorn 같은 ASGI 서버가 비동기 방식으로 요청을 처리하는데, 웹소켓 2개를 동시에 연결하면 리소스를 두 포트에서 분배해야 하므로 성능 저하가 발생할 수 있습니다.
5. 포트별 리소스 할당
- 포트 3389와 8000을 동시에 사용할 때 각 포트가 별도의 리소스를 할당받아 처리하는데, 그 과정에서 병목이 발생할 수 있습니다. 특히 서버에서 사용하는 포트가 많아지면 네트워크 리소스와 운영체제 레벨에서의 연결을 관리하는 데 추가적인 오버헤드가 발생할 수 있습니다.
- 같은 서버에서 여러 포트를 사용할 때는 포트 간의 리소스 경쟁이 발생할 수 있어 성능이 저하될 수 있습니다.
6. 메시지 전송 방식 및 타이밍
- 두 웹소켓 포트를 동시에 사용하면서 각 포트에 메시지가 오고 가면, 메시지 처리 순서나 타이밍에 의한 지연이 발생할 수 있습니다. 예를 들어, 하나의 포트에서 받은 메시지가 다른 포트의 메시지 흐름에 영향을 미쳐 처리 시간이 길어질 수 있습니다.
따라서 웹소켓을 쓰려면 하나만 쓰는 게 정석이라는 평가이다.
그냥 욕심부리지 말고 하나만 쓰자.
반응형