<?xml version="1.0" encoding="UTF-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title>코드 한 줄</title>
		<link rel="alternate" type="text/html" hreflang="ko" href="https://blogz-demo.zitt.me/devlog"/>
	<link rel="self" type="application/atom+xml" href="https://blogz-demo.zitt.me/devlog/atom"/>
	<updated>2026-09-28T05:36:29+09:00</updated>
	<id>https://blogz-demo.zitt.me/devlog/atom</id>
	<generator>Zittme</generator>
		<entry>
		<title>3분기 회고: 느리게, 그러나 꾸준히</title>
		<link rel="alternate" type="text/html" href="https://blogz-demo.zitt.me/devlog/391"/>
	<link rel="replies" type="text/html" href="https://blogz-demo.zitt.me/devlog/391#comment"/>		<id>https://blogz-demo.zitt.me/devlog/391</id>
		<published>2026-09-26T17:12:42+09:00</published>
		<updated>2026-09-28T02:48:45+09:00</updated>
		<author>
			<name>윤서</name>
		</author>
		<summary type="text">분기마다 한 번씩 회고를 쓴다. 이번 분기의 주제는 속도였다. 서비스를 빠르게, 그리고 나는 조금 느리게. 한 일 목표결과상태주문 페이지 1초 이내평균 0.16초달성복원 훈련 분기 1회1회달성모바일 화면 개편70%진행 중블로그 월 4편월 3편아쉬움 하지 않기로 한 일 주말 배포. 월요일 아침에 사고를 수습하는 건 이제 그만.새 프레임워크 도입. 지금 것으로 충분하다.알림 전부 켜 두기. 정말 중요한 알림만 남겼다. 더 많이 하...</summary>
	<content type="html">&lt;p data-bz=&quot;text&quot;&gt;분기마다 한 번씩 회고를 쓴다. 이번 분기의 주제는 속도였다. 서비스를 빠르게, 그리고 나는 조금 느리게.&lt;/p&gt; &lt;nav data-bz=&quot;toc&quot;&gt;&lt;/nav&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;한 일&lt;/h2&gt; &lt;figure data-bz=&quot;table&quot; data-head=&quot;1&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;목표&lt;/th&gt;&lt;th&gt;결과&lt;/th&gt;&lt;th&gt;상태&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;주문 페이지 1초 이내&lt;/td&gt;&lt;td&gt;평균 0.16초&lt;/td&gt;&lt;td data-bg=&quot;green&quot;&gt;달성&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;복원 훈련 분기 1회&lt;/td&gt;&lt;td&gt;1회&lt;/td&gt;&lt;td data-bg=&quot;green&quot;&gt;달성&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;모바일 화면 개편&lt;/td&gt;&lt;td&gt;70%&lt;/td&gt;&lt;td data-bg=&quot;yellow&quot;&gt;진행 중&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;블로그 월 4편&lt;/td&gt;&lt;td&gt;월 3편&lt;/td&gt;&lt;td data-bg=&quot;red&quot;&gt;아쉬움&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;하지 않기로 한 일&lt;/h2&gt; &lt;ul data-bz=&quot;list&quot; data-kind=&quot;bullet&quot;&gt;&lt;li&gt;주말 배포. 월요일 아침에 사고를 수습하는 건 이제 그만.&lt;/li&gt;&lt;li&gt;새 프레임워크 도입. 지금 것으로 충분하다.&lt;/li&gt;&lt;li&gt;알림 전부 켜 두기. 정말 중요한 알림만 남겼다.&lt;/li&gt;&lt;/ul&gt; &lt;blockquote data-bz=&quot;quote&quot; data-style=&quot;big&quot;&gt;&lt;p&gt;더 많이 하지 말고, 덜 망가지게.&lt;/p&gt;&lt;cite&gt;이번 분기 책상 메모&lt;/cite&gt;&lt;/blockquote&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;다음 분기&lt;/h2&gt; &lt;ul data-bz=&quot;list&quot; data-kind=&quot;check&quot;&gt;&lt;li data-checked=&quot;0&quot;&gt;모바일 화면 개편 마무리&lt;/li&gt;&lt;li data-checked=&quot;0&quot;&gt;접근성 점검 10항목 모두 통과&lt;/li&gt;&lt;li data-checked=&quot;0&quot;&gt;필진 한결 님과 연재 하나 시작&lt;/li&gt;&lt;/ul&gt; &lt;div data-bz=&quot;divider&quot; data-style=&quot;dots&quot;&gt;&lt;hr /&gt;&lt;/div&gt; &lt;p data-bz=&quot;text&quot;&gt;읽어 주셔서 고맙습니다. 궁금한 점은 방명록에 남겨 주세요.&lt;/p&gt;</content>	<category term="209" label="회고" />	<category term="회고"/><category term="분기회고"/><category term="사이드프로젝트"/>	</entry><entry>
		<title>좋은 에러 메시지는 무엇을 말해야 할까</title>
		<link rel="alternate" type="text/html" href="https://blogz-demo.zitt.me/devlog/386"/>
	<link rel="replies" type="text/html" href="https://blogz-demo.zitt.me/devlog/386#comment"/>		<id>https://blogz-demo.zitt.me/devlog/386</id>
		<published>2026-09-21T14:48:42+09:00</published>
		<updated>2026-09-28T02:48:45+09:00</updated>
		<author>
			<name>한결</name>
		</author>
		<summary type="text">&quot;알 수 없는 오류가 발생했습니다.&quot; 이 문장을 볼 때마다 사용자는 무력해진다. 좋은 에러 메시지는 세 가지를 말한다. 무엇이 안 됐는지왜 안 됐는지 (알 수 있다면)그래서 어떻게 하면 되는지 나쁜 예좋은 예오류가 발생했습니다.사진을 올리지 못했습니다. 파일이 10MB를 넘습니다. 크기를 줄여 다시 올려 주세요.잘못된 입력입니다.전화번호는 숫자만 입력해 주세요. 예: 01012345678 throw new UserError( &#039;사진을 올리지 못했...</summary>
	<content type="html">&lt;p data-bz=&quot;text&quot;&gt;&quot;알 수 없는 오류가 발생했습니다.&quot; 이 문장을 볼 때마다 사용자는 무력해진다. 좋은 에러 메시지는 세 가지를 말한다.&lt;/p&gt; &lt;ol data-bz=&quot;list&quot; data-kind=&quot;number&quot;&gt;&lt;li&gt;&lt;b&gt;무엇이&lt;/b&gt; 안 됐는지&lt;/li&gt;&lt;li&gt;&lt;b&gt;왜&lt;/b&gt; 안 됐는지 (알 수 있다면)&lt;/li&gt;&lt;li&gt;&lt;b&gt;그래서 어떻게&lt;/b&gt; 하면 되는지&lt;/li&gt;&lt;/ol&gt; &lt;figure data-bz=&quot;table&quot; data-head=&quot;1&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;나쁜 예&lt;/th&gt;&lt;th&gt;좋은 예&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-bg=&quot;red&quot;&gt;오류가 발생했습니다.&lt;/td&gt;&lt;td data-bg=&quot;green&quot;&gt;사진을 올리지 못했습니다. 파일이 10MB를 넘습니다. 크기를 줄여 다시 올려 주세요.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-bg=&quot;red&quot;&gt;잘못된 입력입니다.&lt;/td&gt;&lt;td data-bg=&quot;green&quot;&gt;전화번호는 숫자만 입력해 주세요. 예: 01012345678&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt; &lt;div data-bz=&quot;code&quot;&gt;&lt;pre&gt;&lt;code data-lang=&quot;php&quot;&gt;throw new UserError( &#039;사진을 올리지 못했습니다. 파일이 10MB를 넘습니다.&#039;, hint: &#039;크기를 줄여 다시 올려 주세요.&#039; );&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p data-bz=&quot;text&quot;&gt;개발자에게 필요한 정보(스택, 요청 번호)는 로그에 남기고, 사용자에게는 다음 행동만 알려 주자.&lt;/p&gt;</content>	<category term="206" label="백엔드" />	<category term="UX라이팅"/><category term="에러메시지"/><category term="사용성"/>	</entry><entry>
		<title>사용자 천 명이 되던 날</title>
		<link rel="alternate" type="text/html" href="https://blogz-demo.zitt.me/devlog/381"/>
	<link rel="replies" type="text/html" href="https://blogz-demo.zitt.me/devlog/381#comment"/>		<id>https://blogz-demo.zitt.me/devlog/381</id>
		<published>2026-09-17T17:12:42+09:00</published>
		<updated>2026-09-17T17:12:42+09:00</updated>
		<author>
			<name>윤서</name>
		</author>
		<summary type="text">가입자 수가 1,000을 넘었다. 대단한 숫자는 아니지만 둘이서 퇴근 후에 만든 서비스로는 꽤 멀리 왔다. 지표석 달 전지금가입자3121,004주간 활성 사용자88341월 서버비1만 8천 원3만 2천 원받은 문의14건96건 잘한 것 문의에는 하루 안에 답했다.매주 금요일에 바뀐 점을 짧게 공지했다.기능보다 속도를 먼저 챙겼다. 아쉬운 것 모바일 화면을 너무 늦게 다듬었다.결제 기능을 서두르다 한 달을 버렸다. 천 명 중 한 명이 보낸 긴...</summary>
	<content type="html">&lt;p data-bz=&quot;text&quot;&gt;가입자 수가 1,000을 넘었다. 대단한 숫자는 아니지만 둘이서 퇴근 후에 만든 서비스로는 꽤 멀리 왔다.&lt;/p&gt; &lt;figure data-bz=&quot;table&quot; data-head=&quot;1&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;지표&lt;/th&gt;&lt;th&gt;석 달 전&lt;/th&gt;&lt;th&gt;지금&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;가입자&lt;/td&gt;&lt;td&gt;312&lt;/td&gt;&lt;td data-bg=&quot;blue&quot;&gt;1,004&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;주간 활성 사용자&lt;/td&gt;&lt;td&gt;88&lt;/td&gt;&lt;td&gt;341&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;월 서버비&lt;/td&gt;&lt;td&gt;1만 8천 원&lt;/td&gt;&lt;td&gt;3만 2천 원&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;받은 문의&lt;/td&gt;&lt;td&gt;14건&lt;/td&gt;&lt;td&gt;96건&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;잘한 것&lt;/h2&gt; &lt;ul data-bz=&quot;list&quot; data-kind=&quot;bullet&quot;&gt;&lt;li&gt;문의에는 하루 안에 답했다.&lt;/li&gt;&lt;li&gt;매주 금요일에 바뀐 점을 짧게 공지했다.&lt;/li&gt;&lt;li&gt;기능보다 속도를 먼저 챙겼다.&lt;/li&gt;&lt;/ul&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;아쉬운 것&lt;/h2&gt; &lt;ul data-bz=&quot;list&quot; data-kind=&quot;bullet&quot;&gt;&lt;li&gt;모바일 화면을 너무 늦게 다듬었다.&lt;/li&gt;&lt;li&gt;결제 기능을 서두르다 한 달을 버렸다.&lt;/li&gt;&lt;/ul&gt; &lt;blockquote data-bz=&quot;quote&quot; data-style=&quot;big&quot;&gt;&lt;p&gt;천 명 중 한 명이 보낸 긴 메일이, 천이라는 숫자보다 오래 남는다.&lt;/p&gt;&lt;/blockquote&gt; &lt;p data-bz=&quot;text&quot;&gt;다음 목표는 숫자가 아니라 속도다. 모든 페이지를 0.3초 안에.&lt;/p&gt;</content>	<category term="209" label="회고" />	<category term="회고"/><category term="사이드프로젝트"/><category term="사용자"/>	</entry><entry>
		<title>다크 모드, 색만 뒤집으면 끝일까</title>
		<link rel="alternate" type="text/html" href="https://blogz-demo.zitt.me/devlog/376"/>
	<link rel="replies" type="text/html" href="https://blogz-demo.zitt.me/devlog/376#comment"/>		<id>https://blogz-demo.zitt.me/devlog/376</id>
		<published>2026-09-09T19:36:42+09:00</published>
		<updated>2026-09-28T02:48:45+09:00</updated>
		<author>
			<name>한결</name>
		</author>
		<summary type="text">다크 모드를 처음 만들 때 흰색을 검은색으로, 검은색을 흰색으로 바꾸면 된다고 생각했다. 결과는 눈이 아픈 화면이었다. 순수한 검정 위의 순수한 흰 글자는 대비가 너무 세다. 색은 변수로, 뜻은 이름으로 :root { --bg: #ffffff; --text: #1a1d23; --muted: #69717e; --line: #e8eaee; } @media (prefers-color-scheme: dark) { :root { --bg: #15171c; --text: #e6e8ec; --muted: #9aa2ae; --line: #2a2e36; } } 놓치기 쉬운 ...</summary>
	<content type="html">&lt;p data-bz=&quot;text&quot;&gt;다크 모드를 처음 만들 때 흰색을 검은색으로, 검은색을 흰색으로 바꾸면 된다고 생각했다. 결과는 눈이 아픈 화면이었다. 순수한 검정 위의 순수한 흰 글자는 대비가 너무 세다.&lt;/p&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;색은 변수로, 뜻은 이름으로&lt;/h2&gt; &lt;div data-bz=&quot;code&quot;&gt;&lt;pre&gt;&lt;code data-lang=&quot;css&quot;&gt;:root { --bg: #ffffff; --text: #1a1d23; --muted: #69717e; --line: #e8eaee; } @media (prefers-color-scheme: dark) { :root { --bg: #15171c; --text: #e6e8ec; --muted: #9aa2ae; --line: #2a2e36; } }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;놓치기 쉬운 것&lt;/h2&gt; &lt;ul data-bz=&quot;list&quot; data-kind=&quot;check&quot;&gt;&lt;li data-checked=&quot;1&quot;&gt;버튼 호버 색도 다크용으로 따로&lt;/li&gt;&lt;li data-checked=&quot;1&quot;&gt;그림자는 다크에서 거의 안 보인다. 테두리로 대신&lt;/li&gt;&lt;li data-checked=&quot;0&quot;&gt;흰 배경 로고 이미지&lt;/li&gt;&lt;li data-checked=&quot;1&quot;&gt;사용자가 고른 모드를 기억하기&lt;/li&gt;&lt;/ul&gt; &lt;div data-bz=&quot;callout&quot; data-tone=&quot;note&quot;&gt;&lt;p&gt;&lt;code&gt;color-scheme: light dark;&lt;/code&gt; 를 선언하면 스크롤바와 입력칸도 알맞은 색으로 바뀝니다.&lt;/p&gt;&lt;/div&gt; &lt;p data-bz=&quot;text&quot;&gt;결국 다크 모드는 색을 뒤집는 일이 아니라, 색마다 역할을 정해 두는 일이었다.&lt;/p&gt;</content>	<category term="207" label="프런트엔드" />	<category term="CSS"/><category term="다크모드"/><category term="디자인시스템"/>	</entry><entry>
		<title>Nginx 설정 몇 줄로 첫 화면을 빠르게</title>
		<link rel="alternate" type="text/html" href="https://blogz-demo.zitt.me/devlog/370"/>
	<link rel="replies" type="text/html" href="https://blogz-demo.zitt.me/devlog/370#comment"/>		<id>https://blogz-demo.zitt.me/devlog/370</id>
		<published>2026-09-05T22:00:42+09:00</published>
		<updated>2026-09-05T22:00:42+09:00</updated>
		<author>
			<name>윤서</name>
		</author>
		<summary type="text">서버 코드만 빨라서는 부족하다. 정적 파일이 느리면 첫 화면이 늦게 뜬다. Nginx 설정에서 효과가 컸던 것만 모았다. gzip on; gzip_types text/css application/javascript image/svg+xml application/json; location ~* \.(css|js|woff2|jpg|png|webp)$ { expires 30d; add_header Cache-Control &quot;public, immutable&quot;; } listen 443 ssl http2; 지표전후첫 화면 표시2.4초1.1초전송량1.8MB640KB 파일 이름에 버전이나 해시를 붙...</summary>
	<content type="html">&lt;p data-bz=&quot;text&quot;&gt;서버 코드만 빨라서는 부족하다. 정적 파일이 느리면 첫 화면이 늦게 뜬다. Nginx 설정에서 효과가 컸던 것만 모았다.&lt;/p&gt; &lt;div data-bz=&quot;code&quot;&gt;&lt;pre&gt;&lt;code data-lang=&quot;nginx&quot;&gt;gzip on; gzip_types text/css application/javascript image/svg+xml application/json; location ~* \.(css|js|woff2|jpg|png|webp)$ { expires 30d; add_header Cache-Control &quot;public, immutable&quot;; } listen 443 ssl http2;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;figure data-bz=&quot;table&quot; data-head=&quot;1&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;지표&lt;/th&gt;&lt;th&gt;전&lt;/th&gt;&lt;th&gt;후&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;첫 화면 표시&lt;/td&gt;&lt;td&gt;2.4초&lt;/td&gt;&lt;td data-bg=&quot;green&quot;&gt;1.1초&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;전송량&lt;/td&gt;&lt;td&gt;1.8MB&lt;/td&gt;&lt;td&gt;640KB&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt; &lt;div data-bz=&quot;callout&quot; data-tone=&quot;warn&quot;&gt;&lt;p&gt;파일 이름에 버전이나 해시를 붙이지 않고 immutable 캐시를 걸면, 배포 뒤에도 옛 파일이 보입니다.&lt;/p&gt;&lt;/div&gt;</content>	<category term="208" label="운영 · 인프라" />	<category term="Nginx"/><category term="웹성능"/><category term="gzip"/><category term="캐시"/>	</entry><entry>
		<title>출시 전에 보는 접근성 체크리스트</title>
		<link rel="alternate" type="text/html" href="https://blogz-demo.zitt.me/devlog/365"/>
	<link rel="replies" type="text/html" href="https://blogz-demo.zitt.me/devlog/365#comment"/>		<id>https://blogz-demo.zitt.me/devlog/365</id>
		<published>2026-08-31T12:24:42+09:00</published>
		<updated>2026-08-31T12:24:42+09:00</updated>
		<author>
			<name>한결</name>
		</author>
		<summary type="text">접근성은 특별한 사람을 위한 기능이 아니다. 팔을 다친 사람, 햇빛 아래에서 휴대폰을 보는 사람, 모두가 언젠가는 쓴다. 출시 전에 보는 목록을 공유한다. 모든 이미지에 알맞은 대체 텍스트키보드만으로 모든 기능 사용 가능초점 표시가 보인다글자와 배경 대비 4.5:1 이상버튼과 링크의 이름이 뜻을 말한다입력칸마다 label 연결오류 메시지가 색에만 의존하지 않는다확대 200%에서 가로 스크롤 없음동영상 자막화면 낭독기로 ...</summary>
	<content type="html">&lt;p data-bz=&quot;text&quot;&gt;접근성은 특별한 사람을 위한 기능이 아니다. 팔을 다친 사람, 햇빛 아래에서 휴대폰을 보는 사람, 모두가 언젠가는 쓴다. 출시 전에 보는 목록을 공유한다.&lt;/p&gt; &lt;ul data-bz=&quot;list&quot; data-kind=&quot;check&quot;&gt;&lt;li data-checked=&quot;1&quot;&gt;모든 이미지에 알맞은 대체 텍스트&lt;/li&gt;&lt;li data-checked=&quot;1&quot;&gt;키보드만으로 모든 기능 사용 가능&lt;/li&gt;&lt;li data-checked=&quot;1&quot;&gt;초점 표시가 보인다&lt;/li&gt;&lt;li data-checked=&quot;1&quot;&gt;글자와 배경 대비 4.5:1 이상&lt;/li&gt;&lt;li data-checked=&quot;1&quot;&gt;버튼과 링크의 이름이 뜻을 말한다&lt;/li&gt;&lt;li data-checked=&quot;1&quot;&gt;입력칸마다 label 연결&lt;/li&gt;&lt;li data-checked=&quot;0&quot;&gt;오류 메시지가 색에만 의존하지 않는다&lt;/li&gt;&lt;li data-checked=&quot;0&quot;&gt;확대 200%에서 가로 스크롤 없음&lt;/li&gt;&lt;li data-checked=&quot;0&quot;&gt;동영상 자막&lt;/li&gt;&lt;li data-checked=&quot;0&quot;&gt;화면 낭독기로 한 번 훑어보기&lt;/li&gt;&lt;/ul&gt; &lt;figure data-bz=&quot;table&quot; data-head=&quot;1&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;도구&lt;/th&gt;&lt;th&gt;용도&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;브라우저 개발자 도구&lt;/td&gt;&lt;td&gt;대비 · 접근성 트리 확인&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;화면 낭독기&lt;/td&gt;&lt;td&gt;실제 사용 흐름 확인&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;키보드&lt;/td&gt;&lt;td&gt;Tab, Shift+Tab, Enter, Esc 만으로 써 보기&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt; &lt;blockquote data-bz=&quot;quote&quot; data-style=&quot;line&quot;&gt;&lt;p&gt;접근성 점검의 절반은 마우스를 치우는 것으로 끝난다.&lt;/p&gt;&lt;/blockquote&gt;</content>	<category term="207" label="프런트엔드" />	<category term="접근성"/><category term="웹표준"/><category term="체크리스트"/>	</entry><entry>
		<title>OPcache 설정, 기본값으로 두지 마세요</title>
		<link rel="alternate" type="text/html" href="https://blogz-demo.zitt.me/devlog/360"/>
	<link rel="replies" type="text/html" href="https://blogz-demo.zitt.me/devlog/360#comment"/>		<id>https://blogz-demo.zitt.me/devlog/360</id>
		<published>2026-08-27T14:48:42+09:00</published>
		<updated>2026-08-27T14:48:42+09:00</updated>
		<author>
			<name>윤서</name>
		</author>
		<summary type="text">쿼리를 고치고 나니 이번에는 PHP 자체가 보였다. 서버에 OPcache가 켜져 있긴 했지만 기본값 그대로였다. 파일 수가 많은 프레임워크에서는 기본 메모리가 금방 찬다. opcache.enable=1 opcache.memory_consumption=256 opcache.interned_strings_buffer=32 opcache.max_accelerated_files=20000 opcache.validate_timestamps=1 opcache.revalidate_freq=60 확인하는 법 opcache_get_status() 로 캐시 적중률과 남은 메모리를 본다...</summary>
	<content type="html">&lt;p data-bz=&quot;text&quot;&gt;쿼리를 고치고 나니 이번에는 PHP 자체가 보였다. 서버에 OPcache가 켜져 있긴 했지만 기본값 그대로였다. 파일 수가 많은 프레임워크에서는 기본 메모리가 금방 찬다.&lt;/p&gt; &lt;div data-bz=&quot;code&quot;&gt;&lt;pre&gt;&lt;code data-lang=&quot;ini&quot;&gt;opcache.enable=1 opcache.memory_consumption=256 opcache.interned_strings_buffer=32 opcache.max_accelerated_files=20000 opcache.validate_timestamps=1 opcache.revalidate_freq=60&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;확인하는 법&lt;/h2&gt; &lt;ol data-bz=&quot;list&quot; data-kind=&quot;number&quot;&gt;&lt;li&gt;&lt;code&gt;opcache_get_status()&lt;/code&gt; 로 캐시 적중률과 남은 메모리를 본다.&lt;/li&gt;&lt;li&gt;적중률이 99% 아래라면 메모리나 파일 수 한도를 늘린다.&lt;/li&gt;&lt;li&gt;배포 직후에는 FPM을 다시 불러와 캐시를 비운다.&lt;/li&gt;&lt;/ol&gt; &lt;figure data-bz=&quot;table&quot; data-head=&quot;1&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;항목&lt;/th&gt;&lt;th&gt;기본값&lt;/th&gt;&lt;th&gt;바꾼 값&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;memory_consumption&lt;/td&gt;&lt;td&gt;128&lt;/td&gt;&lt;td&gt;256&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;max_accelerated_files&lt;/td&gt;&lt;td&gt;10000&lt;/td&gt;&lt;td&gt;20000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;캐시 적중률&lt;/td&gt;&lt;td&gt;96.2%&lt;/td&gt;&lt;td data-bg=&quot;green&quot;&gt;99.8%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt; &lt;p data-bz=&quot;text&quot;&gt;응답 시간 평균이 210ms에서 160ms로 더 내려갔다. 코드 한 줄 안 건드리고 얻은 25%.&lt;/p&gt;</content>	<category term="208" label="운영 · 인프라" />	<category term="PHP"/><category term="OPcache"/><category term="서버설정"/>	</entry><entry>
		<title>백업은 복원해 봐야 백업이다</title>
		<link rel="alternate" type="text/html" href="https://blogz-demo.zitt.me/devlog/354"/>
	<link rel="replies" type="text/html" href="https://blogz-demo.zitt.me/devlog/354#comment"/>		<id>https://blogz-demo.zitt.me/devlog/354</id>
		<published>2026-08-22T17:12:42+09:00</published>
		<updated>2026-08-22T17:12:42+09:00</updated>
		<author>
			<name>윤서</name>
		</author>
		<summary type="text">매일 밤 백업이 돌고 있었다. 그런데 한 번도 복원해 본 적이 없었다. 불안해서 주말에 새 서버를 하나 빌려 복원 훈련을 했다. 결과는 반쯤 실패였다. 발견한 문제 DB 덤프에 트리거가 빠져 있었다.첨부 파일 백업이 권한 문제로 절반만 복사되고 있었다.복원 절차를 아는 사람이 나 하나뿐이었다. # 고친 백업 명령 mysqldump --single-transaction --routines --triggers mydb | gzip &gt; db-$(date +%F).sql.gz tar --exclude=&#039;fi...</summary>
	<content type="html">&lt;p data-bz=&quot;text&quot;&gt;매일 밤 백업이 돌고 있었다. 그런데 한 번도 복원해 본 적이 없었다. 불안해서 주말에 새 서버를 하나 빌려 복원 훈련을 했다. 결과는 반쯤 실패였다.&lt;/p&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;발견한 문제&lt;/h2&gt; &lt;ol data-bz=&quot;list&quot; data-kind=&quot;number&quot;&gt;&lt;li&gt;DB 덤프에 트리거가 빠져 있었다.&lt;/li&gt;&lt;li&gt;첨부 파일 백업이 권한 문제로 절반만 복사되고 있었다.&lt;/li&gt;&lt;li&gt;복원 절차를 아는 사람이 나 하나뿐이었다.&lt;/li&gt;&lt;/ol&gt; &lt;div data-bz=&quot;code&quot;&gt;&lt;pre&gt;&lt;code data-lang=&quot;bash&quot;&gt;# 고친 백업 명령 mysqldump --single-transaction --routines --triggers mydb | gzip &amp;gt; db-$(date +%F).sql.gz tar --exclude=&#039;files/cache&#039; -czf files-$(date +%F).tar.gz files&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div data-bz=&quot;callout&quot; data-tone=&quot;info&quot;&gt;&lt;p&gt;석 달에 한 번, 다른 서버에 실제로 복원해 보는 일정을 달력에 넣어 두었습니다.&lt;/p&gt;&lt;/div&gt; &lt;p data-bz=&quot;text&quot;&gt;복원 훈련을 한 뒤로 새벽 알림이 와도 덜 무섭다. 최악의 경우에도 어디까지 되돌릴 수 있는지 알기 때문이다.&lt;/p&gt;</content>	<category term="208" label="운영 · 인프라" />	<category term="백업"/><category term="복원"/><category term="운영"/><category term="데이터베이스"/>	</entry><entry>
		<title>커밋 메시지, 미래의 나에게 쓰는 편지</title>
		<link rel="alternate" type="text/html" href="https://blogz-demo.zitt.me/devlog/349"/>
	<link rel="replies" type="text/html" href="https://blogz-demo.zitt.me/devlog/349#comment"/>		<id>https://blogz-demo.zitt.me/devlog/349</id>
		<published>2026-08-18T19:36:42+09:00</published>
		<updated>2026-08-18T19:36:42+09:00</updated>
		<author>
			<name>윤서</name>
		</author>
		<summary type="text">&quot;수정&quot;, &quot;버그 고침&quot;, &quot;ㅇㅇ&quot;. 석 달 전 내가 남긴 커밋 메시지다. 왜 고쳤는지 알 수 없어서 같은 버그를 두 번 고쳤다. 지키기로 한 규칙 첫 줄은 무엇을 바꿨는지 50자 안쪽으로본문에는 왜 바꿨는지관련 이슈 번호는 끝에 주문 목록 N+1 쿼리를 IN 조회로 바꿈 주문 200개 기준 쿼리가 201회에서 2회로 줄어 평균 응답이 1.8초에서 0.2초가 됨. 문의 #128 코드는 무엇을 하는지 말하고, 커밋은 왜 했는지 말한다.</summary>
	<content type="html">&lt;p data-bz=&quot;text&quot;&gt;&quot;수정&quot;, &quot;버그 고침&quot;, &quot;ㅇㅇ&quot;. 석 달 전 내가 남긴 커밋 메시지다. 왜 고쳤는지 알 수 없어서 같은 버그를 두 번 고쳤다.&lt;/p&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;지키기로 한 규칙&lt;/h2&gt; &lt;ul data-bz=&quot;list&quot; data-kind=&quot;bullet&quot;&gt;&lt;li&gt;첫 줄은 무엇을 바꿨는지 50자 안쪽으로&lt;/li&gt;&lt;li&gt;본문에는 왜 바꿨는지&lt;/li&gt;&lt;li&gt;관련 이슈 번호는 끝에&lt;/li&gt;&lt;/ul&gt; &lt;div data-bz=&quot;code&quot;&gt;&lt;pre&gt;&lt;code data-lang=&quot;text&quot;&gt;주문 목록 N+1 쿼리를 IN 조회로 바꿈 주문 200개 기준 쿼리가 201회에서 2회로 줄어 평균 응답이 1.8초에서 0.2초가 됨. 문의 #128&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;blockquote data-bz=&quot;quote&quot; data-style=&quot;line&quot;&gt;&lt;p&gt;코드는 무엇을 하는지 말하고, 커밋은 왜 했는지 말한다.&lt;/p&gt;&lt;/blockquote&gt;</content>	<category term="206" label="백엔드" />	<category term="Git"/><category term="커밋메시지"/><category term="협업"/>	</entry><entry>
		<title>N+1 쿼리를 한 번에 잡기</title>
		<link rel="alternate" type="text/html" href="https://blogz-demo.zitt.me/devlog/343"/>
	<link rel="replies" type="text/html" href="https://blogz-demo.zitt.me/devlog/343#comment"/>		<id>https://blogz-demo.zitt.me/devlog/343</id>
		<published>2026-08-14T22:00:42+09:00</published>
		<updated>2026-09-28T02:48:45+09:00</updated>
		<author>
			<name>윤서</name>
		</author>
		<summary type="text">지난 편에서 찾은 범인은 이런 코드였다. 주문 목록을 가져온 뒤, 주문마다 상품을 다시 조회한다. foreach ($orders as $order) { // 주문마다 쿼리 한 번씩: 주문 200개면 쿼리 200번 $order-&gt;items = $db-&gt;query(&#039;SELECT * FROM order_items WHERE order_id = ?&#039;, [$order-&gt;id])-&gt;fetchAll(); } IN 으로 한 번에 가져오기 $ids = array_column($orders, &#039;id&#039;); $marks = implode(&#039;,&#039;, array_fill(0, count($ids), &#039;?&#039;)); $rows =...</summary>
	<content type="html">&lt;p data-bz=&quot;text&quot;&gt;지난 편에서 찾은 범인은 이런 코드였다. 주문 목록을 가져온 뒤, 주문마다 상품을 다시 조회한다.&lt;/p&gt; &lt;div data-bz=&quot;code&quot;&gt;&lt;pre&gt;&lt;code data-lang=&quot;php&quot;&gt;foreach ($orders as $order) { // 주문마다 쿼리 한 번씩: 주문 200개면 쿼리 200번 $order-&amp;gt;items = $db-&amp;gt;query(&#039;SELECT * FROM order_items WHERE order_id = ?&#039;, [$order-&amp;gt;id])-&amp;gt;fetchAll(); }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;IN 으로 한 번에 가져오기&lt;/h2&gt; &lt;div data-bz=&quot;code&quot;&gt;&lt;pre&gt;&lt;code data-lang=&quot;php&quot;&gt;$ids = array_column($orders, &#039;id&#039;); $marks = implode(&#039;,&#039;, array_fill(0, count($ids), &#039;?&#039;)); $rows = $db-&amp;gt;query(&quot;SELECT * FROM order_items WHERE order_id IN ($marks)&quot;, $ids)-&amp;gt;fetchAll(); $byOrder = []; foreach ($rows as $row) { $byOrder[$row-&amp;gt;order_id][] = $row; } foreach ($orders as $order) { $order-&amp;gt;items = $byOrder[$order-&amp;gt;id] ?? []; }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;결과&lt;/h2&gt; &lt;figure data-bz=&quot;table&quot; data-head=&quot;1&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;고치기 전&lt;/th&gt;&lt;th&gt;고친 뒤&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;쿼리 수 (주문 200개)&lt;/td&gt;&lt;td&gt;201회&lt;/td&gt;&lt;td data-bg=&quot;green&quot;&gt;2회&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;평균 응답&lt;/td&gt;&lt;td&gt;1,840ms&lt;/td&gt;&lt;td data-bg=&quot;green&quot;&gt;210ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;최대 응답&lt;/td&gt;&lt;td&gt;5,210ms&lt;/td&gt;&lt;td data-bg=&quot;green&quot;&gt;380ms&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt; &lt;div data-bz=&quot;callout&quot; data-tone=&quot;warn&quot;&gt;&lt;p&gt;IN 목록이 수천 개가 넘으면 오히려 느려질 수 있습니다. 페이지 단위로 나눠 가져오세요.&lt;/p&gt;&lt;/div&gt; &lt;p data-bz=&quot;text&quot;&gt;코드 열 줄 남짓 바꿨을 뿐인데 체감이 완전히 달라졌다. 메일을 보내 준 사용자에게 답장을 쓰면서 가장 뿌듯했던 순간.&lt;/p&gt;</content>	<category term="206" label="백엔드" />	<category term="PHP"/><category term="SQL"/><category term="N+1"/><category term="성능"/>	</entry><entry>
		<title>키보드를 바꿨더니 코드가 달라졌다</title>
		<link rel="alternate" type="text/html" href="https://blogz-demo.zitt.me/devlog/338"/>
	<link rel="replies" type="text/html" href="https://blogz-demo.zitt.me/devlog/338#comment"/>		<id>https://blogz-demo.zitt.me/devlog/338</id>
		<published>2026-08-07T00:24:42+09:00</published>
		<updated>2026-08-07T00:24:42+09:00</updated>
		<author>
			<name>윤서</name>
		</author>
		<summary type="text">오 년 쓴 노트북 키보드를 떠나 기계식 키보드를 샀다. 타건감이 좋으니 코드도 잘 써질 거라는 기대가 있었다. 나무 책상 위의 새 키보드 항목느낌타건감좋다. 오래 쳐도 손끝이 덜 아프다소음생각보다 크다. 밤에는 조심생산성변화 없음. 당연하다 결론은 이렇다. 장비는 기분을 바꾸고, 기분은 앉아 있는 시간을 늘린다. 그 정도면 충분히 좋은 투자다.</summary>
	<content type="html">&lt;p data-bz=&quot;text&quot;&gt;오 년 쓴 노트북 키보드를 떠나 기계식 키보드를 샀다. 타건감이 좋으니 코드도 잘 써질 거라는 기대가 있었다.&lt;/p&gt; &lt;figure data-bz=&quot;image&quot; data-size=&quot;normal&quot;&gt;&lt;img src=&quot;https://blogz-demo.zitt.me/files/demo/keyboard-12.jpg&quot; alt=&quot;나무 책상 위의 새 키보드&quot; /&gt;&lt;figcaption&gt;나무 책상 위의 새 키보드&lt;/figcaption&gt;&lt;/figure&gt; &lt;figure data-bz=&quot;table&quot; data-head=&quot;1&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;항목&lt;/th&gt;&lt;th&gt;느낌&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;타건감&lt;/td&gt;&lt;td&gt;좋다. 오래 쳐도 손끝이 덜 아프다&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;소음&lt;/td&gt;&lt;td&gt;생각보다 크다. 밤에는 조심&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;생산성&lt;/td&gt;&lt;td&gt;변화 없음. 당연하다&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt; &lt;p data-bz=&quot;text&quot;&gt;결론은 이렇다. 장비는 기분을 바꾸고, 기분은 앉아 있는 시간을 늘린다. 그 정도면 충분히 좋은 투자다.&lt;/p&gt;</content>	<category term="209" label="회고" />	<category term="키보드"/><category term="작업환경"/><category term="장비"/>	</entry><entry>
		<title>느린 페이지는 어디서 느린가</title>
		<link rel="alternate" type="text/html" href="https://blogz-demo.zitt.me/devlog/331"/>
	<link rel="replies" type="text/html" href="https://blogz-demo.zitt.me/devlog/331#comment"/>		<id>https://blogz-demo.zitt.me/devlog/331</id>
		<published>2026-07-31T19:36:42+09:00</published>
		<updated>2026-07-31T19:36:42+09:00</updated>
		<author>
			<name>윤서</name>
		</author>
		<summary type="text">사용자 한 분이 &quot;주문 내역 페이지가 가끔 5초씩 걸려요&quot;라는 메일을 보냈다. 로컬에서는 0.3초. 이런 문제는 대개 추측으로 고치려다 시간을 버린다. 이번에는 재는 것부터 시작했다. 1. 느린 요청부터 모은다 PHP-FPM의 슬로우 로그를 켜면 일정 시간 넘게 걸린 요청의 호출 스택을 남겨 준다. 설정은 두 줄이면 된다. ; /etc/php/8.1/fpm/pool.d/www.conf request_slowlog_timeout = 2s slowlog = /var/log/php-fpm/slow.log 하...</summary>
	<content type="html">&lt;p data-bz=&quot;text&quot;&gt;사용자 한 분이 &quot;주문 내역 페이지가 가끔 5초씩 걸려요&quot;라는 메일을 보냈다. 로컬에서는 0.3초. 이런 문제는 대개 추측으로 고치려다 시간을 버린다. 이번에는 재는 것부터 시작했다.&lt;/p&gt; &lt;nav data-bz=&quot;toc&quot;&gt;&lt;/nav&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;1. 느린 요청부터 모은다&lt;/h2&gt; &lt;p data-bz=&quot;text&quot;&gt;PHP-FPM의 슬로우 로그를 켜면 일정 시간 넘게 걸린 요청의 호출 스택을 남겨 준다. 설정은 두 줄이면 된다.&lt;/p&gt; &lt;div data-bz=&quot;code&quot;&gt;&lt;pre&gt;&lt;code data-lang=&quot;ini&quot;&gt;; /etc/php/8.1/fpm/pool.d/www.conf request_slowlog_timeout = 2s slowlog = /var/log/php-fpm/slow.log&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p data-bz=&quot;text&quot;&gt;하루 동안 모아 보니 느린 요청의 90%가 같은 함수에서 멈춰 있었다. 주문 목록을 돌면서 상품 정보를 하나씩 가져오는 곳이다.&lt;/p&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;2. 숫자로 확인한다&lt;/h2&gt; &lt;figure data-bz=&quot;table&quot; data-head=&quot;1&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;측정 지점&lt;/th&gt;&lt;th&gt;평균&lt;/th&gt;&lt;th&gt;최대&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;전체 요청&lt;/td&gt;&lt;td&gt;1,840ms&lt;/td&gt;&lt;td data-bg=&quot;red&quot;&gt;5,210ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;DB 쿼리 합계&lt;/td&gt;&lt;td&gt;1,520ms&lt;/td&gt;&lt;td&gt;4,800ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;템플릿 렌더링&lt;/td&gt;&lt;td&gt;95ms&lt;/td&gt;&lt;td&gt;160ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;나머지&lt;/td&gt;&lt;td&gt;225ms&lt;/td&gt;&lt;td&gt;250ms&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt; &lt;div data-bz=&quot;callout&quot; data-tone=&quot;note&quot;&gt;&lt;p&gt;평균만 보면 안 됩니다. 사용자가 느끼는 건 최댓값과 상위 5%입니다.&lt;/p&gt;&lt;/div&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;3. 범인은 반복문 속 쿼리&lt;/h2&gt; &lt;p data-bz=&quot;text&quot;&gt;주문이 많은 사용자일수록 느렸다. 전형적인 N+1 문제다. 다음 편에서 이걸 어떻게 한 번의 쿼리로 줄였는지 적는다.&lt;/p&gt; &lt;blockquote data-bz=&quot;quote&quot; data-style=&quot;line&quot;&gt;&lt;p&gt;측정하지 않은 최적화는 기도와 같다.&lt;/p&gt;&lt;cite&gt;어느 개발자의 책상 메모&lt;/cite&gt;&lt;/blockquote&gt;</content>	<category term="206" label="백엔드" />	<category term="PHP"/><category term="성능"/><category term="프로파일링"/><category term="슬로우로그"/>	</entry><entry>
		<title>첫 장애의 밤</title>
		<link rel="alternate" type="text/html" href="https://blogz-demo.zitt.me/devlog/325"/>
	<link rel="replies" type="text/html" href="https://blogz-demo.zitt.me/devlog/325#comment"/>		<id>https://blogz-demo.zitt.me/devlog/325</id>
		<published>2026-07-23T22:00:42+09:00</published>
		<updated>2026-09-28T02:48:45+09:00</updated>
		<author>
			<name>윤서</name>
		</author>
		<summary type="text">서비스를 연 지 석 달째 되던 날 새벽 두 시, 모니터링 알림이 울렸다. 사이트가 열리지 않는다. 침대에서 노트북을 열었을 때 손이 떨렸다. 타임라인 시각일02:04응답 없음 알림02:09SSH 접속, 디스크 100% 확인02:15원인: 로그 파일 38GB02:18오래된 로그 압축 · 정리, 서비스 복구02:40로그 순환 설정 추가 로그 순환(logrotate)을 설정하지 않은 로그는 언젠가 반드시 디스크를 채웁니다. 배운 것 디스크 사용량 80% 알림 추가...</summary>
	<content type="html">&lt;p data-bz=&quot;text&quot;&gt;서비스를 연 지 석 달째 되던 날 새벽 두 시, 모니터링 알림이 울렸다. 사이트가 열리지 않는다. 침대에서 노트북을 열었을 때 손이 떨렸다.&lt;/p&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;타임라인&lt;/h2&gt; &lt;figure data-bz=&quot;table&quot; data-head=&quot;1&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;시각&lt;/th&gt;&lt;th&gt;일&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;02:04&lt;/td&gt;&lt;td&gt;응답 없음 알림&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;02:09&lt;/td&gt;&lt;td&gt;SSH 접속, 디스크 100% 확인&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;02:15&lt;/td&gt;&lt;td&gt;원인: 로그 파일 38GB&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;02:18&lt;/td&gt;&lt;td&gt;오래된 로그 압축 · 정리, 서비스 복구&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;02:40&lt;/td&gt;&lt;td&gt;로그 순환 설정 추가&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt; &lt;div data-bz=&quot;callout&quot; data-tone=&quot;warn&quot;&gt;&lt;p&gt;로그 순환(logrotate)을 설정하지 않은 로그는 언젠가 반드시 디스크를 채웁니다.&lt;/p&gt;&lt;/div&gt; &lt;h2 data-bz=&quot;heading&quot;&gt;배운 것&lt;/h2&gt; &lt;ul data-bz=&quot;list&quot; data-kind=&quot;check&quot;&gt;&lt;li data-checked=&quot;1&quot;&gt;디스크 사용량 80% 알림 추가&lt;/li&gt;&lt;li data-checked=&quot;1&quot;&gt;애플리케이션 로그 순환 설정&lt;/li&gt;&lt;li data-checked=&quot;1&quot;&gt;장애 대응 절차 문서화&lt;/li&gt;&lt;li data-checked=&quot;0&quot;&gt;두 번째 담당자 정하기&lt;/li&gt;&lt;/ul&gt; &lt;blockquote data-bz=&quot;quote&quot; data-style=&quot;line&quot;&gt;&lt;p&gt;장애는 기술 문제이기 전에 준비의 문제였다.&lt;/p&gt;&lt;/blockquote&gt; &lt;p data-bz=&quot;text&quot;&gt;복구 뒤 공지를 올리고 잠들었더니 아침에 사용자 몇 분이 &quot;고생하셨어요&quot;라고 댓글을 달아 주셨다. 작은 서비스의 가장 큰 힘은 이런 사람들이다.&lt;/p&gt;</content>	<category term="208" label="운영 · 인프라" />	<category term="장애대응"/><category term="운영"/><category term="회고"/><category term="디스크"/>	</entry><entry>
		<title>새 노트북에 개발 환경을 옮기며 정리한 것</title>
		<link rel="alternate" type="text/html" href="https://blogz-demo.zitt.me/devlog/320"/>
	<link rel="replies" type="text/html" href="https://blogz-demo.zitt.me/devlog/320#comment"/>		<id>https://blogz-demo.zitt.me/devlog/320</id>
		<published>2026-07-14T22:00:42+09:00</published>
		<updated>2026-07-14T22:00:42+09:00</updated>
		<author>
			<name>윤서</name>
		</author>
		<summary type="text">노트북을 바꾸면서 개발 환경을 옮기는 데 하루가 걸렸다. 다음에는 한 시간 안에 끝내려고 설치 목록과 설정을 저장소 하나에 모았다. 패키지 목록을 파일 하나로셸 설정 · 별칭 저장소에 보관편집기 설정 동기화SSH 키는 새로 만들고 옛 키 폐기로컬 DB 샘플 데이터 스크립트 #!/usr/bin/env bash set -e xargs -a packages.txt sudo apt-get install -y ln -sf &quot;/.bashrc&quot; ~/.bashrc ln -sf &quot;/.gitconfig&quot; ~/.gitconfig echo &#039;준...</summary>
	<content type="html">&lt;p data-bz=&quot;text&quot;&gt;노트북을 바꾸면서 개발 환경을 옮기는 데 하루가 걸렸다. 다음에는 한 시간 안에 끝내려고 설치 목록과 설정을 저장소 하나에 모았다.&lt;/p&gt; &lt;ul data-bz=&quot;list&quot; data-kind=&quot;check&quot;&gt;&lt;li data-checked=&quot;1&quot;&gt;패키지 목록을 파일 하나로&lt;/li&gt;&lt;li data-checked=&quot;1&quot;&gt;셸 설정 · 별칭 저장소에 보관&lt;/li&gt;&lt;li data-checked=&quot;1&quot;&gt;편집기 설정 동기화&lt;/li&gt;&lt;li data-checked=&quot;1&quot;&gt;SSH 키는 새로 만들고 옛 키 폐기&lt;/li&gt;&lt;li data-checked=&quot;0&quot;&gt;로컬 DB 샘플 데이터 스크립트&lt;/li&gt;&lt;/ul&gt; &lt;div data-bz=&quot;code&quot;&gt;&lt;pre&gt;&lt;code data-lang=&quot;bash&quot;&gt;#!/usr/bin/env bash set -e xargs -a packages.txt sudo apt-get install -y ln -sf &quot;/.bashrc&quot; ~/.bashrc ln -sf &quot;/.gitconfig&quot; ~/.gitconfig echo &#039;준비 끝&#039;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p data-bz=&quot;text&quot;&gt;이 글을 쓰고 나서 동료에게 저장소를 보여 줬더니, 자기 것도 만들겠다며 가져갔다.&lt;/p&gt;</content>	<category term="208" label="운영 · 인프라" />	<category term="개발환경"/><category term="dotfiles"/><category term="생산성"/>	</entry></feed>
