| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | ||
| 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 13 | 14 | 15 | 16 | 17 | 18 | 19 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 |
| 27 | 28 | 29 | 30 |
- nGrinder
- 객체지향
- c
- Oidc
- 코드트리
- Kotlin
- 코딩테스트
- 코딩 테스트
- LLM
- 다형성
- 디프만16기
- model context protocol
- spring ai
- AOP
- 디프만
- C언어
- 코딩
- 자료구조
- depromeet
- flutter
- 상속
- java
- 부하 테스트
- 운영체제
- pub.dev
- Spring boot
- 코드 트리
- Spring
- MCP
- claude code
- Today
- Total
목록전체 글 (75)
Nick Dev
팀 공용 MCP 서버 구축기 — 5편 · 完마지막 편이다. 4편까지 만든 것들이 실전에서 어떻게 굴러가는지 —운영 문의 하나가 풀리는 전 과정을 리플레이하고, 12일 치 감사 로그를 열어 숫자를 세고,그 숫자에서 발견한 예상 못 한 반전으로 시리즈를 닫는다.🔥 문의가 들어온다"고객사 A에서 어제부터 알림톡이 안 나간다고 합니다. 확인 부탁드려요."1편을 기억하는 독자라면 알 거다 — 예전의 나는 이 문의에 창 세 개를 띄웠다.발송 서비스 콘솔에 로그인하고, DB 클라이언트를 켜고, 터미널로 서버 로그를 뒤졌다.지금은 채팅창에 문의를 그대로 붙여넣는다. 이제부터가 이 시리즈에서 만든 모든 것이한 판에 돌아가는 장면이다.(특정을 피하려고 실제 문의 여럿을 하나로 각색했다 — 도구를 쓰는 방식과흐름은 실제 ..
팀 공용 MCP 서버 구축기 — 4편2편에서 요청 하나의 수명주기를 따라갔을 때, 마지막 "실행" 칸은 사실상 블랙박스였다.필터를 지난 요청이 어떻게 내 Java 메서드까지 도달하는지는 안 깠으니까.이번 편은 그 블랙박스를 연다 — 2편이 창구까지였다면 이번엔 창구 뒤 주방이다.여기 적은 동작은 전부 우리가 쓰는 버전(Spring AI 1.1.8 + MCP Java SDK 0.18.3)의소스를 직접 열어 확인한 것이다.🔥 우리가 쓴 건 이게 전부다운영 DB 조회 툴의 실제 코드다(패키지명만 바꿨다). 2편에서 한 번 보여줬지만, 이번엔 뜯어볼 거라 전체를 다시 싣는다.@Component@RequiredArgsConstructorpublic class DbQueryTools { private fin..
팀 공용 MCP 서버 구축기 — 3편1편에서 팀 공용 MCP 서버를 만들기로 했고, 2편에서 서버 골격을 세웠다.이번 편은 세 번째 재료 — 서버 로그다.원래 계획은 MCP에 로그 조회 툴 하나 붙이는 거였는데, 끝나고 보니팀 옵저버빌리티(관측) 스택이 생겨 있었다. 어쩌다 그렇게 됐는지 순서대로 가보자.🔥 시작은 툴 하나였다1편의 장면을 다시 소환하자. 문의 하나가 오면 열리는 창 세 개 — DB 클라이언트,알림톡 발송 콘솔, 그리고 터미널. 앞의 두 개는 MCP 툴이 됐다. 마지막 남은 창이 터미널이다.터미널에서 뭘 하냐면 —$ ssh 운영서버-1$ cd logs/app-api$ grep -A 30 "ERROR" basic.log | less# ...여긴 없네. 다음 서버$ ssh 운영서버-2$ g..
팀 공용 MCP 서버 구축기 — 2편1편에서 CLI·로컬 MCP·공용 서버를 저울질해 팀 공용 MCP 서버를 만들기로 했다.이번 편은 그 서버가 실제로 어떻게 동작하는지 — 그리고 운영하면서 전송 방식을SSE → Streamable HTTP → Stateless로 두 번 갈아탄 이야기다.두 번 다 이론이 아니라 실측이 등을 떠밀었다.🐍 시작 전에 — 뭘로 만들지부터 정해야 했다사실 우리 팀엔 이미 AI 프로젝트가 하나 있다. Python으로 만든 AI 챗봇.팀원 전원이 Java 백엔드 개발자인데, Python을 처음 배워가며 만들었다. 시행착오가 많았고 —솔직히 말하면 그 프로젝트는 지금 AI의 도움 없이는 유지보수가 안 되는 상태가 됐다.코드를 열어도 구조가 눈에 안 들어오고, 뭘 고치려면 일단 AI..
팀 공용 MCP 서버 구축기 — 1편B2B ERP를 만드는 팀에서 일한다. 팀원 모두 Claude Code 같은 AI 코딩 도구를 쓰는데, 어느 순간 "AI가 코드만 알면 반쪽"이라는 걸 체감했다. 그래서 운영 DB와 서버 로그를 AI에 직접 연결하는 팀 공용 MCP 서버를 만들었고, 지금 팀 전원이 쓰고 있다. 이 시리즈는 그 과정에서 내린 선택들의 기록이다.🔥 문의 하나, 창은 세 개운영 문의가 하나 들어온다."고객한테 알림톡이 안 갔대요. 확인 부탁드려요."자, 이제 뭘 해야 할까? 창 세 개를 띄워야 한다.🧑💻나판단은 한 번이면 되는데⬛창 ① 터미널 — 서버 로그SSH 접속 → 로그 파일 grep. 발송 로직이 돌긴 했나? 에러는?서버가 여러 대면? 대마다 반복이다🗄창 ② DB 클라이언트..
홈서버 네트워크 설정 가이드1. Tailscale 설치 및 설정VPN - 내부 전용 접근용도어디서든 안전하게 내 서버에 직접 접속1.1 Tailscale 설치# Tailscale 설치curl -fsSL | sh# Tailscale 시작 및 인증sudo tailscale up# 상태 확인tailscale statustailscale ip -41.2 Tailscale 자동 시작 설정# 서비스 활성화sudo systemctl enable tailscaledsudo systemctl start tailscaled2. Nginx 설치 및 설정reverse proxy - 내부 라우터용도한 서버에서 여러 서비스를 도메인별로 분배2.1 Nginx 설치# Nginx 설치sudo apt updatesudo apt ins..
공부하게 된 이유순수 Java 활용한 WAS 구현 과제를 진행하면서 예외 처리 공통화 부분을 구현하려고 했다.기존에 SpringBoot 활용해서 개발했을 때는 @ExceptionHandler 구현하고 그냥 어디서든지 예외 던지면 “알아서” 이 핸들러가 동작해서 예외에 대한 ResponseEntity를 만들어서 반환했다.이걸 직접 구현하려니깐 저 “알아서”가 어떻게 되는건지 궁금해졌다.그래서 Spring의 예외 핸들링 과정을 알아보쟈가정아래와 같이 커스텀 예외를 구현하고, 글로벌로 예외를 처리하는 예외 처리기 있다는 가정커스텀 예외애플리케이션 전반에서 사용되는 예외@Getterpublic class ApiException extends RuntimeException { private final Err..
상속으로 재사용을 구현하게 되면 몇 가지 문제가 발생한다. 그래서 상속 말고 객체 조립을 통해 재사용을 구현하자.상속 단점 3가지1. 상위 클래스 변경 어려움class BasicStorage { public void save(String fileName, String data) { System.out.println("파일 저장: " + fileName); // 기본 저장 로직 }}class CompressedStorage extends BasicStorage { @Override public void save(String fileName, String data) { System.out.println("데이터 압축 중..."); // ..
다형성과 상속다형성이란?한 객체가 여러 타입을 가질 수 있는 것인터페이스 상속순전히 타입 정의만 상속, 다중 상속을 지원하지 않는 Java에서는 interface를 이용해 객체가 다형을 갖는다.구현 상속상위 클래스에 정의된 메서드들을 재사용하기 위한 목적 → 오버라이딩추상화추상화란?데이터 or 프로세스 등을 의미가 비슷한 개념이나 표현으로 정의하는 과정실제 사물을 모델링하는 과정(모델링 결과는 주로 클래스)이미지 업로드 추상화AWS S3 버킷에 이미지 저장하기NCP 버킷에 이미지 저장하기로컬 디렉토리에 이미지 저장하기⇒ 이 세 기능을 추상화하면 ‘이미지 저장’ 이라는 개념으로 정의할 수 있음타입 추상화 interface ImageSave { public void save(Image img); ..
객체지향적으로 코드를 작성해야 하는 이유는 뭘까?데이터와 그 데이터를 사용하는 기능을 한 객체로 묶음으로써, 객체를 사용하는 다른 코드에 영향을 최소화하면서 객체 내부 구현 변경할 수 있는 유연함. 즉, 구현 변경의 유연함을 가질 수 있기 때문이다.→ 변경 지점을 최대한 한 곳으로 모은다객체지향적이지 않은 방식class StudentData { private String name; private int koreanScore; private int englishScore; private int mathScore;}public class StudentDataService { // 평균 계산을 외부에서 직접 처리 public double calculateAvg(StudentData st) { return (..