피드백 수용
Gateway - Other Server 최적화
-
현재 Gateway에선 Payload를 디코딩하여 객체로 생성하는데, 이 생성된 객체는 Heap 영역에 저장되어 Garbage 컬렉션에 의해 사라지기 전까지 메모리를 사용하게된다..
-
그렇기에 불필요한 메모리 사용을 줄이기 위해 Gateway에서 무조건적으로 Payload를 디코딩하지 않고,
Payload 정보가 필요한 핸들러에서만 직접 디코딩하도록 수정하여 기본 Packet 전달 시의 Heap 영역 사용을 최소화 하였다!
// 핸들러에 직접 payloadBuffer를 주도록 변경
const packet = socket.buffer.subarray(0, headerLength + payloadByte);
const packetType = packet.readUInt16BE(0);
const payloadBuffer = packet.subarray(headerLength, headerLength + payloadByte);
const handler = handlers[packetType];
// const proto = getProtoMessages().GamePacket;
// const gamePacket = proto.decode(payloadBuffer);
// const payload = gamePacket[gamePacket.payload];
await handler({ socket, payloadBuffer, packetType });
// 기존 Payload를 받아 인코딩하는 방식 또는 PayloadBuffer를 직접 받아 인코딩을 생략하는 방식으로 나눴다!
function makePacket([packetType, packetTypeName], payload, payloadBuffer = null) {
if (!payloadBuffer) {
const proto = getProtoMessages().GamePacket;
let message = null;
// payload 생성
try {
message = proto.create({ [packetTypeName]: payload });
payloadBuffer = proto.encode(message).finish();
} catch (e) {
console.error(e);
}
}
// header 생성
const packetTypeBuffer = Buffer.alloc(2);
packetTypeBuffer.writeUInt16BE(packetType);
const versionBuffer = Buffer.from(config.client.version);
const versionLengthBuffer = Buffer.alloc(1);
versionLengthBuffer.writeUInt8(versionBuffer.length);
const payloadLengthBuffer = Buffer.alloc(4);
payloadLengthBuffer.writeUInt32BE(payloadBuffer.length);
const packet = Buffer.concat([
packetTypeBuffer,
versionLengthBuffer,
versionBuffer,
payloadLengthBuffer,
payloadBuffer,
]);
return packet;
}
// 또한 다른 서버에서 받은 값에서 userId 요소만 빼서 바로 보내도록 수정!
const user = userSession.getUserByID(userId);
if (!user) continue;
const header = packet.subarray(
0,
headerLength - (userIdLengthByte + userIdByte + payloadLengthByte),
);
const payload = packet.subarray(headerLength - payloadLengthByte);
const resPacket = Buffer.concat([header, payload]);
user.socket.write(resPacket);
- 이후 프로파일링을 통해 결과가 얼마나 달라지는지 clinic.js를 활용해 비교해봤지만!
-> 바뀐게 객체 1 개와 일부 인코딩/디코딩 생략인데 그렇게 큰 차이가 있을리가 없지…
-
Latency Check
-
그래도 실행시간은 단축되었을 거라 생각되어 더미클라이언트에 latency 체크를 추가하여 확인해보았다!
-
코드 변경 이전
- 코드 변경 이후
-> 대략 30%(2/7) 정도의 실행시간 절감을 확인할 수 있었다! 하지만 하면할수록 Latency의 불확실성 때문에 다른 방법으로 확인을 해보기로 했다..
-
-
Runtime Check
- 변경 전
- 변경 후
-> 전체적으로 실행시간이 줄어들긴했다!
( 평균 0.165ms -> 0.134ms (약 19% 정도 개선))
한줄 평 + 개선점
- 왠지모르게 가끔씩 지치는 기분이 든다.. 그래도 힘내야지