Login Server

2022. 5. 19. 18:41게임서버/namespace univ_dev

320x100
안녕하세요 대학생개발자입니다.

오랜만에 제 원래 전공으로 돌아왔습니다.

오늘은 오랜만에 서버에 대한 포스팅으로 돌아왔는데요.

 

이전까지는 데이터베이스에 대한 설치와 간단한 쿼리를 익히는게 시간을 쓰느라 포스팅에 지연이 있었습니다.

 

그럼 시작하도록 하겠습니다.

 

우선 이전까지는 채팅서버를 만들었었습니다.

일반적으로 우리가 아는 채팅서버라는건 로그인이라는 과정을 통해서 인증을 받은 유저들에 한해서 접근이 가능하도록 설계가 되어있을겁니다.

생각해보면 너무나도 당연한 얘기입니다.

로그인도 하지않은 유저가 채팅서버에 들어와서 채팅 메시지를 보낸다는건 상식적으로 봤을때 정상적으로 보이지 않는 것 같습니다.

반대의 경우도 마찬가지입니다.

로그인도 안한 유저가 로그인이 되어있는 유저의 채팅을 받아 본다는것도 말이안되는건 똑같은 상황입니다.

 

하지만 이전에 만들었었던 채팅서버의 경우에는 로그인 서버가 따로 존재하지 않았습니다.

그렇기 때문에 따로 로그인이라는 과정은 없었고 그냥 들어와서 채팅을 하고 나가는 구조로 되어있었습니다.

그리고 이부분은 일반적인 관점에서 봤을때 상식적이지 않습니다.

 

로그인서버 왜 필요한지 가장 큰 틀부터 말씀드리겠습니다.

이제부터는 로그인 서버를 거쳐온 세션만이 채팅을 할 수 있는 구조로 만들것입니다.

그리고 이는 일반적인 관점에서의 상식적인 모습으로 보여지기도 합니다.

그러기 위해서는 당연하게도 로그인 서버라는 존재가 필요할것 같습니다.

 

로그인 서버가 왜 필요합니까?

그럼 우선 로그인 서버라는게 왜 필요한지를 먼저 봐야할 것 같습니다.

예전 글에서 말씀을 드린 기억이 있습니다.

요즘 나오는 cpu들은 상당히 고사양입니다.

서버에서 사용하기에 충분할 정도의 코어 갯수를 가지고 있다는 점 또한 분산을 안하는 이유중 하나입니다.

그럼에도 왜 우리는 로그인 서버를 분산 처리를 해야하는가 입니다.

 

이유는 단순합니다.

유저의 로그인 요청을 처리하는데 필요한 작업인 DB접근이 너무 느리기 때문입니다.

 

C++ 코드로 작성되어있는 게임 서버는 초당 몇십만, 몇백만건의 패킷을 처리할 수 있습니다.

하지만 DB의 경우에는 많아도 일반적으로 몇백건 정도의 쿼리를 수행합니다.

아무리 DB의 성능을 개선하고 코드를 잘짠다고 해도 분명 게임 서버의 처리 속도에 비해 현저히 느린것은 명백합니다.

그렇기 때문에 아무리 좋은 성능의 하드웨어를 사용한다고해도 DB자체가 느리기 때문에 분명 한계에 도달합니다.

 

만약 모든 클라이언트의 로그인 요청이 올 때마다 게임서버에 ms단위의 고부하 작업을 걸게 된다면 서버는 엄청난 부담을 느끼게 될겁니다.

그와 동시에 당연히도 나머지 로직에 대한 처리 능률도 현저히 떨어질 겁니다.

 

간단히 생각해본다면 단순합니다.

하나의 클라이언트의 로그인을 처리하는데 DB접근 포함 약 1ms정도가 들어간다고 가정해보겠습니다.

이럴 경우 우리는 초당 1000건 이상의 로그인을 수행할 수 없습니다.

물론 동시에 들어온 다른 로직 또한 저 엄청난 시간에 의해서 딜레이가 걸리게 될것입니다.

 

물론 한명의 클라이언트에게 1ms라고 한다면 그렇게 큰 느낌으로 다가오지 않을 수 있습니다.

하지만 mmo와 같은 대형 게임서버는 5천이상의 클라이언트를 상정해둔 상태로 서비스가 된다는 점을 고려해야합니다.

 

5천명의 유저를 통한 쿼리가 한건당 1ms정도만 나와도 5초 이상의 긴 시간이 소모되는 아주 무거운 작업이 되는겁니다.

그리고 이런 무거운 작업을 하는 동안 당연히 서버의 로직과 다른 메시지들은 제대로 처리되지 못할겁니다.

 

물론 게임서버 또한 DB를 사용하게 되긴 할겁니다.

거래와 아이템 획득 퀘스트 완료등 이런 이벤트는 게임서버를 통해서 들어오게 될 것이고 이는 게임서버가 즉각 반영을 해줘야 하는 부분입니다.(물론 100% 실시간이라고 할수는 없습니다.)

이 부분도 매우 느리기 때문에 채널 개념을 적용해서 성능 개선을 할 수 있습니다.

추가로 db에 대한 부자 자체를 줄이는 방법으로 db자체의 분산을 생각해 볼 수도있을 것 같습니다.

하지만 이 부분은 나중에 게임 서버를 다룰 때 언급하도록 하겠습니다.

 

지금은 로그인 서버를 제외하면 채팅서버는 DB에 접근할 일이 없다 라고 가정하고 가겠습니다.

 

 

알겠다구요. 로그인서버는 분산되어야하는거 그럼 로그인 서버는 어떻게 작동하는건가요?

우선 로그인서버는 어떤일을 해야되는지부터 고민을 해봐야하는것 같습니다.

 

일반적으로 로그인 서버라고하면 ID와 PW를 확인해서 일종의 입장 표를 주는 서버라고 알고계십니다.

맞습니다 결국 이게 로그인의 과정이기 떄문입니다.

처음으로 위와같은 구조입니다.

클라이언트가 로그인을 요청하면 로그인 서버는 클라이언트가 요청한 ID와 PW를 DB에서 확인해 유효한 값인지 확인을 하고 그에 따른 인증키(토큰키)를 발급합니다.

 

유효한 인증키가 발급이 되었다면 먼저 그 유저의 고유번호와 인증키를 채팅 서버로 보낼겁니다.

그후 인증키정보와 다음 서버의 아이피 포트를 클라이언트에게 제공할 것입니다.

그리고 클라이언트는 그 인증키와 함께 주어진 채팅서버의 IP(도메인), Port를 이용해 채팅서버에 접근을 시도할겁니다.

 

그리고 채팅서버는 받은 정보를 기억해뒀다가 클라이언트가 보내는 인증키와 비교하는 일련의 작업을 마치면 로그인이 완료되는 과정입니다.

 

언뜻보기에 정말 간결하고 깔끔해 보입니다.

하지만 이건 로그인 서버와 DB가 우리 회사에서 관리하는 서버일 경우의 일입니다.

 

대부분의 게임회사는 위의 그림처럼 되어있지 않죠.

아직도 완성은 아니지만 점점 괜찮은 모양으로 발전해 나가고 있습니다.

갑자기 메모리 DB라는게 생겼습니다.

대부분의 게임회사들은 게임 회사가 직접 퍼블리싱을 하는게 아니라 다른 퍼블리셔를 통해서 퍼블리싱을 합니다.

 

그리고 로그인은 퍼블리셔의 웹에서 처리될겁니다.

그럼 퍼블리셔가 과연 우리 서버로 직접 이 메시지를 날려주느냐 입니다.

아뇨... 절대 그러지 않을겁니다.

퍼블리셔가 우리 서버로 직접 뭔가를 해주는 일은 없을겁니다.

대신에 퍼블리셔가 가진 메모리 DB에올려놓고 Platform API를 제공하고 그 API를 통해서 가져갈 수 있게 할겁니다.

그건 다음그림을 보면서 말씀드리겠습니다.

 

위와 같은 그림이 나오게 될텐데요.

DB와 로그인서버는 퍼블리셔의 영역이 되어버렸습니다.

그리고 메모리 DB라는것도 퍼블리셔가 제공하는 메모리 DB이며 우리는 API를 통해서만 접근가능합니다.

그리고 이 API는 상당히 느립니다.

 

그럼 우리가 이렇게 할 것인가를 물어본다면 그렇지 않습니다.

그러기 위해서는 아주 처음, 로그인 서버라는게 나오게된 배경으로 돌아갈 필요가 있을것 같습니다.

 

가장 근본적인 이유는 DB가 너무 느리다입니다.

우리가 채팅서버에서 DB 접근을 하지 않으려고 했던 이유는 당연 성능때문입니다.

위에서 언급했듯 채팅서버의 속도는 DB에 비해서 아주 빠를겁니다.

 

이 단점을 극복하고자 우리는 로그인 서버라는걸 만들었는데 퍼블리셔가 제공하는 메모리 DB를 사용하기 위한 작업또한 만만치 않게 서버에 부담이 되는 작업입니다.

 

이런 부하가 생겼기 때문에 우리는 분산을 통해서 이 부하를 줄여줬었습니다.

이 논리를 그대로 다시 적용시키면 새로운 그림이 나올 것 같습니다.

결국 제가 말하려는건 퍼블리셔가 제공하는 메모리 DB에 접근하는 로그인 서버가 하나 나와주면 좋을 것 같다는 겁니다.

그림이 꽤나 많이 복잡해졌습니다..

 

아직 부족한점이 많겠지만 제 선에서는 이정도면 최선을 다해서 구조를 그렸다고 생각합니다.

클라이언트에게 인증키가 도착한다는 점은 동일합니다.

 

여기서 이전 같았으면 채팅서버로 바로 연결을 했겠습니다만 이제는 다릅니다.

우리의 로그인서버로 한번더 진입을 해서 인증키를 비교하는 로직을 거치게 될겁니다.

퍼블리셔가 제공하는 저 메모리 DB또한 매우 느리기 때문입니다.

 

이렇게 한다면 우리가 직접 DB나 플랫폼API와 같은 상당한 부하가 걸리는 작업을 직접 채팅서버나 게임서버가 접근하지 않고도 충분히 처리 할 수 있을겁니다.

아... 로그인서버는 안느려지냐고 하신다면...

로그인에서 몇초 기다린다고 화내는 사람 없습니다.

하지만 게임서버에서 몇초 기다리게 된다면 많은 유저들이 불만을 가질겁니다.

 

다음 작업에 대한 예정

우선 추후에 다시 말씀을 드릴거지만 로그인 저 메모리 DB연동은 Redis를 이용할것입니다.

DB의 경우에는 mysql을 쓰고있는데 사실상... 지금 상황에서는 큰 역할은 하지 못하고 로그인서버에 부하를 줘서 느려지게 하는것이 주된 목적입니다.

 

 

오늘도 긴글 읽어주셔서 감사합니다.

다음에 더 좋은글로 돌아오도록 하겠습니다.

그럼 안녕히계세요.

320x100

'게임서버 > namespace univ_dev' 카테고리의 다른 글

Chatting Server(Multi Thread)  (0) 2022.05.04
NetServer(Chatting Server)  (0) 2022.05.03
LockFreeStack Trouble Shooting  (2) 2022.03.28
DumpClass  (0) 2022.03.28
LockFree  (0) 2022.03.22