본문 바로가기
포스코x코딩온

3차 프로젝트 디벨롭 (https, socket.io, express.js, react) - 경제적인 버전

by 김선지 2024. 4. 22.

서버마다 인스턴스가 있는 경우에는 그냥 호스트 별로 모두 443번 포트를 이용하면 되니까 https 연결이 모두 가능한데

 

나는 돈이 없기 때문에 t2 micro 인스턴스 하나에서 어떻게든 socket.io, express. js, react(정적파일)를 nginx를 이용하여 돌려보려고 했다.

다음은 시행착오의 과정이다.

 

실험1. 가비아 도메인 + acm + Route 53 + Ec2 roadbalancer

    일단 가비아에서 500원짜리 도메인을 산 다음에 acm(ssl)을 발급받고 Route 53에서 DNS 처리를 해준다(네임서버 설정). 그리고 로드밸런서로는 80번포트의 요청을 자동적으로 443번 포트로 리다이렉트 해준다. 여기까지는 괜찮은데 인스턴스 한개, 즉 443번 포트가 하나밖에 없는 경우에는 nginx의 리버스 프록시 기능이 필수다. 하지만 acm을 사용할 경우 pem 파일은 aws 내에서 밖에 쓰지 못하기 때문에 리버스 프록시를 사용할 수 없없다.

(게다가 돈 적게 나가는 줄 알았는데 어느순간 보니까 결제금액이 너무 많이나와서 돈이 없는 지금으로써는 못쓸 것 같다.)

 

실패

 

실험 2. 가비아 도메인 + 가비아 네임서버 DNS관리 + letsencript ssl(.pem) + Nginx 리버스프록시 (conf 설정)

   원래 80번 포트에서 static파일인 index.html을 제공하고(nginx), 4000번 포트에서 express 서버와 socket.io 서버를 같이 돌리고있었다. 이걸 리버스 프록시로 다 퉁친다면 어떨까..? 일단 해봤다.

  a. 443번 포트 (https) 요청이 오면 index.html 파일을 제공한다.

  b. 프론트와 백 모두 https로 받아야 block을 방지할 수 있으므로 https:도메인/api 경로를 따로 넣어서 /ip주소:4000으로 proxy_pass를 설정한다. 그렇게 된다면 백엔드의 요청 또한 https://도메인/api/다른경로 <- 이런 식으로 설정할 수 있고 결과적으로는 block을 방지할 수 있을 거라 생각했다.

(아래 스샷 참고)

 

이렇게 할 경우 백엔드와의 연동은 되는데 network쪽을 보니까 소켓서버에서는 핸드쉐이크조차 되지 않는 상황을 발견할 수 있었다.

실패

 

실험 2-1. 핸드쉐이크가 되지 않는 원인을 개발자 도구 network에서 찾을 수 있지 않을까?

하고 로컬에서 돌릴때(http 요청으로 잘 되는 케이스)와 비교해보니 network쪽에서 연결할 때는 ws:도메인/ws , http:도메인/socket.io/~ 위 두가지 방식으로 연결을 요청하고 있음을 확인할 수 있었다. 그래서 다음과 같이 conf를 추가해봤다. 프록시 설정은 socket.io 공식문서를 참고했다.

 

어림도 없이 똑같은 에러가 발생했다.

실패

 

다만 한가지 실마리를 찾을 수 있었다. 프론트 단에서 socket.io client를 설정할 때 io를 https://도메인/api로 설정했었는데 막상 네트워크에 보낸 요청을 보니 https://도메인/socket.io~ 이런식으로 되어있었다. 즉 /api라는 경로 자체가 무시당한 것이다.

근데 컴퓨터는 틀리는 일이 없기 때문에 내가 모르는 어떤 기능이 있는 것 이 확실하다고 생각했다.

그렇게 된다면 아예 443번 포트에서 바로 제공하는 것을 index.html이 아닌 백엔드 서버로 돌려버리면 https://도메인 자체는 index.html이 아닌 백엔드 서버가 되기 때문에 문제를 해결할 수 있지 않을까? 라는 생각이 들었다,

 

 실험 3. 443번 포트에 요청을 보내면 바로 백엔드 서버와 연동되게 하기 (소켓 서버 자체를 443번으로 줘버리기)

 마지막 아이디어였다. socket.io client에서 io = https://도메인/api로 설정했는데도 개발자도구 - 네트워크에서 https://도메인으로 나온다면 그냥 소켓 서버 자체를 https://도메인 <= 이렇게 설정하면 될 거라는 생각이 들었다. 그래서 예전에 했었던 기억을 살려서 443번 포트는 바로 백엔드 서버와 연결하고 거기서 미들웨어의 마지막에 res.sendFile로 index.html파일을 보냈다.

 

성공

은 했지만 사이트 속도가 진짜 겁나느려졌다. 이유에 대해 조금 생각해본 결과 다음과 같기 때문이 원인이 아닌가 싶다.

원래:     유저의 요청 -> 프론트 -> 백엔드 -> 소켓 -> 프론트 -> 유저

바뀐 후: 유저의 요청 -> 백엔드 -> sendFile(프론트) ->  백엔드 -> 소켓 -> 프론트 -> 유저

체감은 한 100배 느려진 것 같다... 

 

 

실험 4. 443번 포트를 어떻게든 두개를 써보자

호스트를 naiclover.shop(프론트)이랑 api.naiclover.shop(백) 이렇게 네임서버를 두개 설정하고 443 포트를 두번 쓰게 해봤다.

결과는 실험 3보다 get 요청은 원래정도 속도가 나오고 post의 경우 좀 느리긴 하지만 나쁘지 않은 수준까지 올라왔다.

ssl을 두개 써서 그런가 좀 애매한 결과가 나왔다. (물론 다른 인스턴스였다면 이런 문제는 없다.)

(호스트를 새로 만들었기 때문에 api.naiclover.shop에 대한 ssl 또한 sudo certbot --nginx -d api.naiclover.shop을 통해서 pem파일을 생성해줘야한다.)

이렇게 호스트 두개
https 주소로 들어갈 수는 있지만 보안연결이 되지 않았다고 뜬다.

 

그래도 https로 주소가 되기도 했고 속도도 나름 빨라졌으니 가설 4를 채택하기로 했다.

 

240423 기준 주의 요함이 사라지고 제대로된 https 연결이 된다!!!! (근데 소켓은 여전히 조금 느리다)