C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
분야별 포럼
C++빌더
델파이
파이어몽키
C/C++
프리파스칼
파이어버드
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

자유게시판
세상 살아가는 이야기들을 나누는 사랑방입니다.
[10501] 주절... HTTP 파일 업로드...
박지훈.임프 [cbuilder] 3472 읽음    2005-04-22 02:48
요즘 짬짬이.. 정말 짬짬이 포럼 게시판 보수작업을 하고 있는데요.
특히 글쓰기에서 파일 업로드 부분을 좀 많이 개선했습니다.
물론 성능이 20~30% 정도 빨라졌고 자잘한 버그들을 개선한 거라서 여러분이 뭐 특별히 체감하긴 힘들겠습니다만... ^^;;
참 씰데없는 걸로 땀빼네.. 하실지도 모르겠습니다만, 뭐 취미삼아 하는 거니깐 맘이 가는 대로 작업을 하는 거지요.

사실 이번에 제일 손이 많이 간 것은 C++빌더 코드로 되어 있던 업로드 컴포넌트를 파스칼.. 그러니까 델파이 코드로 바꾼 건데.. 이 컴포넌트의 메인 코드가 포인터 연산이라 파스칼 코드로 바꾸는 데 좀 신경이 쓰이더군요. 아시다시피, 파스칼에서도 포인터를 충분히 쓸 수 있습니다만 아무래도 C++보다는 좀 덜 자유로와서...

잠도 안오고 일도 하기 싫은 김에 이 HTTP 파일업로드에 대해 생각나는 대로 주절거려보겠슴다.

원래.. 파일 업로드 부분은 델파이나 C++빌더의 5 버전까지는 아예 VCL에 없었습니다만 6 버전부터 파일 업로드가 지원되기 시작했습니다. VCL 6 버전에서 추가된 특정 유닛을 uses하거나(델파이) 링크하면(C++빌더) 파일 업로드가 지원되죠. 근데 이 VCL 6 이상 버전의 파일 업로드 부분이, 클래스 구현 면에서는 참 멋지게 설계되었습니다만, 성능 면에서는 엽기스럽습니다. 300, 400KB 정도까지는 무난하게 업로드가 됩니다만, 1메가가 가까워지면서 지나치게 속도가 느려지기 시작하다가.. 10메가 단위가 넘어서면 황당하게 속도가 느려집니다.

일전에 테스트로 200메가짜리를 업로드했더니 파일 데이터의 전송이 끝난 후로도 10분 이상 파싱이 안끝나고 버벅이더군요. 결국 IIS를 다시 시작시켰습니다. VCL 6 파일업로드의 소스코드를 보면 이런 극악의 성능을 보이는 이유가 있는데.. 뭐 한마디로 말하자면 200메가짜리 파일을 업로드하면 200메가짜리 스트링 변수를 쓰기 때문입니다. 물론 200메가짜리 스트링을 만들어도 그보다는 훨 낫게 할 수도 있는데도, VCL 코드를 보면 여러가지 부분에서 최악의 선택을 많이 했더군요. 결국 대용량에서 엄청나게 느린데다가 CPU 부하도 필요 이상으로 너무 많이 잡아먹습니다. 다만, 위에도 썼다시피 클래스 구조는 참 설계했습니다. (빛좋은 개살구???)

델파이와 C++빌더의 5 버전까지는 그런 극악의 클래스조차도 아예 파일업로드가 지원되지 않았기 때문에, 처음 포럼 게시판을 만들 때는(아마도 1999년 가을 정도였던 듯..) 파일 업로드 루틴을 직접 만들 수밖에 없었습니다. 그래서 C++ 코드로 파일업로드 컴포넌트를 만들었던 건데(며칠전에 파스칼 코드로 바꾸었지만).. 제가 사용한 방식은 대략 다음과 같은 시나리오로 되어있습니다.

1. 일단 HTTP POST로 전송받은 데이터를 그대로 통째로 하나의 파일로 저장합니다. (이 "폼 파일"에는 하나 혹은 복수개의 업로드된 파일과 기타 다른 자잘한 폼 데이터들이 같이 저장됩니다)
2. 그 파일을 메모리맵파일로 오픈해서 메모리 주소공간에 올려놓습니다.
3. 다음으로 이 메모리 공간에서 파싱을 합니다.

복잡하게 파일로 저장한 다음 메모리로 매핑한 이유가 있는데... 그냥 메모리에 버퍼를 만들어서 파일 데이터를 통째로 받아버리면, 버퍼 크기를 늘릴 때마다 메모리 재배치가 발생하기 때문에 1MB 정도만 업로드해도 서버의 메모리가 개판이 됩니다. 일반적으로 HTTP 전송에서 보통 한번에 8KB~40KB 정도씩 전송되는 것이 보통인데, 1MB면 한번 전송되는 블럭이 40KB라고 하더라도 25번이나 나누어서 전송하게 되고, 그때마다 realloc이 일어나면서 기존의 데이터를 복사하게 되는 비효율적인 일이 벌어집니다. 설상가상으로 업로드 데이터가 서버의 물리적 여유 메모리에 비해 대략 1/2 정도 이상 넘어가는 대용량일 경우에는 당연히 실제 메모리로는 모자라게 되므로, 1/2을 넘어서는 순간부터 매 블럭이 전송될 때마다 매번 하드디스크로 스와핑이 발생하므로 어쩔 수 없이 성능이 무쟈게 느려질 뿐 아니라 다른 일반적인 서버 동작의 성능에도 큰 영향을 미치게 됩니다. (여기서 실제 메모리 여유공간이 파일업로드 데이터의 두배가 되어야 스와핑이 일어나지 않는 이유는 realloc 때문입니다)

전송된 데이터를 파일로 바로 저장해버리면, 연속된 데이터에 대해 끊어지지 않는 일련의 주소공간을 가져야 하는 메모리와 달리 하드디스크 파일은 여러 클러스터에 걸쳐서 띄엄띄엄 저장될 수 있기 때문입니다. 따라서 한 파일에 새 데이터 블럭을 추가로 써넣어도 기존의 데이터가 재배치되거나 하지 않습니다. 그럼 왜 그걸 다시 메모리로 매핑하느냐 하면.. 파일로 저장된 상태에서 그대로 파싱하려면 파일 IO 함수를 사용해서 읽고 써야 하는데 절차가 메모리의 경우보다 복잡할 뿐 아니라 성능면에서도 떨어집니다. 따라서 파일을 메모리로 매핑해버리면 완전히 메모리로 다룰 수 있게 되므로 성능상이나 코드상으로도 훨씬 낫습니다.

그러면 대용량이 아니라 작은 용량이라서 메모리 버퍼에 직접 올리는 것이 나은 경우도 있지 않느냐, 라고 할 수도 있습니다만, 그렇게 작은 파일이라면 메모리 버퍼에 쓰거나 파일로 쓰거나 서버 장비에서는 사실 성능 차이는 거의 무시할 정도가 됩니다.

그래서.. 사실 대단한 것도 아니고 잔머리에 불과한 겁니다만, 어쨌든동, 제 업로드 컴포넌트는 상당히 빠릅니다. (자랑입니다^^;;) 당연히 VCL 6 이상의 파일업로드 루틴보다는 훨 빠르고요. 가끔씩 보이는 공개된 자작 파일업로드 클래스나 컴포넌트들보다도 빠릅니다. 요즘은 빌더나 델파이로 웹개발하는 분이 전보다도 더 줄어든 거 같아서 얼마나 필요할지는 모르겠습니다만 조만간 공개는 할 겁니다. 단지 지금 클래스 구조가 맘에 안들어서... --;;;

근데.. 델파이나 빌더도 그렇긴 하지만, 웹 개발 언어라고 할 수 있는 ASP에서도 파일 업로드는 기본 지원이 안됩니다. ASP.NET에서는 기본 포함이 되었는지 어떤지 모르겠습니다만.. 웹 개발 전문으로 만들어진 ASP에서 파일업로드조차 안된다는 것은 정말 웃기지요? 어쨌든 그래서 ASP 개발하다가 파일 업로드가 필요하면 액티브 서버 오브젝트를 사용합니다. 액티브 서버 오브젝트라는 것이 뭐 대단한 것은 아니고 일종의 액티브X인데, ASP 스크립트에서 불러쓸 수 있도록 된 액티브X지요. 이걸 ASP 컴포넌트라고 부르기도 합니다.

당연하지만, 용도와 하는 일은 똑같아도 제가 만든 것은 VCL 버전이기 때문에 ASP 컴포넌트로는 바로 못씁니다. 그래도 껍데기부분만 바꾸면 어렵지 않게 컨버팅할 수 있지요. 참고로 C++빌더와 델파이에서도 이 ASP 컴포넌트를 만들 수 있습니다. ASP 컴포넌트를 보통 VC++로 만드는 것을 생각해보면, C++빌더나 델파이로는 오히려 더 쉽게 만들 수 있지요.

파일업로드가 ASP에서 지원은 안해주고, 또 자주 필요한 기능이라서 파일업로드용 ASP 컴포넌트는 꽤 많이 나와있습니다. 상용도 여러개 있고 공개도 몇가지 되는 거 같더군요. 사실 저희 회사에서도 웹 개발 일이 꽤 많기 때문에 제 팀원들은 제 입사 전에 구매한 파일업로드 컴포넌트를 쓰고 있습니다. 이름이 사이트갤럭시던가...

참고로.. 제 파일업로드 컴포넌트가 꽤 빠르기는 하지만 가장 빠른 것은 아닙니다. 사실 제가 테스트해본 것들 중 가장 빠른 것은 데브피아에서 팔고 있는 덱스트업로드입니다. 왜 그렇게 빠른지는 대충 짐작은 갑니다만.. 뭐 제가 그렇게 못만들어서가 아니라, 빠른 대신 업로드 동안에 CPU 점유율이 제것보다 더 높이 올라가더군요. 결국 단일 업로드의 속도는 빠르지만 CPU 부하가 더 높아서 결과적으로 총 CPU 소요시간은 거의 비슷한 거 같았습니다. 단일 요청에 대해 빠르다고 하더라도 동시에 여러 요청을 처리해야 하는 서버에서 CPU 부하가 더 높은 것은 결과적으로는 좋다고 보이지 않아서 그런 방식은 쓰지 않았죠. 만약 디스크 파일이 아니라 DB상의 객체라면 요청들 사이에 데드락 같은 크로스 락의 가능성도 있고 해서 최대한 빨리 끝내는 것이 더 유리하겠습니다만. (더욱이 SCSII 하드라면 더욱 더)

주저리주저리 썰이 무쟈게 길었는데... (전혀 이해가 안되시는 분도 있겠지만 이런 웹개발 파트는 몰라도 밥벌이에 전혀 지장이 없는 분이 더 많을 겁니다) 제가 문득 글을 쓰고 싶어졌던 원래의 이유는... 제 VCL 컴포넌트의 껍데기를 좀 바꿔서 ASP 컴포넌트로 만들어서 공개로 뿌리면 쓰실 분이 얼마나 될까 해서요. 다른 조건 없이 완전 무료로 뿌리되, C++빌더 혹은 델파이로 만들었다는 크레디트 정도는 나오게 하면 어떨까 싶습니다. 업로드 컴포넌트를 사용하는 페이지에 조그만 Powered by C++Builder 혹은 Powered by Delphi 배너를 올리도록 한다든지...? 넘 과한 요구인감...? 뭐 30X8 정도의 크기면 아주 작은 크긴데.. ^^ 그게 비현실적이라면, 안타깝지만 소스 내에 크레디트를 올리도록 강제할 수도 있겠고...

어떻게 생각해보면, 이미 웹개발자들은 구입을 했든 혹은 공개를 쓰든 어떤 방식으로든 업로드 컴포넌트를 구해쓰고 있을 테니 제가 만들어뿌려도 갖다쓸 사람은 별로 없을 거 같기도 하고... 아리송하네요.
소리바람.OJ [phonon]   2005-04-22 10:47 X
공개해 주세요.
예전에 친구에게 ASP로 간단한 파일 업로드 게시판을 만들어 줬을때, 아쉬운 부분이 자체적으로 업로드를 할 방법이 없어서 CodeProject에서 빼껴서 만든 기억이 있습니다. 성능은 그럭저럭이었지만, 임프님 말씀대로 조금만 용량이 많아지면 걱정이 되더군요. 지금은 MS XML  Component로도 구현이 가능하더군요. (상용도 많이 나와있지만.)

ASP.NET에서는 기본적으로 지원이 됩니다. 그러나, 대용량은 CPU 부하와 속도는 심각한 문제입니다. 서버의 메모리가 수 기가바이츠가 되어도 문제가 있을듯. 개개인이 따로 개발도 많이 하더군.(역시 상용제품도 나와있습니다.)

개인적인 의견을 올리겠습니다.
돈이 되는 것이라 이것저것을 하다보니, Application과 Web를 왔다갔다하는 경우가 많았습니다. Web사이트의 경우에 중요한 점은 안정성과 유지보수의 편의가 도모되어야 하는데, 한 사람의 유저로서 볼렌드포럼은 그럼 점이 부족하다고 봅니다.(매일 눈팅만 합니다. -.ㅡz) 그래서, 대대적인 개편을 한번 해주세요. (C#Builder로.)
개발자 커뮤니티 중의 데브피아 사이트는 유저들이 문제의 수정을 요구하는데요 요지부동이더군요.

전면 개편을 한번 고려해 주세요.
예쁜 디자인도 넣어 주시면 더 좋구요.
bhp영화 [h1800]   2005-04-22 14:58 X
소스를 공개하시는 동시에 상용화하셔서 용돈이라도 버시는 것도 나쁘지 않을 듯 한데요.
저는 업무의 반 이상이  웹쪽인 놈이라, 데브피아 쪽 덱스트를 많이 쓰고 있습니다만, 솔직히 유지보수 정책이나 이런 부분에서 상당한 불만이 있는 편이라서요.
(몇 주 전에도 전화 붙들고 거의 장시간의 설교를 뿜어냈는데, 개발자로서 너 말이 맞는데 영업 쪽에서 안 된다고 하니 안된다는 대답으로 결론이 났었죠.)

어느 쪽이라도 공개해주시면 참 감사하겠다는 생각이 듭니다. ^^
박지훈.임프 [cbuilder]   2005-04-22 18:11 X
그렇군요... 머 짬짬이 만들어서 공개해보겠습니다.
그리고 asp 버전은 소스 공개할 생각이 없고요. VCL 버전만 공개할 겁니다.

소리바람.OJ님, 사이트 개편은... 하핫~ 저도 하고 싶긴 합니다만 제 디자인 능력이 짜쳐서 쉽지가 않네요~ 디자인 면을 제외하고 기능적이나 안정성 면에서 불편한 점이 있으면 구체적으로 말씀해주시면 적극 참고하겠습니다.
소리바람.OJ [phonon]   2005-04-25 10:10 X
이미지 없이 CSS로만 꾸며도 괜찮게 보일 수 있습니다.
이글루 블로그에 그렇게 구현한 스킨들이 있습니다.
속도 빠르고, 보기도 좋습니다.

우리도 디자인 공모를 한번 합시다.
'CSS와 HTML만 가지고 꾸미기'
박지훈.임프 [cbuilder]   2005-04-25 10:46 X
CSS나 자바스크립트는 저도 웬만큼은 쓴답니다. 여기 포럼 디자인에도 많이는 아니지만 CSS가 꽤 들어가있지요.

하지만 디자인을 뭘로 하느냐.. 이미지냐 CSS냐가 아니라... 그 디자인의 감각 자체가 떨어져서리~ ^^;;
소리바람.OJ [phonon]   2005-04-25 15:16 X
현재 디자인 보다 더 간단하게 하시면 될 듯 합니다.
거의 Wiki수준으로 하셔도 되고 Blog 사이트의 디자인을 참고하는 방법도 있습니다.

디자인 공모대회를 열어서 회원들의 투표로 당선된 것을 반영하면 좋겠습니다.
시샵께선 조그마한 경품을 준비하시면 될 겁니다. 오프모임에 나와야 준다고 하십시오. 안 나오시면 공짜로 디자인을 얻으신 것이 되지요.
홍환민.행복 [hhshhm]   2005-04-26 10:28 X
볼랜드포럼 개발자들한테 블로그하나씩 임대해주는건어떨까요
박지훈.임프 [cbuilder]   2005-04-26 14:58 X
디자인 공모대회라... 뭐 조그만 경품이야 협력업체들을 졸라서 얻어낼 수 있습니다만.
생각해보겠습니다. 공모전이라고 하려면 그래도 쓸만한 디자인이 두어개 이상 나와야 가능하지 않을까 싶어서요. 최악의 경우 디자인은 멋진데 포럼에 적당하지 않을 경우는 어떻게 할지도 참 애매하고요...

블로그는... 가능합니다.
뭐 그거야 디자인 부분보다는 개발만 열시미 하면 되는 거니까요. 추진하겠습니다.

+ -

관련 글 리스트
10501 주절... HTTP 파일 업로드... 박지훈.임프 3472 2005/04/22
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.