Problem
node.js
를 사용하고 AWS SDK
1를 이용해 S3
에서 파일을 다운로드를 구현 중 아래와 같이 코드를 작성해서 서비스 하고 있었다. 비교적 작은파일 (50MB
미만)는 문제가 없었지만 대용량 파일 400MB
이상을 다운로드 시 서버 자원을 많이 사용하고 속도도 매우 느려지는 등 문제가 발생하기 시작했다.
download(bucket, folder, type, id, callback) {
const params = {
Bucket: (bucket || process.env.AWS_S3_BUCKET) + '/' + folder,
Key: id
};
this.client.getObject(params, function(err, data) {
let rstream = null;
if (!err && data) {
rstream = new stream.PassThrough();
rstream.end(new Buffer(data.Body, 'binary'));
}
return callback(err, _.omit(data, ['AcceptRanges', 'Metadata', 'Body']), rstream);
});
}
Solution
S3
링크를 직접 만들거나 권한을 부여하는 등의 방법을 사용해서 해당 링크로 redirect
시키는 방법도 있지만2, 예를들면 유료로 결제한 사용자들만 받을 수 있는 파일이어서 나는 링크를 외부에 완전히 숨기기를 원했고 따라서 권한 관리도 서버에서 온전히 통제하고 싶었기 때문에 위 방법을 적용하지는 못했다. 썸네일이나 한 페이지에 대량의 요청을 해야하는 상황이라면 redirect
방식이 더 적절할 것 같았다.
해결 방법은 아래와 같이 createReadStream
을 만들고 stream
을 전달하여 사용하면 된다3.
download(bucket, folder, type, id, callback) {
const params = {
Bucket: (bucket || process.env.AWS_S3_BUCKET) + '/' + folder,
Key: id
};
const rstream = this.client.getObject(params).createReadStream();
return callback(null, null, rstream);
}