ACME Tech Blog 최신 글
techblog.ahnlabcloudmate.com에서 발행한 기술 글을 테크곳간이 수집해 최신순으로 보여드립니다.
최신 글
월간 AI 보안 소식 10월호
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css"); .acme10{--navy:#0f2540;--blue:#527cdb;--pill:#8cb7fa;--tag:#91bbfb;--ink:#243b58; --grad:linear-gradient(120deg,#dfecff 0%,#eef4ff 30%,#ffffff 50%,#f1efff 75%,#e3e0ff 100%); font-family:"Pretendard",-apple-system,BlinkMacSystemFont,"Apple SD Gothic Neo","Malgun Gothic",sans-serif; color:var(--ink);max-width:1024px;margin:0 auto;background:#fff;word-break:keep-all;overflow-wrap:break-word;-webkit-font-smoothing:antialiased;} .acme10 *{box-sizing:border-box;} .acme10 h1,.acme10 h2,.acme10 h3,.acme10 p,.acme10 ul,.acme10 li,.acme10 table,.acme10 figure{margin:0;padding:0;font-family:inherit;} .acme10 img{display:block;max-width:100%;height:auto;margin:0;border:0;} .acme10 strong{font-weight:700;color:inherit;} .acme10 .u{text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px;} /* hero */ .acme10 .hero{position:relative;overflow:hidden;background:var(--grad);height:463px;padding:29px 0 0 29px;} .acme10 .hero .logo{width:189px;} .acme10 .hero .copy{position:relative;z-index:1;margin:118px 0 0 47px;} .acme10 .eyebrow{font-size:32px;font-weight:700;color:var(--navy);letter-spacing:-.02em;line-height:1.2;} .acme10 .hero h1{font-size:69px;font-weight:700;color:var(--blue);letter-spacing:-.02em;line-height:1.1;margin:28px 0 0 -10px;} .acme10 .issue{display:inline-block;margin-top:38px;background:var(--pill);color:#fff;font-size:14px;font-weight:700;line-height:30px;padding:0 24px;border-radius:15px;} .acme10 .hero .art{position:absolute;left:60%;top:139px;width:34.3%;} /* body text */ .acme10 .sec{padding:0 24px 0 40px;font-size:16px;line-height:1.8;letter-spacing:-.1px;} .acme10 .sec.g{background:var(--grad);} .acme10 .sec p+p{margin-top:18px;} .acme10 .sec h2{font-size:29px;font-weight:700;color:var(--navy);letter-spacing:-1px;line-height:1.35;margin:0 0 26px;} .acme10 .sec p+h2{margin-top:48px;} .acme10 .intro{padding-top:26px;padding-bott
2026년 10월 14일
ISF 2026 Wrap up: AI, 이제는 실전이다!
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css"); .isf26{--navy:#00264e;--blue:#1b70cb;--pill:#91bbfb;--ink:#141516;--grad:linear-gradient(120deg,#dceafd 0%,#eef4fe 28%,#ffffff 48%,#f1efff 72%,#e3e0fe 100%); font-family:"Pretendard",-apple-system,BlinkMacSystemFont,"Apple SD Gothic Neo","Malgun Gothic",sans-serif;color:var(--ink); max-width:1024px;margin:0 auto;background:#fff;line-height:1.75;word-break:keep-all;overflow-wrap:break-word;-webkit-font-smoothing:antialiased;} .isf26 *{box-sizing:border-box;} .isf26 h1,.isf26 h2,.isf26 p,.isf26 ul,.isf26 li,.isf26 figure{margin:0;padding:0;font-family:inherit;letter-spacing:normal;} .isf26 img{display:block;max-width:100%;height:auto;margin:0;border:0;} .isf26 strong{font-weight:700;color:inherit;} .isf26 .u{font-weight:700;text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px;} /* Hero */ .isf26 .hero{position:relative;overflow:hidden;background:var(--grad);padding:30px 32px 56px;} .isf26 .hero .logo{width:188px;} .isf26 .hero .inner{padding:44px 0 0 88px;position:relative;z-index:1;} .isf26 .eyebrow{font-size:29px;font-weight:400;color:var(--navy);letter-spacing:-.02em;line-height:1.3;} .isf26 .hero h1{font-size:90px;font-weight:800;color:var(--navy);letter-spacing:-.045em;line-height:1.1;margin:30px 0 44px;} .isf26 .hero .sub{font-size:39px;font-weight:700;color:var(--blue);letter-spacing:-.035em;line-height:1.3;} .isf26 .deco{position:absolute;top:50%;font-size:84px;font-weight:700;line-height:1;color:transparent;-webkit-text-stroke:1.4px rgba(0,38,78,.13); writing-mode:vertical-rl;transform:translateY(-50%) rotate(180deg);white-space:nowrap;letter-spacing:.01em;pointer-events:none;} .isf26 .deco.l{left:8px;top:58%;} .isf26 .deco.r{right:8px;top:56%;} /* Body blocks */ .isf26 .blk{padding:40px 36px 44px 68px;font-size:16px;line-height:1.8;color:#243b58;} .isf26 .blk.first{padding:38px 36px 28px 76px;} .isf26 .blk.b2{padding:40px
2026년 10월 2일
월간 AI 소식 9월호
2026년 9월 11일
월간 AI 소식 8월호
.ai-news{--ink:#1a1a2e;--muted:#5b5b73;--accent:#3b5bdb;--accent2:#1098ad;--bg:#f4f6fb;--line:#e2e6f0; max-width:900px;margin:0 auto;color:var(--ink); font-family:-apple-system,BlinkMacSystemFont,"Apple SD Gothic Neo","Malgun Gothic","Noto Sans KR",sans-serif; line-height:1.7;font-size:16px;} .ai-news *{box-sizing:border-box;} .ai-news img{max-width:100%;height:auto;display:block;margin:0 auto;} .ai-news .sec-img{border-radius:12px;} .ai-news .lead{color:var(--muted);font-size:16px;max-width:760px;margin:22px auto 0;} .ai-news .lead strong{color:var(--ink);} .ai-news .wrap{max-width:760px;margin:0 auto;} .ai-news h2{font-size:22px;font-weight:800;margin:48px 0 6px;} .ai-news h2 .sub{display:block;font-size:16px;font-weight:600;color:var(--muted);border:0;margin-top:6px;line-height:1.7;} .ai-news .note{color:var(--muted);font-size:16px;margin:6px auto 14px;max-width:760px;} .ai-news .subhead{font-size:18px;font-weight:700;color:var(--ink);margin:26px auto 8px;max-width:760px;} .ai-news .wrap p{margin:0 auto 12px;max-width:760px;} .ai-news a{color:var(--accent);} .ai-news table{width:100%;border-collapse:collapse;margin-top:18px;font-size:14px;} .ai-news thead th{background:var(--ink);color:#fff;text-align:left;padding:10px 12px;font-weight:700;} .ai-news tbody th{background:#eef1f8;text-align:left;padding:10px 12px;font-weight:700;white-space:nowrap;vertical-align:top;border-bottom:1px solid var(--line);} .ai-news tbody td{padding:10px 12px;vertical-align:top;border-bottom:1px solid var(--line);color:#33334a;} .ai-news tbody td:nth-child(3){color:var(--accent2);} .ai-news .closing{max-width:760px;margin:8px auto 0;} .ai-news .closing p{margin:0 0 12px;color:#33334a;} .ai-news .closing .thanks{font-weight:600;color:var(--ink);margin:22px 0 28px;} .ai-news .closing .logo{width:200px;height:auto;margin:0;} .ai-news .sources{font-size:13px;color:var(--muted);max-width:760px;margin:0 auto;} .ai-news .sources li{margin-bottom:8px;word-break:break-all;} .ai-news .sources a{
2026년 8월 5일
React와 DoS
1. 들어가며 안녕하세요. AIPD팀 정승화입니다. 최근 모던 웹 생태계는 클라이언트 사이드에서 서버 사이드로 그 중심이 이동하고 있습니다. React Server Components(RSC)와 Server Actions의 등장이 대표적인 예입니다. 클라이언트의 로직이 서버로 이동하면서 클라이언트의 한계를 넘어선 일도 할 수 있게 되었습니다. 하지만 기존 클라이언트 개발에서는 겪을 수 없었던 '서버 보안 위협'에도 그대로 노출되게 되었습니다. 관련해 이번 포스팅에서는 최근 발견된 React의 DoS(Denial of Service) 관련 취약점을 분석하고 그 원인인 React Flight Protocol(RFP)을 간단히 살펴보겠습니다. 이 글을 통해 React의 독자적인 데이터 전송 방식인 React Flight Protocol(RFP) 구조를 이해하고, 조작된 페이로드가 Node.js의 싱글 스레드 환경을 어떻게 무력화하는지 그 메커니즘을 파악할 수 있을 것입니다 2. 만악의 근원(?) React Flight Protocol 이 취약점을 이해하려면 먼저 React가 서버 컴포넌트를 브라우저로 전송하는 방식, 즉 React Flight Protocol(RFP)을 이해해야 합니다. RFP는 RSC를 직렬화하여 전송하기 위한 전용 프로토콜입니다. JSON으로는 표현하기 어려운 컴포넌트 트리, 비동기 의존성, Suspense 경계 등을 처리하기 위해 독자적인 타입 기호를 사용합니다. 기호의미설명 $Lazy/Reference다른 청크를 참조하거나 지연 로딩되는 컴포넌트를 정의합니다. @Reference ID다른 청크의 ID를 가리킬 때 사용합니다. (예: $@1) JJSON 모델실제 컴포넌트 트리나 UI 구조가 담긴 JSON 데이터입니다. MModule클라이언트 컴포넌트 파일의 경로 정보를 담습니다. IInlined인라인된 데이터나 비동기 요청의 결과를 의미합니다. RFP는 서버에서 직렬화되어 클라이언트로 전송됩니다. 그리고 React 서버는 클라이언트에서 넘어온 요청을 자체 기준에 따라 역직렬화하고 실행합니다. 3. Node.js와 DoS React 서버는 대부분 Node.js와 같은 싱글 스레드 런타임 환경에서 동작합니다. 따라서 역직렬화 과정에서 특수 참조 기호($)로 인한 순환 참조를 적절히 처리하지 못하면 스레드가 무한 루프에 빠져 블로킹 상태가 될 수 있습니다. 최근 발생한 취약점인 CVE-2025-55184는 바로 이 지점을 노렸습니다. 공격자가 조작된 RFP 페이로드를 서버로 보내면 서버는 이를 해석하려다 순환 참조의 늪에서 헤어나오지 못하게 됩니다. 이는 단순한 정보 탈취보다 치명적일 수 있습니다. 서버 자체를 무력화하여 서비스 전체를 다운시킬 수 있기 때문입니다. 4. React 서버 공격해보기 (PoC) React는 RSC 동작을 검증할 수 있는 테스트 환경을 갖추고 있습니다. 이 환경을 활용해 실제 DoS 공격이 어떻게 이루어지는지 테스트할 수 있습니다. React 팀이 문제를 해결하기 위해 적용한 두 단계의 패치 과정을 살펴보겠습니다. DoS 취약점 해결은 한 번에 끝나지 않고 두 차례에 걸쳐 진행되었습니다. 각 패치가 어떤 문제를 해결하려 했는지 코드를 통해 확인해 보겠습니다. 4-1. 자기 순환 참조 방지하기 첫 번째 문제는 페이로드가 자기 자신을 계속 참조하는 경우입니다. 공격자가 React 서버로 다음과 같이 조작된 데이터를 전송한다고 가정해 봅시다. 핵심은 then이 자기 자신을 가리키도록 하여 Promise가 영원히 resolve되지 않게 만드는 것입니다. import requests target = "http://localhost:3000" timeout = 5 requests.post( target, files={"0": ("", '"$@0"')}, headers={ "rsc-action": "file:///Users/seunghwajeong/space/react/fixtures/flight/src/actions.js#increment", }, timeout=timeout, ) 이
2026년 3월 10일
빌링 3.0 성능 이슈 개선 기록 - Part 1
1. 들어가며 최근 안랩클라우드메이트의 SD파트는 '빌링 3.0' 서비스 고도화 작업을 수행하였습니다. SD파트는 이번 작업을 통해 서비스 오픈 후 발생한 대량 인보이스 발송 시의 성능 저하 문제를 분석하고 해결하였습니다. 예상치 못한 DB 쿼리 타임아웃, 커넥션 고갈, 외부 API 연동 지연 등 실제 운영 환경에서 마주할 수 있는 기술적 난제들을 복합 인덱스 생성, 커넥션 풀 설정 최적화, 프론트엔드 로직의 배치 처리 방식 도입 등을 통해 단계적으로 풀어나가며 트러블슈팅을 한 경험을 이번 포스팅을 통해 공유해보겠습니다. 2. 성능 이슈 발생 SD 파트는 지난 해 가을 고객사를 대상으로 새로 개편된 빌링 포털 서비스를 오픈하였습니다. 서비스 오픈 후 몇 가지 예상치 못한 이슈가 있었는데요. 그중 하나가 매월 청구 시기마다 인보이스 200건 정도를 일괄 발송할 때 성능 저하가 발생하는 이슈였습니다. 여러 시행착오 끝에 성능 저하 이슈를 어느 정도 해결할 수 있었습니다. 관련해 1편에서는 발생한 문제 해결 방법을 먼저 알아보고 2편에서는 OpenTelemetry와 Azure Application Insights를 활용한 관측 가능성(Observability) 구축과 K6를 활용한 부하 테스트로 추가적인 문제를 미리 확인하여 개선한 사례를 소개하겠습니다. 3. 발생한 이슈의 정체 당시 운영 중인 빌링 3.0에서 발생한 이슈는 매달 청구서를 발행할 때 발견되었습니다. 서비스 오픈 후 사내 청구 담당자가 발송 대상 청구서를 모두 선택해 일괄 발송을 진행했습니다. 그런데 오픈 전 테스트와 달리 대부분의 청구서 발행 및 이메일 발송이 정상적으로 처리되지 않는 문제가 발견되었습니다. 기존에 구현된 청구서 발송 로직은 건별로 따로 이메일 발송을 요청하는 형태였습니다. 오픈 전 10건 이하로 테스트할 때는 문제가 없었습니다. 그런데 실제 운영 환경에서 200건 이상을 동시에 요청하자 다음과 같은 복합적인 문제가 발생하며 정상적으로 처리되지 않았습니다. ● 건별 인보이스 데이터 조회 시 DB 쿼리 타임아웃 오류 발생 ● 이메일 발송 시 SMTP 서버 업체의 전송 제한(Rate limit)으로 인한 발송 지연 ● 이메일 발송 등에 필요한 사용자 및 고객사 정보 조회 시 DB 최대 커넥션 초과 오류 발생 4. 원인 파악하기 원인을 파악하기 위해 인보이스가 발송되는 과정을 먼저 다시 한번 확인해 보았습니다. 당시 빌링 3.0에서 사용자가 발송할 인보이스를 선택하고 발송을 누르면 다음과 같은 작업이 수행되었습니다. 발송 대상 인보이스의 체크박스를 활성화하여 선택합니다. 이때 선택한 인보이스 정보를 가져오기 위해 백엔드 API를 호출합니다. 발송 버튼을 누르면 선택한 항목들에 대해 다음 작업을 수행합니다. 프론트엔드에서 각 인보이스 PDF 파일을 렌더링합니다. 백엔드의 발송 API를 호출합니다. 인보이스 ID, 공급자/공급받는 자 식별코드, PDF 파일 등을 요청 본문(Request Body)에 담아 일괄 발송을 요청합니다. 백엔드에서는 해당 인보이스의 기본 정보를 조회하고 이를 바탕으로 이메일 발송에 필요한 고객사 및 담당자 정보를 IAM 서비스 API로 조회합니다. 각 인보이스별로 이메일을 발송한 후 결과값을 정리하여 반환합니다. 실제로 200건 정도를 선택해 실행해 보니 발송 단계에 진입하기 전 인보이스 조회를 동시에 여러 건 호출하면서 문제가 발생했습니다. 이전에도 10건 이하를 선택했을 때 조회가 수 초 정도 소요되긴 했으나 한번에 200건의 조회가 몰리자 쿼리가 정상적으로 수행되지 못하고 타임아웃이 발생한 것입니다. 이 문제를 해결한 후에도 실제 발송 과정에서 다시 오류가 발생했습니다. 발송 전 필요한 정보를 IAM에서 조회할 때 처음 수십 건은 처리되었으나 이후 응답이 지연되거나 IAM 측 DB에서 'Too many connection' 오류가 발생했습니다. 5. 인보이스 조회 시 쿼리 타임아웃 해결하기 먼저 인보이스 목록에서 약 200건의 항목을 체크할 때 발생하는 대량의 API 응답 오류부터 해결하고자 했습니다. 이럴 때 흔히
2026년 3월 10일
ALB Health Check Logs 지원
1. 들어가며 그동안 ALB(Application Load Balancer)의 상태 확인은 대상 그룹(Target Group)의 Target Health 화면과 일부 CloudWatch 지표에 의존해 왔습니다. 그러나 이 정보만으로는 "정확히 어떤 요청이 어떤 이유로 실패했는지" 파악하는 데 한계가 있었습니다. 타임아웃인지, 응답 코드 문제인지, 혹은 애플리케이션 내부 오류인지 명확히 구분하기 어려웠기 때문입니다. 결국 EC2나 애플리케이션 로그를 직접 확인하거나 AWS Support에 케이스를 생성해야 하는 번거로운 상황이 종종 발생했습니다. 다행히 Health Check Logs(상태 검사 로그) 기능이 추가되었습니다. 이제 각 타깃에 대해 어떤 프로토콜로 언제 상태 검사를 보냈고, 응답 시간은 얼마나 걸렸으며, 어떤 상태 코드와 실패 사유로 인해 비정상(Unhealthy)으로 판단되었는지를 한 줄의 로그로 바로 확인할 수 있게 되었습니다. What's new? 2. ALB Health Check Logs 개요 2.1 활성화 절차 Health Check Logs는 기본적으로 비활성화된 선택 기능이므로 해당 ALB에서 직접 활성화해야 합니다. 절차는 크게 다음과 같습니다. S3 버킷 준비 헬스 체크 로그를 저장할 Amazon S3 버킷을 지정하거나 새로 생성합니다. 버킷에 필요한 접근 제어(예: 조직 내에서만 접근 가능하도록 버킷 정책 설정, 퍼블릭 액세스 차단 등)를 구성합니다. ALB에서 Health Check Logs 활성화 Application Load Balancer 설정에서 Health Check Logs 기능을 활성화하고 로그를 보낼 S3 버킷과 프리픽스를 지정합니다. 활성화 이후 ELB는 각 로드 밸런서 및 대상 그룹에 대해 지정된 간격으로 상태 검사 로그 파일을 설정한 버킷에 gzip 형식으로 업로드합니다. 로그 파일은 bucket[/prefix]/AWSLogs/계정ID/elasticloadbalancing/리전/연/월/일/health_check_log_...log.gz 경로와 이름으로 저장됩니다. 대상(Target) 수가 많거나 상태 검사 주기를 짧게 설정했다면 같은 5분 구간 내에도 여러 개의 로그 파일이 생성될 수 있습니다. 2.2 로그에서 확인할 수 있는 주요 필드 Health Check Logs의 각 로그 라인은 한 번의 상태 검사 결과를 의미하며, 공백으로 구분된 여러 필드로 구성됩니다. 주요 필드는 아래와 같습니다. type (1): 헬스 체크 요청 타입니다. http, https, h2, grpc, lambda 등으로 어떤 프로토콜/타입으로 헬스 체크를 했는지 나타냅니다. time (2): 타임스탬프입니다. 타깃에 헬스 체크를 시작한 시점으로 ISO 8601 형식으로 기록됩니다. latency (3): 지연 시간입니다. 해당 헬스 체크 요청을 완료하는 데 걸린 총 시간(초 단위)입니다. target_addr (4): 타깃 주소입니다. IP:Port 형식의 EC2 또는 IP 타겟 주소, 혹은 Lambda 타깃인 경우 함수 ARN이 기록됩니다. target_group_id (5): 타깃 그룹 식별자입니다. 타깃이 속한 Target Group 이름/ID 입니다. status (6): 헬스 체크 결과입니다. 성공 시 PASS 실패 시 FAIL이 기록됩니다. status_code (7): 응답 코드입니다. HTTP/HTTPS의 경우 타깃이 반환한 HTTP 상태 코드가 기록됩니다. reason_code (8): 실패 원인 코드입니다. 헬스 체크가 실패했을 때만 기록되는 필드입니다. 세부 사항은 공식 문서를 참고 부탁드립니다. 3. Health Check Logs 활성화 ALB, 타겟 그룹 생성 절차는 생략하겠습니다. 3.1. 로그 적재 용 S3 버킷 생성 버킷은 로드 밸런서와 동일한 리전에 있어야 합니다. 서로 다른 계정에 있어도 무방합니다. 서버 측 암호화 옵션은 Amazon S3에서 관리하는 키(SSE-S3)만 지원됩니다. 3.2. S3 버킷 정책 적용 S3 버킷의 퍼블릭 액세스를 차단한
2026년 1월 26일
Amazon S3 Tables와 MCP, 자연어로 확장하는 데이터 경험
1. 들어가며 현대 비즈니스 환경에서 데이터 활용은 나날이 중요해지고 있습니다. 이에 따라 복잡한 SQL 쿼리나 코딩 지식 없이도 자연어로 데이터를 직접 질문하고 분석 결과를 즉시 확인할 수 있는 환경의 필요성이 커지고 있습니다. Amazon S3 Tables와 MCP(Model Context Protocol)를 활용하면 누구나 쉽게 대화형 AI와 S3에 저장된 구조화된 데이터를 연결하여 다양한 업무를 손쉽게 처리할 수 있습니다. 2. MCP(Model Context Protocol)란? MCP는 AI와 여러 데이터·서비스를 안전하고 표준화된 방식으로 연결하는 프로토콜입니다. MCP 서버: 데이터를 저장하거나 서비스 기능을 제공하는 실제 프로그램(예: S3 테이블, SQL DB) MCP 클라이언트: 챗봇, AI 개발 어시스턴트 같은 MCP 서버와 통신하며 명령을 주고 받는 소프트웨어 MCP 서버를 통해 필요한 데이터와 기능에 안전하게 접근하고 AI가 제공하는 답변이나 작업 결과 품질을 높일 수 있습니다. 예를 들어 Claude Desktop 같은 챗봇은 MCP를 통해 S3 테이블 정보를 직접 읽고, 생성·수정·분석 등의 작업을 할 수 있습니다. 3. S3 테이블 MCP 서버 주요 기능 및 적용 사례 S3 Tables MCP 서버는 AI가 S3 테이블 데이터에 자연어 기반으로 접근해 다양한 작업을 수행할 수 있도록 돕습니다. 테이블 버킷, 네임스페이스, 테이블 생성 및 리스트 확인 테이블 스키마 정의 및 수정 CSV 등 외부 데이터 가져와 S3 테이블로 저장 데이터 추가, 수정, 쿼리 수행 유지보수 정보 조회, 테이블 이름 및 네임스페이스 이동 등 관리 작업 사용자는 복잡한 SQL이나 API 호출 없이 자연어 질문만으로 데이터를 처리할 수 있어 즉각적인 분석과 인사이트 확보가 가능해집니다. 4. Amazon Q Developer CLI 실전 테스트 1단계: 사전 준비 AWS 리전: ap-northeast-2 (서울) 도구: Amazon Q Developer CLI 목표: 자연어로 완전한 데이터 분석 워크플로우 구현 S3에 사전 업로드된 샘플 csv 데이터 (test-bucket/sample_customers.csv) 고객ID 이름 가입일 구매횟수 총구매금액 상태 C001 홍길동 2025-01-15 3 150,000 활성 C002 김영희 2024-12-10 5 230,000 활성 C003 박철수 2025-03-03 1 50,000 휴면 C004 이민아 2023-08-20 7 420,000 활성 C005 최지우 2025-06-01 0 0 신규 2단계: 인프라 구성 자연어 명령: "서울 리전에 'sales-anlytics-bucket'이라는 새로운 S3 테이블 버킷을 만들어줘" Q Developer 응답: ✅ 네임스페이스 생성 완료! • 네임스페이스명: retail_analytics • 소속 테이블 버킷: sales-analytics-bucket 1단계 완료 요약 •테이블 버킷 및 네임스페이스 약 8초 만에 생성 완료 자연어 명령: "방금 만든 sales-analytics-bucket에 'retail_analytics'라는 네임스페이스를 생성해줘" Q Developer 응답: ✅ 네임스페이스 생성 완료! • 네임스페이스명: retail_analytics • 소속 테이블 버킷: sales-analytics-bucket 1단계 완료 요약 • 테이블 버킷 및 네임스페이스 약 8초 만에 생성 완료 3단계: CSV 파일을 테이블로 변환 자연어 명령: "test-bucket에 있는 sample_customers.csv 파일을 retail_analytics 네임스페이스의 customers 테이블로 가져와줘" Q Developer 응답: 🎉 CSV → S3 테이블 변환 성공! • 처리된 행 수: 5개 • 새 테이블 생성: retail_analytics.customers • 테이블 UUID: e081dd9b-56de-44a1-bd45-c6e970581920 • 컬럼 구조: 고객id, 이름, 가입일, 구매횟수, 총구매금액, 상태 • 자동
2026년 1월 26일
Amazon EC2는 이제 EC2 인스턴스에 대한 강제 종료를 지원합니다!
1. 들어가며 AWS 사용자라면 누구나 한 번쯤 답답한 상황을 겪어보셨을 겁니다. 바로 EC2 인스턴스 중지를 시도했음에도 불구하고 몇 분이 지나도록 'stopping(중지 중)' 상태에서 넘어가지 않고 멈춰있는 경우입니다. 이런 상황은 긴급한 작업이나 장애 대응 시 시간을 지연시키는 주범이 되기도 합니다. 다행히 최근 AWS 업데이트를 통해 이 문제를 해결할 수 있는 새로운 도구인 '강제 중지' 기능이 추가되었습니다. EC2 인스턴스가 왜 멈추는지 그리고 새롭게 추가된 이 강력한 기능을 어떻게 활용할 수 있는지 알아보겠습니다. 2. EC2 인스턴스 상태 EC2 인스턴스를 중지하는 것은 단순히 전원 스위치를 내리는 것과는 다릅니다. 인스턴스는 안전한 데이터 보존을 위해 정해진 절차에 따라 종료됩니다. 예를 들어 구동(running) 중인 EBS 기반(EBS-backed) 인스턴스를 중지(stop)하면 running -> stopping -> stopped상태를 거치게 됩니다. 이때 OS 내부에서는 다음과 같은 절차가 진행됩니다. API로 (하이퍼바이저)게스트에 button press(버튼 누름) 이벤트를 전송합니다. 하이퍼바이저의ACPI shutdown button press 이벤트는 시스템의 graceful shudown(정상 종료)를 트리거합니다. 각 시스템의 정상 종료는 Linux의 경우 systemd, Windows의 경우 System process에 의해 제공됩니다. ACPI 종료가 시작됩니다. 정상 종료 프로세스가 끝난 뒤 인스턴스가 종료(terminated)됩니다. 3. AS-IS vs TO-BE: 무엇이 달라졌나? 이번 업데이트의 핵심인 '강제 중지'는 stopping 상태에서 멈춰버린 인스턴스를 해결하기 위해 설계된 옵션입니다. 기존 방식과 비교해 보겠습니다. running -> stopping -> stopped 3.1 AS-IS 기존 중지 옵션 기존에는 running 상태에서 중지 명령을 내릴 때 다음 두 가지 옵션만 선택할 수 있었습니다. 기본 중지(Default stop) 용도: 가장 권장되는 방식으로 OS의 정상적인 종료 절차를 밟습니다. 데이터 영향: EBS 루트 볼륨 및 데이터 볼륨의 데이터가 안전하게 보존되지만 인스턴스 스토어(Instance Store)의 데이터는 손실됩니다. 사용 시기: 일반적 중지를 위한 첫 번째 중지 시도입니다. OS 종료 건너뛰기를 사용한 중지(Stop with skip OS shutdown) 용도: OS의 정상 종료 과정을 무시(Bypass)하고 즉시 중지를 시도합니다. 데이터 영향: 데이터 손실 또는 손상이 발생할 수 있습니다. 메모리 콘텐츠가 디스크로 플러싱되지 않고 진행 중인 IO가 손실될 수 있습니다. 종료 스크립트를 건너뛸 수 있습니다. 사용 시기: OS가 응답하지 않거나 빠른 중지가 필요할 때 제한적으로 사용합니다. 3.2 TO-BE 강제 중지 기능 추가 이제는 이미 중지 명령을 내려 stopping 상태가 된 인스턴스에 대해서도 추가 조치를 할 수 있게 되었습니다. 강제 중지(Force stop) 용도: stopping 상태에서 멈춘 인스턴스를 처리합니다. 먼저 기본 중지를 재시도하고 그래도 되지 않으면 강제로 인스턴스를 종료합니다. 데이터 영향: 기본 중지를 먼저 시도하지만 강제 중지가 진행되면 데이터 손실 또는 손상이 발생할 수 있습니다. 드문 경우 EBS 볼륨이나 기타 공유 리소스에 대한 중지 후 쓰기가 발생합니다. 사용 시기: 기본 중지 시도 후 인스턴스가 계속 stopping 상태에 머물러 있을 때 사용합니다. OS 종료 건너뛰기를 사용한 강제 중지(Force stop with skip OS shutdown) 용도: stopping 상태의 인스턴스를 즉시 끄고 싶을 때 강제 중지와 정상적 OS 종료 바이패스를 결합해 사용합니다. 데이터 영향: OS 종료를 건너뛰면 데이터가 손실되거나 손상될 수 있습니다. 메모리 콘텐츠가 디스크로 플러싱되지 않고 진행 중인 IO가 손실될 수 있습니다. 종료 스크립트를 건너뛸 수 있습니다. 강제 중지가 진행
2026년 1월 26일
Amazon ECS, 기본 제공 블루/그린 배포 지원
1. 들어가며 2025년 7월 17일, AWS는 ALB, NLB 또는 ECS Service Connect를 통해 트래픽을 처리하는 ECS 서비스에대해 '블루/그린 배포 전략'을 기본으로 지원한다고 발표했습니다. 블루/그린 배포 전략을 사용하면 Amazon ECS는 기존 애플리케이션 버전과 함께 새로운 애플리케이션버전을 프로비저닝합니다. 이를 통해 프로덕션 트래픽을 새로운 애플리케이션으로 라우팅하기 전에 새버전을 미리 검증할 수 있습니다. 또한, 배포 수명 주기(Lifecycle) 후크를 사용하여 사용자 지정 검증 단계를 수행하고 검증이 완료될 때까지 배포를 대기시킬 수도 있습니다. 아울러 프로덕션 트래픽이 새로운 버전으로 전환된 후에는 미리 지정된 기간 동안 새 애플리케이션을 안정화(Bake)하고 이 과정에서 회귀(Regression)가 탐지되면 가동 중지 시간 없이 이전 버전으로 즉시 롤백할 수 있습니다. Amazon CloudWatch 경보 및 ECS 배포 회로 차단기(Circuit Breaker)를 구성하여 배포를 모니터링하고 장애를 자동으로 탐지하는 것도 가능합니다. 이러한 기능을 함께 사용하면 소프트웨어 업데이트의 안정성을 높이고 새로운 기능을 더 빠르게 제공할 수 있습니다. 2. 콘솔에서 배포 옵션 변경해보기 AWS 콘솔에서 확인되는 ECS 배포 전략은 아래와 같이 네 종류입니다. 롤링 업데이트(Rolling Update): 기존 태스크를 순차적으로 종료하면서 새 태스크로 점진적으로 교체하는 기본 배포 방식 블루/그린(Blue/Green): 기존 버전(Blue)과 새 버전(Green)을 동시에 실행한 뒤 트래픽을 한 번에 전환하는 방식 카나리(Canary): 일부 트래픽만 먼저 새 버전에 보내 안정성을 검증한 후 점진적으로 확대하는 방식 선형(Linear): 일정한 비율과 시간 간격으로 트래픽을 새 버전으로 균등하게 증가시키는 방식 기본 옵션인 롤링 업데이트를 블루/그린 업데이트로 구성을 변경해 보겠습니다. 단순한 배포 옵션 변경이므로 네트워킹 설정은 그대로 유지합니다. 참고로 블루/그린 배포를 위해서는 로드밸런싱 또는 서비스 연결(Service Connect)을 먼저 구성해야 합니다. 로드밸런싱 구성 후 배포 옵션을 블루/그린으로 변경할 수 있습니다. 3. 검증 이제 상세하게 검증해 보겠습니다. 로컬 도커(Docker)에서 블루/그린 이미지를 각각 빌드하여 ECR로 푸시한 뒤 ECS 블루/그린 배포 시 해당 이미지가 실제로 잘 동작하는지 확인합니다. 3.1 이미지 빌드 및 테스트(로컬) 먼저 블루 버전의 Dockerfile을 작성하고 빌드합니다. # Dockerfile.v1 FROM nginx:alpine RUN echo '<h1>NGINX v1 - BLUE</h1>' > /usr/share/nginx/html/index.html 빌드 및 실행은 다음과 같이 합니다. # 빌드 및 실행 docker build -f Dockerfile.v1 -t nginx-blue:v1 . docker run --rm -p 8080:80 nginx-blue:v1 다음으로 그린 버전의 Dockerfile을 작성하고 빌드합니다. # Dockerfile.v2 FROM nginx:alpine RUN echo '<h1>NGINX v2 - GREEN</h1>' > /usr/share/nginx/html/index.html 빌드 및 실행은 다음과 같이 합니다. # 빌드 및 실행 docker build -f Dockerfile.v2 -t nginx-green:v2 . docker run --rm -p 8081:80 nginx-green:v2 3.2 ECR 푸시 및 배포 준비 로컬에서 확인한 이미지를 ECR에 업로드합니다. # ECR 로그인 aws ecr get-login-password \ --region ap-northeast-2 \ --profile mini \ | docker login \ --username AWS \ --password-stdin xxxxxxxxxxxx.dkr.ecr.ap-northeast-2.amazonaws
2026년 1월 26일
AI 검색 최적화를 위한 LLMS.txt 적용
회사 홈페이지를 운영하면서 검색 엔진 최적화(SEO)는 늘 해오는 작업이지만, AI가 급속도로 확산되면서 LLMS.txt라는 것이 등장했습니다. 이미 robots.txt가 있는데 LLMS.txt는 어떤 차이점이 있는지 궁금해서 정리해보았습니다. AI 확산에 따른 새로운 웹 최적화의 필요성 우리는 지금 인공지능(AI) 기술이 세상의 모든 것을 빠르게 변화시키는 시대에 살고 있습니다. 기존 웹은 주로 검색 엔진 최적화(SEO, Search Engine Optimization)라는 개념을 통해 관리되었습니다. 웹사이트 소유자들은 구글이나 네이버 같은 검색 엔진이 자신의 페이지를 잘 찾고, 순위를 높여줄 수 있도록 웹사이트를 설계했습니다. robots.txt 파일은 검색 엔진 봇에게 어떤 페이지를 크롤링할지 말지 지시하는 중요한 도구였습니다. 이제는 AI 챗봇에게 특정 주제에 대한 질문을 던지면, 웹사이트에 있는 정보를 종합하여 답변을 생성하는 것이 일반화 되었습니다. 이런 AI들은 단순히 링크를 따라가는 것을 넘어, 콘텐츠의 의미를 이해하고, 핵심 정보를 추출하며, 심지어는 요약하거나 재구성하는 능력을 가지고 있습니다. 전통적인 SEO만으로는 AI가 우리 웹사이트의 가치를 제대로 인식하고 활용하기 어렵다는 한계에 봉착하게 되었습니다. LLMS.txt의 등장 배경 이러한 배경 속에서 LLMS.txt라는 새로운 개념이 등장했습니다. LLMS.txt는 "Large Language Model Sitemaps"의 약자로, 이름에서 짐작할 수 있듯이 대규모 언어 모델이 웹 데이터를 소비하고 해석하는 방식에 대한 새로운 지침을 제공하는 파일입니다. 마치 robots.txt가 검색 엔진 봇을 위한 길 안내자였다면, LLMS.txt는 AI가 우리 웹사이트의 콘텐츠를 더욱 효과적으로 "이해"하고 "활용"할 수 있도록 돕는 일종의 "AI 친화적인 콘텐츠 지도"라고 할 수 있습니다. LLM은 방대한 양의 텍스트 데이터를 학습하여 사람처럼 자연스러운 언어를 이해하고 생성합니다. 이 과정에서 웹은 가장 중요한 학습 소스 중 하나입니다. 웹에는 수많은 정보가 혼재되어 있고, 모든 정보가 AI 학습에 유용하거나 적절한 것은 아닙니다. 심지어 잘못된 정보나 중복된 정보, 저작권 문제가 있는 콘텐츠 등도 존재합니다. LLMS.txt는 이러한 문제들을 해결하고, 웹사이트 소유자가 자신의 데이터를 AI에게 어떻게 제공하고 싶어하는지에 대한 명확한 신호를 보낼 수 있도록 고안되었습니다. LLMS.txt의 정의 LLMS.txt는 웹사이트 소유자가 대규모 언어 모델(LLM) 기반의 AI 시스템에게 자신의 웹사이트 콘텐츠를 어떻게 크롤링하고, 분석하며, 활용해야 할지에 대한 지침을 제공하는 텍스트 파일입니다. AI가 우리 웹사이트에 방문했을 때 "여기는 이런 정보가 중요하고, 저기는 보지 않아도 돼"라고 알려주는 역할을 합니다. 이 파일은 robots.txt와 마찬가지로 웹사이트의 루트 디렉토리에 위치하며, 보통 https://www.yourwebsite.com/llms.txt와 같은 주소를 갖습니다. AI 에이전트(LLM 크롤러)가 웹사이트를 방문하기 전에 이 파일을 확인하여 콘텐츠 처리 방침을 따르게 됩니다. 이는 AI가 웹 콘텐츠를 단순히 "긁어가는" 것을 넘어, 웹사이트 소유자의 의도를 반영하여 더 똑똑하게 데이터를 학습하고 활용하도록 유도하는 데 목적이 있습니다. 핵심 기능 및 목적 LLMS.txt의 핵심 기능과 목적은 다음과 같습니다. 1) AI의 콘텐츠 이해도 향상: 웹사이트 내에서 AI가 중요하게 다루어야 할 핵심 콘텐츠와 불필요한 정보를 명확히 구분할 수 있도록 가이드라인을 제공합니다. 예를 들어, 본문 내용은 중요하지만 댓글이나 광고 영역은 무시하도록 지시할 수 있습니다. 이는 AI가 정보를 더 정확하게 추출하고 요약하는 데 기여합니다. 2) AI 검색 결과 품질 개선: AI 기반의 검색 엔진이나 챗봇이 사용자의 질문에 답변할 때, LLMS.txt의 지침을 따른다면 더 정확하고 신뢰성 있는 정보를 제공할 수 있습니다. 이는 사용자 경험을 향상시
2026년 1월 26일
Knowledge MCP vs Documentation MCP
1. 들어가며 최근 AI와 클라우드의 결합이 본격화되면서, 대형 언어 모델(LLM)과 외부 지식 출처를 안정적으로 연동하는 방법이 중요한 과제로 떠오르고 있습니다. 이러한 요구를 충족하기 위해 제안된 표준이 Model Context Protocol(MCP)이며, AWS 역시 MCP 서버를 적극적으로 지원하고 있습니다. 기존의 Documentation MCP Server는 AWS 공식 문서 활용에 적합했지만, 최근 AWS는 이를 확장한 Knowledge MCP Server를 선보였습니다. 이 새로운 서버는 공식 문서를 넘어 블로그, 아키텍처 가이드, 최신 발표까지 포함하며 더 폭넓은 지식 접근을 제공합니다. 이번 글에서는 두 MCP 서버의 차이점과 특징을 정리하고, 실제 업무에서 어떤 상황에 적합한지 비교해보겠습니다. 2. AWS Documentation MCP Server 개요 Documentation MCP Server는 AWS 공식 문서 전용 로컬 실행형 MCP 서버입니다. 주요 특징 로컬 실행: uvx를 통해 환경 내 직접 실행 Python 기반: uv 패키지 관리자로 설치 및 실행 공식 문서 전용: docs.aws.amazon.com 접근 인증 불필요: 별도 AWS 자격 증명 필요 없음 글로벌/중국 지원: 환경 변수로 파티션 선택 가능 제공 기능 AWS 문서를 Markdown 형식으로 변환 키워드 기반 문서 검색 (글로벌 리전만 지원) 관련 문서 추천 (글로벌 리전만 지원) 중국 리전 서비스 목록 조회 (중국 전용) 3. AWS Knowledge MCP Server 개요 Knowledge MCP Server는 AWS에서 호스팅하는 완전 관리형 원격 MCP 서버입니다. 주요 특징 완전 관리형: AWS 원격 서버에서 실행 원격 접근: https://knowledge-mcp.global.api.aws 엔드포인트 제공 로컬 설치 불필요: 클라이언트의 프록시 도구를 통해 연결 인증 불필요: 별도 계정이 필요하지 않음 (단, 사용량 제한 존재) 프리뷰 상태: 현재 테스트·평가 단계에서 제공 지식 소스 AWS 공식 문서 + API 레퍼런스 What's New 발표 내용 Getting Started 가이드 Builder Center 콘텐츠 AWS 블로그 포스트 아키텍처 레퍼런스 Well-Architected 프레임워크 가이드 4. 핵심 차이점 비교 4.1 호스팅 및 실행 방식 구분 Documentation MCP Knowledge MCP 실행 위치 로컬 환경 AWS 원격 서버 설치 방식 uvx 패키지 설치 프록시 도구 연결 관리 주체 사용자 직접 관리 AWS 완전 관리 네트워크 의존성 docs.aws.amazon.com 접근 knowledge-mcp.global.api.aws 접근 4.2 지원 도구 및 기능 Documentation MCP read_documentation: 문서 → Markdown 변환 search_documentation: 키워드 검색 (글로벌만) recommend: 관련 문서 추천 (글로벌만) get_available_services: 중국 리전 서비스 목록 (중국만) Knowledge MCP search_documentation: 통합 지식 검색 read_documentation: 다중 소스 문서 읽기 recommend: 확장된 자료 추천 4.3 정보 범위 및 품질 구분 Documentation MCP Knowledge MCP 정보 소스 AWS 공식 문서만 공식 문서 + 블로그 + 아키텍처 + 뉴스 업데이트 실시간 docs 사이트 접근 AWS 최신 지식 관리 검색 범위 문서 내 키워드 검색 통합 지식베이스 검색 추천 품질 단순 문서 기반 LLM 최적화 추천 5. 설치 및 환경 구성 5.1 사전 준비 Python 3.10 이상 (Install Python 3.10 or newer using uv python install 3.10 (or a more recent version) uv 패키지 관리자 설치 (Install uv from Astral or the GitHub README) 5.2 설정 파일
2026년 1월 14일
AI와 함께하는 Kafka 클러스터 관리: Amazon MSK용 MCP 서버 출시
들어가며 2025년 7월, AWS는 Amazon MSK(Managed Streaming for Apache Kafka)용 Model Context Protocol(MCP) 서버를 출시했습니다. 이는 AI 에이전트가 자연어로 Kafka 클러스터를 관리할 수 있게 해주는 혁신적인 도구입니다. 복잡한 CLI 명령어나 콘솔 조작 대신, "내 MSK 클러스터 성능이 어때?"라고 물어보면 AI가 알아서 답해주는 시대가 온 것입니다. 이 글에서는 MCP와 MSK를 처음 접하는 엔지니어들을 위해 기본 개념부터 실제 활용법까지 단계별로 알아보겠습니다. 1. MCP(Model Context Protocol)란 무엇인가? AI와 외부 시스템을 연결하는 표준 프로토콜 Model Context Protocol(MCP)는 Anthropic이 개발한 오픈소스 프로토콜입니다. AI 에이전트가 데이터베이스, 지식 소스, 마이크로서비스 등 외부 시스템과 표준화된 방식으로 소통할 수 있게 해줍니다. 기존 방식의 문제점 기존에는 AI가 외부 시스템과 소통하려면: 각 시스템마다 다른 API 형식 복잡한 인증 및 권한 관리 일관성 없는 데이터 형식 개발자마다 다른 구현 방식 MCP 해결하는 것 MCP는 이런 문제들을 해결합니다: 표준화된 인터페이스: 모든 시스템이 동일한 방식으로 소통 구조화된 데이터 교환: AI가 이해하기 쉬운 형태로 정보 제공 보안 정책 통합: 일관된 권한 관리 체계 확장성: 새로운 시스템 추가가 용이 2. Amazon MSK 기초 이해 Apache Kafka와 Amazon MSK Apache Kafka는 실시간 스트리밍 데이터를 처리하는 분산 플랫폼입니다. 로그 수집, 실시간 분석, 마이크로서비스 간 통신 등에 널리 사용됩니다. Amazon MSK는 AWS의 완전 관리형 Kafka 서비스로: 자동 패치 및 업데이트: 운영 부담 최소화 자동 확장: 트래픽에 따른 동적 스케일링 보안 통합: AWS IAM, VPC, 암호화 지원 모니터링: CloudWatch와 완전 통합 MSK의 주요 구성 요소 3. Amazon MSK용 MCP 서버의 핵심 기능 자연어 인터페이스 기존 방식: aws kafka describe-cluster --cluster-arn arn:aws:kafka:us-east-1:123456789012:cluster/my-cluster/uuid MCP 방식: "내 MSK 클러스터 상태를 확인해줘" 지능적인 클러스터 분석 MCP 서버는 다음과 같은 정보를 AI가 이해할 수 있는 형태로 제공합니다: 클러스터 메트릭: CPU, 메모리, 디스크 사용률 구성 상태: 현재 설정과 권장 설정 비교 용량 제한: 할당량 및 확장 가능성 모범 사례: 워크로드 특성에 맞는 최적화 제안 운영 컨텍스트 제공 AI는 단순히 데이터를 보여주는 것이 아니라: 제약사항 인식: 현재 설정의 한계점 파악 종속성 분석: 변경 시 영향받는 다른 구성 요소 식별 위험도 평가: 제안된 변경사항의 리스크 분석 4. 실습: MSK MCP 서버 설치 및 사용 사전 준비사항 1.Python 환경 설정 # uv 설치 (Python 패키지 관리자) curl -LsSf https://astral.sh/uv/install.sh | sh # Python 3.10 설치 uv python install 3.10 AWS 자격 증명 설정 # AWS CLI 설정 aws configure # 또는 환경 변수 설정 export AWS_ACCESS_KEY_ID=your-access-key export AWS_SECRET_ACCESS_KEY=your-secret-key export AWS_DEFAULT_REGION=us-east-1 필요한 IAM 권한 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "kafka:*", "ec2:DescribeVpcs", "ec2:DescribeSubnets", "ec2:DescribeSecurityGroups", "logs:CreateLogGroup", "logs:CreateLog
2026년 1월 14일
Notion RAG 검색 시스템 구축: Go로 구현하는 개인 지식 베이스 구축기
1. 서론: 개인 지식 베이스의 진화 안녕하세요, AIPD팀 문광석 입니다. 현대 지식 근로자들에게 Notion은 제2의 뇌와 같습니다. 하지만 데이터가 쌓일수록 "분명 어딘가에 적어뒀는데..." 하며 헤매는 시간이 길어집니다. Notion의 내장 검색은 키워드 매칭 방식이라, 문맥이나 의미를 파악하는 질문(Semantic Search)에는 한계가 명확하기 때문입니다. 이 프로젝트는 Notion을 단순한 저장소가 아닌, 살아있는 개인 지식 베이스로 활용하기 위해 시작되었습니다. Go 언어의 강력한 동시성 모델로 데이터를 수집하고, Google Gemini의 임베딩과 LLM을 활용해 RAG(Retrieval-Augmented Generation) 시스템을 CLI 도구로 구현했습니다. 구현한 프로그램으로 할 수 있는 일 한마디로 설명하면 내가 노션에 기록한 모든 내용을 기억하고 있는 AI 비서를 만드는 것입니다. 예를 들어, "나 8월 23일에 무슨 업무 했었지?" 라고 물어보면, AI가 내 노션 페이지를 뒤져서 그날의 업무 기록을 찾아 요약해 줍니다. 일일이 페이지를 들어가서 날짜를 확인할 필요가 없죠. 물론, 이미 훌륭한 'Notion AI' 서비스가 존재합니다. 하지만 이 프로젝트의 핵심은 내 데이터를 내 입맛대로, 그리고 무엇보다 무료(또는 아주 저렴하게)로 다루는 것에 있습니다. 이렇게 직접 구현하면 다음과 같은 매력이 있습니다. 검색 스트레스 해방: 키워드가 정확히 기억나지 않아도, 대충 물어보면 찰떡같이 찾아줍니다. 새로운 인사이트: 단순히 찾는 것을 넘어, "이 문서랑 저 문서 내용을 합쳐서 요약해줘" 같은 요청도 가능합니다. 압도적인 가성비: 비싼 구독료 대신, 무료 API 티어를 활용해 지갑을 지킬 수 있습니다. 다음은 실제로 프로그램을 사용하여 원하는 데이터를 검색한 예 입니다. 주요 기능 • 자동Notion 동기화: Notion API를 통해 모든 페이지를 자동으로 가져와서 벡터화 • Gemini 임베딩: Google Gemini Embedding API를 사용한 고품질 텍스트 임베딩 • 유사도 기반 검색: Cosine Similarity를 사용한 정확한 문서 검색 • RAG 기반 답변: Gemini를 사용한 컨텍스트 기반 답변 생성 2. 시스템 아키텍처 및 기술 스택 🛠️ 기술 스택 • Go: 페이지를 크롤링하고 벡터화하기 위해 Goroutine과 Channel을 활용한 병렬 처리를 활용 • chromem-go: 복잡한 설정 없이 바이너리에 내장 가능한 로컬 임베딩 벡터 DB입니다. 배포 용이성을 위해 선택했습니다.외부 벡터 DB 서버를 띄우지 않아도 되기 때문에, • Google Gemini (Embedding & 2.5 Flash): 긴 컨텍스트 윈도우와 빠른 처리 속도, 그리고 우수한 한국어 처리 능력을 갖추고 있으며 무엇보다 무료 또는 저렴한 가격으로 사용 가능하여 개인 프로젝트에 최적입니다. Gemini 모델 정보 gemini-embedding-001 역할 : 임베딩 용도 : 텍스트 → 벡터 변환 스펙 : 3072 차원 Gemini-2.5-Flash 역할 : 생성 / 추론 3. 사전 준비 작업 프로젝트 시작 또는 사용을 위해서는 먼저 사전준비가 필요했습니다. Gemini API 사용을 위한 Key 발급과 프로그램이 Notion 문서에 접근할 수 있도록 키를 발급하고 권한을 부여하는 일 입니다. 🔑 Google Gemini API Key 발급 및 설정 이 프로젝트에서는 텍스트를 벡터로 변환하는 Embedding 모델과 답변을 생성하는 Generative 모델 모두 Google Gemini를 사용합니다. Google AI Studio를 통해 무료로 API 키를 발급받을 수 있습니다. 1. Google AI Studio 접속 키 발급 링크 Google AI Studio 에 접속하여 구글 계정으로 로그인합니다. 좌측 상단 메뉴에서 Get API key 버튼을 클릭합니다. 2. API Key 생성 Create API key 버튼을 클릭합니다. Create API key in new proje
2025년 12월 26일
Sprint Boot 에서 HTTP/3(QUIC) 적용 및 성능 비교
안녕하세요, AIPD팀 최주영입니다. AIPD팀에서 서비스 중인 ADS, SecureBridge의 게이트웨이 성능 최적화 관점에서, HTTP/3 (QUIC)의 실효성과 적용 가능성을 확인하기 위해 이 글을 작성했습니다. what is QUIC? QUIC (Quick UDP Internet Connections) 는 Google 에서 처음 제안하고, 현재는 IETF 표준(RFC 9000) 으로 정의된 차세대 전송 프로토콜입니다. 기존 TCP 위에서 동작하는 HTTP/1.1, HTTP/2와는 달리, QUIC 은 UDP 기반으로 설계되었으며, 이를 통해 연결 지연을 최소하고 네트워크 성능을 크게 개선하는 것을 목표로 합니다. HTTP/3 는 바로 이 QUIC 을 전송 계층으로 사용하는 HTTP 프로토콜입니다. QUIC의 특징 UDP 기반 전송 QUIC는 TCP 대신 UDP 위에서 동작합니다. 이를 통해 커널 수준의 TCP 제약에서 벗어나, 사용자 공간(User Space)에서 빠르게 프로토콜을 진화시킬 수 있습니다. 연결 설정 지연 최소화(0-RTT/1-RTT) TCP + TLS 조합에서는 연결을 위해 여러 번의 핸드셰이크가 필요합니다. 반면 QUIC는 전송 계층과 암호화를 통합해, 초기 응답 속도가 크게 향상됩니다. Head - of - Lind Blocking 문제 해결 HTTP/2는 멀티플렉싱을 지원하지만, TCP 레벨에서 패킷 하나가 유실되면 전체 스트림이 지연되는 문제가 있습니다. QUIC는 스트림 단위로 독립적인 전송과 재전송을 처리하므로 하나의 스트림 패킷 손실이 다른 스트림에 영향을 주지 않습니다. 이로 인해 대용량 데이터 전송이나 불안정한 네트워크 환경에서도 성능에 이점을 보입니다. TLS 1.3 내장 QUIC는 모든 통신이 기본적으로 암호화되며, TLS 1.3이 프로토콜에 내장되어 강제 적용됩니다. 기존 HTTP 통신(HTTP/1.1 or HTTP/2)을 HTTP3으로 변경하기 HTTP/1.1이나 HTTP/2 프로토콜로 동작하면 REST API 를 코드 변경 없이 HTTP 프로토콜로 변경할 수 있습니다. 테스트 환경 조건은 아래와 같습니다. Spring Boot3 gradle JAVA 17 build.gradle 라이브러리 추가 implementation 'org.springframework.cloud:spring-cloud-starter-gateway' runtimeOnly 'io.netty.incubator:netty-incubator-codec-http3:0.0.28.Final' Http3NettyWebServerCustomizer.java (서버 요청 수신용 설정) package com.ahnlab.fogger.http3; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.stereotype.Component; import reactor.netty.http.Http3SslContextSpec; import reactor.netty.http.HttpProtocol; import java.time.Duration; @Component class Http3NettyWebServerCustomizer implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> { @Override public void customize(NettyReactiveWebServerFactory factory) { factory.addServerCustomizers(server -> { SslBundle sslBundle = factory.getSslBundles().getBundle("server-http3");
2025년 12월 19일