엔지니어링

네이버 블로그 RPA 자동 발행: 크롬이 옆 작업에 꺼진 이유

네이버 블로그 RPA 발행이 실패한 원인은 네이버도 로그인도 아니라 같은 PC에서 돌던 다른 자동화 작업의 정리 코드였습니다. 저희는 크론 전용 크롬을 세션 대역 밖 포트에 두면 안전하다고 봤지만, 그 정리 코드는 대역 밖 크롬을 주인 없는 창으로 보고 바로 껐습니다. 이 글은 그 가설이 틀린 지점, 판정 기준 한 줄을 바꾼 수리, 재측정 숫자, 그리고 크롬을 살린 뒤에도 남은 실패까지 그대로 적은 기록입니다.

2026-11-07사고 시각: 2026년 9월 15일 22:02 크론 전용 크롬 로그인, 옆 세션 도구 호출 뒤 22:03:41 재기동, 조립 중 탭 소멸원인: 정리 코드 두 번째 단계가 살려 둘 크롬을 9222~9241 소켓 소유자로만 판정해 대역 밖 9250 크롬을 Stop-Process -Force로 종료선례: 2026년 7월 23~25일 지식iN 발행 크론 3일 연속 전량 실패(초안 8건, 발행 0건), 9222 크롬을 다른 세션이 종료조치: 판정을 디버그 소켓을 가진 chrome.exe 전부로 변경, 포트 값은 cdp_ports.py 상수 한 곳재측정: 수리 직후 보호 루트 7개·종료 대상 0개, 기동 유예 90초 뒤 정리 실행에도 PID 163736 유지미해결: 9월 19일 수정 발행 7편 검색 소실 원인 후보 3개 미분리, 성과 지표 5개는 기록 당시 기준선

네이버 블로그 RPA 발행에서 무엇이 문제였나?

네이버 블로그 RPA 발행이 실패한 이유는 발행 스크립트가 아니라 같은 PC에서 돌던 다른 자동화 작업이었습니다. 크론 전용 크롬을 띄워 글을 조립하는 도중, 다른 세션이 화면 조작 도구를 한 번 부르면 그 크롬이 강제 종료됐습니다. 조립하던 탭이 통째로 사라지니 그 회차 발행은 처음부터 다시 해야 했습니다.

출발점은 2026년 9월 15일 밤의 지시 한 줄이었습니다. “블로그 발행은 크론 배선 깔고 자동으로 돌아가도록”. 같은 날 낮에 네이버 스마트에디터에 글을 조립해 올리는 발행 스크립트를 만들었고, 두 번째 원고를 편집기 안에서 조립하고 검증하는 단계까지 확인한 상태였습니다. 그때까지 크론 설정 파일 317번째 줄에는 “발행은 사람 승인을 거쳐야 하니 크론에 넣지 않는다”는 주석이 남아 있었는데, 이 지시로 그 원칙을 풀었습니다.

자동 발행이 한 번 실패할 때 드는 비용은 작지 않습니다. 한 회차는 로그인, 원고 선택, 그림 굽기, 편집기 조립, 검증, 발행 순서로 흐르고 조립에만 약 10분이 걸립니다. 그 사이 크롬이 꺼지면 10분 작업이 사라지고, 다음 예약 시각까지 그날 글은 나가지 않습니다. 사람이 지켜보지 않는 시간에 돌기 때문에 실패를 바로 알아챌 사람도 없습니다.

이런 사고는 이번이 처음이 아니었습니다. 같은 해 7월에는 매일 23:00에 네이버 지식iN 답변을 올리던 크론이 7월 23일부터 25일까지 3일 연속 전량 실패했습니다. 초안 8건 가운데 발행은 0건이었습니다. 로그는 매번 “네이버 로그인 만료”라고 적었지만, 실제로는 다른 세션이 발행용 크롬을 정상 종료시켰고, 네이버 기본 로그인이 브라우저를 닫으면 사라지는 쿠키만 주는 바람에 재기동 직후 로그아웃 상태로 굳었습니다.

흐름도. 22:02 크론 전용 크롬 9250 로그인 성공, 옆 세션이 화면 조작 도구 호출, 정리 코드가 9250 크롬을 주인 없는 창으로 판정해 강제 종료, 22:03:41 9250 크롬 재기동, 조립 중이던 탭 소멸
9월 15일 밤 22시대: 로그인 직후 크롬이 다른 세션의 정리 코드에 꺼진 순서

처음 잰 숫자: 22:02 로그인, 22:03:41 재기동

먼저 시각을 나란히 놓았습니다. 크론 전용 크롬은 22:02에 로그인 유지 쿠키로 네이버 로그인을 마쳤습니다. 그 직후 옆 세션이 화면 조작 도구를 호출했고, 22:03:41에 같은 포트의 크롬이 새로 떠 있었습니다. 로그인 시각과 재기동 시각 사이에 들어온 사건은 옆 세션의 도구 호출 하나뿐이었습니다. 조립 중이던 편집기 탭은 재기동과 함께 사라졌습니다.

이 PC에서 크롬을 쓰는 주체는 여럿입니다. 포트 9222는 지식iN 답변 크론과 캡차 처리 크론이 같이 쓰는 공용 자리입니다. 사람과 함께 일하는 세션들은 9222~9241 대역에서 포트를 하나씩 받습니다. 새로 만든 발행 크론은 이 대역 밖의 9250을 쓰고, 크롬 프로필도 chrome-debug-9250이라는 전용 폴더로 따로 뒀습니다.

표. 포트별 사용 주체. 9222 공용 포트는 지식iN·캡차 크론이 함께 사용, 9222~9241은 세션 대역, 9250은 블로그 발행 크론 전용으로 프로필 chrome-debug-9250, 9224 프로필은 4.4GB
재기동 직전의 포트 배치: 9250만 세션 대역 밖에 있었다

숫자로 정리하면 이렇습니다. 로그인부터 강제 종료까지는 2분이 채 걸리지 않았고, 필요한 조건은 “아무 세션이든 화면 조작 도구를 1회 호출”뿐이었습니다. 한 회차 조립이 약 10분이니, 세션이 하나라도 그 10분 안에 도구를 부르면 발행은 실패합니다. 낮 시간에 세션 여러 개가 돌아가는 이 PC에서는 사실상 매번 실패한다는 뜻이었습니다.

세운 가설: 세션 대역 밖 고정 포트면 아무도 건드리지 않는다

포트를 9250으로 고른 데는 근거가 있었습니다. 크론은 사람이 여는 세션이 아니라서 세션용 포트를 배정받지 못합니다. 그렇다고 공용 9222를 쓰면 지식iN·캡차 크론과 같은 창을 나눠 쓰느라 창이 서로 밀립니다. 세션 대역 안의 포트 하나를 크론용으로 고정하는 방법도 따져 봤지만, 크론이 쉬는 동안 그 포트가 비면 다른 세션이 그 포트와 로그인된 프로필을 그대로 물려받습니다.

그래서 세운 가설은 단순했습니다. “세션 대역(9222~9241) 밖에 고정 포트를 두면, 세션들이 서로 정리하는 코드에 휘말리지 않는다”. 세션 쪽 정리 코드는 세션끼리 남긴 크롬을 치우는 장치이니, 대역 밖은 관심 밖일 거라고 봤습니다.

7월 사고 때 넣은 장치도 이 가설에 힘을 실었습니다. 그때는 정리 코드가 “내 세션 포트가 아니면 꺼도 안전하다”고 판단해 9222 발행 크롬을 끈 데서 사고가 났고, 보호 목록에 9222를 고정으로 추가해 막았습니다. 보호 목록이 있으니 오래 살아야 하는 크롬은 안전하다는 인식이 남아 있었습니다.

돌아보면 그 7월 수리 기록에는 단서가 적혀 있었습니다. “보호 포트가 하드코딩 상수라 두 번째 장수 프로필이 생기면 같은 파일을 다시 고쳐야 한다”. 9250은 정확히 그 두 번째 장수 프로필이었고, 저희는 그 파일을 고치지 않았습니다.

가설은 어디서 틀렸나?

가설이 틀린 지점은 정리 코드의 두 번째 단계에 있었습니다. 화면 조작 도구는 부를 때마다 쓰다 남은 디버그용 크롬을 치우는데, 이 단계는 살려 둘 크롬을 “9222~9241 포트의 소켓을 쥔 프로세스”로만 골랐습니다. 그 밖의 크롬은 전부 주인 없는 창으로 보고 PowerShell의 Stop-Process -Force로 끝냈습니다.

이 규칙에서 대역 밖은 안전지대가 아니었습니다. 오히려 정반대였습니다. 대역 안의 크롬은 적어도 살려 둘 후보로 검토라도 받지만, 대역 밖 크롬은 검토 없이 곧바로 종료 대상으로 넘어갔습니다. 9250을 대역 밖으로 뺀 결정이 격리를 만든 게 아니라, 이 크롬을 가장 먼저 죽을 자리로 옮긴 셈이었습니다.

표. 정리 코드의 살려 둘 크롬 판정 규칙 전후 비교. 수리 전은 9222~9241 소켓 소유자만 보호해 9250 크롬이 강제 종료, 수리 후는 디버그 소켓을 가진 chrome.exe 전부 보호해 9250 크롬 유지
같은 정리 코드, 판정 기준 한 줄 차이: 포트 범위에서 디버그 소켓 보유로

가설을 세울 때 정리 코드를 직접 열어 보지 않았다는 점도 인정해야 합니다. “세션끼리 쓰는 장치니까 대역 밖은 모를 것”이라는 짐작은 코드에 적힌 판정 기준이 아니라 그 장치의 용도에서 나온 추측이었습니다. 실제 코드는 “모르는 크롬은 지운다” 쪽으로 짜여 있었습니다.

진짜 원인은 무엇이었나: 살려 둘 창을 포트 번호로 골랐다

근본 원인은 “이 크롬을 살려 둘까”라는 질문에 포트 번호 목록으로 답하던 구조였습니다. 번호 목록은 지금 아는 사용처만 담습니다. 새 자동화가 새 포트로 크롬을 띄우는 순간 목록은 낡고, 목록 밖 크롬은 경고 없이 꺼집니다. 꺼지는 쪽은 사람이 지켜보지 않는 크론이라 실패가 늦게 드러납니다.

7월 사고와 9월 사고는 겉모습이 달랐습니다. 7월에는 세션 대역 안의 9222가 “내 포트가 아니라서” 꺼졌고, 9월에는 대역 밖의 9250이 “대역 밖이라서” 꺼졌습니다. 하지만 둘 다 같은 질문에 같은 방식으로 답하다 생긴 사고였습니다. 두 번째 사고가 나기 전에 첫 번째 수리 기록이 이미 다음 사고를 예고하고 있었다는 점이 이번 일의 핵심입니다.

크롬을 살려 둘지 판단할 더 직접적인 표지가 있었습니다. 원격 조종용 디버그 소켓을 열고 있는 크롬은 누군가 자동화 목적으로 띄운 크롬입니다. 그 소켓이 어느 포트에 있든, 지금 그 크롬을 쓰는 프로그램이 있을 수 있습니다. 판단 기준을 “몇 번 포트인가”에서 “디버그 소켓이 있는가”로 바꾸면 새 자동화가 생겨도 목록을 고칠 일이 없습니다.

조치: 디버그 소켓을 가진 크롬은 전부 살린다

정리 코드의 판정을 “디버그 소켓을 가진 chrome.exe 전부”로 바꿨습니다. 포트 대역 조건은 지웠습니다. 이제 정리 단계가 끄는 대상은 디버그 소켓도 없이 남은 크롬뿐입니다. 9250뿐 아니라 앞으로 다른 크론이 다른 고정 포트를 쓰더라도 같은 규칙으로 보호받습니다.

포트 값은 한 곳에만 둡니다. 9250은 cdp_ports.py 파일의 NAVER_SE_PORT 상수 한 줄에 있고, 발행 스크립트와 로그인 스크립트는 이 값을 가져다 씁니다. 같은 숫자가 여러 파일에 흩어지면 하나만 바뀌는 순간 엉뚱한 크롬을 붙잡습니다.

발행 크론 자체도 이날 함께 짰습니다. 크론 한 줄이 실행 기록 감시 스크립트를 거쳐 발행 스크립트를 부르고, 한 회차는 아래 순서로 흐릅니다. 조립이 실패하면 새 편집기를 열어 1회만 다시 조립하고, 그림 수·표 수·순서 검증을 통과한 경우에만 발행 버튼을 누릅니다. 발행 뒤에는 로그인하지 않은 상태로 글 주소를 열어 200 응답을 확인하고, 발행 목록 파일에 한 줄을 적고, 슬랙 콘텐츠 채널에 알립니다. 실패는 운영 알림 채널에도 사본을 보냅니다.

흐름도. 크론 회차 순서: 일시정지 플래그 확인, 오늘 발행분 있으면 종료, 로그인 유지 쿠키로 로그인, 다음 미발행 원고 선택, 그림 없으면 굽기, 편집기 조립(실패 시 새 편집기로 1회 재조립), 그림 수·표 수·순서 검증 통과 시만 발행, 비로그인 200 확인, 발행 목록 파일 기록, 슬랙 알림
크론 한 회차: 검증을 통과해야만 발행 버튼까지 간다

로그인도 사람 손을 거치지 않게 했습니다. 7월 사고 뒤 만든 무인 재로그인 스크립트는 네이버 로그인 화면의 “로그인 상태 유지” 체크를 켜고 들어가, 브라우저를 닫아도 남는 쿠키를 받습니다. 크롬이 다시 뜨더라도 다음 회차가 이 스크립트로 로그인을 되살리므로, 9224 프로필을 복사해 로그인 상태를 옮겨 올 필요가 없었습니다.

멈추는 장치도 같이 넣었습니다. 정해진 경로에 일시정지 플래그 파일을 하나 만들면 다음 회차부터 발행하지 않습니다. 크론 설정을 바꾸기 전 원본은 날짜를 붙인 백업 파일로 남겼습니다.

기각한 대안 3가지와 사유
대안기각 사유
로그인된 9224 프로필(4.4GB)을 복사해 크론용으로 쓴다무인 재로그인 스크립트가 이미 있어 4.4GB를 복사할 이유가 없다
공용 포트 9222를 같이 쓴다지식iN·캡차 크론과 같은 창을 나눠 써서 창이 밀린다
세션 대역 안의 포트 하나를 크론용으로 고정한다포트가 비는 동안 다른 세션이 그 포트와 로그인 프로필을 물려받는다

세 대안 모두 크롬을 어디에 둘지만 바꾼다. 정리 코드의 판정 기준은 그대로 남는다.

재측정 결과는 어땠나?

수리 직후 정리 코드가 무엇을 끌지 다시 계산했습니다. 보호 대상으로 잡힌 루트 크롬은 7개, 종료 대상은 0개였습니다. 수리 전에는 같은 상황에서 9250 크롬이 종료 대상에 들어갔습니다.

계산만으로 끝내지 않고 실제로 정리를 돌렸습니다. 정리 코드에는 막 뜬 크롬을 건드리지 않는 기동 유예 90초가 있어서, 이 시간이 지난 뒤 세션 없이 도구를 호출해 정리 단계를 그대로 실행했습니다. 9250 크롬의 프로세스 번호(PID 163736)는 호출 전후로 같았습니다. 수리 전에는 도구 호출 1회로 꺼지던 크롬이, 수리 후에는 정리 단계를 끝까지 통과하고도 살아 있었습니다.

통계 카드. 수리 전 도구 호출 1회로 9250 크롬 강제 종료, 수리 후 보호 루트 7개, 종료 대상 0개, 기동 유예 90초 뒤 정리 실행에도 PID 163736 유지
수리 전후 재측정: 같은 정리 단계를 돌려도 9250 크롬이 살아남았다

발행 쪽 측정 계획은 한 번 틀렸습니다. 처음에는 하루 1편으로 시작해 첫 2~3편이 네이버 서치어드바이저에 색인되는 모습을 보고 간격을 정하려 했습니다. 그런데 서치어드바이저는 우리 도메인을 재는 도구라 blog.naver.com에 올라간 글의 노출은 잴 수 없었습니다. 같은 날 밤 23시에 이 계획을 버렸습니다.

대신 노출을 직접 셌습니다. 그날 발행한 두 글은 모두 3시간 안에 글 제목 전체로 블로그 검색을 했을 때 결과에 나왔습니다. 이 확인을 매 회차 자동으로 하도록 노출 감시 함수를 넣었습니다. 최근 3편 가운데 발행 후 2시간이 지났는데도 제목 전체 검색에 나오지 않는 글이 있으면 발행을 멈추고 알림을 보냅니다. 노출을 확인한 뒤 상한을 하루 1편에서 2편으로 올렸습니다.

원고 공급도 다시 봤습니다. 리포트 원고 무인 발행은 9월 15일 세 번 돈 회차 모두 “쓰지 않은 질문 0건”으로 0편이었습니다. 새 리포트가 늘지 않는 상태라 남은 원고 169편은 소모만 됩니다. 반면 기술블로그는 9월 7일 이후 매일 4~6편씩 새 글이 나왔고, 당시 피드에 66편, 자동매매·주식 주제 4편을 빼면 62편이 있었습니다.

9월 15일 밤 기준 원고 공급
리포트 남은 원고169편 (새 원고 0편)
기술블로그 피드66편
주제 제외 후 기술블로그62편 (매일 4~6편 추가)

리포트는 줄기만 하고, 기술블로그는 매일 늘어난다.

그래서 네이버 블로그에 “기술블로그” 카테고리(2번)를 새로 만들고, 발행 스크립트가 기술블로그 피드를 직접 읽어 요약 원고를 만들게 했습니다. 요약은 리드와 소제목별 앞 두 문장으로 짜고, 표지 그림은 따로 굽습니다. 글 전체를 옮기는 안은 원문 사이트 유입이 줄고 같은 문서가 두 곳에 생겨서 기각했습니다. 네이버 계정을 따로 만드는 안도 신뢰를 0부터 쌓아야 해서 기각했습니다. 리포트는 10:40, 기술블로그는 06:40으로 회차를 나눠 서로 겹치지 않게 했습니다.

남는 한계: 크롬이 살아도 발행은 실패할 수 있다

이번 수리가 막은 일은 “다른 작업이 크롬을 끄는 일” 하나입니다. 한 회차 조립은 여전히 약 10분이 걸리고, 로그인에 캡차나 2차 인증이 걸리면 그날은 실패 알림만 남습니다. 그때는 사람이 한 번 손을 대야 합니다.

크롬이 살아 있어도 그 안의 탭이 멈출 수 있다는 사실도 나중에 드러났습니다. 9월 19일 10:40 회차가 실패했을 때 처음에는 원격 중계의 응답 대기 시간이 원인처럼 보였습니다. 실제로는 발행 크롬에 열려 있던 빈 새 탭 하나가 Page.enable 명령에 응답하지 않아 로그인 확인이 끝없이 기다리고 있었습니다. 중계 타임아웃은 증상이었지 원인이 아니었습니다. 응답 없는 탭을 정리하는 함수를 로그인 스크립트에 따로 넣었습니다.

노출 쪽에도 풀지 못한 질문이 남았습니다. 9월 19일 밤, 이미 발행한 글의 문장 부호를 고치려고 7편을 수정 발행했습니다. 이후 세 차례 실측에서 7편 모두 제목 전체 검색에서 사라졌고, 같은 기간 손대지 않았다고 본 1편만 노출을 유지했습니다. 블로그 글 8편 가운데 7편이 빠졌으니 계정 전체 문제는 아니라고 판단했고, 처음에는 “수정하면 검색에서 영구히 돌아오지 않는다”고 적었습니다.

그 결론은 과했습니다. 대조군으로 쓴 1편도 실은 9월 18일 구조 개편 때 이미 한 번 수정 발행한 글이었고, 그 뒤에도 노출을 유지했습니다. 원인이 셋 중 무엇인지 아직 모릅니다. 회복에 21시간보다 긴 시간이 걸리는지, 한 시간 안에 7편을 몰아서 고친 탓인지, 제목까지 바꾸며 이틀 연속 두 번 고친 탓인지 가르지 못했습니다. 셋을 가르는 실험은 하지 않았습니다. 대신 새 글 발행 뒤 기존 글을 자동으로 고쳐 다시 올리는 단계만 기본으로 껐습니다. 이 변경의 테스트는 17개가 통과했습니다.

표. 미해결 질문. 9월 19일 수정 발행 7편이 제목 검색에서 사라진 원인 후보 3가지: 회복 시간이 21시간보다 긺, 한 시간 안 7편 몰아서 수정, 제목 변경과 이틀 연속 이중 편집. 대조군 1편도 9월 18일 이미 수정 발행한 글
수정 발행 뒤 검색 소실: 후보 3개를 가르는 실험은 아직 없다

요약 원고 끝에 붙이던 원문 링크도 오래 가지 않았습니다. 이틀 뒤인 9월 17일, 네이버가 외부 링크가 있는 글을 노출에서 밀어낸다는 판단에 따라 원고 181편을 다시 만들어 홈페이지 링크가 남은 원고를 0편으로 줄였습니다. 지금 발행 스크립트는 우리 네이버 블로그 주소가 아닌 링크가 하나라도 있으면 발행 자체를 막습니다. 그 대가로 네이버 글에서 홈페이지로 넘어오는 유입은 포기했습니다.

가장 큰 한계는 사업 쪽입니다. 발행이 쌓여 매출로 이어지는지는 성과 지표 5개로 판정하기로 했는데, 이 기록을 남길 당시에는 5개 모두 기준선뿐이었습니다. 같은 시기 자사 리포트 페이지에 넣은 상담 폼은 배포 후 16일 동안 외부 세션 51회, 제출 0건이었습니다. 자동 발행을 아무리 안정시켜도 유입이 적으면 결과는 같습니다. 크롬을 살려 둔 일은 출발선을 지킨 일이지 성과가 아닙니다.

같은 종류의 사고를 막으려면 무엇을 확인해야 하나?

RPA로 브라우저를 오래 띄워 두는 자동화가 둘 이상이면, 서로의 정리 코드가 서로를 끌 수 있습니다. 이번 일에서 얻은 점검 항목은 네 가지입니다.

  • 정리 코드가 살려 둘 대상을 무엇으로 고르는지 코드를 열어 확인한다. 포트 번호나 이름 목록이면, 목록 밖은 지워진다고 가정한다.
  • “살려 둘지”는 번호 목록이 아니라 속성(예: 디버그 소켓 보유)으로 판정한다. 그래야 새 자동화가 생겨도 목록을 고칠 일이 없다.
  • 크론 전용 포트 같은 값은 한 파일의 상수 하나에만 두고 나머지는 가져다 쓴다.
  • 발행처럼 바깥으로 나가는 작업에는 멈춤 플래그와 결과 감시(이번 경우 제목 전체 검색 노출)를 처음부터 함께 둔다.

로그가 “로그인 만료”라고 말할 때도 그대로 믿지 않는 편이 낫습니다. 7월에도 9월에도 로그 문구는 증상을 적었고, 원인은 같은 PC의 다른 프로그램에 있었습니다. 크롬이 언제 다시 떴는지와 그 직전에 누가 무엇을 불렀는지를 나란히 놓는 데서 원인이 보였습니다.

네이버 편집기 안에서 소제목·인용구·링크 카드를 자동으로 조립한 과정은 네이버 블로그 링크 카드 자동 발행 글에 따로 정리했습니다. 사내 반복 업무를 이런 방식으로 자동화하고 싶다면 상담으로 지금의 작업 순서를 보내 주세요.

같은 방식으로 우리 업무를 재보고 싶다면

이 글에 쓴 계측·판정·자동화는 저희가 실제로 매일 돌리는 방식 그대로입니다. 어떤 작업을 자동화할 수 있고 어디를 사람이 잡아야 하는지, 현재 업무 흐름을 놓고 같이 짚어 드립니다.

새 글이 올라오면 알려 드립니다

이런 계측 기록을 새로 쓰면 메일로 한 통 보냅니다. 광고나 판촉은 보내지 않습니다.