• 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    미해결

클라가 죽는 문제

21.03.18 14:16 작성 조회수 253

1

안녕하세요

드디어 완강을 하고 프로젝트를 이리저리 만저보고 있는중입니다.

좋은 강의 감사드립니다.

프로젝트에 한가지 질문이 있어서 여쭙습니다.

프로젝트를 구동중 비특정 타이밍에 자기 자신의 플레이어의 스킬이 나가지 않습니다.

패킷은 서버에 보내는것 같은데 클라에서는 응답을 받지 못하는 상황같은데, 중요한건 이 상황이 발생하면

클라를 다시 재부팅시켜서 접속시키려하면 로그인에서 게임씬으로 넘어가기는 하는데 Connect Server까지는 되고(클라 로그)

PlayerInfo, ITemInfo등의 패킷은 받고 있는데 EnterGame패킷이 오지를 않습니다. (때문에 맵만 덩그라니 있고 크리쳐 객체는 아예 생성이 안되는 상황)

클라에서 디버깅을 걸어서 보았지만 딱히 문제가 될만한 부분이 안보여서 질문 드립니다.

잘 부탁드립니다^^

답변 8

·

답변을 작성해보세요.

2

궁금해서 살짝 확인해보니

JobTask가 넘쳐 흘러서 문제가 일어난 것은 맞지만,
그 원인은 비정상적인 Update 증식 때문이었습니다.

Player가 리스폰될 때 EnterGame을 호출하고,
EnterGame 내부에서 다시 VisionCube Update를 첫 호출하는데
여기서 VisionCube Update에서 Owner.Room.PushAfter(100, Update);
으로 다음 틱 예약을 하고 있습니다.

그런데 플레이어가 죽으면 다시 Leave-EnterGame이 호출되는데
이 때 기존에 예약한 VisionCube Update Job을 Cancel하지 않아서
운 나쁘게 플레이어가 연속해서 여러번 죽으면
VisionCube Update Job이 중복해서 Queue에 예약될 수가 있습니다.
그래서 JobTask에 일감이 계속 증식하다가 말도 안 되는 수치까지 도달하면
엄청 오래 기다려야 클라가 접속할 수 있게 된 것으로 보이네요.

해결 방법은 VisionCube에서 예약한 Job을 추적해서

죽거나 LeaveGame을 할 때 Job을 취소하면 되겠습니다.

위와 같이 수정하니 제 환경에서 2000 Monster 까지 '일단은' 실행 되긴 하네요.
물론 그럼에도 AI나 VisionCube Update 일감이 워낙 무거워 틱이 밀려서 렉이 있는 상황이니,
그 정도로 Monster을 늘려서는 안되겠습니다.

JobTimer만 확인하고 그냥 지나쳤던 문제였는데
꼼꼼하게 확인해주신 덕에 찾고 갑니다 ^^

2

앗 그런가요?
JobTimer가 늘어나는 것만 확인하고 끝냈는데
만약 그렇다면 VisionCube가  유력한 범인일 것 같네요.
저녁에 집에 들어가면 살펴보겠습니다

1

iamparkc님의 프로필

iamparkc

질문자

2021.03.18

정말 감사합니다 ^^

루키스님의 해결방법으로 '일단은' 해결된것처럼 보입니다 ^^

항상 친절한 댓글 대응 감사합니다 ^^

다른 강의들도 기대됩니다 !

1

iamparkc님의 프로필

iamparkc

질문자

2021.03.18

문제의 상황에서 잡 카운트를 열람해본 결과 0으로 병목은 없는것 같습니다.

몬스터 개체수는 대략 500으로 셋팅해 두었는데 모두 아이들 상태에서 타겟이 없어 브로드캐스팅은 안하는 상황이네요.

뭔가 다른게 원인일 수도 있을것 같다는 생각이 드네요 ;

1

일감이 밀리는 상황에 병목현상이라고한다면 지연이 있을 뿐 일감을 기다리면 처리될
문제라고 생각되는데 병목현상이 심해지면 일감이 처리되지 않고 손실되는 경우가 되는것인지요?

-> 물론 일반적이라면 그렇습니다.

여기서 이런 문제가 발생하는 이유는 당연히 하드웨어 문제는 아니고,
우리가 작성한 코드의 흐름 때문인데요.
Update할 때 JobTimer에 예약되어 있는 일을 먼저 찾아서 쭉 실행하고,
그 다음에 JobQueue를 비우기 시작하는데
만약 예약되는 일감이 추가되는 속도가, 처리되는 속도보다 월등하다면
JobTimer에 점점 일감이 쌓이게 됩니다.
이게 계속 쌓이다 보면은 결국 GameRoom은
JobTimer를 비우려고 평생 루프를 돌지만,
그 와중에도 DummyClient에서 계속 일감을 밀어넣기 때문에
평생 JobTimer의 노예로 살게 됩니다.
그리고 GameRoom의 JobQueue에 있는 (당장 실행되었어야 할) 일감들은
아예 실행도 못하는 상황이 발생하게 됩니다.

EnterGame 이전까지는 네트워크 담당 쓰레드 (얘는 비교적 부하 없음)이
처리해줬기 때문에 문제 없지만
EnterGame 부터는 GameRoom의 Serializer를 통해서
받아와야 하는데 이 부분에서 먹통이 된 상태이죠.

1

https://www.inflearn.com/questions/146675

위 질문 참고 바랍니다.

제 예상으로 해당 문제는 단일 쓰레드에서 너무 많은 일을 실행하려다가
일감이 점점 밀리는 상황으로 판단됩니다.
더미 클라를 몇 개로 설정하셨을까요?
개수를 줄여보고 동일하게 발생하는지 테스트를 하거나,
총 일감 개수를 로그로 남겨서 살펴보는 것도 필요할 것 같네요.

그리고 단일 GameRoom 방식이 가장 쉽고 직관적이지만
AI(길찾기)랑 게임 로직이랑 묶어서 실행하면 사실 병목이 많이 심하긴 합니다.
나중에는 AI를 따로 빼서 관리를 하거나,
애당초 JobSerializer 같은 JobQueue를 Actor 단위로 배치해서
멀티쓰레드 능력을 활용하게 유도를 해야 합니다.

0

iamparkc님의 프로필

iamparkc

질문자

2021.03.18

부탁드립니다 ^^

0

iamparkc님의 프로필

iamparkc

질문자

2021.03.18

답변 감사합니다 ^^

저의 경우는 더미 800, 몬스터 800으로 놓고 테스트 하였습니다.

https://www.inflearn.com/questions/146675 가 완전희 저의 상황이네요 ^^

참고가 되었습니다.

한가지 더 질문이라면 일감이 밀리는 상황에 병목현상이라고한다면 지연이 있을 뿐 일감을 기다리면 처리될

문제라고 생각되는데 병목현상이 심해지면 일감이 처리되지 않고 손실되는 경우가 되는것인지요?

이 경우 코드 문제라기 보단 하드웨어 영향인 경우인가요?