
이전 테스트에서는 몇가지 부족한 점이 있었습니다.
이번에는 이전 테스트의 부족한 점을 보완하고, 더욱 정확한 벤치마킹을 위해 다시 한번 테스트를 진행하고자 합니다.
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 LTSNode.js v20.13.1Node.js v20.13.1Docker 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 환경에서도 안정적이고 일관된 성능을 제공할 수 있음을 알 수 있습니다.
혹시 이번 테스트에서도 부족한 점이 있을 수 있으니, 추가적인 피드백이 있다면 언제든지 환영합니다!