-
Notifications
You must be signed in to change notification settings - Fork 4
2. 라이브러리 선택
- HTTP 프로토콜 기반으로 동작합니다.
- 클라이언트로부터 요청을 받아 정적 파일을 응답해줍니다.
- Web Application Server(WAS)가 너무 많은 역할을 담당하면 트래픽을 감당하지 못할 수 있다.
- WAS 앞에 Web Server를 둬서 정적 리소스는 Web Server가 처리하도록하고, 애플리케이션 로직 같은 동적인 처리를 WAS한테 요청해서 처리합니다. (이를 통해 WAS 장애 발생 시 Web Server에서는 별도의 화면 처리가 가능합니다.)
- 대표적으로 Apache와 Nginx가 있습니다.
- Nginx는 Event-Driven 방식을 사용합니다.
- Node.js가 대표적으로 이 방식을 사용하고 있는데, 싱글 스레드의 Event Loop가 계속해서 돌아가면서 Event Queue에 요청이 들어오면 Thread Pool에 분배하여 넣어 비동기적으로 처리하도록 합니다.
- 많은 요청이 한꺼번에 오더라도 무리 없이 서비스할 수 있습니다.
event-driven의 비동기 구조이므로 채팅 기능이나 RTC기능을 사용 할 때, 동시 접속자 수가 증가를 대비하여 적합한 방식의 웹 서버라고 생각했습니다. 또한 NginX는 이벤트 처리 방식, 비동기식 처리, 논블로킹 방식 처리를 통해 고속으로 처리하는 특징이 있어 사용하게 되었습니다. 동시 접속자 수가 많아져도 Apache에 비해 메모리 사용률이 낮고, 처리하는 초 당 요청 수가 앞도적으로 높은 모습을 보여줍니다. 이러한 모습은 메모리를 좀 더 효율적으로 운영할 수 있는 결과를 갖고 오기 때문에 사용하게 되었습니다. 또한 reverse proxy로 서버 확장에 용이하고 보안적으로 뛰어나기 때문에 사용했습니다. (웹 서버를 직접 노출 시키지 않고 사용자의 요청을 nginx를 통해 웹 서버로 전달해 주기 때문에 보안적으로 위험성이 적음)
- Hypertext Transfer Protocol 의 약자
- Hypertext 인 HTML을 전송하기 위한 통신규약
- 그러나 HTML 텍스트 뿐만 아니라 모든 것을 전송할 수 있다.
- HTML, TEXT, 이미지, 음성, 영상, 파일, JSON, XML, 서버 간에 데이터 주고 받기 등등
(1991) HTTP/0.9
(1997) HTTP/1.1 : 가장 많이 사용, 대부분의 기능이 여기 들어 있음. TCP.
(2015) HTTP/2 : 성능 개선. TCP.
(현재진행형) HTTP/3 : 성능 개선. UDP.
개발자 도구의 네트워크 탭에서 protocol 컬럼을 활성화 하면 어느 네트워크 프로토콜을 사용하는지 알 수 있다. 예를 들어, h2는 HTTP/2, h3은 HTTP/3이다.
-
클라이언트-서버 구조
- 클라이언트는 서버에 요청을 보내고 대기. 서버는 요청 결과를 만들어서 응답을 준다.
- 구조를 분리한 것에 대한 이점이 존재. 클라이언트는 UI를 그리는 것에 집중하고, 서버는 복잡한 비즈니스 로직을 담당. 각자 구조를 발전시키는 데에도 용이.
-
무상태(stateless), 비연결성(connectionless)
- stateliss : 서버가 클라이언트의 이전 상태를 보존하지 않음.
- connectionless : 클라이언트가 서버에 요청을 하고 응답을 받으면 바로 TCP/IP 연결을 끊어 연결을 유지 하지 않는 것.
- 현재는 HTTP 지속연결(Persistent Connections)로 문제 해결 (처음 연결 이후 일정 시간 연결을 유지하거나, 여러 개의 요청(HTML, 자바스크립트, 이미지 등등)에 대한 응답이 다 올 때까지 기다린 후 연결을 종료)
-
HTTP 메시지
- 요청메세지와 응답메세지로 구분
- HTTP 헤더 : HTTP 전송에 필요한 모든 부가 정보가 들어 있다.
-
단순함, 확장 가능
-
문제점
서버에서부터 브라우저로 전송되는 정보가 암호화되지 않기에 데이터가 쉽게 도난당할 수 있다.
HTTPS 에서 마지막의 S는 Over Secure Socket Layer의 약자로 Secure라는 말을 통해서 알 수 있듯이 보안이 강화된 HTTP를 말한다. SSL/TLS 인증서로 통신 내용(데이터)을 암호화시킨다.
HTTPS와 SSL을 같은 의미로 이해하는 경우가 많은데, 결론적으로 말하면 웹이 인터넷 위에서 돌아가는 서비스 중의 하나인 것처럼 HTTPS도 SSL 프로토콜 위에서 돌아가는 프로토콜이다.
- 브라우저에 녹색 주소 표시줄이 표시된 EV 인증서를 받으면 방문자에게 신뢰감을 줄 수 있다. 그렇지만 올바르게 사용되지 않는다면 사용자들에게 보안에 대한 잘못된 안심을 줄 수 있으므로 주의해야 한다.)
- 방문자에게 서버의 사용자가 실제 사용자임을 보장하기 때문에, 접속하려는 서버가 신뢰할 수 있는 서버인지를 판단할 수 있다.
- 통신 내용의 악의적인 변경을 방지할 수 있다.
-
검색엔진 최적화
- 구글에서 가산점을 주기도 하고, 더 쉽게 노출되어 사람들이 더 많이 방문할 수 있다.
-
보다 빠른 브라우징 경험 제공
- 암호화가 서버 자원 및 페이지 로드 시간에 부정적인 영향을 미칠 것이라는 우려가 있었지만, 그 동안 서버와 클라이언트 소프트웨어 양츠겡서 이뤄져 온 개선점들로 인해 TLS 암호화가 속도에 미치는 부정적 영향은 무시할 수 있는 수준으로 감소했다고 한다.
- HTTP/2의 최적화로 인한 다수의 속도 개선 사항들이 배경으로 작용했다. 공식적으로 HTTP/2 스펙에는 암호화가 요구사항으로 포함되어 있지 않지만, 브라우저 제작사들이 이를 의무화하고 있었고, 웹사이트 개발자들은 자사 사용자들이 HTTP/2의 주요 속도 개선 기능들을 온전히 이용할 수 있도록 하려면 HTTPS를 배치해야 했던 것.
- 대칭키
- 암호화/복호화에 사용되는 키가 동일한 방식
- A와 B가 암호 통신을 하려 한다면 A와 B는 공통된 대칭키를 가지고 있어야한다.
- 공개키/비밀키
- 대칭키와 다르게 공개키와 비밀키 두가지로 나눈 방식.
- 공개키는 다른사람들에게 공개되고, 비밀키는 오직 비밀키의 소유자만이 알고있는 key.
- 공개키로 암호화된 평문은 비밀키로 복호화가 가능하고, 비밀키로 암호화된 평문은 공개키로 복호화가 가능하다.
- 공개키는 이상적인 통신 방법이지만, 대칭키 방식보다 암호화 연산 시간이 더 소요되어 비용이 크다.
- SSL 통신
암호화된 데이터를 전송하기 위해 공개키와 대칭키를 혼합해서 사용 클라이언트와 서버가 주고 받는 실제 정보는 대칭키 방식으로 암호화 대칭키 방식으로 암호화된 실제 정보를 복호화할 때 사용할 대칭키는 공개키 방식으로 암호화해서 클라이언트와 서버가 주고 받는다.
- 실제 데이터 : 대칭키
- 대칭키의 키 : 공개키
- 공개키-개인키 교환 과정 (TLS/SSL handshake)
- 프로토콜과 사용할 암호화 알고리즘에 대한 동의가 이뤄진다.
- 클라이언트는 임시 생성값을 서버에 보내 접속을 시도한다.
- 서버 또한 이에 대응하는 임시 생성값을 만들어 인증서(내부에 서버의 공개키)와 함께 보낸다.
- 클라이언트는 클라이언트에 내장된 CA의 공개키를 이용해 인증서를 복호화한다.
- 검증 후, 클라이언트는 pre master secret key(위의 과정에서 생성된 임시 생성값을 조합해 만든 key) 를 서버가 준 공개키로 암호화해서 서버에 보낸다.
- 서버는 자신의 개인키로 이를 복호화한다.
- 이렇게 클라이언트와 서버는 모두 pre master secret key를 공유하게 된다. (대칭키 완성)
- 클라이언트와 서버는 pre master secret key를 master secret key로 바꾸고, 이는 다시 session key를 생성한다.
- 이 session key로 클라이언트와 서버는 대칭키 방식으로 통신한다.
- 데이터의 전송이 끝나면 SSL 통신이 끝났음을 서로에게 알려준다. 이 때 통신에서 사용한 대칭키인 session key를 폐기한다.
1. webRTC 라이브러리에서 HTTP를 지원하지 않음.
- 프로젝트의 핵심기능인 화상 채팅을 구현하기 위해 webRTC를 사용하기로 결정.
- webRTC의 내부 메소드 중 필수로 사용해야 하는 getUserMedia 메소드가 HTTP를 지원하지 않음.
2. 보안 과 속도, 그리고 검색엔진최적화 의 관점에서 모두 HTTP보다 HTTPS가 우수
- 애초에 보안이 강화된 HTTP이므로 HTTP의 장점도 모두 가지고 있음.
- HTTPS를 적용함으로써 발생하는 단점에 비해 이점이 훨씬 크다고 판단.
- 단점: 인증서 적용의 번거로움 및 비용 발생, 암호화로 인한 서버 비용 증가 등등
Reference
https://www.ssl.com/article/pros-and-cons-of-ssl-https-tls/
https://opentutorials.org/course/228/4894
https://www.itworld.co.kr/print/103924
- 웹소켓은 양방향 소통을 위한 프로토콜입니다. 여기서 프로토콜은 '서로 다른 컴퓨터끼리 소통하기 위한 약속' 이라고 하네요
- socket.io 는 양방향 통신을 하기 위해 웹소켓 기술을 활용하는 라이브러리 입니다. 자바스크립트와 jQuery의 관계와 비슷하다고 볼 수 있습니다.
websocket | socket.io |
---|---|
HTML5 웹 표준 기술이기 때문에 오래된 버전의 웹 브라우저는 웹소켓을 지원하지 않습니다. | 표준 기술은 아니고 라이브러리. |
매우 빠르게 작동하며 통신할 때 적은 데이터를 이용함. | 소켓 연결 실패 시 fallback을 통해 다른 방식으로 알아서 해당 클라이언트와 연결을 시도함. |
이벤트를 단순히 듣고 보내는 것만 가능함. | 방 개념을 이용해 일부 클라이언트에게만 데이터를 전송하는 브로드캐스팅이 가능함. |
같은 기능을 구현하더라도 약간 느리지만 많은 편의성을 제공하며 Java, C++, Python 등 여러 언어들의 라이브러리 또한 지원 |
- 통상적으로 사용자(서버에 연결된 소켓들)을 세밀하게 관리해야하는 서비스에는
socket.io에 있는 브로드캐스팅을 사용하는게 더 효율적이라고 합니다.
socket을 이용해서 게임 로직과 같은 복잡한 구조를 갖고 socekt이라는 객체를 활용해서 서비스 내에서 활용하는 부분들을 생각하면 socekt.io가 더 적합하다고 판단했습니다.
WebRTC는 서버를 최대한 거치지 않고 P2P(Peer-to-Peer Network)로 브라우저나 단말 간에 데이터를 주고받는 기술의 웹 표준입니다.
또한 WebRTC는 표준임과 동시에 표준을 구현한 오픈소스 프로젝트의 이름이기도 합니다. 사실 프로젝트가 먼저 있었고 표준화는 나중에 되었는데, 통신사와 통신솔루션 기업이 독점하고 있던 핵심 통신 기술을 구글이 주도해서 오픈소스화 및 표준화를 진행했습니다. (갓구글!)
1:1의 화상채팅을 구현하는 것은 노마드코더 강의에서만 봐도 생각보다 간단했었습니다. 하지만 저희 프로젝트 특성 상 N:N 의 희의형 서비스의 특징을 띄기 때문에 기존보다 더 복잡한 flow를 가지게됩니다.
-
CPaaS 이용 클럽하우스를 비롯한 많은 성공 서비스는 WebRTC 기술과 인프라를 전문적으로 제공하는 CPaaS(Communication Platform as a Service)를 활용하고 있습니다. 매우 현명한 방법이라고 생각합니다. WebRTC 응용 서비스에서 성공을 결정하는 핵심은 WebRTC가 아니라 콘텐츠 자체이기 때문입니다. 핵심에 집중하기 위하여 WebRTC 같은 매우 전문화된 기술은 클라우드 기업에 맡기는 것 입니다. 해외의 경우 Twilio나 Agora.io가 유명하고 국내의 경우 Kakao i Connect Live가 유일한 CPaaS입니다. 이들 CPaaS를 이용하면 WebRTC 응용 서비스 개발에서 WebRTC와 관련된 거의 모든 부분에서 도움을 받을 수 있습니다. 웹 뿐만 아니라 모바일 플랫폼 지원과 대용량 트랜잭션 제어 그리고 미디어 서버 및 TURN서버 등을 지원받게 됩니다.
-
webRTC 서버 직접 구현 WebRTC 덕분에 이전보다 라이브 스트리밍 혹은 통화 서비스를 개발하기가 한결 쉬워지고 저렴해진 것은 사실입니다. webRTC 서버를 구축하기 위해 필요한 여러 서버들(signaling, media, stun, turn 등)이 있는데 각 서버들을 쉽게 구현할 수 있게 도와주는 오픈소스 라이브러리도 많이 존재합니다. peerJS, openvidu, simple-peer 등 여러가지를 조합해서 필요에 맞게 서버를 구현하는 방법들도 존재합니다.
웹에서 실시간 미디어 스트림을 송수신할 수 있는 유일한 표준이고 또 유일한 P2P 표준이기도 합니다.
WebRTC 등장 이전에는 고가의 라이선스 구매 비용을 들여서 통화 기능, 화상회의 기능 등을 개발해야 했습니다. 하지만 2010년, IT 기술 중에서도 유독 라이선스 사용에 많은 비용이 드는 기술이었던 VoIP(Voice over Internet Protocol) 시장에 기존에는 상상하기 어려웠던 뉴스가 등장했습니다. 구글이 WebRTC의 근간이 되는 여러 독점 기술 기업들(On2, GIPS)을 인수해서 WebRTC 기술을 오픈소스로 풀어버린 겁니다. 이 기술들은 그전까지는 그야말로 세계 탑 수준의 미디어 엔진 및 코덱이었는데 이것을 오픈 한 뒤, 급기야 크롬 브라우저에 탑재시키고 표준화 단체까지 만듭니다.
- 코드 포멧터(Code Formatter)란 개발자가 작성한 코드를 정해진 코딩 스타일을 따르도록 변환해주는 도구를 말합니다. Prettier는 이러한 코드 포멧터 중에서도 최근에 가장 인기를 많이 얻어 거의 표준이 되고 가고 있는 자바스크립트 라이브러리 입니다.
- ESLint는 JavaScript, JSX의 정적 분석 도구로 오픈 소스 프로젝트입니다. 코드를 분석해 문법적인 오류나 안티 패턴을 찾아주고 일관된 코드 스타일로 작성하도록 도와줍니다. JSLint, JSHint와 같이 다른 JavaScript 정적 분석 도구들도 있지만, ESLint가 커스터마이징이 쉽고 확장성이 뛰어나 많이 쓰이고 있는 추세입니다. ESLint는 스타일 가이드를 좀 더 편리하게 적용하기 위해 사용하기도 하는데, 외부에 공개되어 많은 개발자가 사용 중인 Airbnb, Google 이 그 대표적인 예입니다.
- Babel을 이용하면 ES6 이상의 최신 문법으로 작성한 자바스크립트 코드를 ES5 이하의 예전 문법으로 작성한 것 처럼 소스 코드 내의 문법의 형태를 변경할 수 있습니다. 이렇게 Babel을 통해 문법 형태가 바뀐 소스 코드는 최신 문법을 지원하는 실행 환경 뿐만 아니라 아직 최신 문법들이 적용되지 않은 실행 환경에서도 문제없이 작동하게 됩니다.
- prettier
- 깔끔한 코드와 협업을 위해서 일관성 있는 코드 스타일을 제공해주기 때문에.
- eslint
- 다양한 방식으로 구현할 수 있는 코드 방식을 일관성 있게 구현할 수 있도록 해주기 때문에.
- babel
- Babel을 이용하면 ES6 이상의 최신 문법으로 작성한 자바스크립트 코드를 ES5 이하의 예전 문법으로 작성한 것 처럼 소스 코드 내의 문법의 형태를 변경해주어 다양한 실행환경에서 작동할 수 있게 해주기 때문에.
Redis는 Memcached와 비슷한 캐시 시스템으로서 동일한 기능을 제공하면서 영속성, 다양한 데이터 구조와 같은 부가적인 기능을 지원하고 있습니다. 레디스는 모든 데이터를 메모리에 저장하고 조회합니다. 즉, 인메모리 데이터베이스 입니다. 이 말만 들으면 Redis에 모든 데이터를 메모리에 저장하는 빠른 DB가 다라고 생각할지도 모릅니다. 하지만 빠른 성능은 레디스의 특징 중 일부분 입니다. 다른 인메모리 디비들과의 가장 큰 차이점은 레디스의 다양한 자료구조 입니다.
- 각 게임에 대해 투표 결과 집계나 각 게임 준비 상태 등 DB에 저장할 필요는 없지만 I/O이 빈번한 간단한 액션들에 대해 가볍게 저장해 둘 DB를 찾다가 memcached랑 redis 가 후보였는데 memcached보다 redis가 cloud서비스로도 제공이 되고 초기 세팅하기에 더 빨라서 선택하게 됬습니다.간단한 데이터 타입들과 key, value 형식으로 저장할 수 있는 메모리를 사용하는 DB라서 위에서 언급한 저런 데이터들의 I/O을 다루기에는 redis가 적합하다고 생각했습니다.
- redis를 선택할 때 local과 cloud 두가지 옵션이 있었는데 협업하면서 사용하기에는 아무래도 local보단 cloud가 더 효율적일 것 같다는 생각이 들었습니다.
- JWT(JSON Web Token)은 당사자 간 정보를 안전하게 전송할 수 있는 방법을 JSON 객체로 정의한 개방형 표준(RFC 7519)이다.
- JWT는 대칭키 혹은 공개키/비밀키 방식을 선택하여 서명할 수 있고, 서명된 토큰은 그 안에 포함된 클레임의 무결성을 검증할 수 있으며, 암호화된 토큰은 그러한 클레임을 다른 당사자로부터 숨길 수 있다.
- 권한 부여: JWT를 사용하기 위한 가장 일반적인 사용처
- 사용자가 로그인하면 이후의 각 요청에는 JWT가 포함되어 사용자가 해당 토큰으로 허용된 경로, 서비스 및 리소스에 액세스할 수 있다.
- 정보 교환: JSON 웹 토큰은 당사자 간에 정보를 안전하게 전송하는 좋은 방법
- JWT는 예를 들어 공용/개인 키 쌍을 사용하여 서명할 수 있기 때문에 보낸 사람이 자신이 누구인지 확인할 수 있다.
- 또한 헤더와 페이로드를 사용하여 서명을 계산하므로 내용이 조작되지 않았는지 확인할 수도 있다.
- 카카오에서 발급받은 accessToken을 그대로 사용해도 되지만 카카오의 accessToken 의 유효시간이 11시간으로 굉장히 긴 편이다.
- 직접 accessToken을 발급하고 유효시간을 줄여 보안을 조금 더 강화하고자 하였다.
- 세션 방식과 다르게 별도의 인증 저장소가 필요하지 않아 서버와의 커뮤니케이션을 최소한으로 할 수 있어 트래픽에 대한 부담이 적다.
저희 프로젝트에서 고민한 데이터베이스는 MongoDB 와 MySQL 이었습니다.
- MongoDB : JSON 과 유사한 형태인 BSON 을 기반 의 형태인 Document 들의 집단인 Collection 을 가지고 있습니다.
- MySQL : 표의 형태인 행과 열 로 구성된 테이블 가지고 있습니다.
구분 | 장점 | 단점 |
---|---|---|
MongoDB | 유연한 동적 스키마로 확장성이 좋습니다. TTL 인덱싱 으로 손쉽게 문서의 만료 기한을 지정 | 공식문서 에서 단일 문서 원자성으로 대부분의 Transaction 은 불필요하다고 언급하였고 일부 상황에 한정해서 어려운 Trasaction 을 지원. 단일 문서 를 포커스로 두고 있어서, 복잡한 비즈니스 논리(복잡한 단계별 인증 처리) 를 구현하는 데 어렵다. |
MySQL | 구조화된 데이터 처리에 안정적입니다. Transaction 의 사용이 편리하며 안정적입니다. 오랜 역사와 많은 사용으로 인해 참고자료가 많습니다. | Transaction 으로 인한 락쿼리가 발생합니다. 정규화 작업을 진행하면 정보가 분할되기 떄문에, 조회 시 많은 Row 를 조회하게 됩니다. |
프로젝트에 대한 기본적인 설계 후에 처음 구현해보는 게임 부분에서 처음 해보는 거라 후에 어떤 데이터들이 추가되거나 데이터 형식에 대한 변화가 생길 것을 예상하고 있어서 비정형 데이터를 다루기에 적합한 mongoDB를 선택하게 됬습니다.