이전 테스트에서는 몇가지 부족한 점이 있었습니다.
이번에는 이전 테스트의 부족한 점을 보완하고, 더욱 정확한 벤치마킹을 위해 다시 한번 테스트를 진행하고자 합니다.
AWS Ubuntu 24.04 LTS
, Node.js v18.19.1
을 사용하였으나, 도커 컨테이너 환경에서는 Node:18(v18.20.3)
이미지를 사용하였습니다. 물론 둘 다 데비안 계열 OS이긴 했지만, 버전이 다르고 시스템 구성도 다르기 때문에 성능 차이가 발생할 수 있었습니다.DinD(Docker in Docker)
를 사용하여 세 가지 경우 모두 동일한 환경을 구성하였습니다.AWS EC2 t2.xlarge(4 vCPU, 16GB RAM)
, Ubuntu 24.04 LTS
Node.js v20.13.1
Node.js v20.13.1
Docker in Docker(DinD)
를 사용하여 동일한 환경을 구성하였습니다.docker run -v /var/run/docker.sock:/var/run/docker.sock ...
FROM docker:27.0.0-rc.1-dind
RUN apk add --no-cache nodejs npm
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["sh", "-c", "dockerd-entrypoint.sh"]
function generateStringDataInMB(baseString, sizeInMB) {
const repeatCount = Math.ceil((sizeInMB * 1024 * 1024) / baseString.length);
return baseString.repeat(repeatCount);
}
app.get('/network', (req, res) => {
res.send('Network endpoint response');
});
app.get('/disk-io', async (req, res) => {
const filePath = './shared/testfile.txt';
const fileContent = generateStringDataInMB('Some content to write to the file', 100); // Generate ~100MB of data
try {
await fs.writeFile(filePath, fileContent);
const data = await fs.readFile(filePath, 'utf8');
await fs.unlink(filePath);
res.send(`File content length: ${data.length} and file deleted successfully`);
} catch (err) {
res.status(500).send(`Error: ${err.message}`);
}
});
app.get('/cpu', (req, res) => {
const start = Date.now();
for (let i = 0; i < 1e5; i++) {
crypto.createHash('sha256').update('test').digest('hex');
}
const end = Date.now();
res.send(`CPU intensive task completed in ${end - start} ms`);
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
docker build -t outer-container .
docker run -d \
--rm \
--name outer-container \
--privileged \
-p 3000:3000 \
-v /home/ubuntu/shared:/usr/src/app/shared \
outer-container
docker build -t inner-container .
# 네트워크 모드
docker run -it \
--rm \
--name inner-container \
--privileged \
-v /usr/src/app/shared:/usr/src/app/shared \
-w /usr/src/app \
--network host \
inner-container \
/bin/sh
# 호스트 모드
docker run -it \
--rm \
--name inner-container \
--privileged \
-v /usr/src/app/shared:/usr/src/app/shared \
-w /usr/src/app \
-p 3000:3000 \
inner-container \
/bin/sh
...
THREADS=32
CONNECTIONS=400
wrk -t$THREADS -c$CONNECTIONS -d$DURATION ${base_url}/network > $OUTPUT_DIR/${output_prefix}_network.txt
echo "Network benchmark completed."
THREADS=3
CONNECTIONS=4
wrk -t$THREADS -c$CONNECTIONS -d$DURATION ${base_url}/disk-io > $OUTPUT_DIR/${output_prefix}_disk_io.txt
echo "Disk I/O benchmark completed."
THREADS=5
CONNECTIONS=5
wrk -t$THREADS -c$CONNECTIONS -d$DURATION ${base_url}/cpu > $OUTPUT_DIR/${output_prefix}_cpu.txt
echo "CPU benchmark completed."
...
테스트 | 네이티브 | Docker(host) | Docker(bridge) |
---|---|---|---|
1회차 | 5360.21 | 5417.84 | 5195.34 |
2회차 | 5026.70 | 5193.76 | 5212.29 |
3회차 | 5389.39 | 5492.70 | 5100.49 |
평균 | 5258.77 | 5368.10 | 5169.37 |
테스트 | 네이티브 | Docker(host) | Docker(bridge) |
---|---|---|---|
1회차 | 2.80 | 2.75 | 2.80 |
2회차 | 2.73 | 2.66 | 2.76 |
3회차 | 2.63 | 2.65 | 2.66 |
평균 | 2.72 | 2.69 | 2.74 |
테스트 | 네이티브 | Docker(host) | Docker(bridge) |
---|---|---|---|
1회차 | 4.23 | 4.21 | 4.19 |
2회차 | 4.10 | 4.14 | 4.16 |
3회차 | 4.06 | 4.16 | 4.23 |
평균 | 4.13 | 4.17 | 4.19 |
네트워크 성능: Docker 호스트 모드가 가장 우수한 성능을 보였지만, 네이티브와 Docker 브리지 모드도 유사한 성능을 보였습니다.
디스크 IO 성능 / CPU 성능: 세 환경 모두에서 유사한 성능을 보였으며, 유의미한 차이가 없었습니다.
결과적으로, Node.js 서버의 성능은 네이티브 환경과 Docker 환경(호스트 모드, 브리지 모드)에서 큰 차이가 없고, Docker 환경에서도 안정적이고 일관된 성능을 제공할 수 있음을 알 수 있습니다.
혹시 이번 테스트에서도 부족한 점이 있을 수 있으니, 추가적인 피드백이 있다면 언제든지 환영합니다!