목차
개요
프로젝트 진행 중 null 값에 비교연산자를 사용하여 null인 경우와 아닌 경우를 구분해서 작업을 진행해야하는 순간이 있었습니다. 아무 생각 없이 null 값은 객체가 값을 참조하지 않은 경우니까 객체의 값을 비교하는 .equals()를 써야겠지라고 생각했다가 문제가 생겨 부끄러운 순간이지만 내용을 공유해보려고합니다.
==을 사용해야하는 이유
null은 힙 영역의 객체를 참조하지 않는다는 뜻으로 존재하는 특수한 상태 타입입니다.
null로 초기화된 참조 변수는 스택영역에 생성되죠.
그렇기 때문에 .equals()가 아닌 ==을 사용해야합니다.
결론
그런데 생각해보니 null을 처리하기 위한 Optional이라는 좋은 선택지가 있었는데 왜 생각하지 못했는지...
'코드스테이츠 > 메인프로젝트(MuDuck) 이슈정리' 카테고리의 다른 글
AWS 서버 한국 시간으로 변경하는 것을 까먹지 말자 (0) | 2023.07.28 |
---|---|
Lombok @Builder 사용 시 기본값을 지정해줘야한다면 @Builder.Default를 사용하자 (0) | 2023.07.28 |
gradlew test -i 를 사용해 테스트코드 오류를 찾자 (0) | 2023.07.28 |
스프링에서 같은 엔드포인트에 쿼리 파라미터가 다른 컨트롤러 메서드 구성하기 (0) | 2023.07.28 |
LocalDateTime 시간 출력 형식에 따라 변환하기 (0) | 2023.07.27 |
목차
개요
프로젝트에서 커뮤니티 글의 작성 시간을 LocalDateTime 타입으로 저장하도록 되어 있었는데요. 게시글을 들어갔을 때 작성 시간을 알려주기 위해 LocalDateTime을 그대로 사용하면 년-월-일-시간-분(ms까지) 나오기 때문에 저희가 원하는 형태인 년.월.일 형태로 변경해서 응답을 보내주어야했습니다.
DateTimeFormatter.ofPattern 사용하기
개요
LocalDateTime 타입에는 format 이라는 함수를 사용할 수 있습니다.
DateTimeFormatter 타입의 값을 인자로 넣어 원하는 날짜 형식으로 변환하는 함수입니다.
이 때, DateTimeFormatter 타입의 ofPattern 함수를 사용하여 String으로 원하는 날짜 형식을 정할 수 있습니다. 원하는 날짜 형식은 주어진 Symbol을 따라 작성하면 됩니다.
아래는 Symbol의 일부입니다. 사진의 출처사이트에 방문하시면 더 많은 Symbol을 확인하실 수 있습니다.
예시
우선 제게 주어진 요구사항과 같이 년.월.일 형태로 변경해보는 예시를 보겠습니다.
LocalDateTime dateTime = LocalDateTime.now()를 통해 현재 시간을 저장하고 해당 타입을 년.월.일 형태로 변경하는 코드 입니다.
이를 통해 출력된 결과는 아래와 같습니다.
이번에는 다양한 타입의 형태를 출력하도록 해보겠습니다.
연도를 나타내는 y Symbol의 개수를 조절해서도 서로 다른 형태로 나타낼 수 있고 월을 나타내는 M Symbol의 개수를 조절해서도 서로 다른 형태를 나타낼 수 있습니다.
다양한 조합을 Documentation 내용을 참고해서 변경해보셔도 좋을 것 같습니다.
'코드스테이츠 > 메인프로젝트(MuDuck) 이슈정리' 카테고리의 다른 글
AWS 서버 한국 시간으로 변경하는 것을 까먹지 말자 (0) | 2023.07.28 |
---|---|
Lombok @Builder 사용 시 기본값을 지정해줘야한다면 @Builder.Default를 사용하자 (0) | 2023.07.28 |
gradlew test -i 를 사용해 테스트코드 오류를 찾자 (0) | 2023.07.28 |
스프링에서 같은 엔드포인트에 쿼리 파라미터가 다른 컨트롤러 메서드 구성하기 (0) | 2023.07.28 |
Null 값에 비교연산자를 사용해야한다면 == 을 사용해야한다. (0) | 2023.07.27 |
목차
개요
Codestates PreProject 진행 시, Github Actions와 AWS Connector를 막아놔서 CI/CD를 쉽게 연결하기가 어려운 상황이 있었습니다. 수업 때 배웠던 내용이 적용이 안되어 당황스러웠지만 언제나 그렇듯이 답을 찾을 것입니다.
Github 권한 중 Webhooks 기능은 열려 있는 것을 확인하여 Jenkins에 Webhooks로 신호를 보내 CI/CD를 진행하면 어떨까라는 생각이 들어 기록을 남기고자 합니다.
이 내용이 다른 동기님들께도 도움이 되었으면 좋겠습니다.
큰 흐름 설명
시도했던 블로그들을 소개하기 전에 큰 흐름부터 설명하고 넘어가고자 합니다.
1. AWS EC2에 Jenkins 설치 및 포트 오픈
2. Github Webhooks로 main branch에 push 작업이 일어날 시 Jenkins에 알림을 보내도록 설정
3. Jenkins Pipeline을 이용하여 빌드 작업 진행
4. Jenkins Pipeline을 이용하여 EC2 내부에서 백그라운드로 빌드된 파일 실행
위 순서대로 진행했습니다.
작업한 순서대로 설명을 진행할 때, 제가 참고했던 블로그도 함께 소개드리겠습니다.
Ubuntu에 Jenkins 설치할 때 참고한 블로그
https://hyunmin1906.tistory.com/272
[Ubuntu 20.04] 젠킨스(Jenkins) 설치 및 설정
■ Jenkins Jenkins는 Java로 빌드 된 오픈 소스 CI (Continuous Integration) 및 CD (Continuous Delivery) 도구이며, Jenkins는 기본적으로 소프트웨어 프로젝트를 빌드, 테스트 및 배포하기 위해서 사용한다. 또한 DevO
hyunmin1906.tistory.com
Jenkins 설치 후, EC2에 인바운드 규칙을 추가해야합니다.
아래 블로그의 2번 내용인 EC2 인스턴스 접근 허용 포트 추가 내용을 참고하여 진행하였습니다.
https://junhyunny.github.io/information/jenkins/jenkins-deploy-ec2-using-docker/
젠킨스(Jenkins) 파이프라인 서비스 배포 on EC2 인스턴스
<br /><br />
junhyunny.github.io
Github와 Jenkins 연결하기
해당 과정에서 가장 많은 삽질을 진행하여 참고한 블로그와 제 코드를 함께 공유하겠습니다.
[우젠구2편] 젠킨스 파이프라인을 활용한 배포 자동화
지속적 배포를 할 수 있는 대표적인 오픈소스 툴, 젠킨스!서버 구성을 직접해야하는 단점이 있지만, 오랫동안 사랑받아온 만큼 레퍼런스도 다양하고 플러그인도 많이 제공합니다!오늘은 젠킨스
velog.io
우선 큰 뼈대는 위 블로그를 참고했습니다.
위 블로그를 참고하여 완성한 최종 코드는 아래와 같습니다.
stage는 내가 원하는 작업의 제목을 뜻한다고 이해하시면 됩니다.
build 부분에서 steps 안에 있는 dir는 내가 빌드하고자하는 파일의 시작 폴더를 작성하시면 됩니다.
저희 프로젝트 같은 경우 Frontend 작업 폴더는 client, Backend 작업 폴더는 server 폴더로 작성해두었기 때문에 dir('server')라 적어 두었습니다.
sh는 쉘 명령어를 뜻합니다. 내부에 적힌 내용을 모두 쉘 명령어들입니다.
echo build start는 쉘에 그냥 build start를 기록하기 위함입니다.
sudo chmod +x ./gradlew는 gradlew를 실행파일로 인식하게 하기 위함입니다.
sudo ./gradlew clean build는 빌드된 파일이 있다면 지우고 빌드하라는 명령어입니다.
EC2 환경 내에서 위의 두 명령어는 sudo 권한이 있어야 실행이 되기 때문에 sudo를 작성해주었습니다.
이슈 발생: Jenkins에 sudo를 사용하려면 권한이 없어서 안된다는 오류가 발생합니다.
해결을 위한 참조 블로그
이슈 발생: 메모리 문제로 빌드가 안된다.
위와 같이 잘 설정해두었음에도 빌드가 안되는 문제가 발생하였습니다.
직접 CLI 환경으로 접속하여 진행해봤는데도 진행이 안되는 문제가 발생하였습니다.
오류가 발생하는 것이 아닌 진행이 너무 느린 것을 보아 메모리 문제라 예상했습니다.
확인 결과 실제로 Jenkins가 메모리의 절반을 소비하고 있었고 무료 EC2를 사용하여 총 메모리가 1GB이기 때문에 문제가 발생한 것이었습니다.
이슈 해결을 위한 참조 블로그.
아래의 개인 블로그에서 스왑 파일 크기를 참고하였고 진팽 과정은 AWS 공식 사이트의 방식을 따랐습니다.
[Jenkins] swap file 설정을 통한 메모리 누수문제 해결
젠킨스를 이용하여 톰캣 또는 spring boot jar 앱을 실행시킬 때, 아래의 메시지를 출력하며 build fail이 될 때가 있습니다. OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000e0800000, 130023424, 0) failed;
blog.jiniworld.me
https://aws.amazon.com/ko/premiumsupport/knowledge-center/ec2-memory-swap-file/
스왑 파일을 사용하여 Amazon EC2 인스턴스의 스왑 공간으로 메모리 할당
Amazon Elastic Compute Cloud(Amazon EC2) 인스턴스에서 스왑 파일로 사용할 메모리를 할당하려고 합니다. 어떻게 해야 하나요?
repost.aws
스왑 메모리를 설정한 후에는 빌드가 무사히 진행됨을 확인하였습니다.
빌드된 파일 배포 진행
빌드가 모두 완료가 되었고 이제 배포만 자동화하면 되는 상황입니다.
참고한 블로그는 아래의 블로그이고 해당 블로그를 참고해서 변경한 제 코드를 이용해 설명을 진행하겠습니다.
https://pjh3749.tistory.com/261
[Spring] Jenkins(젠킨스)를 활용한 스프링부트 앱 간단 배포하기
젠킨스를 활용한 스프링부트 앱 배포 젠킨스란? 젠킨스란 소프트웨어 개발 시 지속적 통합 (Continuous Integration) 서비스를 제공하는 툴이다. 젠킨스의 공식 홈페이지를 가보자. 메인화면에 젠킨스
pjh3749.tistory.com
위 블로그에서 다른 것들은 보지 않고 아래의 스크립트 내용만 참고하였습니다.
위 스크립트 내용을 참고해 제가 작성한 코드는 아래와 같습니다.
마지막 끝에 있는 &는 꼭 추가해주셔야합니다.
코드 설명을 드리자면
위 코드는 저희가 빌드한 파일의 이름이 바뀌더라도 해당 이름을 파일명에서 따오는 명령어입니다.
위 코드는 만약 저희가 앞서 빌드 후 실행한 jar 파일이 있다면 해당 Process ID를 찾아내는 명령어입니다.
위 코드는 만약 우리가 앞서 빌드 후 실행한 jar 파일의 Process ID가 존재한다면 종료시키는 명령어입니다.
위 코드는 우리가 빌드한 파일을 실행하는 명령어입니다.
뒤에 작성한 >>는 앞에서 실행되는 내용을 뒤에 있는 파일에 쓰라는 내용입니다.
Spring boot의 실행 내용을 로그로 기록하고 보기 위함입니다.
가장 앞에 있는 nohup 명령어를 통해 세션과 연결을 종료해도 우리의 빌드된 파일은 실행이 종료되지 않을 것입니다.
가장 마지막에 있는 & 연산자 덕분에 우리는 빌드된 파일을 백그라운드에서 돌릴 수 있게 됩니다.
EC2 Jenkins 폴더에 해당 쉘 스크립트 파일을 만들었다면 Jenkins의 파이프라인을 수정해줍시다.
위 내용은 stages 코드가 닫힌 시점부터 작성을 해줍니다.
post는 빌드가 완료된 다음 어떤 작업을 진행할건지에 대한 코드입니다.
always는 빌드가 성공하든 실패하든 항상 실행하라는 뜻입니다.
success, failure 등 다양한 조건이 있지만 만약 main branch에 merge된 코드가 빌드에 실패한 경우를 대비해 항상 실행되도록 always를 설정하였습니다.
sudo ./backend_deploy.sh를 통해 앞서 소개드린 쉘 스크립트 파일을 실행하도록하였습니다.
이후 빌드를 진행하였고 메인 브랜치에 push를 진행하였을 때도 webhooks로 잘 진행됨을 확인하였습니다.
목차
기존에 사용하던 블로그가 너무 지저분하게 관리가 되어 새로운 자리에 새로운 형태로 블로그를 다시 시작하게 되었습니다. 기존 블로그에서 사용할만한 글은 다시 가져와 새롭게 만들어서 작성하려고 합니다.
또한 제 스스로 다짐하기를 글을 자주 써야한다라는 생각에 매몰되지 않고 정말 공부한 내용을 나 스스로가 나중에 다시 봤을 때 도움이 되도록 글을 정리해야하겠다라는 생각을 했습니다.
매번 블로그가 마음에 들지 않는다고 이렇게 블로그를 재정비할 수는 없을 것 같으니 이번이 처음이자 마지막일 수 있도록 잘 관리해보고 싶습니다.