AWS EC2랑 집에 있는 맥미니 서버로 같이 사용하기

     

 

현재 AWS에서 EC2와 RDS를 사용해서 사이드 프로젝트 앱 서버를 운영 중인데 돈이 한 달에 15만 원 정도 나온다 ㅎㅎ

 

RDS가 한 7만 원 나오고 EC2가 한 7만 원 나오고 기타 세금이 만원인데 서버도 고급 서버도 아니고 후진 서버인데 돈이 너무 많이 나가고 있다 ㅠㅠ 개빡..

 

사용자가 점점 늘어나고 추가 기능들을 넣고 싶은데 서버가 느려서 못하고 있는 상황.. 그렇다고 서버를 늘리면 돈이 너무 많이 나가서 집에 있는 맥미니를 서버로 사용할 수 있으려나 생각해봄..

 

일단 지금 구조가 아래와 같은 구조인데

 

 

ROUTE53으로 들어오면 ALB가 EC2에 로드밸런싱을 해주는데 사실 로드밸런싱의 의미가 없긴 하다. ALB의 역할은 SSL 터미네이터 역할 ㅎㅎ 그리고 EC2가 지금 t3a.medium 한대라서 타깃그룹이 의미가 없다.

 

그래서 내가 원하는 방향은 요런 건데...

 

내가 생각한 구조

근대 아쉽게도 AWS에 있는 ALB에서는 AWS내에 인스턴스만 target group으로 지정이 가능하다. ip로 지정하는 방법도 있긴 한데 그것도 같은 VPC에 있는(같은 AWS 네트워크 상에 있는) 서버만 가능하기 때문에 실제로는 저 구조가 불가능하다.

 

그래서 내가 떠올린 것은 nginx를 이용한 로드밸런싱을 만들기인데, 일단 현재 ec2에는 docker를 이용해서 nginx와 web app이 구동 중인 상황이다. 

요런 구조. 도커 귀엽누

그래서 내가 생각한 방법은 AWS EC2에 있는 docker NGINX에서 같은 EC2에 있는 Django와 맥미니를 로드밸런싱 하는 구조로 만드는 것이다. 

 

요런 너낌

 

일단 nginx config를 건드려 볼 텐데 운영을 바로 건드릴 순 없으니 베타에서 진행했다. (나름 베타 서버도 있는 ㅋㅋㅋ)

 

nginx에 config파일은 두 개를 쓰는데 하나는 nginx.conf고 다른 하나는 nginx-app.conf이다. nginx.conf는 리얼 nginx 컨피그고 nginx-app.conf는 sites-available폴더에 보통 넣어놓는 config파일이다. 여기서 nginx-app.conf에 보면 실제로 애플리케이션 서버 주소가 적혀있는데 요기에 다른 서버를 추가하면 로드밸런싱을 할 수 있다.

 

docker로 만들어진 nginx에 기본 파일들
nginx-app.conf

지금은 upstream에 uwsgi라고 해서 unix소켓을 사용하는 server가 하나 들어있는데 여기에 다른 server를 추가하고 로드밸런싱 알고리즘을 적으면 된다. 로드밸런싱 알고리즘은 least_conn을 사용할 거다. 적지 않으면 디폴트로 라운드 로빈으로 적용된다. least_conn은 쉽게 설명하면 일 빨리빨리 하는 서버로 더 많은 요청을 보내는 것인데, 라운드 로빈을 안 하는 이유는 맥미니가 사양이 더 높기 때문에 맥미니 쪽으로 더 많이 가게 하려고 least_conn으로 설정해봤다.

 

요롷게

정말 이렇게만 하면 되려나? 싶을 정도로 심플,,, 과연 될지 한번 실행해보겠다.

 

안되네? ㅎㅎ

 

기존에 nginx -> uwsgi로 보낼 때 포맷이 nginx -> nginx로 보내는 거에는 안 먹히는지 데이터가 이동하는 것은 보이는데 응답이 제대로 안 오고 400 에러가 뜬다. 일단 맥미니로 데이터가 이동하는 것까지는 확인했고, 맥미니에 nginx가 아니라 uwsgi만 띄워서 확인해봐야겠다.

 

요런구조

그러니까 요런 구조인 것이다. 물론 nginx -> nginx 구조가 이상해서 결론적으로는 이렇게 하려고 했는데 ㅎㅎ nginx->nginx가 잘 안 돼서 결국 이 구조로 왔다. ㄱㅇㄷ!!

 

맥미니에서 nginx를 띄우지 않고 uwsgi만 띄우기를 해보자. 그럼 uwsgi를 소켓으로 사용하고 있었는데 네트워크를 사용하도록 바꿔야 한다. 가물가물해서 좀 찾아보고...

 

[uwsgi]
http = :8080
# socket = xxxx.sock

 

uwsgi.ini에서 원래는 nginx와 함께 unix소켓으로 통신하기 위해 socket이라는 옵션을 주었는데 요걸 지우고 http로 바꾸면 될 것 같다. 8080 포트 사용하기 위해 8080 적어줬다. 아까 nginx에서 :80 포트로 해줬는데 8080으로 바꾸는 거 잊지 말자

 

자 이제 다시 nginx를 통해서 잘 가는지 해보자

 

안된다...

 

왜 안되는지 이것저것 찾아보자..

 

일단은 nginx-> 맥미니로 자꾸 499 타임아웃이 난다.

그래서 nginx에서 uwsgi_pass로 되어있는 부분을 proxy_pass로 바꾸니까 된다.

uwsgi_pass와 proxy_pass의 차이점을 보면 uwsgi 프로토콜을 쓸지 http를 쓸지의 차이점이라고 한다.

 

음?? 뭔가 띵한 게,, 아까 나는 맥미니에서 uwsgi.ini를 http로 바꿔줬다. 원래는 socket이었는데, socker이 unix소켓 옵션만 있는 줄 알고 바꿨는데 socket으로 TCP 소켓도 할 수 있더라 ㅎㅎㅎ 다시 uwsgi 옵션을 바꿔보자

 

 

[uwsgi]
socket = 0.0.0.0:8080

 

매우 삽질을 한 끝에 uwsgi.ini를 위와 같이 바꾸고 정상적으로 실행되는 것을 확인했다.

 

이제 로드밸런싱 알고리즘을 한번 확인해보기 위해 least_conn을 해보고 라운드 로빈도 해보고 weight도 바꿔보고 해 보자

 

일단은 맥미니 쪽에 웨이트 2를 주고 최대 실패 5회면 죽은 걸로 간주하도록 만들었다. 로드밸런싱 옵션이 라운드 로빈이기 때문에 ec2 한번 맥미니 두 번 찌를 것으로 예상된다.

 

두번 찌를 때 한 번찌른다.

 라운드 로빈은 잘 되는 것 같은데 뭔가 least_conn으로 해봤자 세션 연결에 따른 로드밸런싱이기 때문에 성능에 따라 차별화된 로드밸런싱은 못해줄 것 같다. %로 관리하면 몰라도.. 그냥 라운드 로빈 + 웨이트가 좋을 듯.

 

일단 이렇게 운영에 반영해 놓고 잘 돌아가는지 한번 확인해봐야겠다.

 

아 그전에 서버 내렸을 때 nginx가 자동으로 서버를 죽은 지 판단해보자

오.. 서버가 내려가면 nginx가 알아서 로드밸런싱에서 뺀다.

헬스체크를 안 하는 것처럼 보였는데 네트워크 연결이 끊기면 알아서 빼는 것 같다.

 

ec2에 있는 걸 내리고 맥미니에 있는 거만 올려도 알아서 맥미니로만 보낸다. 좋네...

 

근데 운영 앱이랑 비교했을 때 응답이 살짝 느린 것 같은데,, nginx 쪽이 느려서 그런 걸 수도 있으니까 한번 반영해보고 정말 느린지 봐야겠다. 아마 맥미니를 추가하고 맥미니 쪽으로 호출이 느리다면 서버 성능보다는 네트워크가 느려서 그럴 수도 있다. 기본적으로 nginx(ec2)-django(ec2)가 같은 서버에 있던 게 nginx(ec2) ------> django(맥미니) 요롷게 되니까 aws 밖으로 나갔다가 다시 들어가는 구조니까.

 

어라.. 생각해보니 그러면 요금 차징이 두배로 되네... ㅋㅋㅋㅋㅋ aws에 들어가는 패킷은 공짜지만 나가는 패킷은 돈이 들기 때문에 ec2->맥미니로 갈 때 돈이 든다. ㅂㄷㅂㄷ 

 

맥미니를 메인으로 하던지 해야 돈이 조금 나갈 것 같다.

 

일단 운영에 적용해보자 돈 얼마 올라가나 ㅋㅋㅋ

 

아니.. 운영에 적용해보니 느리다 ㅡㅡ 

 

다시 원복...

 

맥미니가 메인이 아닌 이상 느릴 듯싶다...

 

 

정리

 

- uwsgi.ini에서 socket방식은 무조건 unix 파일 소켓이 아니라 tcp소켓도 된다.

- nginx 로드밸런싱은 간단하지만 헬스 체크하려면 nginx plus 있어야 한다.

- aws ec2와 자체 서버(맥미니나 기타 등등) 같이 쓰려면 시작점이 자체 서버여야 과금이 덜된다.

- ec2내에서 생각보다 네트워크 속도가 빠르다. 맥미니가 생각보다 느리다.

반응형

댓글

Designed by JB FACTORY