JAVA (16) 썸네일형 리스트형 Logback/SLF4j 사용 이유 한 줄 요약코드는 SLF4J(리모컨)만 보고 말하고, 실제로 로그를 찍는 일은 Logback(TV)이 함. 그래서 TV를 바꿔도(Logback→다른 것) 코드는 거의 안 바꿔도 됨SLF4J는 로깅 Facade라서 코드가 구현체에 묶이지 않음. 서드파티가 JUL/Log4j/JCL을 써도 브리지로 한 채널로 모음. 또한 {} 파라미터 로깅과 MDC 덕에 성능과 추적성이 좋음. 구현체는 Spring Boot 기본인 Logback을 쓰면 Appender/MDC/Async/JSON 로깅까지 운영 기능이 기본 제공되어, 배포·관리가 쉬움왜 이 조합이 좋을까? (현업 포인트 5개)갈아끼우기 쉬움 : 내일 Logback 대신 Log4j2로 바꿔도, 코드는 SLF4J 그대로 (SLF4J는 ‘로깅 API’ 앞단 추상화 계.. 다국어 Papago API 연결 공식 사이트 설명도 좋음. 쉽게 따라하기1) 콘솔에서 키 발급네이버 클라우드에서 Papago Translation 사용 설정 → 애플리케이션 등록 → Client ID/Secret 발급2) 설정 (환경변수/설정파일)application.ymlpapago: base-url: ${PAPAGO_URL} client-id: ${PAPAGO_CLIENT_ID} client-secret: ${PAPAGO_CLIENT_SECRET}운영에선 실제 값은 환경변수로 주입3) WebClient Bean@Configuration@RequiredArgsConstructor@FieldDefaults(level = AccessLevel.PRIVATE)public class Config { @Bean WebClient pa.. Sentry + OpenSearch 로그 수집 왜 이렇게 하나요?Sentry : 예외·에러 알림과 이슈 그룹핑 자동화. (Spring Boot 스타터 + Logback 연동) OpenSearch : JSON 로그를 모아 검색/대시보드. (에이전트로 수집 or Logback에서 바로 전송)1) 의존성 추가 (Gradle 예시)dependencies { // Sentry (Spring Boot + Logback) implementation "io.sentry:sentry-spring-boot-starter-jakarta:8.19.1" implementation "io.sentry:sentry-logback:8.19.1" // JSON 로그 인코더 (Logback) implementation "net.logstash.logback:logstash.. Retry 시스템 만들기 왜 필요한가?네트워크 순간 끊김, 외부 API 일시 장애, DB 잠깐 과부하… 이런 일시적(Transient) 오류는 “조금 있다 다시” 하면 종종 해결...이걸 자동으로 해주는 게 Retry. 단, 영구적(Permanent) 오류는 다시 해도 안됨 (예: 잘못된 파라미터)재시도 대상만 고르는 게 핵심1) 기본 원칙대상 선별 : 재시도할 예외만 고르기 (네트워크 타임아웃, 429/503 등). 재시도해도 소용없는 예외는 제외Backoff + Jitter : 점점 기다리는 시간 늘리기(Exponential Backoff) + 최대 대기 시간(cap)서버 힌트 존중 : HTTP 429에 Retry-After 있으면 그만큼 쉬었다 재시도Idempotency : 같은 요청을 여러 번 보내도 한 번만 처리되게 키.. 실무형 Global Exception Handler 만들기 (ErrorCode Enum + 국제화 + 로그 시스템까지) * 에러 응답 표준(Contract)부터 결정클라이언트와 약속이 제일 중요 { "timestamp": "2025-08-19T12:34:56.789Z", "path": "/api/v1/orders", "status": 400, "code": "ORD_001", /** 비즈니스 오류 식별자(사내 표준) **/ "message": "잘못된 주문 요청입니다.", /** 사용자 노출용(i18n 적용) **/ "errors": [ /** 바인딩/검증 상세 **/ {"field": "quantity", "reason": "must be greater than or equal to 1"} ], "traceId": "a1b2c3d4e5f6" /** 로그 추적(MDC)과 연결 **/}1) ErrorCo.. Global Exception Handler 만들기 1. 왜 필요한가?서비스 규모가 커질수록 예외(Exception)가 발생하는 지점이 많아짐매번 try-catch를 넣으면 코드가 지저분해지고 유지보수가 힘들어짐Global Exception Handler를 쓰면, 모든 예외를 한 곳에서 모아서 처리 가능 → 일관성 있는 에러 응답 제공2. 구현 방법(1) @RestControllerAdvice + @ExceptionHandler 사용 @RestControllerAdvicepublic class GlobalExceptionHandler { // 사용자 정의 예외 처리 @ExceptionHandler(CustomException.class) public ResponseEntity handleCustomException(CustomExcepti.. MyBatis → JPA 전환 이유 1. 생산성 향상MyBatis SQL을 직접 작성해야 해서 세밀한 제어는 가능하지만, CRUD 코드도 전부 만들어야 함 → 반복되는 코드가 많음JPA save(), findById() 같은 기본 CRUD를 제공 → 개발자는 비즈니스 로직에 집중 가능2. 유지보수성 & 가독성MyBatis는 SQL과 매핑 XML 관리가 필수 → 규모가 커지면 XML 관리가 복잡JPA는 객체 중심 접근 → 도메인 모델이 코드로 명확하게 표현되므로, 엔티티 관계 파악이 쉬움도메인 변경 시 XML 수정보다는 엔티티 필드 변경으로 대응 가능3. 표준 기술 & 호환성JPA는 자바 표준 (JSR 338) 이라서 Spring Data JPA, Hibernate 등 다양한 구현체와 호환벤더 종속성을 줄이고, 추후 기술 교체/확장 용이다른.. [SPRING]스프링 입문을 위한 자바 객체 지향의 원리와 이해(1) 책을 시작하자마자 작가가 의문을 던진다. 스프링을 이해하려면 이전의 어떤 기술을 이해하고 있어야 하는가? 나는 당연하게 OOP라고 생각했다. 하지만 작가는 다양한 답변을 내놓았고 그중 물론 OOP라는 답변이 있었다. 작가가 원했던 답변은 아래와 같다. SOA CBE OOP 절차적/구조적 프로그래밍 기계어/어셈블리어 5 로 갈수록 작가의 만점과 가까워지는 것 같은데 나는 아쉽게도 OOP만 생각해냈다. 그다음 장으로 넘어가서 작가는 T 메모리 구조를 보여주면서 static, stack, heap 영역들의 역할과 구조 등을 알려 주었는데 정리를 하자면 아래와 같다. 스태틱 영역 스택 영역(메서드들의 놀이터) 힙 영역 스레드 스레트 스태틱 = 클래스의 놀이터 스택 = 메스드의 놀이터 힙 = 객체의 놀이터 위의 .. 이전 1 2 다음