쿠키 하나로 직접 만든 방문 통계 — IP 없이 세고, 5초마다 모아서 저장
블로그에 방문 통계를 직접 만들었다. IP와 User-Agent는 저장하지 않고 무작위 ID 쿠키 하나로 방문자를 구분한다. 요청 처리 중에는 DB를 건드리지 않도록 메모리 큐에 쌓았다가 5초마다 일괄 저장한다. 수집 대상 거르기, 유입 경로 분류까지 설계를 정리했다.
태그
글 8 개
블로그에 방문 통계를 직접 만들었다. IP와 User-Agent는 저장하지 않고 무작위 ID 쿠키 하나로 방문자를 구분한다. 요청 처리 중에는 DB를 건드리지 않도록 메모리 큐에 쌓았다가 5초마다 일괄 저장한다. 수집 대상 거르기, 유입 경로 분류까지 설계를 정리했다.
블로그 디자인을 Bootstrap 5에서 Tailwind CSS v4로 바꿨다. dotnet build에 CSS 빌드를 끼워 넣은 방법과, 마크다운 표의 class="table" 충돌, 코드 블록 이중 배경, 관리자 표의 sr-only 때문에 모바일 폭이 넓어진 문제를 정리했다.
.NET Framework 4.8 MVC 5로 만들어 운영에 올린 블로그를 같은 날 ASP.NET Core 10으로 옮겼다. URL, 운영 DB, 관리자 비밀번호를 그대로 둔 채 프레임워크만 바꾸기 위해 정한 원칙과, EF6가 만든 기존 스키마를 EF Core 10이 이어받게 한 방법을 정리했다.
디자인 개편을 운영 서버에 배포하다 동기화가 실패했고, 사이트가 2~3분 동안 503을 냈다. Web Deploy의 AppOffline 규칙이 올려 둔 app_offline.htm이 실패한 배포 뒤에 그대로 남은 것이 원인이었다. 동작 원리와 재시도로 바꾼 배포 스크립트를 정리했다.
배포 스크립트에 비밀번호 마스킹 코드를 넣어 두었는데도, 배포가 실패하자 비밀번호가 평문으로 출력됐다. msdeploy가 실패 시 인수를 그대로 다시 찍는 동작과 PowerShell의 $ErrorActionPreference = 'Stop'이 만나 생긴 일이다. 원인과 수정 코드, 사고 뒤 처리를 정리했다.
잘 돌던 사이트가 MySQL 재시작 직후 모든 페이지에서 500 오류를 냈다. 원인은 MySQL 8의 기본 인증 방식 caching_sha2_password가 재시작 뒤 비암호화 연결을 거부하는 동작이었다. 증상, 원리, 세 가지 해결책 비교와 최종 선택을 정리했다.
.NET Framework 4.8 + EF6 + MySQL Connector 조합으로 Code First 마이그레이션을 만들다 만난 세 가지 문제. 인덱스 이름 따옴표 누락, dbo. 접두사로 인한 Down() 실패, 무시되는 기본값과 각각의 해결 방법을 정리했다.
빈 솔루션에서 운영 배포, 프레임워크 전환, 디자인 개편, 방문 통계까지 하루 동안 12단계로 진행한 애드소프트 블로그 구축기. 시리즈 첫 글로 전체 흐름과 그날 겪은 일들을 정리했다.