<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Spring Boot on 얼쑤 · Team Edo</title><link>https://team-edo.github.io/tags/spring-boot/</link><description>Recent content in Spring Boot on 얼쑤 · Team Edo</description><generator>Hugo</generator><language>ko-kr</language><lastBuildDate>Wed, 28 Oct 2026 00:00:00 +0900</lastBuildDate><atom:link href="https://team-edo.github.io/tags/spring-boot/index.xml" rel="self" type="application/rss+xml"/><item><title>21MiB와 26MiB가 받은 서로 다른 413</title><link>https://team-edo.github.io/posts/2026/10/recording-upload-size-layers/</link><pubDate>Wed, 28 Oct 2026 00:00:00 +0900</pubDate><guid>https://team-edo.github.io/posts/2026/10/recording-upload-size-layers/</guid><description>&lt;p>얼쑤의 녹음 업로드를 확인하면서 &lt;strong>21MiB&lt;/strong>와 &lt;strong>26MiB&lt;/strong> 크기의 입력을 같은 Nginx를 거쳐 보냈습니다. 두 요청 모두 HTTP 413이었습니다. 21MiB 요청에는 백엔드가 만든 JSON 오류 코드 &lt;code>RECORDING_TOO_LARGE&lt;/code>가 들어 있었고, 26MiB 요청에는 Nginx가 만든 HTML 응답이 돌아왔습니다. 상태 코드는 같았지만 요청을 멈춘 곳이 달랐습니다.&lt;/p>
&lt;h2 id="파일-하나의-한도와-요청-본문의-한도를-나눴다">파일 한도와 요청 본문 한도&lt;/h2>
&lt;p>연주 녹음 한 파일에는 &lt;strong>20MiB&lt;/strong>, 즉 20,971,520바이트까지 허용하기로 했습니다. 앱은 녹음 파일을 multipart 요청의 한 파트로 보냅니다. 이 요청의 본문에는 파일 바이트 외에도 파트를 구분하는 경계와 파트 헤더가 붙습니다. 요청 본문은 Nginx를 지나고, Spring이 multipart를 파싱한 뒤에야 백엔드의 녹음 검사기가 파일 파트의 크기를 확인할 수 있습니다.&lt;/p></description></item><item><title>Flyway를 끈 운영 프로필에서 API 켜기</title><link>https://team-edo.github.io/posts/2026/10/spring-profile-ops-terms-route/</link><pubDate>Wed, 28 Oct 2026 00:00:00 +0900</pubDate><guid>https://team-edo.github.io/posts/2026/10/spring-profile-ops-terms-route/</guid><description>&lt;p>얼쑤의 백엔드는 운영에서 &lt;code>ops&lt;/code> 프로필로 실행했습니다. 이 프로필에서는 앱이 이미 만들어진 DB에 연결하고, 스키마 변경은 별도 작업에서 적용합니다. 업무 API를 켜기 전의 구성을 확인해 보니 약관을 비롯한 업무 컨트롤러와 서비스가 &lt;code>db&lt;/code> 프로필에만 등록돼 있었습니다. 프로세스가 기동해도 &lt;code>ops&lt;/code>로 뜬 컨텍스트에는 약관 요청을 받을 컨트롤러가 없었습니다.&lt;/p>
&lt;h2 id="업무-빈과-스키마-변경의-조건을-분리했다">업무 빈과 마이그레이션 분리&lt;/h2>
&lt;p>처음에는 두 프로필을 함께 켜면 업무 빈도 만들 수 있다고 생각했습니다. 하지만 당시 &lt;code>db&lt;/code>는 Flyway를 켰고 &lt;code>ops&lt;/code>는 껐습니다. 두 프로필에 같은 설정 키가 있으면 뒤에 지정한 프로필의 값이 적용됩니다. 순서를 바꾸는 것만으로 운영 앱이 기동할 때 마이그레이션을 실행할 수 있는 구성이었습니다.&lt;/p></description></item><item><title>HTTP 테스트에서만 수신 시각 고정하기</title><link>https://team-edo.github.io/posts/2026/10/scope-fixed-clock-to-http-test/</link><pubDate>Wed, 28 Oct 2026 00:00:00 +0900</pubDate><guid>https://team-edo.github.io/posts/2026/10/scope-fixed-clock-to-http-test/</guid><description>&lt;p>악보 화면을 본 시간을 서버에 보낼 때, 서버는 앱이 보낸 시간과 실제로 요청을 받은 시각을 대조합니다. 화면을 본 시간이 수신 시각에서 시작 시각을 뺀 값보다 지나치게 길면 저장하지 않습니다. 이런 API를 고정된 날짜로 테스트하면, 테스트를 실행하는 날짜에 따라 같은 요청이 허용되거나 거절될 수 있습니다.&lt;/p>
&lt;h2 id="실제-http-테스트에만-수신-시계를-고정했다">테스트 설정에 고정 &lt;code>Clock&lt;/code> 주입&lt;/h2>
&lt;p>체류 기록 테스트는 애플리케이션을 띄우고 실제 HTTP로 요청합니다. 서비스만 직접 호출하는 테스트처럼 생성자에 시계를 건네는 것으로는 서버의 수신 시각을 고정할 수 없습니다. 그래서 이 테스트가 가져오는 &lt;code>@TestConfiguration&lt;/code>에 고정된 &lt;code>Clock&lt;/code>을 만들고 &lt;code>@Primary&lt;/code>를 붙였습니다. 이 설정을 가져온 테스트에서는 같은 타입을 주입할 때 고정 시계를 우선합니다.&lt;/p></description></item><item><title>분석 실행기를 공용 Bean으로 등록하지 않은 이유</title><link>https://team-edo.github.io/posts/2026/10/own-analysis-executor-lifecycle/</link><pubDate>Wed, 28 Oct 2026 00:00:00 +0900</pubDate><guid>https://team-edo.github.io/posts/2026/10/own-analysis-executor-lifecycle/</guid><description>&lt;p>얼쑤는 녹음을 접수한 뒤 분석을 별도 작업으로 실행합니다. 이 기능을 붙이던 때에는 악보를 채점용 음표로 바꾸는 구현, 녹음 읽기 주소를 만드는 구현, 분석 서버 주소가 서로 다른 작업에서 들어왔습니다. 일부만 합쳐졌을 때도 앱은 켜져야 했습니다. 세 가지가 모두 준비되면 분석을 열고, 동시에 처리할 작업과 대기열은 이 기능의 규모에 맞춰 제한하기로 했습니다.&lt;/p>
&lt;h2 id="앱은-켜-두고-조건이-갖춰지면-분석-열기">앱은 켜 두고 조건이 갖춰지면 분석 열기&lt;/h2>
&lt;p>설정은 Spring의 &lt;code>ObjectProvider&lt;/code>로 악보 변환기와 녹음 읽기 주소 제공자를 찾고, 분석 서버 주소가 비었는지도 봅니다. 세 가지가 모두 있으면 HTTP 클라이언트와 분석기를 전용 실행 경로에 연결합니다. 하나라도 빠지면 분석이 꺼진 객체를 반환합니다. 이 상태에서는 업로드가 끝나도 누락 항목을 기록하고 작업을 넘기지 않습니다. 분석을 명시적으로 다시 요청하는 경로에서는 제출 거절을 알려, 호출자가 이미 열었던 시도를 정리할 수 있게 했습니다.&lt;/p></description></item><item><title>인증 추가 뒤 자동 배포가 10번 실패한 이유</title><link>https://team-edo.github.io/posts/2026/10/separate-deployment-health-probes/</link><pubDate>Wed, 28 Oct 2026 00:00:00 +0900</pubDate><guid>https://team-edo.github.io/posts/2026/10/separate-deployment-health-probes/</guid><description>&lt;p>얼쑤에서 새로 병합한 약관 조회 API를 운영에서 호출했더니 404가 돌아왔습니다. 기존 서비스는 계속 응답하고 있었지만, 실행 중인 JAR의 버전과 컨테이너가 시작한 시각을 확인하니 그 뒤의 변경은 배포되지 않은 상태였습니다. 처음 살펴본 Jenkins 실행 열 건은 연속으로 배포 검사에서 실패했습니다.&lt;/p>
&lt;p>Jenkins API에서 인증 때문에 실행 기록을 읽을 수 없어, 서버에서 빌드별 &lt;code>build.xml&lt;/code>과 콘솔 로그를 읽었습니다. &lt;code>build.xml&lt;/code>의 결과·시작 시각·커밋 SHA를 콘솔 로그의 마지막 실패 단계와 맞춰 보니, 서로 다른 커밋의 배포가 같은 검사에서 멈췄습니다.&lt;/p></description></item></channel></rss>