Loading the catalog…
Loading the catalog…
[TIL] LG CNS AM INSPIRE CAMP 37일차 어제 72쪽 구성도에서 칸 하나로만 봤던 서비스 디스커버리가 오늘 실제 프로젝트가 됐다. 유레카 서버를 띄우고, 거기에 서비스 하나를 등록하고, 그 서비스를 네 대까지 늘려봤다. 그 전에 오전 앞부분은 IntelliJ와 메이븐에 썼다. 지금까지 VS Code로 수업해왔기 때문에, 툴을 한 바퀴 둘러보고 빌드한 결과물을 터미널에서 직접 띄워보는 데까지가 먼저였다. 1. 어제를 두 장으로 접고 시작했다 강사님은 어제 내용 중 두 장만 다시 짚어주셨다. 모놀리스와 MSA의 장단점 표, 그리고 MSA 표준 구성도다. 어느 쪽이 더 좋다가 아니라 프로젝트의 성격과 규모에 맞춰 고르는 것이고, 구성도는 규칙이 아니라 선도 기업들이 갖춘 베스트 프랙티스라는 정리였다. 오늘 순서는 셋이었다. IntelliJ로 간단한 스프링 부트 프로젝트를 만들고 메이븐으로 빌드·실행해보는 것, 강의 노트 섹션 2의 서비스 디스커버리 이론, 그리고 오후 내내 유레카 실습이다. 마지막 시간에는 다음 수업인 API 게이트웨이를 위해 공유받은 코드가 잘 뜨는지 확인했다. 명령어로 실행해보는 연습을 하는 이유도 말씀해주셨다. 실제 배포에서는 재생 버튼을 누르는 게 아니라 명령을 입력해야 하고, 나중에 CI/CD를 구축할 때도 이 명령들을 파이프라인에 적어둬야 하기 때문이다. 메모: "명령어를 알아두는 것도 굉장히 중요해요." 2. 오늘 손에 쥔 구문들 IntelliJ와 메이븐 명령, 유레카 서버·클라이언트 설정, 그리고 실행 시점에 포트를 바꾸는 옵션까지가 오늘의 범위였다. 구분 구문 역할 메이븐 mvn clean target 폴더(빌드 산출물)를 지운다 메이븐 mvn compile / mvn package 컴파일 / 배포 가능한 jar로 압축 메이븐 mvn clean compile package -DskipTests 세 단계를 한 번에, 테스트는 건너뜀 메이븐 mvn spring-boot:run jar 없이 빌드부터 돌려 바로 기동 ( pom.xml 위치에서) 자바 java -jar <jar 파일> 패키징된 jar를 직접 실행 JVM 옵션 -Dserver.port=60001 실행 시점에 포트를 덮어쓴다 터미널 ls / dir 파일 목록 (CMD는 dir 만 된다) 어노테이션 @EnableEurekaServer 이 앱을 유레카 서버로 동작시킨다 어노테이션 @EnableDiscoveryClient 이 앱이 디스커버리 클라이언트임을 명시 (생략해도 동작) yml eureka.client.register-with-eureka 내 정보를 유레카에 등록할지 yml eureka.client.fetch-registry 유레카의 등록 목록을 받아올지 yml eureka.client.service-url.defaultZone 유레카 서버 주소 + /eureka yml server.port: 0 랜덤 포트 yml eureka.instance.instance-id 인스턴스마다 고유한 ID yml eureka.instance.prefer-ip-address 호스트 이름 대신 IP로 등록 pom <properties> + ${spring-cloud.version} 버전을 변수로 빼서 참조 용어 구분 용어 의미 디스커버리 서비스 레지스트리 / 서비스 디스커버리 등록한다는 쪽 이름 / 찾아준다는 쪽 이름 (같은 제품) 디스커버리 Spring Cloud Netflix Eureka 넷플릭스가 만들어 기부한 디스커버리 제품 디스커버리 fetch 등록 목록을 주기적으로 받아오는 것 (기본 30초) 디스커버리 heartbeat "살아 있다"를 주기적으로 알리는 신호 패키징 jar / war Java Archive / Web Archive 서버 WAS 웹 애플리케이션 서버. 톰캣이 대표 종료 graceful shutdown 강제 종료가 아니라 순차적으로 정상 종료 프로젝트 Group ID / Artifact ID 조직 도메인을 뒤집은 것 / 결과물(앱)의 고유 ID 환경 프로필 dev·prod처럼 환경별로 설정 파일을 나눠 고르는 것 HTTP 204 No Content 성공했지만 응답 바디에 줄 내용이 없음 HTTP 400 Bad Request 클라이언트가 필요한 값을 빠뜨린 잘못된 요청 IntelliJ 모듈 상위 프로젝트 하나 아래에 여러 프로젝트를 묶는 단위 3. IntelliJ 한 바퀴 새 프로젝트를 만들 때 고르는 것들 New Project 에서 Spring Boot 를 골라 helloworld 라는 프로젝트를 만들었다. 예전에는 무료인 Community 버전에 이 메뉴가 없어서 start.spring.io 에서 프로젝트를 만들어 압축을 받아야 했는데, 버전이 통합된 뒤로 무료 사용자도 IDE 안에서 바로 만들 수 있게 됐다. 메뉴가 잠겨 있던 수강생 분들에게는 start.spring.io (Spring Initializr)에서 같은 항목을 고르고 Generate한 뒤 압축을 풀어 열면 된다 고 하셨다. IDE 안에서 만드는 것도 결국 그 서버에서 만들어 가져오는 것이라 차이가 없다. 항목 오늘 고른 값 이유 Type Maven 요즘은 XML 문법이 복잡한 메이븐보다 그레이들을 더 쓰는 추세다. 그래도 수업에서 메이븐 명령으로 서비스를 여러 대 띄울 것이라 맞춰두면 좋다고 하셨다 JDK · Java 설치된 JDK와 같은 버전 둘이 어긋나면 호환성 오류가 난다. 강사님은 21, 각자 17이면 17 Packaging Jar 스프링 부트에 내장된 톰캣으로 실행하기 때문 Configuration YAML properties는 spring.application.name= 식의 키-값, YAML은 계층 구조라 가독성이 좋아 요즘 더 많이 쓴다 Spring Boot 태그 없는 정식 버전 뒤에 SNAPSHOT 이나 M2 가 붙은 것은 정식 릴리스 전의 실험 단계라 피한다 Dependencies Spring Web 오늘은 실행만 해볼 것이라 하나만 프로젝트를 만들면 오른쪽 아래에서 의존성을 내려받는다. 그게 끝나면 가장 먼저 pom.xml 을 확인 하라고 하셨다. 스프링이든 리액트든 프로젝트를 만들면 설정 파일부터 보는 습관이다. pom.xml을 고쳤다면 싱크까지 pom.xml 의 버전을 0.0.1 에서 1.0 으로 함께 바꿔봤다. ⚠️ 저장했다고 끝나는 게 아니다. 오른쪽 위에 뜨는 M 아이콘(Sync Maven Changes) 을 눌러야 반영된다. 그레이들이라면 같은 자리에 코끼리 아이콘이 뜬다. Spring Web 하나를 골랐더니 pom.xml 에는 웹 MVC 스타터와 그 짝인 테스트 스타터가 들어가 있었다. 그런데 왼쪽의 External Libraries 를 열어보면 스프링 관련 라이브러리가 잔뜩 들어 있다. 스타터 하나가 여러 의존성을 품고, 그 의존성이 또 다른 의존성을 물고 오기 때문이다. 빌드 도구는 빌드만 하는 게 아니라 이런 의존성 관리 까지 맡는다. 툴 창과 단축키 왼쪽과 오른쪽에 붙은 툴 창을 하나씩 짚어주셨다. Project (폴더 구조), Structure (열린 클래스 안의 구조), Commit (Git), TODO , Build , Services , Terminal , Version Control , Problems , 그리고 오른쪽의 Notifications , AI Assistant , Database , Maven 이다. TODO 는 팁으로 알려주셨다. 주석에 TODO 를 남겨두면 그것만 모아 볼 수 있어서 잊어버린 작업을 다시 찾기 좋다. VS Code에는 기본 기능이 없어 Todo Tree 같은 익스텐션을 설치해야 한다고 하셨다. Keymap 에 따라 단축키가 달라진다. 강사님은 기본값이 아닌 다른 키맵을 쓰신다. 기본 키맵에서는 Ctrl+Y 가 되돌리기 취소가 아니라 줄 삭제 라서, Ctrl+Z / Ctrl+Y 습관 때문에 자꾸 줄을 지우게 되어 바꾸셨다고 했다. 기본 키맵에서 되돌리기를 취소하려면 Ctrl+Shift+Z 다. 이클립스나 VS Code 키맵을 불러와 쓸 수도 있다. 하려는 것 IntelliJ 단축키 (강사님 키맵 기준) 프로젝트 전체 검색 Shift 두 번 줄 복제 Ctrl+D (Duplicate) 한 줄 이동 Alt+Shift+↑/↓ 블록 전체 이동 Ctrl+Shift+↑/↓ 같은 키워드 다중 선택 Alt+J 원하는 곳 다중 선택 Alt+Shift+클릭 또는 드래그 꼬였을 때와 설정 받은 의존성은 실제로 사용자 폴더의 .m2/repository 에 쌓인다. 예전에는 의존성이 꼬이면 이 폴더를 통째로 지우고 다시 받기도 했는데, 요즘은 그럴 일이 드물다고 하셨다. 빨간 줄이 이유 없이 뜨면 File → Invalidate Caches 에서 캐시를 지우고 재시작하면 대부분 해결된다. Settings 에서는 테마와 글꼴, 그리고 Change font size with Ctrl+Mouse Wheel 을 켜두는 것을 추천하셨다. 설정은 메뉴를 뒤지는 것보다 검색이 가장 빠르다. 소스 구조와 YAML src/main/java 아래에 main 메서드를 가진 클래스가 있다. 자바 프로그램의 진입점이고, 실행되면 SpringApplication.run 이 내장 톰캣을 띄운다. resources 에는 application.yml , 정적 파일용 static , UI 템플릿용 templates 가 있다. test 에는 기능마다 짝을 이루는 테스트 코드를 두는 것이 권장 사항이고, 이 테스트들이 빌드 과정에서 자동으로 돈다. YAML은 들여쓰기 가 가장 중요하다. 들여쓰기가 어긋나면 값을 못 불러와 제대로 실행되지 않는다. 확장자는 .yml 과 .yaml 둘 다 된다. .jpg 와 .jpeg 처럼, 옛날 운영체제가 확장자를 세 글자로 제한했던 흔적이라고 하셨다. 여기에 server.port: 8080 을 적고 실행했다. IntelliJ는 기본이 자동 저장 이라 Ctrl+S 를 누르지 않아도 된다. 실행은 main 옆 재생 버튼, 파일 우클릭 → Run , 한 번 실행한 뒤에는 오른쪽 위 실행 바 어디서든 된다. 그 옆 벌레 모양이 디버그 모드다. 4. 빌드하고, 터미널에서 띄우기 메이븐 라이프사이클 오른쪽 Maven 창의 Lifecycle 에 있는 항목 하나하나가 메이븐의 기능이다. 여기서 clean 을 더블 클릭하는 것과 터미널에서 mvn clean 을 치는 것은 같은 일이다. IntelliJ 안의 메이븐은 내장된 것이라 명령이 조금 다르게 찍힐 뿐이다. 흐름 — 소스에서 실행까지 두 갈래 소스 코드 (.java) │ clean : target 폴더(이전 산출물)를 지운다 │ compile : .java → .class 바이트코드, target 폴더가 다시 생긴다 │ package : 산출물을 배포 가능한 jar로 압축 (이 과정에서 테스트도 돈다) ↓ target/<artifactId>-<version>.jar ├─▶ java -jar <jar> jar가 있어야 실행된다 │ pom.xml 위치에서 └─▶ mvn spring-boot:run jar 없이 빌드부터 돌려 바로 기동 jar 이름은 pom.xml 의 Artifact ID와 버전 을 조합해 만들어진다. 그레이들을 쓰면 target 대신 build 폴더가 생긴다고 하셨다. 터미널에서 실행 IntelliJ 내장 터미널을 열고 target 폴더로 이동해 jar를 확인한 뒤 java -jar 로 실행했다. 파워셸과 macOS 터미널은 ls 와 dir 이 모두 되지만, 윈도우 명령 프롬프트는 dir 만 된다. 파일 이름은 Tab 으로 자동 완성된다. bash · 터미널 — jar 실행과 메이븐 실행 cd target dir # 또는 ls java -jar <artifactId>-<version>.jar # 루트(pom.xml이 있는 폴더)로 올라와서 cd .. mvn clean mvn spring-boot:run 코드 리뷰 ⚠️ 처음 java -jar 는 포트 충돌 로 실패했다. IntelliJ에서 띄운 것을 멈추지 않아 8080을 두 서버가 쓰려 한 것이다. 앞의 것을 멈추고 방향키 위로 이전 명령을 불러와 다시 실행하니 떴다. jar 하나로 서버가 뜨는 이유는 jar 자체가 실행 가능한 파일이고, 그 안의 스프링 부트에 톰캣이 내장 되어 있기 때문이다. 종료는 Ctrl+C 다. 로그에 찍히는 graceful shutdown 은 강제 종료가 아니라 순차적으로 정상 종료됐다는 뜻이다. 일괄 작업을 끝내겠냐고 물으면 Y . ⚠️ mvn spring-boot:run 은 pom.xml 이 있는 위치 에서 쳐야 한다. 강사님도 처음에 target 에서 치셨다가 루트로 올라와 다시 실행하셨다. pom.xml 을 기준으로 빌드가 먼저 돌고, 끝나면 스프링 부트가 기동된다. ⚠️ mvn 을 인식하지 못한다면 먼저 mvn --version 이 되는지 본다. 안 되면 원인은 둘이다. 어제 bin 폴더를 환경변수에 잘못 넣었거나, 아예 넣지 않았거나다. 5. 서비스 디스커버리 — 주소를 매번 물어볼 수는 없다 여기서부터 강의 노트 섹션 2다. 왜 필요한가 서비스 A, B, C를 한 PC에서 띄우면 IP는 같고 포트만 다르다(8080, 8081, 8082). 각자 다른 PC나 컨테이너에서 띄우면 IP나 호스트 이름이 다르니 포트는 8080으로 같아도 된다. 어느 쪽이든 서로 통신하려면 상대의 IP와 포트를 둘 다 알아야 한다. 서비스가 늘어날 때마다 기존 서비스들이 새 주소를 다 알아야 한다는 뜻이다. 강사님은 편지에 비유하셨다. 친구의 존재는 알아도 집 주소를 모르면 보낼 때마다 물어봐야 한다. 실제 상용 서비스는 수십에서 수백 개이고, IP가 동적으로 할당 되어 계속 바뀌기도 하니 하드코딩으로는 관리할 수 없다. 그래서 서비스들의 등록·삭제·위치 정보를 관리해주는 서비스를 둔다. 등록받는다는 의미에서 서비스 레지스트리 , 위치를 찾아준다는 의미에서 서비스 디스커버리 라고 부르는데, 보통 한 제품이 두 기능을 다 하므로 섞어 써도 된다. 수업에서 쓰는 제품은 넷플릭스가 만들어 스프링 재단에 기여한 Spring Cloud Netflix Eureka 다. 그림과 실제는 다르다 강의 노트 그림에는 클라이언트 요청이 유레카로 들어가는 것처럼 그려져 있다. ⚠️ 강사님은 이해를 돕기 위한 그림일 뿐이라고 분명히 하셨다. 유레카는 바깥에 따로 있고, 요청은 앞단의 게이트웨이 가 받는다. 게이트웨이도 요청마다 유레카에 물어보는 게 아니라 주기적으로 목록을 받아와(fetch) 자기 로컬 메모리에 캐싱 해두고 그것을 보고 보낸다. 주기는 기본값이 30초일 것이라고 하셨다. 프로젝트 설정 항목, 이번엔 의미까지 helloworld 때는 기본값으로 넘겼던 항목을 하나씩 설명해주셨다. Group ID 는 조직이나 회사의 도메인을 뒤집어 쓰는 것이 일반적이다. lg.com 이면 com.lg 다. Artifact ID 는 이 프로젝트의 고유 ID다. artifact가 결과물이라는 뜻이니 곧 스프링 부트 애플리케이션의 ID다. Package name 은 두 값을 조합해 자동으로 만들어지는데, 자바 네이밍 규칙에 따라 하이픈은 빠진다. jar와 war 의 차이도 이때 나왔다. jar는 클래스와 인터페이스 파일을 압축한 Java Archive이고, war는 거기에 웹 애플리케이션 형태를 더한 Web Archive다. 스프링 부트 이전의 스프링 프레임워크는 톰캣이 내장되어 있지 않아서, war를 만들어 외부 톰캣의 webapps 폴더 에 넣고 서버를 띄웠다. 그때는 톰캣 하나에 war 여러 개를 넣어 앱 여러 개를 동시에 돌릴 수 있었다. 스프링 부트는 프로젝트마다 톰캣이 하나씩 내장 되어 있어서 jar만으로 독립 실행된다. 강사님은 레거시 스프링과 스프링 부트의 가장 큰 차이로 이 내장 톰캣 과 의존성 관리의 편리함 을 꼽으셨다. 예전에는 Maven Repository 사이트에서 의존성을 검색해 빌드 도구에 맞는 코드를 복사해 pom.xml 에 붙여 넣었는데, 이제는 프로젝트를 만들 때 클릭으로 고른다. 물론 만든 뒤에 추가하는 의존성은 여전히 직접 넣는다. 스프링 클라우드 버전 스프링 클라우드는 여러 서브 프로젝트를 묶은 패키지라서, 서브 프로젝트마다 버전이 제각각일 수 있다. 중요한 것은 스프링 클라우드 버전을 스프링 부트 버전과 맞추는 것 이다. 공식 사이트의 호환 표를 보고 맞추며, 둘 다 최신을 고르면 크게 문제가 없을 것이라고 하셨다. ⚠️ 강의 노트는 스프링 부트 3.5 기준이지만 지금은 그 버전을 고를 수 없어서, 수업은 최신 버전 으로 진행했다. 강사님 화면에서는 스프링 부트 4 버전대가 선택됐고, pom.xml 에는 스프링 클라우드 2025.1 버전대가 자동으로 들어갔다. 6. 실습 1 유레카 서버 띄우기 service-discovery 라는 프로젝트를 Maven, Java 21(각자 JDK 버전), Jar, YAML로 만들고 의존성은 Eureka Server 하나만 골랐다. 유레카로 검색하면 세 가지가 나오는데, 지금 만드는 것은 전화번호부 쪽이다. pom.xml 에서는 스프링 부트와 스프링 클라우드 버전, 의존성을 확인했다. <properties> 에 버전을 변수로 선언해두고 아래에서 ${spring-cloud.version} 으로 꺼내 쓰는 구조도 함께 봤다. 하드코딩해도 되지만 변수로 빼두면 여러 곳에서 같은 값을 참조할 수 있고, 필요하면 직접 변수를 더 만들어도 된다. 유레카 서버가 되려면 두 가지가 필요하다. 의존성 , 그리고 main 클래스의 @EnableEurekaServer 다. @SpringBootApplication 이 내장 톰캣을 띄우고, 그 위에서 유레카 서버가 기동되는 방식이다. yml · service-discovery/src/main/resources/application.yml — 전화번호부 자신은 등록도 조회도 하지 않는다 server: port: 8761 spring: application: name: service-discovery eureka: client: register-with-eureka: false # 내 정보를 유레카에 등록할 것인가 fetch-registry: false # 유레카의 등록 목록을 받아올 것인가 코드 리뷰 8761 은 유레카가 관례적으로 쓰는 기본 포트 다. 꼭 이 번호일 필요는 없다. ⚠️ 클라이언트 설정을 적지 않으면 두 값의 기본값은 true 다. 유레카 서버는 자기 자신이 전화번호부 라 스스로를 등록할 필요도, 목록을 받아올 필요도 없으므로 둘 다 false 로 끈다. ⚠️ 일반 마이크로 서비스는 반대로 둘 다 true 다. 유레카 서버만 예외다. 실행하면 로그에 활성 프로필을 정하지 않아 기본(default) 프로필 로 돈다는 줄이 찍힌다. 강사님은 프로필을 짧게 짚어주셨다. application-dev.yml 과 application-prod.yml 처럼 환경별로 설정을 나눠두면, 개발 DB와 운영 DB처럼 서로 다른 정보를 프로필만 바꿔 골라 쓸 수 있다. 25일차부터 써온 application-dev.yml 의 그 dev 가 프로필 이름이었다. 자세한 것은 컨피그 서버에서 다시 배운다고 하셨다. 이어서 Started Eureka Server 와 8761 포트가 찍히면 브라우저에서 유레카 대시보드 에 접속할 수 있다. 주소는 localhost:8761 , 자기 자신을 뜻하는 루프백 IP 127.0.0.1:8761 , 또는 실제 PC의 IP 중 무엇을 써도 된다. 대시보드에는 기동 시각과 업타임, 복제본(replicas), 그리고 가장 중요한 Instances currently registered with Eureka 가 있다. 아직 등록한 서비스가 없으니 No instances available 이 정상이다. 7. 실습 2 user-service 등록하기 유레카 서버는 켜둔 채로 새 창에 user-service 프로젝트를 만들었다. 이번에는 서버가 아니라 서버에 등록될 클라이언트 라서 Eureka Discovery Client 를 고르고, 앞으로 기능을 붙여갈 것이라 Spring Boot DevTools, Lombok, Spring Web 까지 네 개를 넣었다. main 클래스에는 @EnableDiscoveryClient 를 붙였다. ⚠️ 사실 의존성과 yml 설정만 있으면 이 어노테이션 없이도 등록된다. 그래도 명시적으로 선언하는 것이 관리 차원에서 명확 하다는 것이 강사님의 권장이다. yml · user-service/src/main/
What RADAR observed and classified to build this opportunity. It is what the source published, not a verification that the offer is still active.
[LG CNS AM INSPIRE CAMP - TIL] - 37일차 - 유레카 서비스 디스커버리와 메이븐 빌드·실행. [TIL] LG CNS AM INSPIRE CAMP 37일차 어제 72쪽 구성도에서 칸 하나로만 봤던 서비스 디스커버리가 오늘 실제 프로젝트가 됐다. 유레카 서버를 띄우고, 거기에 서비스 하나를 등록하고, 그 서비스를 네 대까지 늘려봤다. 그 전에 오전 앞부분은 IntelliJ와 메이븐에 썼다. 지금까지 VS Code로 수업해왔기 때문에, 툴을 한 바퀴 둘러보고 빌드한 결과물을 터미널에서 직접 띄워보는 데까지가 먼저였다. 1. 어제를 두 장으로 접고 시작했다 강사님은 어제 내용 중 두 장만 다시 짚어주셨다. 모놀리스와 MSA의 장단점 표, 그리고 MSA 표준 구성도다. 어느 쪽이 더 좋다가…
Open source