inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

Dowon Lee님의 게시글

Dowon Lee Dowon Lee

@kenneth

수강생
32,726
수강평
1,806
강의 평점
4.8
함께한 멘티
-
멘토링 리뷰
-
멘토링 평점
-

게시글 1395

질문&답변

제공된 스크립트를 어디서 받을 수 있나요?

안녕하세요, 이도원입니다. 강의 실습을 위한 스크립트는 아래 github에서 확인하실 수 있습니다. https://github.com/joneconsulting/cicd-practice-lab repo 하위에 infra, product-service-manifests, product-service 3개의 폴더가 있습니다. infra: jenkins, argocd 설치를 위한 스크립트 파일 product-service-manifests: 실습용 실행 스크립트 파일 product-service: 프로젝트 소스 파일 감사합니다.

좋아요수
0
댓글수
1
조회수
50

질문&답변

강의 내용중에 var

안녕하세요, 이도원입니다. 강의에 관심을 가져 주셔서 감사드립니다. 질문하신 내용에 대해 아래에 의견 및 답변 드립니다. 1. 강의에서 var 를 사용하는 이유가 있나요? 기존에 타입을 직접 적는 방식에 익숙하시면 var 가 낯설게 느껴질 수 있습니다. 😊 Java의 var 는 타입을 지정하지 않는 것이 아니라, 오른쪽의 값을 보고 컴파일러가 타입을 결정하는 문법 입니다. String message = "안녕하세요"; var message = "안녕하세요"; // 컴파일러가 String으로 판단 두 코드에서 message 는 모두 String 타입입니다. var 로 선언했더라도 이후에 숫자 등 다른 타입의 값을 넣을 수는 없습니다. 따라서 JavaScript의 var 와는 다른 개념으로 보시면 됩니다. 강의 코드에서 var 를 사용하면 긴 타입 이름의 반복을 줄이고, 서비스의 처리 흐름에 집중할 수 있다는 장점이 있습니다. var runner = new PromptRunner(); 위 코드는 오른쪽만 봐도 PromptRunner 타입임을 알 수 있습니다. 반면 다음 코드는 말씀하신 것처럼 타입이 바로 드러나지 않을 수 있습니다. var result = service.execute(); 이런 경우에는 타입을 명시하는 편이 읽기 좋습니다. 무조건 var 를 사용하는 것이 좋은 것은 아니며, 타입을 쉽게 알 수 있는 곳에 선택적으로 사용하고 프로젝트의 코딩 규칙에 맞추시면 됩니다. 참고로 Java의 var 는 Java 10부터 지원하는 지역 변수 타입 추론 문법이며, 메서드의 반환 타입을 var 로 선언할 수는 없습니다. 메서드에 선언된 반환 타입은 그대로 유지됩니다. var 타입의 장단점을 간략하게 정리하면 아래와 같습니다. 장점: 긴 타입 이름을 생략해 코드가 간결해집니다. 중복되는 타입 표기를 줄일 수 있습니다. 코드의 실제 처리 흐름에 집중하기 좋습니다. 단점: 오른쪽 표현식이 복잡하면 타입을 바로 알기 어렵습니다. 타입 확인을 위해 IDE나 메서드 선언을 확인해야 할 수 있습니다. 과도하게 사용하면 가독성이 오히려 떨어집니다. 참고로, Java의 var 는 타입을 직접 명시하는 것과 성능 차이가 없습니다. var 사용 여부는 성능보다 가독성과 팀의 코딩 규칙을 기준으로 결정 하시면 됩니다. 2. 실제 프로젝트에서는 PromptRunner 외에도 필요한 것들이 많나요? 네, 맞습니다. 실제 서비스에서는 프롬프트를 실행하는 기능 외에도 여러 기능이 필요해질 수 있습니다. 다만 모든 기능을 PromptRunner 하나에 넣기보다는 역할별로 나누는 편이 유지보수에 좋습니다. 예를 들면 다음과 같습니다. 프롬프트 관리: 프롬프트를 파일이나 템플릿으로 관리하고 변경 이력 추적 모델 호출 설정: 모델 이름, 응답 길이, 타임아웃 등의 설정 관리 예외 처리와 재시도: 호출 실패나 사용량 제한에 대응 응답 변환과 검증: 응답을 DTO로 변환하고 필수 값이나 형식 확인 대화 이력 관리: 사용자별 이전 대화를 저장하고 필요한 내용 전달 문서 검색 연동: 사내 문서를 검색해 답변에 필요한 근거 제공 사용량과 품질 기록: 토큰 사용량, 비용, 응답 시간, 오류 등을 확인 예를 들어 금액 계산 서비스라면 LLM은 질문에서 조건을 추출하고, 실제 계산은 별도의 Java 코드가 수행하도록 구성 할 수도 있습니다. 처음부터 모두 만들 필요는 없습니다. 우선 공통 호출·예외 처리·응답 검증부터 구성하고, 서비스 요구사항에 따라 확장하시면 됩니다.

좋아요수
0
댓글수
1
조회수
55

질문&답변

강의내용중에 CoT 부분

안녕하세요, 이도원입니다. 강의에서 사용하는 모델은 gpt-4o-mini 모델입니다. 정확한 답변을 얻어서 서비스해야하는 경우가 아니기 때문에, 강의에서는 비용이 저렴한 이전 버전을 사용했습니다. 공식 문서 기준으로 GPT-4o mini의 최신 공개 스냅샷은 2024-07-18 이며, 현재는 API 지원 종료가 예고된 상태입니다. 단계별 계산에서도 오류가 발생할 수 있습니다. 다만 업데이트 중단이 이번 계산 오류의 원인이라고 단정할 수는 없지만, 단계별 계산(CoT) 문제에서 오류 가능성습니다. 이유는 다음과 같습니다. 추론 모델이 아님 : 내부 추론 단계 없이 바로 답을 생성합니다. 조건 4~5개를 순서대로 적용하는 문제에서 중간 값을 놓치거나 섞기 쉽습니다. 이전 질문에서 38,400원과 40,800원이 번갈아 나온 것이 그 예입니다. 산술 실수 : 소형 모델이라 곱셈, 할인율 같은 다단계 산술에서 토큰 단위로 숫자가 틀어지는 일이 자주 생깁니다. 비결정성 : temperature가 0보다 크면 같은 질문에도 경로가 달라져 답이 흔들립니다. 조건 순서 해석 : "화요일 할인"과 "전체 금액 10%" 중 무엇을 먼저 적용할지 같은 규칙 해석도 일관되지 않습니다. 위 부분은 고려하셔서 실무에 적용하셔야 되며, 강의에서는 OpenAI API 모델을 사용하기 위해 저렴한 모델을 사용하였습니다. 참고 부탁드립니다. 감사합니다.

좋아요수
0
댓글수
2
조회수
59

질문&답변

service-discovery 프로세스 가동 이유

안녕하세요, 이도원입니다. 먼저 답변이 늦어 죄송합니다. AI 답변이 추가되고 있어 바로바로 체크하기 못했었습니다. API Gateway가 Service Discovery와 함께 동작하는 이유는 각 마이크로서비스의 실제 위치(IP/Port 를 Gateway가 직접 관리하지 않고, 서비스 이름으로 동적으로 찾아서 호출하기 위해서입니다. API Gateway는 Service Discovery를 통해 이 인스턴스 목록을 조회하고 적절한 서버로 요청을 전달합니다. 주요 장점은 다음과 같습니다. 로드밸런싱 동일 서비스의 여러 인스턴스에 요청을 분산할 수 있습니다. 동적 위치 탐색 서비스의 IP나 Port가 변경되어도 Gateway 설정을 매번 수정할 필요가 없습니다. Scale-out 대응 서비스 인스턴스가 추가되거나 제거되어도 Service Discovery가 이를 자동으로 반영합니다. 장애 인스턴스 제외 비정상 인스턴스를 서비스 목록에서 제외하여 정상 인스턴스로 요청을 전달할 수 있습니다. Spring Cloud Gateway에서는 보통 다음과 같이 사용합니다. uri: lb://USER-SERVICE 여기서 lb:// 는 Service Discovery에서 USER-SERVICE 의 인스턴스를 찾고, 그중 하나를 선택하여 요청을 전달하라는 의미입니다. 추가 문의사항 있으시면 글 남겨 주시기 바랍니다. 감사합니다.

좋아요수
0
댓글수
2
조회수
89

질문&답변

Inner class로 Config를 지정하는 이유

안녕하세요, 이도원입니다. Inner Config 클래스는 해당 Gateway Filter에 필요한 설정값을 필터 내부에 캡슐화하고, Spring Cloud Gateway의 설정 바인딩 구조와 자연스럽게 연결하기 위한 용도로 사용됩니다. Config를 CustomFilter의 inner class로 두는 장점을 간단하게 정리하면 다음과 같습니다. 필터 전용 설정을 한 곳에 묶을 수 있음 Config가 CustomFilter에서만 사용된다면 별도 파일로 분리하는 것보다 응집도가 높습니다. 설정값 바인딩이 쉬움 AbstractGatewayFilterFactory 와 연결되어 YAML/Properties의 필터 파라미터를 Config 객체로 받을 수 있습니다. 가독성이 좋아짐 필터 동작과 그 필터가 사용하는 설정 구조를 같은 클래스에서 확인할 수 있습니다. 불필요한 클래스 증가 방지 작은 설정 객체를 위해 별도 Java 파일을 만들 필요가 없습니다. 필터별 설정 캡슐화 다른 필터의 설정과 섞이지 않고 CustomFilter.Config라는 명확한 범위를 가집니다. 추가 문의사항 있으시면 글 남겨 주세요. 감사합니다.

좋아요수
0
댓글수
2
조회수
66

질문&답변

장애 격리 관련해서 궁금한 부분이 있어요

안녕하세요, 이도원입니다. 네, 이해하신 방향이 맞습니다. MSA에서 말하는 장애 격리(Fault Isolation) 는 “한 서비스에 장애가 발생해도 다른 서비스는 전혀 영향을 받지 않는다”는 의미라기보다는, 장애의 영향 범위를 줄이고 장애가 연쇄적으로 확산되는 것을 제어하기 쉬운 구조를 만든다 는 의미에 가깝습니다. 서비스별 실행 환경과 자원을 분리하고 Timeout, Circuit Breaker, Bulkhead, Fallback, 비동기 메시징 등의 패턴을 통해 장애의 영향 범위와 전파 경로를 통제할 수 있다는 의미입니다. 말씀하신 예처럼 회원 서비스가 여러 서비스의 공통 의존 대상이라면 충분히 장애 전파가 발생할 수 있습니다. 단순히 서비스를 나누었다고 해서 자동으로 장애가 격리되는 것은 아닙니다. 오히려 서비스 간 의존 관계를 잘못 설계하면 MSA에서도 하나의 서비스 장애가 여러 서비스로 연쇄적으로 퍼지는 Cascading Failure 가 발생할 수 있습니다. 그래서 말씀하신 것처럼 MSA의 장애 격리는 다음과 같이 이해하는 것이 좋습니다. 장애를 완전히 없앤다 -> (X) 장애가 발생했을 때, 영향 범위를 제한하고 연쇄 장애를 제어할 수 있도록 한다 -> (O) 추가 문의사항 있으시면 다시 글 남겨 주세요. 감사합니다.

좋아요수
0
댓글수
2
조회수
66

질문&답변

pg사가 있다고 가정하면

안녕하세요, 이도원입니다. 답변이 늦어 죄송합니다. 지금이라도 문의하신 내용에 대한 추가 답변이 되었으면 하는 마음에 글 남깁니다. 말씀하신 내용은 PG 결제 처리부분에 있어 전체적인 방향은 맞습니다. 다만 PG 연동이 들어가는 경우에는 Saga를 단순히 “결제 완료 → 재고 차감”으로 보기보다는, 주문·재고·결제의 상태를 각각 관리하고 실패 시 보상할 수 있도록 구성하는 것이 좋습니다. 우선 질문하신 2번의 주문서버 → 결제서버 호출은 동기식으로 처리해도 전혀 문제가 없습니다. 사용자가 결제하기 버튼을 누른 뒤 PG 결제창을 바로 받아야 하기 때문에, Client → 주문서버 → 결제서버 → PG 결제 준비 API 구간은 일반적인 Request/Response 흐름으로 보는 것이 자연스럽습니다. 결제를 시작하기 전에는 동기 요청 흐름을 처리하시고, 그 이후에는 아래와 같이 Saga 처리를 위한 일관성 관리가 중요합니다. 예를 들어, 1. 주문 생성 주문 상태 = PENDING 2. 재고 예약 재고 서버에서 실제 차감보다는 RESERVED 상태로 일정 시간 확보 3. 결제 준비 주문 서버 → 결제 서버 동기 호출 결제 서버: - Payment 생성 - 상태 = READY - PG 결제 준비 API 호출 - paymentId / redirectUrl 반환 4. 사용자가 PG에서 결제 5. PG 결제 인증 완료 PG → callback/redirect → 서버 6. 결제 서버가 PG 승인 API 호출 7. 승인 성공 Payment = PAID PaymentCompleted 이벤트 발행 8. 주문 서버 PaymentCompleted 수신 Order = PAID 또는 COMPLETED 9. 재고 서버 예약된 재고를 실제 판매 확정 RESERVED → CONFIRMED 위 예시와 같은 흐름으로, Saga 관점에서는 실패 시 보상 트랜잭션도 같이 설계해야 합니다. 추가로, Saga라고 해서 모든 서비스 호출을 비동기 이벤트로 만들어야 하는 것은 아닙니다. 2번의 주문서버 → 결제서버 동기 호출은 잘못된 것이 아니고 오히려 적절하다고 볼 수 있습니다. 추가 문의사항 있으시면 다시 글 남겨 주세요. 감사합니다.

좋아요수
0
댓글수
2
조회수
85

질문&답변

verify.sh 4단계 실패 — Jenkins 컨테이너에서 127.0.0.1:6443 connection refused

안녕하세요, 이도원입니다. 정보 공유해 주셔서 감사드립니다. macOS에 Docker Desktop을 설치했다고 해서 /etc/hosts 에 kubernetes.docker.internal 항목이 반드시 생성되는 것은 아닙니다. Docker Desktop은 내부 DNS/가상 네트워크를 통해 host.docker.internal , kubernetes.docker.internal 같은 이름을 해석하는 경우가 많아서, /etc/hosts 에 명시적으로 다음 항목이 없어도 동작할 수 있습니다. kubernetes.docker.internal 은 Docker Desktop에서 Kubernetes를 활성화했을 때 Kubernetes API 서버 접근용 이름으로 사용될 수 있지만, 버전이나 설정에 따라 /etc/hosts 에 직접 기록되는 방식이 아닐 수 있습니다. 말씀하셨던 문제를 해결하는 방법으로 /etc/hosts 를 수정하는 것과 현재의 kubeconfig를 확인해서 적용하시는 것이 좋다고 생각됩니다. kubectl config view --minify 감사합니다.

좋아요수
0
댓글수
2
조회수
83

질문&답변

햅틱? 백틱?

안녕하세요, 이도원입니다. 말씀하신 내용처럼 백틱을 의미했습니다. ` 백틱(backtick) ``` 마크다운 코드블록 확인 감사합니다.

좋아요수
0
댓글수
1
조회수
66

질문&답변

api응답내용이 한글이 아닌 다른 언어와 섞여서 나옴.

안녕하세요, 이도원입니다. Spring AI에서 gpt-4o-mini 를 사용할 때 응답에 영어, 중국어, 일본어 같은 한글 이외의 문자가 간헐적으로 섞이는 현상은 Spring AI 자체의 인코딩 문제라기보다 대부분 모델의 생성 특성과 프롬프트 구성 문제 입니다. 특히 gpt-4o-mini 같은 다국어 모델은 입력 문맥에 여러 언어가 섞여 있으면 그 언어 패턴을 그대로 따라가는 경향이 있다고 합니다. OpenAI도 일관된 언어 출력을 원한다면 가능하면 프롬프트 전체를 한 언어로 유지하는 것을 권장합니다. 질문은 한글이지만 모델에게 "반드시 한국어로 답하라"는 제약은 없습니다. 따라서 학습 데이터나 내부적으로 참고한 문맥에 따라 다음과 같이 섞일 수 있습니다. 아래와 같이 system() 메서드에서 출력 형식을 지정해 볼 수 있습니다. String response = chatClient.prompt() .system(""" 당신은 한국어로 답변하는 AI Assistant입니다. 다음 규칙을 반드시 지키세요. - 모든 답변은 한국어로 작성합니다. - 영어, 일본어, 중국어 등 다른 언어를 사용하지 않습니다. - 단, 기술 용어와 고유명사는 원문을 사용할 수 있습니다. """) .user(question) .call() .content(); 추가로 temperature도 일반 질의응답/RAG 서비스라면 0.0~0.3 정도를 사용하고, 창의적 글쓰기 라면 0.5~0.7 정도를 사용해 보는 게 조을 것 같습니다. 추가 문의사항 있으시면 다시 글 남겨 주세요. 감사합니다.

좋아요수
0
댓글수
1
조회수
63