저번 포스팅에서 minecraft서버 운영에 대한 전반적인 진행 사항들을 모두 정리했었다. 따라서 이번 포스팅부터는 전체적인 진행했던 내용, 내 진행사항 위주로만 작성해보겠다.
새해이다 보니 회의는 12월23일 이후 한주 건너뛰고 1월 3일인 오늘 진행했다. 팀원 한 명은 게임 내부 설계, 한 명은 인프라 세팅, 나는 여전히 데이터 분석 및 웹사이트 시각화 파트를 진행했다.
서버 보안 설정 , 본서버 세팅등이 진행되었다. 서버를 담당하는 팀원이 이사를 가야했기 때문에 서버를 모두 다시 세팅했다. 이번에 세팅한 서버가 본서버가 될 것 같다.
게임 내부에는 본격적으로 맵을 만들기 시작했다. 실시간으로 내 위치를 알려주는 3D맵 웹사이트 만들고 , 맵 컨셉에 맞는 설계를 통해 실제 리소스와,맵을 배치했다. 이 부분은 완성이 되면 다음 포스팅때 자세하게 설명하도록 하겠다.
지난주보다 나름 진전되었다. 우선 지난주에 하지 못했던 그래프를 그리는 것에 성공했으며, ubuntu에서 웹서버실행, view 테이블 구조잡기, trigger사용 등 다양하게 시도했다.
위 사진은 지난번 라인 그래프 상태이다. 내가 원하는 그래프는 x축 날짜별로 last_login_count(즉 마지막으로 로그인한 사람 수) , register_login_count(즉 득록자수)를 동시에 y축에 나타나는 것이다.
하지만 지난 포스팅 때 두 개가 동시에 그려지지 않았고, 실시간 반영도 되지 않았다. 오류 났던 이유는 group을 한 번만 사용해서였다. 따라서 이 부분은 db에서 테이블을 가져오는 쿼리에서 한번 , javascripts 집계 부분에서 한번 총 2번 사용해서 해결했다.
또한, 게임에서 쌓이는 log는 다양한 db 형태로 저장되므로 db 자체가 여러 개이다. 각 db마다 여러 개의 테이블이 존재하고 다양한 시도를 하려는 쿼리 테스트 과정이 필요하다. 그러나 잘못하다 원본 테이블에 손상이라도 가면 매우 골치 아파진다. 따라서 원하는 대로 가공 및 테스트가 자유로운 view를 활용해 하는 방법을 생각했다.
view란 무엇인가? view는 말 그대로 가상의 테이블이다. 원본 데이터 다양한 db에서 원하는 데이터만 가지고 와 만들어주면 복잡한 쿼리를 거치지 않아도 손쉽게 사용 가능하다.
query 코드는 한눈에 보기 편하게 mysql workbench를 활용했고
먼저 , db_view 이름의 view를 관리하는 db를 만들고 총 3가지로 나눠서 view를 설계했다.
1. player_info_view
-> 3개의 테이블을 join시켜 user의 정보만 모아놨으며 money,bankmoney , last_login 등이 있다.
2. towny_info_view
-> 3개의 테이블을 join시켜 유저 외 정보를 모아놨으며 추후 더 추가할 예정이다
3. sumuser
-> 집계를 위한 view로 위와 같이 날짜별로 event_type이 나온다. 나중에 js에서 집계함수를 써서 그래프를 그리는 용도로 사용된다. 집계함수 view도 마찬가지로 추후에 더 만들예정이다.
이후 과정은 지난 번과 비슷하다. 먼저, 비동기식으로 만들었던 views를 불러오는 함수를 정의한다. get_data_from_db2와 같은 경우, 위에서 만든 집계를 위한 테이블에서 본격적으로 집계를 해준다. 즉, 날짜와 event_type별로 몇 명씩인지 나오는 테이블을 불러올 수 있다.
get_data_from_db3와 같은 경우, 실제 x축으로 사용되는 dates를 str으로 바꿔서 가져왔다. 이유는 나중에 JavaScript를 활용해 웹에 그래프를 그릴 때 datetime 형식이면 데이터가 전송되는 과정에서 아주 애먹는다. 그래서 str 형식으로 바꿔버렸다.
이후, 그래프를 그리는 데 성공했다. 하지만 팀원 한 명이 'last_login_count는 데이터 변동에 따라 실시간으로 안 바뀌고, 그 날에 한 번만 집계되었으면 좋겠다'라는 의견을 주었다. 듣고 보니 last_login_count는 자주 바뀔 필요가 없었다. 그래서 구상한 방법은 trigger를 활용하는 것이다.
Trigger는 일종의 이벤트를 예약하는 개념으로, 특정 조건에 따라 자동으로 작업을 수행하는 데 유용하게 사용된다. 나는 trigger를 생성하여 집계 주기 이벤트를 만들고 싶었다.
쿼리를 설명하자면, 먼저 빈 'tri_table' 테이블을 생성한다. 그리고 앞서 만든 sumuser 뷰에서 event_type에 따라 카운트되어 집계된 값을 'tri_table' 빈 테이블에 삽입하는 과정을 30분 주기로 실행시켜주는 'update_daily_stats' trigger를 생성한다. 이렇게 하면 30분마다 트리거가 실행되면서 'tri_table' 테이블에 집계된 값들이 업데이트된다.
이렇게 event가 잘 생성된것을 확인 할 수 있고
이벤트가 발생해서 생기는 'tri_table'모습이다.
앞서 간단하게 언급했지만 tri_table을 만든 이유는 register_count와 login_count를 실시간 주기를 분리하기 위해서였다. 그래서 떠오르는 방법은 "데이터를 분리해버리면 되지 않을까?" 였다. 즉, y축 register_count는 data_from_db2로 그리고, login_count는 data_from_db3로 그리는 방법을 생각했다.
두 개의 DB를 10초 주기로 동시에 불러와도 trigger event로 인해 tri_table에 30분마다 데이터가 쌓이므로 업데이트는 30분 간격으로 이루어질 것이다. 아직 제대로 테스트해보지 못했지만 만약 원하는 대로 잘 작동된다면 30분을 24시간으로 바꾸기만 하면 될 것이다. 또한 그래프를 그릴 때 이벤트를 분리하기 위해 데이터를 불러오면서 type을 지정해줬다.
위 코드는 본격적으로 그래프를 그리는 코드이다. 앞서 지정한 타입에 따라 그래프를 그린다. 이 부분은 gpt에 도움을 많이 받았다. register_count의경우 data_from_db2로의 데이터로 , login_count는 data_from_db3로 y축을 구성하는 내용이다. 처음에 시도했을떄는 date type지정 사전에 안 하고 했었는데 그래프가 안 그려져서 정말 어려웠다 ...
위와 같이 원하는 그래프가 잘 그려진 것을 확인 할 수 있다. 날이 지나면 추가 테스트를 해볼 예정이다. 위에 db는 1월 3일인데 그래프 x축은 12월인 이유는 인프라를 하면서 db서버를 오늘 새로 만들었다. 따라서 위 그래프는 전 db를 활용해 그렸다. 과정은 모두 동일하다.
다음은 해당 fast api환경을 ubuntu 환경에서 작동하게 하는 것을 시도했다. 이유는 window는 서버를 안정적으로 가동하는데 제한이 있다고 판단했고, 인프라 및 서버를 담당하는 팀원에게 전달해 주기 위해 ubuntu 환경에서 작동되는것을 만들고 싶었다.
Ubuntu는 커뮤니티에 의해 개발되고 유지되는 리눅스 기반 오픈 소스 운영 체제이다. Ubuntu 공식 웹사이트에서 다운받아 이것저것 선택해 설치하는 방법이 있지만 나는 mircrostore에서 ubuntu 20.04.6 LTS 설치해서 만들었다. 일부 제한사항이 있지만 ubuntu를 처음 사용하는 나에게는 편한게 최고였다..
일단 설치하고 실행하자마자 오류가 났다. 구글링을 통해 찾아보니 다양한 방법이 있어 시도해 보았지만 다 안되었다. 그러다 마지막 윈도우 업데이트가 안 돼서 그럴 수 있다는 글을 보고 window10 업데이트를했더니 오류가 사라졌다 .. 젠장 업데이트는 미리미리 하자.
일단 처음이라 모든게 어려웠다. window환경이랑 다른 명령어 , 파일구조등등 머리를 많이 박았다. 결론적으로 구현하고 싶은 것은 컴퓨터가 부팅되면 Ubuntu 환경에서 웹 서버가 작동되도록 하는 것이었따. 하지만 웹을 작동시키기 위한 패키지가 담긴 python venv 가상환경과 웹을 실행하는 python코드가 담긴 파일 모두 windows에 있었다.
팀원이 조금 아이디어를 주었다. ubuntu-20.4 etc/systemd/system은 서비스관리를 위한 파일을 포함하는 디렉터리인데 여기에 '서비스이름.service' 파일을 vi,vim등으로 만들고 거기에 웹서비스를 가동하는 scripts를 넣는것이다. 참고로 vi,vim 텍스트 편집기를 생성하는것이다 . 즉 sudo /etc/systemd/system/fa.service 이렇게 fa.service를 만들고 거기에 가동하는 scirpts를 넣는다.
흐름은 간단해 보이는데 위와 아주아주 비슷하지만 다른 많은 오류들을 만나고 가상환경도 여러번 갈아 엎고 맨탈이 나갔다.. 이래서 인프라 하는 분들은 대단하다고 생각이 든다
여러 시도를 해보다가 결국 경로 문제였다는점을 깨달았다. 내 windows에있는 파일 경로를 참조하려면 /mnt/c ~ 이렇게 해줘야 했었다. 드디어 my가상환경을 활성화 시키고 fast api 웹인 dbjs.py 를 uvicorn을 활용해 서버를 열었다. 역시 컴퓨터는 잘못이없다.
이후 부팅되면 자동으로 실행되게 하기위해 'sudo systemctl daemon-reload'으로 변경된 설정을 적용하고 'sudo systemctl enable fa.service'로 서비스 부팅시 자동으로 실행되게 한다.
localhost에서 간단하게 진행했지만 잘 되는것을 확인 할 수있다.
우선, db서버 및 게임 메인 서버는 sentos환경에서 작동한다. 따라서 ubuntu에서는 되었지만 sentos환경에서도 똑같이 잘되도록 해야한다.
또한, 팀원이 게임 내부 맵,리소스,기능 추가 작업들이 어느 정도 마무리 되면 이제 본격적으로 게임에 들어가 log를 쌓아볼 예정이다. towny db에만 칼럼이 몇백개다.. 이 쌓인 log를 가지고 새로운 시각화 구현 , 웹사이트 최적화 , log분석등을 앞으로 더 수행할 것 같다.
프로젝트를 하면서 매번 배우는 게 많은 것 같다. 최근 sqld자격증을 공부하면서 이론상으로만 접했던 trigger, view기능을 직접 사용해 볼 수도 있었고 , 인프라에 핵심인 리눅스도 다뤄볼 수 있었다. 앞으로도 발전가능성은 무궁무진 하다고 생각한다. 원활한 게임 서버를 만드는 그날까지 파이팅 !