platanus-kr / plata-anywhere-chat

Spring WebFlux Reactive WebSocket Backend application
15 stars 1 forks source link

application: 최초 배포 #27

Closed platanus-kr closed 1 year ago

platanus-kr commented 1 year ago

실제 인스턴스 배포

로컬에서 테스트용도로만 사용한 것을 데모용으로 실제 서버에 배치해보는 티켓

시작 전 생각 했던 것

1) 예상

그냥 프로파일만 잘 찍어서 보내면 되는거 아닌가..?
이미 로컬 테스트부터 standalone mode, kafka mode, production mode 다 나눠놨는데..

2) 예상과 달랐던 점

wss 바인딩

자연스럽게 web모듈쪽에 SSL 인증서를 붙이고 일단 message랑 websocket 통신을 해야하니 주소만 어거지로 붙여놓고 서버를 올리니 CORS 는 둘째치고 무수히 많은 mixed contents 오류가 나를 맞이한다. plain http와 https를 섞어서 쓸 수 없는 크롬의 정책이 올라온지 꽤 됐는데 막상 생각해보니 ws:// 역시 http로 부터 시작되는 파생 프로토콜 아니였나? 그래서 일단 SSL 인증서를 올리긴 해야하는데..

생각해보니 nginx에서 https 이외에 다른 프로토콜에 SSL 인증서를 붙여볼 일이 없었다. 어떻게 하나 찾아보니 스프링의 WebFilter에서 ws:// 업그레이드를 인지하듯 nginx에서도 ws에 대한 업그레이드 네고를 인식하고 포워드 하는데 활용 할 수 있는듯 하다.

CORS

다음으로 예상되는 문제가 이건데.. 4월에 프로토타입 만들어서 노트북으로 시연 했을때도 이 문제때문에 외부에서 접근할때 CORS 이슈가 있었다. 어쨌든 현재는 message 서비스가 밖으로 노출되어 있으므로 CORS를 서버에서 허용해 줄 필요가 있음.

3) 정말로 필요했던 것

어디선가 도메인을 미리 지정해줘야함

템플릿에 미리 뷰를 내려줘야 하는 주소를 위한 팩토리

그런데 이쯤되면 진짜 ws 서버를 외부에 노출하는게 맞나 싶음

그럼에도 불구하고 이거 아니면 방법이 없긴함

이 티켓에서 실제로 한 것

application.yml에 미리 도메인 지정

환경 간 URL 표현이 다르고, localhost의 경우 고정된 값이며, 로컬에서 실행할 경우 환경변수를 강제 할 수 없기 때문에 default 프로파일에서 참고할 property와 그 외의 환경에서 참고할 property를 구분함.

환경별 주소 표현 차이로 인한 URL 제네레이터

production에서는 SSL 인증서를 사용한 보안 통신을 활용하기 때문에 http://https://뿐만 아니라 ws://wss://에 대한 주소 팩토리를 추가함.

이것이 팩토리라는 표현이 옳은지는 모르겠으나 Thymeleaf 템플릿에 직접 WebSocket서버를 바라보고 있어 URL 을 지정할 필요가 있기 때문에, 백엔드에서 주소를 완성시켜 뷰로 내려주는 방식을 채택했다.

게이트웨이에 wss 리버스 프록시 및 프록시 타임아웃 설정

두 WAS 앞에 정적 nignx 하나가 리버스 프록시 역할로 붙어있는데 http에 SSL 인증서를 붙이면 mixed content 문제를 해결하기 위해 ws도 SSL인증서를 붙여줘야 한다. wss를 개통시켜본적은 처음이였지만 기존처럼 https를 개통하고 뒤에 upgrade 키워드를 location에 붙여주면 된다.

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Accept-Encoding "";

이후 1분마다 WebSocket연결이 끊어지는 문제가 있어 대충 지나가는 길목마다 keepalive 설정을 해주면 되겠지 헀는데 nginx는 웹 뿐만 아니라 TCP를 처리하는 서버로써 WebSocket 업그레이드 부분에 아래 설정을 넣어주면 해결 된다.

proxy_connect_timeout 7d;
proxy_read_timeout 7d;
proxy_send_timeout 7d;

CORS 다시 지정

다시 맞이한 CORS문제는 별도 도메인을 사용한다면 꼭 부딪히는 문제인데 템플릿에 내려주기 위한 URL 팩토리를 활용해 CORS를 허용할 도메인을 프로파일에 따라 동적으로 지정할 수 있게 만들었다.

이부분은 SpringSecurity와 필터쪽 두군데 다 해줘야 하는데 기회가 되면 여기도 교통정리가 필요해보임.

OAuth2 로 인한 엔티티 정책 변경

각 OAuth2 벤더마다 제공하는 사용자 정보가 다르다 보니 발생한 문제인데 지금 들어가있는 GitHub의 경우 사용자 email을 공개하지 않는것이 기본값이다. 그래서 급하게 더미 email을 넣도록 수정했으나 엔티티에 unique가 걸려있어 결국 이메일 필드에 unique를 제거해야만 했다.

이후 구현할 내용