JSCODE 시니
@synee
수강생
2,333
수강평
153
강의 평점
4.9
주요 이력
국가 핵심 망 관리: 대법원 및 조달청 시스템 운영·최적화 전문가
차세대 공공 플랫폼 구축: 지능형 나이스(NEIS) 응용 SW 개발 및 아키텍처 설계
풀스택 전문 교육자: K사 부트캠프 등 다수의 강의를 통한 실전 기술 전수
엔터프라이즈 솔루션 전문가: 대규모 시스템 유지보수 및 고도화 설계 역량 보유
안녕하세요! 개발자로 시작해 지금은 교육자로 활동하고 있는 JSCODE 시니입니다.
국가 중요 시스템을 직접 만들고 운영도 해봤지만, 사실 제가 가장 잘하는 건 "그 어려운 걸 누구나 이해하게 설명하는 것" 입니다.
실무 현장은 원래 거칠고 복잡합니다. 🤯
하지만 배우는 과정까지 그럴 필요는 없잖아요?
여러분이 지금 당장 배우고 싶은 스택이 무엇이든 상관없어요.
실무 현장의 복잡한 기술들을 여러분의 눈높이에 맞춰 아주 쉽게 씹어서 떠먹여 드릴게요! 🍀
머릿속에만 있던 복잡한 생각들이 실제 돌아가는 서비스로 바뀌는 신기한 경험, 저랑 같이 쉽고 재밌게 시작해 봐요!
강의
로드맵
전체 1수강평
- Jenkins를 활용한 CI/CD 입문 (with. AWS)
- Jenkins를 활용한 CI/CD 입문 (with. AWS)
- 로그관리와 모니터링 - ELK, 프로메테우스, 그라파나
- Jenkins를 활용한 CI/CD 입문 (with. AWS)
- Jenkins를 활용한 CI/CD 입문 (with. AWS)
게시글
질문&답변
Docker + Spring Boot CI/CD 방법
안녕하세요, agachansong님! JSCODE 시니입니다~현재 이 강의에서는 Jenkins의 초점을 맞추어 Node.js 환경을 기반으로 CI/CD의 핵심 원리와 흐름을 다루고 있습니다! 질문해 주신 Spring Boot의 경우, 기본적인 Docker 및 Jenkins 활용 흐름은 유사하지만 빌드 도구(Gradle/Maven)나 Dockerfile 작성 방식에서 약간의 차이가 있습니다.추후 시간이 된다면 Spring Boot 프로젝트를 활용한 CI/CD 과정도 별도 강의로 제작해 볼 계획을 가지고 있습니다! 🥹다만, 현재 강의를 완강하신 분이라면 이미 CI/CD의 전체적인 메커니즘을 충분히 이해하고 계실 거예요. 따라서 다음 과정을 참고하여 스스로 자료를 찾아보며 직접 환경을 구축해 보시는 것을 강력히 추천드립니다!• Dockerfile 작성: openjdk 이미지를 기반으로 Gradle/Maven 빌드 결과물(.jar)을 실행하는 Dockerfile을 만들어 보세요!• Jenkins Pipeline 수정: Node.js 빌드 단계 대신 ./gradlew build와 같은 명령어를 사용하도록 Pipeline 스크립트를 변경해 보세요.• 컨테이너 배포: 생성된 JAR 파일을 Docker 이미지로 빌드하고 컨테이너로 띄우는 과정을 실습해 보세요.직접 부딪히며 해결하는 과정이 강의를 들을때보다 훨씬 실력 향상에 가장 큰 도움이 되실거에요! 실습하시다가 막히는 부분이 생기면 언제든 질문 남겨주세요!agachansong님의 성장을 응원하겠습니다~!
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 29
질문&답변
(강의 6분 50초 부분) Workspace 안에 index.html이 비어있음
안녕하세요! 쿠카이든님~ JSCODE 시니입니다!ㅎㅎ 질문해 주신 Playwright 리포트 빈 화면 현상은 리포트 구성 파일이 정상적으로 로드되지 않을 때 주로 발생합니다. 정확한 문제 원인을 파악하여 해결책을 드리기 위해, 번거로우시겠지만 아래 세가지 정보를 추가로 확인 부탁드립니다.1. 브라우저 콘솔 에러 로그 빈 화면이 뜬 상태에서 키보드의 F12(개발자 도구)를 누른 뒤, 상단의 [Console] 탭을 클릭해 보세요.그곳에 빨간색으로 표시되는 에러 메시지들이 있다면 캡처하거나 복사해서 공유해 주세요. (문제를 해결할 가장 중요한 단서가 됩니다.🥹)2. 수강 중인 강의 정보 현재 수강하고 계신 강의의 전체 제목과 몇 강인지 알려주실 수 있을까요~?젠킨스 설정 단계에 따라 해결 방법이 달라질 수 있어 확인이 필요합니다. 3. 젠킨스 스크립트 콘솔 설정 확인[젠킨스 관리] > [Script Console]에 아래 코드를 입력하고 Run을 실행한 뒤, 다시 리포트를 확인해 보시기 바랍니다.System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "sandbox allow-same-origin allow-scripts; default-src 'self' 'unsafe-inline' 'unsafe-eval'; script-src * 'unsafe-inline' 'unsafe-eval'; style-src * 'unsafe-inline'; img-src * data:; font-src *;") (참고: 이 설정은 젠킨스 재시작 시 초기화될 수 있으니, 우선 실행 후 리포트가 정상적으로 나오는지 확인 부탁드립니다.)위 정보들을 확인해 주시면 정확한 원인을 잡아드리겠습니다!ㅎㅎ
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 38
질문&답변
강의순서가 바뀌어 있습니다.
안녕하세요! p4sh4님~ JSCODE 시니 입니다!강의를 수강하시며 꼼꼼하게 확인해 주신 덕분에 오류를 바로잡을 수 있었습니다. 제보해 주셔서 진심으로 감사드립니다! ㅎㅎ말씀하신 대로 업로드 과정에서 혼선이 있어 47강과 48강의 순서가 바뀌어 있었습니다. 확인 즉시 [실습] Jenkins와 S3를 활용한 정적 웹사이트 호스팅하기 내용이 정상적으로 이어지도록 수정을 완료했습니다.참고로, 해당 강의 자료는 'Jenkins와 S3를 활용한 정적 웹사이트 호스팅하기'라는 하나의 강의자료 페이지 안에 다음과 같이 구성되어 있으니 학습에 참고해 주세요.47강: [실습] Jenkins와 S3를 활용한 정적 웹사이트 호스팅하기48강: 버킷에 정책 추가하기학습에 불편을 드려 죄송합니다. 혹시 수정된 내용 확인 후에도 이상이 있거나 궁금한 점이 생기시면 언제든 말씀해 주세요. 완강까지 화이팅 하시길 바랍니다~!
- 좋아요수
- 0
- 댓글수
- 1
- 조회수
- 43
질문&답변
build.zip 퍄일이 없습니다.
안녕하세요 p4sh4님! JSCODE 시니 입니다~파일이 없어 당황스러우셨을 것 같아요,,! 불편드려 죄송합니다! ㅠㅠ해당파일이 업로드 중 누락된 것 같아 다시 다운로드 받으실 수 있게 강의자료에 재 업로드 해놓았습니다~!혹시나 윈도우 사용자분이시라면, 반디집을 이용해 압축 해제 부탁드립니다!또한 기타 문의 사항 있으시다면 언제든 편하게 연락주시길 바랍니다~!완강까지도 응원하겠습니다!
- 좋아요수
- 0
- 댓글수
- 1
- 조회수
- 52
질문&답변
7~8강 Log Level 관련 상세 설명/명세가 필요할 경우 log.info/warn <-> 주석의 적절한 사용 방법에 대한 질문
안녕하세요! Hyo Kyun Lee님~ JSCODE 시니 입니다! ㅎㅎ강의 내용을 아주 깊이 있게 소화하고 계시네요! 질문 주신 내용은 실무에서 개발자가 늘 고민하게 되는 가독성(코드)과 가시성(운영) 사이의 균형에 대한 아주 훌륭한 주제인 것 같습니다! ㅎㅎ말씀하신 것처럼 프로젝트의 성향이나 규모에 따라 천차만별이긴 하겠지만,,, 질문하신 내용에 대해 제 실무적 경험을 바탕으로 정리해드릴게요! 1. 주석과 로그의 본질적인 차이제가 생각할때 주석과 로그의 본질척인 차이를 두기 위해 가장먼저 구분해야 할 것은 '누가, 언제 읽는가' 인 것 같습니다!주석 : 개발자가 코드를 수정하거나, 기능을 파악하기 위해 코드 편집툴에서 읽는 것 입니다. 비즈니스 로직의 의도나 복잡한 알고리즘 설명, 오픈소스 사용법등이 여기에 포함됩니다.로그 : 운영자가 애플리케이션이 실행 중일 때 콘솔이나 파일을 통해 읽는 것 입니다. 프로그램의 상태를 확인하는 용도라고 생각하시면 쉬울 것 같습니다!2.상세 명세와 설명은 어떤 영역일까?결론부터 말씀드리면, '상세한 명세와 설명은 100% 주석의 영역 ' 입니다.오픈 소스나 프레임워크(Spring Batch, Tomcat 등)에서 로그를 상세하게 남기지 않는 이유는 크게 두가지입니다..!성능 저하 : 상세한 설명을 모두 로그로 세세하게 남기면 디스크 I/O 가 발생하여 전체 시스템 성능이 크게 떨어집니다!로그 노이즈 : 너무 많은 정보가 로그에 찍히면, 정작 장애가 났을 때 중요한 로그를 찾기가 불가능해질 수 있습니다.그래서 결론적으로는 저는 클래스나 메서드의 역할을 설명하실때는 주석으로 작성하는걸 추천 드립니다. 특히 이때 작성하시는 주석은 일반 주석 보다는 /** 내용 */ 주석으로 작성하시는걸 추천드립니다! ㅎㅎ만약 로그로 남겨야 할 특징적인 부분이 뭘까 라고 한다면,, 어떤 데이터가 들어와서 어떤 결과가 나갔는지에 대한 상태의 변화라고 생각합니다..!3.Log Info와 Warn의 실무적 활용 가이드우선 강의에서 이해하신 내용이 아주 정확합니다! ㅎㅎ 이를 실무/오픈소스 관점에서 조금 더 구체화 해볼게요..!Log INFO : 실행되는 로직의 핵심단계만 남기시면됩니다.예를들어, log.info("이제부터 사용자 유효성 검사를 시작하고 디비에 저장 한 뒤~~ 어쩌고 저쩌고") 이런 내용은 로그 보다는 주석으로 가는것이 훨씬 알맞겠죠!대신 좋은 예시는 log.info("배치 작업 xxx 시작 : [TargetDate : {}]", targetDate);이런식으로 이 작업이 시작이 됐고 성공적으로 끝났다는 사실 여부 같은걸 쓰면 좋습니다. 참고로 식별자를 남기는 것이 핵심입니다! ㅎㅎLog WARN : 시스템이 중단되지는 않지만, 나중에 문제가 될 요소를 남깁니다.예를들어 오픈소스라면 설정값이 권장 사양보다 낮을때나, 곧 사라질 기능을 호출 했을때 남기면 좋을 것 같습니다.또는, 재시도 로직 중 1차 실패 발생시나, api 응답이 평소보다 늦어지는 임계치 도달시 남기는 것을 추천드립니다..! 이것 저것 말씀드리다 보니 답변이 길어졌네요,,! 제 답변이 도움이 되셨을지 모르겠습니다!근데 다만 확실한건 제가 강의에서도 말씀드렸지만 전적으로 이런건 정답은 없고 프로젝트의 상황과 규모를 토대로 잘 판단하신다면 그게 정답입니다! ㅎㅎ 여러가지 적용 해보시면서 적절한 트레이드 오프를 하시면 좋을 것 같습니다! ㅎㅎ강의 열심히 들어주셔서 감사하고, 추후에 질문 사항이 또 생긴다면 언제든 남겨주시길 바랍니다! ㅎㅎ항상 응원하겠습니다~!!
- 좋아요수
- 1
- 댓글수
- 1
- 조회수
- 54
질문&답변
마이크로미터는 별도 설정이 없어도 되나요?
안녕하세요 gibbs님! ㅎㅎ JSCODE 시니 입니다~! 아직 실습은 못해보고 영상만 보는 중이시군요! 전체적인 흐름을 먼저 파악하시는 것도 아주 좋은 학습 방법입니다.결론부터 말씀드리면, 의존성을 추가하면 마이크로미터가 자동으로 기본 지표들을 수집하지만, 이 데이터를 프로메테우스가 가져갈 수 있도록(Scraping) 길을 열어주는 설정 파일(application.yml) 수정이 반드시 필요합니다!강의에서 다루고 있는 설정을 기준으로 설명해 드릴게요! ㅎㅎ 1. 의존성 추가implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'io.micrometer:micrometer-registry-prometheus' 이 두 가지 의존성을 추가하면 스프링 부트가 중간에서 마이크로미터와 관련된 설정들을 자동으로 처리하고, JVM, CPU, 웹 요청 등 다양한 기본 지표를 수집하기 시작합니다. 2. 엔드포인트 노출 및 추가 설정 (application.yml)데이터를 수집하고 있더라도 보안상 기본적으로는 외부에서 접근할 수 없습니다. 따라서 프로메테우스가 데이터를 수집할 수 있도록 아래와 같이 설정을 추가해주어야 합니다.spring: application: name: waiting-api management: endpoints: web: exposure: include: prometheus,health,info,metrics,env,loggers metrics: tags: application: waiting-api endpoint: health: show-details: always 이 설정을 통해 /actuator/prometheus 등의 엔드포인트를 외부에 노출하고, 수집되는 모든 지표에 application: waiting-api라는 공통 태그를 붙여 프로메테우스에서 식별하기 쉽게 만들어 줍니다.이후 실습을 진행하시면서 설정 파일이 어떻게 동작하는지 직접 확인해 보시면 구조가 훨씬 명확하게 이해되실 거에요!ㅎㅎ 강의 수강하시다가 더 궁금한 점이 생기면 언제든 질문 남겨주세요~!! 화이팅하시고 좋은하루 보내세요~!!
- 좋아요수
- 0
- 댓글수
- 1
- 조회수
- 71
질문&답변
소스코드 빈파일 문의
dsadadsa님 안녕하세요! JSCODE 시니 입니다~자료 다운로드가 안돼서 굉장히 답답하셨겠네요! ㅠㅠ제가 방금 다시 다운로드 해보았는데, 제 PC에서는(사진)이렇게 폴더 및 파일들이 잘 보이고 있어서 조치방법 안내드립니다.혹시 몰라 직접 인프런 문의해보니 현재 정상 다운로드 되는것으로 확인 되었습니다!해당 증상의 경우 캐시 문제일 가능성이 높아서 캐시 삭제후 재 다운로드 진행해보시고캐시 삭제후에도 동일 문제 발생시 인프런 채널톡으로 문의주시면 감사하겠습니다!혹시라도 진행이 잘 안되신다면 1:1 개인 채팅방으로 이메일 남겨주세요! 파일 보내드리도록 하겠습니다~!!
- 좋아요수
- 0
- 댓글수
- 1
- 조회수
- 63
질문&답변
jobParameter를 통한 멱등성 질문
iii님 안녕하세요! JSCODE 시니입니다~ 우선 강의를 재미있게 들어주시고, 중급 강의까지 기대해 주신다니 정말 감사합니다! ㅎㅎ남겨주신 질문들을 읽어보니, 배치 프로세스 설계의 핵심이자 가장 까다로운 부분 중 하나인 멱등성과 실패 복구에 대해 아주 정확하고 깊이 있는 고민을 하고 계신 것 같아요~! 질문주신 내용은 실제 실무에서 배치를 설계할 때 반드시 고려해야 하는 포인트들 입니다! ㅎㅎ iii님이 질문 주신 세 가지 질문에 대해 하나씩 답변 드리겠습니다! 1. 실패 지점부터 재실행할 때의 파라미터 유지 여부"만약에 job을 실패지점부터 재실행 하고 싶은 경우에는 targetDate 뿐만 아니라 실패한 시간대에 time 파라미터까지 넣어서 재시작을 해야하는 것인가요?"네! 정확히 맞습니다.Spring Batch에서 동일한 Job을 식별하는 기준은 Job Parameters 입니다. 파라미터가 완벽하게 동일해야 Spring Batch는 이를 새로운 실행이 아닌 기존 JobInstance의 재실행으로 인식합니다!따라서, 실행도중 실패한 Job을 처음부터가 아닌 실패한 지점(Chunk) 부터 이어서 재실행 하고 싶다면, targetDate는 물론이고 실패했던 당시의 time 파라미터 값까지 똑같이 넣어서 실행하셔야 합니다!만약 time 값을 조금이라도 다르게 부여하면, Spring Batch는 이를 완전히 새로운 JobInstance로 판단하여 처음부터 새로운 작업을 시작하게 됩니다~! 2.다른 time 파라미터로 재실행시 DELETE Step 분리 여부"정산 테이블에서 targetDate에 해당하는 값을 DELETE를 하고 INSERT를 진행해야 멱등성이 유지될 것 같습니다. 이럴 경우 DELETE 같은 경우는 Settlement INSERT 작업 이전에 별도의 Step으로 구성이 되야할까요?"네 맞습니다!이전 실행이 완료되었거나, 실패했더라도 처음부터 완전히 다시 돌리고 싶어 새로운 time 파라미터를 부여하여 실행하는 경우가 있습니다. 이때 기존에 처리된 데이터가 남아있다면 중복 정산이 발생하므로 멱등성이 깨지게 됩니다..!이런 상황에서 멱등성을 보장하기 위해 iii님께서 말씀주신 것 처럼 INSERT 이전에 기존 데이터를 DELETE 하는 작업이 필수적 입니다.그리고 이 DELETE 작업은 별도의 Step(예를 들면 deleteSettlementStep) 으로 구성하여INSERT Step 바로 직전에 배치하는 것이 가장 권장되는 설계 방식입니다.이렇게 Step을 분리하면 역할이 명확해지고, 트랜잭션 관리도 훨씬 깔끔해질거에요!ㅎㅎ 3.DELETE 실행 방식 (한 번에 삭제 OR 나누어서 삭제)"만약에 DELETE를 해야한다면 DELETE의 경우에는 targetDate의 해당 하는 값을 한번에 전부 지우고 INSERT를 시작하는지 궁금합니다..!"일반적으로는 targetDate에 해당하는 값을 한 번에 벌크연산으로 전부 지우고 시작하는 것이 맞습니다.정산 배치의 특성상 해당 날짜(targetDate)의 정산 데이터를 처음부터 다시 만든다는 의미이므로,특정 날짜의 데이터를 초기화 하는 개념 입니다. 따라서 다음과 같이 쿼리를 작성해서 삭제하는 방식을 주로 사용합니다.DELETE FROM settlement WHERE target_date = :targetDate단, 실무에서 작업을 하다보면 삭제해야할 targetDate의 하루치 데이터가 수천만건 이상 이여서 한번에 DELETE 쿼리를 날리게 되면 DB락이 걸리게 되거나 성능상 이슈가 발생할 수도 있습니다..!이때는 예외적으로 삭제 작업도 Chunk 단위로 나누어 지우거나, 파티셔닝을 고려해야 할 수도 있습니다.하지만 제 경험상 일반적인 실무 환경에서는 날짜 조건 인덱스를 활용하여 벌크 연산으로 처리하는 경우가 가장 많았던 것 같습니다.제가 iii님의 질문을 잘 이해하고 답변을 달아드렸는지 모르겠네요~! 혹시라도 잘 해결이 되지 않는 부분이 있다면 언제든 편하게 게시판에 남겨주세요!최대한 빠르게 확인 후 답변드리도록 하겠습니다~! 오늘도 즐거운 하루 보내세요! ㅎㅎ
- 좋아요수
- 1
- 댓글수
- 2
- 조회수
- 74
질문&답변
bootRun FAILED 에 대한 문의
쿠카이든님 안녕하세요~ JSCODE 시니 입니다!배치 실패 시 메일 전송 수업 들으시다가 궁금한점이 생겨 많이 답답하셨을 것 같아요! 캡쳐해주신 사진을 확인해보니, 결과 화면이 저와 다르게 bootRun FAILED로 나오셨네요!이 현상의 원인은 바로 main 메서드의 설정 차이 때문입니다~!아마 쿠카이든님 같은 경우는 실습하시면서 main 메서드를 다음과 같이 설정하셨을 거예요. System.exit(SpringApplication.exit(SpringApplication.run(SyBatchSystemApplication.class, args))); 그러나 저는 해당 실습을 진행할 때 main 메서드를 변경하지 않고 기본 상태 그대로 사용 했습니다! :)SpringApplication.run(SyBatchSystemApplication.class, args); 스프링 부트는 기본적으로 애플리케이션 내에서 예외가 발생해 프로그램이 죽더라도(우리의 경우죠!), 프로세스 종료 코드(Exit Code)를 0(정상 종료)으로 반환하며 끝나는 경우가 있습니다.! 쿠카이든님이 작성하신 System.exit(...) 코드는 스프링 애플리케이션의 종료 코드를 읽어와서 OS(운영체제)에 정확한 상태를 전달해 주는 역할을 합니다! 즉, 배치가 실패(예외 발생)했으니 비정상 종료 코드를 반환하게 되고, 그 결과 Gradle이 이를 감지해서 > Task :bootRun FAILED라고 명확하게 빌드 실패 에러를 출력한 것이죠!반면, 제가 실습한 기본 코드에서는 이 예외에 따른 비정상 종료 코드를 시스템으로 명시적으로 전달하지 않았기 때문에, 결과 화면이 다르게 나타났던 거라고 이해해주시면 될 것 같습니다! 결론적으로 쿠카이든님이 작성하신 코드가 실제 운영 환경에서 배치의 성공/실패 여부를 시스템이나 스케줄러에 정확히 알리기 위해 꼭 필요한 권장 방식이니, 아주 잘 적용하신 겁니다! ㅎㅎ 자세한사항은 저희 노션 강의자료 섹션3 - '[실습] 스프링 배치 프로젝트 생성(Spring Boot 4.x & Gradle)' 페이지의 4번 항목인 메인 메소드 변경 파트를 참고해주시면 더 좋을 것 같습니다! ㅎㅎ 오늘도 좋은 하루 보내시고, 앞으로도 배치를 공부하시다가 궁금한 점이 생기면 언제든 편하게 질문 남겨주세요!
- 좋아요수
- 1
- 댓글수
- 2
- 조회수
- 86
질문&답변
[참고] Tasklet 인터페이스로 단일 배치 작업 처리 수업에 나온 코드 돌리는 방법
쿠카이든님 안녕하세요! JSCODE 시니 입니다~직접 코드까지 작성해주시고 공유해주시는 열정 너무 멋집니다!! 👍 수업에서 다룬 Tasklet의 개념도 잘 이해하고 작성하신 것 같아서 더더욱 좋은 것 같습니다!다른 수강생 분들께도 큰 도움이 될 것 같아요! 다른 수강생 분들도 쿠카이든님의 코드를 참고하셔서 Step => Tasklet으로 이어지는 스프링 배치의 기본 구조를 실습해보시면 공부에 큰 도움이 될 것 같습니다! 좋은 자료 공유해주셔서 너무 감사합니다!공부하시다 궁금한 점 생기시면 언제든 질문 남겨주세요! ㅎㅎ 항상 응원하겠습니다~!!
- 좋아요수
- 2
- 댓글수
- 2
- 조회수
- 85




