워드프레스에서 PHP 세션은 독이 될 수 있습니다.

이전에 잠시 쓴 포스트의 검증을 위한 작업을 했습니다. 두 포스트를 통해 저는 PHP 세션(session)은 어지간하면 사용하지 말기를 권고드리며, 다른 방법을 사용하시기를 조언드립니다. 세션 사용시 사이트의 성능 저하가 발생할 수 있기 때문입니다.

이유는 이렇습니다. 세션을 선언하게 되면 서버에서는 세션 파일을 생성합니다. 세션 파일은 각 브라우저의 쿠키 값에 의해 식별 가능합니다.  그래서 로그인하지 않은 상태라도 쿠키만 사용할 수 있다면 사용자의 상태를 서버에서 유지할 수 있게 됩니다. 이 점이 매우 유용하므로, 게시판 같은 비로그인 상태의 사용자도 상태를 기억해야 하는 상황에서 종종 세션을 사용하고는 합니다.

그러나 워드프레스의 코어에는 아예 세션을 쓰는 코드가 발견되지 않습니다. 그리고 점차 세션은 사용하지 않는 추세입니다. 왜 그럴까요? 그것은 세션의 치명적인 단점 때문인데, 세션은 한 번에 단 하나의 연결만 사용할 수 있기 때문입니다.

그래서 만약 서버에서 동시에 두 개의 요청이 들어오면, 둘 중 먼저 도착한 하나가 세션 파일을 선점합니다. 조금 늦은 나머지 요청은 첫번째 요청이 끝날 때까지 기다려야만 합니다. 세션을 선언한 이상, 아무리 그 연결이 서로 독립적인 일을 하더라도 관계없이 한 번에 하나의 연결만 처리할 수 있게 됩니다.

요즘은 웹 페이지 로딩 초기부터 많은 정보를 들고 오기보다는 REST API 같은 것을 이용해 그때그때 필요한 만큼 데이터를 읽어옵니다. 그만큼 원래 서버 페이지 요청과 더불어 AJAX 요청이 웹브라우저 뒤에서는 많이, 여러번 일어나게 됩니다.

AJAX 특성상 작업은 비동기적으로 일어납니다. 순차적으로 보냈다고 해서 꼭 순차적으로 오지 않습니다. 요청의 응답은 콜백 함수에 의해 진행되나 처리되는 시점에 대해서는 명확하지 않습니다. 콜백의 순차적인 흐름을 보장받으려면 promise 같은 패턴을 사용해야 하죠.

워드프레스는 여러 사이트에서 플러그인 및 테마가 맞물려 돌아갑니다. AJAX 요청을 어디서 어떻게 보내는지는 다 파악하기란 어렵습니다. 사이트가 커지면 커질수록, 처리하는 자료가 많으면 많을수록 당연히 응답 시간도 비례해서 오래 걸릴 겁니다. 그러나 최소한 우리는 AJAX 요청은 비동기적이어서 몇 개의 요청을 보내더라도 요청이 처리되는 ‘그때그때’  와 줄거라고 기대합니다.

그러나, 세션을 쓰게 되면 이런 기대는 와장창 무너집니다. AJAX는 더이상 비동기적이지 않습니다. 연결이 요구하는 한 동시에 접속하여 동시에 처리되어야 하지만 그렇지 못하게 되죠. 비유하자면 보통 최소 2개에서 많개는 8개의 차선을 가진 고속도로가 세션 때문에 단 1개의 차선만 이용 가능하게 되는 셈입니다.

그럼 이제 실제로 그런지 검증을 해 보도록 하겠습니다. 세션을 쓸 때와 쓰지 않을 때를 구분해서 AJAX 요청을 보내는 시험 플러그인을 작성해 두었습니다. 이 플러그인을 활성화 화면 관리자 화면에서 ‘WAS Test’라는 메뉴를 확인할 수 있습니다. (GIT 저장소: https://github.com/chwnam/wp-ajax-sesion)

메뉴로 들어가면 아래처럼 나옵니다. 2개의 버튼이 있는데 첫번째 버튼은 세션을 이용한 상태에서 AJAX요청을 연속 3개를 보냅니다. 두번째 버튼은 동일한 동작을 하나, 세션을 사용하지 않습니다.

AJAX로 하는 일은 단순합니다. 그저 3초간 멈췄다가 성공 응답을 주는 것 말고는 없습니다. 그저 AJAX가 하는 일이 다소 시간을 소요하는 것임을 알리는 것입니다.

그러면 각각의 버튼을 눌러 응답이 어떻게 진행되는지 보겠습니다. 일반 화면에서는 그 차이를 확인하기 어렵고, F12 키를 눌러 나오는 개발자 도구 화면을 눌러야 차이를 볼 수 있습니다.

  • 크롬 기준 F12 키를 눌러 나온 개발자 화면 > Network 탭을 선택합니다.
  • AJAX만 볼 것이므로 ‘XHR’만 필터합니다.
  • 첫번째 버튼을 누르면 총 4개 (1개는 실험 시작 연결, 나머지 3개가 본 실험 연결)의 AJAX 연결이 이뤄집니다. 모든 연결의 응답이 올 때까지 잠시 대기합니다.
  • 두번째 버튼을 눌러 모든 연결의 응답이 올 때까지 대기합니다.

아래는 결과를 갈무리한 것입니다.

두 버튼은 가장 처음엔 실험이 시작될 것임을 서버에게 먼저 알립니다. 이 요청에 의해 세션이 만들어지거나 정리됩니다. 이 응답을 받은 후 3개의 동일한 AJAX 요청을 보냅니다. 말씀드렸듯, 하는 일은 없고, 그냥 3초간 대기했다가 응답 보내는 것이 다입니다.

그림의 처음 4개는 세션을 적용했을 때의 결과입니다. 웹브라우저에서는 1->2->3 순서로 요청을 보냈지만, 1->3->2 순으로 응답이 왔습니다. 이 순서는 상황에 따라 그때그때 달라질 수 있습니다. 그러나 시간을 보면 대략 3초, 6초, 9초로 응답이 순차적으로 오는 것을 알 수 있습니다.

반면 나중 4개는 다릅니다. 분명 똑같은 AJAX 요청을 파라미터만 다르게 해서 보냈지만 3개의 요청이 거의 동시에 들어온 것을 볼 수 있습니다. 즉 세션을 쓰지 않으면 동시에 처리되어 약 3~4초면 처리될 일이 세션을 써 버리는 바람에 9~10초로 늦어지게 됩니다.

이런 이유로 코어에서는 기존 PHP의 세션을 사용하는 일이 없으며, 앞으로도 플러그인이나 테마를 개발할 때 세션을 사용하는 일은 자제하기를 권하는 것입니다.

그러나 안타깝게도 아직 다수의 한국형 게시판들은 여전히 세션을 사용하고 있습니다. 아무래도 비회원을 위한 처리가 반드시 필요한 게시판에서는 어쩔 수 없는 선택이었겠죠. 아무튼 관리자 편집 화면 등등에서 알 수는 없지만 페이지 로딩 시간이 현저히 느리다면 AJAX 요청, 응답 상태를 한 번 점검해 보시기 바랍니다. 위 그림처럼  AJAX 요청이 폭포수처럼 떨어지고 있다면 십중팔구 사용 중인 플러그 내지 테마 어딘가에서 세션을 썼다고 의심할 수 있을 것입니다.

댓글 남기기