일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- Java 22
- Runtime Area
- docker
- 미니미프로젝트
- DB
- 완벽이해
- ComponentScan
- pair programming
- Self Descript Message
- Spring/JAVA 서적
- M:N
- 자식객체
- 스프링으로하는마이크로서비스구축
- RESAPI
- testdrivendevelopment
- Be
- Execution Engine
- TDD
- 도커
- KPT
- Solid
- hateoas
- 클린코드
- G1GC
- GC
- 트랜잭션 격리 수준
- ATDD
- java
- 마이크로서비스디자인패턴
- 부모객체
- Today
- Total
Programming Summary
[2023-06-01] EC2에서 Jupyter 노트북에 websocket 서버 만들기 본문
개요
local 환경에서 다음과 같이 Jupyter Notebooke과 연결을 해주었다.
> JupyterNoteBook
import asyncio
import websockets
import random
def randomVal():
return random.randrange(0, 2)
async def main():
event = asyncio.Event()
async with websockets.serve(echo, "localhost", 8765):
await event.wait() # 이벤트를 대기하도록 설정
async def echo(websocket, path):
async for message in websocket:
# 처리
my_list = message.split("\n")
my_sum = 0.0
for l in my_list:
val += randomVal();
my_sum += val
print("val : " + str(val))
await websocket.send(str(my_sum / len(my_list)))
print("success")
# 현재 실행 중인 이벤트 루프 가져오기
loop = asyncio.get_event_loop()
# 이벤트 루프에서 비동기 코드 실행
loop.create_task(main())
> Spring
package flash.flash.Controller;
import lombok.extern.slf4j.Slf4j;
import javax.websocket.*;
import java.io.IOException;
import java.net.URI;
@Slf4j
@ClientEndpoint
public class WebSocketClient {
@OnMessage
public void onMessage(String message, Session session) {
// 서버로부터 메시지를 수신할 때마다 실행되는 코드
// 받은 message를 분석하여 사용자 입력 값을 체크하는 코드 작성
float accuracy = Float.parseFloat(message);
//accuracy = 1- accuracy;
log.info("accuracy : " + accuracy);
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
try {
session = container.connectToServer(WebSocketClient.class, URI.create("ws://localhost:8080/dementia/result/save?accuracy=" + accuracy));
} catch(Exception e) {
//e.printStackTrace(); //throw e;
}
}
public void analysisSTT (String result) throws DeploymentException, IOException {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
try {
log.info("Toserver : " + result);
//ip 변경해야될 수도
Session session = container.connectToServer(WebSocketClient.class, URI.create("ws://localhost:8765"));
session.getBasicRemote().sendText(result); // 서버에 메시지 전송
} catch(Exception e) {
e.printStackTrace(); throw e;
}
}
}
localhost 에선 데이터를 통신 작동이 잘 되었는데 AWS EC2에 서버를 올리고 Docker를 통해 Jupyter NoteBook을 실행하니 통신이 안되는 문제가 발생했다. 이 문제를 해결하기 위해 다음과 같은 여러가지 해결방안을 모색하였다.
1) 방화벽
2) 보안 설정
3) 인바운드/아웃바운드
4) docker 방화벽
5) 서버 로그
6) 포트/IP 입력
그 결과 다음과 같은 과정을 통해 문제를 해결할 수 있었다.
해결 과정
1) EC2에 Jupyter Notebook 설치
다음 명령어를 이용해 docker의 Jupyter Notebook을 다운받고 백그라운드에서 실행시켜주었다.
docker run -e GRANT_SUDO=yes -d -p 8888:8888 -p 8765:8765 jupyter/scipy-notebook
백그라운드 환경에서 jupyter/scipy-notebook을 실행시켰다. 여기서 눈 여겨봐야할 점은 포트를 두개를 열어주는 것이다. 이는 후술하겠지만, 8888포트로 주피터 노트북에 접속을 8765포트로 통신을 하게 하기 위함이다.
2) 포트 열어주기
먼저 보안 그룹을 설정해주었다.
상세 인스턴스 하단의 보안 탭을 통해 보안 그룹에 접속할 수 있다.
그리고 인바운드 규칙 변경을 통해 규칙을 변경해준다. 인바운드는 해당 포트에 대한 요청을 받아들일 수 있게 방화벽을 열어주는 역할을 한다.
필자는 이렇게 4개의 포트(22제외)를 열어주었다.
그러나 이렇게 해서는 docker의 jupyter Notebook에서 데이터를 수신할 수 없었다. 왜일까? 해당 문제가 밤을 새며 방법을 찾아보게한 원인이었다.
이유는 docker 자체에도 방화벽이 있었기 때문이었다. 그 때문에 ec2만 인바운드 규칙을 설정할 것이 아니라, docker에서 port를 열어주는 추가 작업을 해주어야 했다. 필자는 위의 명령어를 통해 jupyter-notebook에 8888포트 외에도 8765포트도 열어주었다.
3) websockets.serve 주소 변경
이후 어느 host에서 요청이 오더라도 처리할 수 있게 websocket.serve 부분의 "localhost"를 "0.0.0.0"으로 변경해주었다.
import asyncio
import websockets
import random
def randomVal():
return random.randrange(0, 2)
async def main():
event = asyncio.Event()
async with websockets.serve(echo, "0.0.0.0", 8765):
await event.wait() # 이벤트를 대기하도록 설정
async def echo(websocket, path):
async for message in websocket:
# 처리
my_list = message.split("\n")
my_sum = 0.0
for l in my_list:
val += randomVal();
my_sum += val
print("val : " + str(val))
await websocket.send(str(my_sum / len(my_list)))
print("success")
# 현재 실행 중인 이벤트 루프 가져오기
loop = asyncio.get_event_loop()
# 이벤트 루프에서 비동기 코드 실행
loop.create_task(main())
4) telnet localhost 8765로 연결되는지 확인해보기
이제 telnet으로 연결이 되나 확인해보자.
telnet을 통해 잠시 연결되는 모습을 볼 수 있다.
느낀점
인바운드 규칙도 살펴보고 내 컴퓨터 인바운드 규칙까지도 살펴봤는데 답을 구할 수 없었다. 그래도 계속 코드를 유심히 보다보니 의심되는 부분을 발견하여 수정할 수 있어 다행이었다.
'2022-23 Final Project' 카테고리의 다른 글
[2023-05-22] Docker를 활용한 서버 이미지 빌드 및 AWS에 배포 (0) | 2023.05.22 |
---|---|
[2023-04-02] Spring Security 적용 실패 (0) | 2023.04.02 |
[2023-04-02] ipynb파일과 spring java파일 소통하기 (0) | 2023.04.02 |
[2023-03-17] JPA Buddy 오류 해결 (0) | 2023.03.17 |
[2023-03-17] ModelAttribute npe 해결 (0) | 2023.03.17 |