처제 졸업식으로 나가있던 사이에 문제가 터졌더군요.
오전 11시 정도부터 3시까지 약 4시간 정도 서버가 오동작을 했습니다.
대략적인 원인을 파악했는데...
일단 직접적인 원인은, 제가 오늘 새벽에 해피브레이크에 올렸던 오뎅장사 이야기였습니다.
이 글의 본문이 무려 100kB나 되는 엄청난 양인데요.
이걸 파싱하는데 시간이 너무 많이 걸려서, 한사람만 이 글을 읽는데도 4~5초 정도 걸려야 화면이
뜹니다. 그런데 그 4~5초를 못기다린 분이 다시 F5를 눌러서 페이지를 리로드하려고 시도하면
그전의 요청이 아직 처리되고 있는 중에 또 한번의 요청이 들어가게 됩니다.
안그래도 50% 이상의 CPU 타임을 먹고 있었기 때문에, 두개의 쓰레드가 거의 100%에 가까운 CPU를
점유하게 되는데, 이 상태에서 몇번 더 F5를 눌러버리면 사실상 서버가 뻗어버리게 됩니다.
본문을 뭘 파싱할 필요가 있겠냐 싶겠지만, 실제로는, 본문에 포함되어 있을 수 있는 링크들,
즉
http://www.borlandforum.com 이렇게 쓰기만 해도 자동으로 링크로 인식해야 하고, 또 그외에
html 태그를 그대로 썼을 경우에 대해서도 처리를 해주어야 하기 때문에 보기보단 파싱이 상당히
복잡합니다.
이 파싱 루틴은 시간을 많이 잡아먹을 수밖에 없는 건데, 최대한 빠르게 처리를 해야 하는거지요.
그래서 제가 몇주에 걸쳐 나름대로 최적화를 해서, VCL의 기본 StringReplace() 함수를 그냥 호출
했을 때와 거의 비슷한 속도를 내고 있었는데요.
파싱 대상이 100kB 단위가 되니 시간이 몇초 단위로 늘어지는 것을 어떻게 할 수가 없네요.
메모리 재할당 한번도 없이 문자열의 처음부터 끝까지 선형으로 포인터 검색만 하도록 최적화시킨
거라서 어셈블리를 쓰지 않는 한은 더이상 최적화할 방법이 없구요.
사실 작년부터 이런 문제가 생길 가능성 정도는 예측을 하고 있었기 때문에, 다른 대안을 모색하고
있었는데요. 가장 좋은 방법은, 파싱이 끝날 때까지 응답을 쌓아두지 말고 파싱 중간에 분석된
부분이 어느정도 되면 빨랑빨랑 보내주는 것입니다.
이렇게 하면 기존보다 더 빠른 시간내에 일단 사용자에게 현재 분석이 된 부분들을 계속 보내주기
때문에 사용자가 답답할 이유가 없지요.
근데.. 현재로서는 이게 생각보다는 간단하지 않게 되어있답니다.
포럼 게시판에는, 제가 만든 여러가지 웹처리용 컴퍼넌트들이 포함되어 있는데, 그 관계가 좀 복잡합니다.
그래서 아직 처리를 못했던 거구요. 웹브로커의 기반 구조를 약간 바꾸어야 하는 문제라서...
그래서리... 일단은, 눈물을 머금고(?) 해피브레이크의 오뎅장사 이야기를 삭제했답니다.
100kB 단위의 엄청난 본문을 올리면 또 문제가 생기겠지만, 포럼 역사상 본문 100kB가 올라온 적은
이번이 처음이니까 당분간은 문제가 없을거구요.
게시판의 구조 개선 문제는.. 이달 말쯤 되어야 할 거 같습니다.
그럼...