전체보기

    [Spring] Custom Exception Handler

    Spring에서 exception을 다루는 방식에 대해 다룰 것이다. 총 4개의 파일을 만든다. 디렉토리 구성 exception - CustomException.java - ErrorCode.java - ErrorResponse.java - GlobalExceptionHandler.java 이렇게 된다. 1. CustomException RuntimeException을 extend한 것으로, 선언한 ErrorCode를 가지고 있다. exception/CustomException.java @Getter @AllArgsConstructor public class CustomException extends RuntimeException{ private final ErrorCode errorCode; } 2. ..

    [Spring + Jwt] Spring Boot + Spring Security + Redis + Jwt를 이용한 회원가입 및 로그인

    https://bcp0109.tistory.com/301 이 글을 많이 참고했다. spring security를 이용하는 이유는 spring에서 로그인 기능을 구현하기 위해서이고 session이 아니라 token을 사용하려 하는 이유는 앱 환경에서 로그인을 유지시켜주기 위함이다. jwt는 그 이유 때문이고, redis는 jwt를 관리하기 위함이다. 1. 환경 설정 https://blog.naver.com/jhi990823/222509215989 위 게시글을 따라가면서 docker 위에 redis를 올리면 된다. https://blog.naver.com/jhi990823/222505297298 이후엔 이 게시글을 참조해서 redis를 사용할 수 있는 함수를 만든다. build.gradle implement..

    build server 부터 배포까지 - 5. GKE Spring Redis 배포 - Local, CI Server, Deploy Server에서 Redis와 연동

    이번엔 로그인 기능에서 사용하는 토큰을 올리기 위해 redis를 올려보고자 한다. 1. Local /application.properties spring.redis.host=127.0.0.1 spring.redis.port=6379 이걸 추가한다. /local/docker-compose.yml version: "3" services: mysql: image: mysql:5.6 environment: MYSQL_DATABASE: bizschema MYSQL_ROOT_PASSWORD: rootpw MYSQL_USER: devroot MYSQL_PASSWORD: devpw LANG: C.UTF-8 volumes: - local-mysqlvol:/var/lib/mysql ports: - 3306:3306 com..

    build server 부터 배포까지 - 4. GKE Spring MySQL 배포 - Local, CI Server, Deploy Server에서 MySQL 연동

    이전 글에서는 deploy server인 GKE에서 MySQL의 IP를 할당받아서 사용했다. 그러나, 이 방법을 사용하면 test할 때 실 서버의 db를 이용하기 때문에 상당히 위험한 방식이라 생각한다. 이를 보완하기 위해 다른 방법을 이용하고자 한다. 지금 구축되어있는 서버는 크게 3가지이다. 로컬, CI 서버, Deploy 서버. 먼저 로컬과 CI 서버에 추가적으로 docker 위에 mysql을 올리고 임의로 id, pw를 지정한다. 그러면 로컬에서 빌드할 때는 로컬에 있는 docker의 mysql을, CI 서버에서 빌드할 때는 CI 서버의 docker에 있는 mysql을 참조할 것이다. 마지막으로 GKE는 deploy.yml 파일을 작성했을 때 만든, 실제 서비스 DB mysql을 참조하게 될 것이..

    build server 부터 배포까지 - 3. GKE Spring MySQL 배포 - MySQL 배포 및 Mysql + Spring 배포

    먼저, gcp terminal에서 편집기를 이용할 수 있다! 어제 vs code로 연결할라고 아득바득 할 필요가 없었다... 1. mysql 배포 GKE 기반 kubenertes에서 mysql을 수행하기 위해서는 pvc 생성, deploy 및 service가 필요하다. /home/hyelie/k8s-test/mysql-pvc.yml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi GKE에서 1Gi의 pvc를 만들겠다는 것이다. 그냥 kubernetes만 사용하낟면 pvc, pv도 생성해야 하지만 gke이기 때..

    build server 부터 배포까지 - 2. GKE Spring MySQL 배포 - GKE 클러스터 생성 및 spring 예제 배포

    내 프로젝트에서 FE가 필요없고 BE와 DB만 있으면 되기 때문에 이에 대한 kubernetes 환경을 구축하고자 한다. 1. GKE 클러스터 생성 공부하는 게 목적이니까, 표준으로 일단 해보자. 기본 사항에선 딱히 건들 게 없고, 수정할 거라면 default-pool - 노드 - 머신 계열 정도만 골라주면 될 것이다.그러면 클러스터 하나가 생성된다. VM instance 목록에 들어가 보면 3개의 vm이(노드들) 생성되어 있다. 이후 우상단의 gcloud shell을 실행시킨다. 나는 지금 활성화되어 있어서 꺼져 있다. https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl?hl=ko 그러면 master node..

    [GCP] GKE 중지시키기

    gcloud shell에서 아래 명령어를 입력하면 된다. 우상단의 gcloud shell을 활성화 시키고, 위치를 본다. gcloud container clusters resize $NAME --size=0 --zone=$LOCATION 위 명령어에서 $NAME은 컨테이너 이름인 cluster-1을, $LOCATION은 위치인 us-central1-c를 입력하면 된다. 이걸 하면 vm instance에 있던 node들이 사라지는 걸 볼 수 있다.

    [GCP] Cloud IP가 바뀌었을 때, 수정해야 할 것

    바로 앞 포스팅에서 cloud의 external/public ip가 바뀌면 4가지를 바꾸어야 한다. 1) jenkins - gitlab webhook ip 변경 jenkins 구성 - gitlab webhook ip를 gitlab에 재등록해야 함. 2) sonarqube ip 재등록 jenkinsfile에 있는 stage('SonarQube Analysis'){ steps{ withSonarQubeEnv('sonar-server'){ sh './gradlew sonarqube -Dsonar.projectKey=ciserver -Dsonar.host.url=http://35.225.76.162:9000 -Dsonar.login=8ec502617dd7b039e3179fadb5ec83f0127544cc' } ..

    build server 부터 배포까지 - 1. GCP + Docker + Jenkins + Gitlab + JUnit + SonarQube + GCR image push

    그럼 이제 GCP 위에 docker를 올리고, docker 위에 jenkins, sonarqube를 올리고 gitlab webhook으로 pull받아서 build 후 GCR push까지, 한 번에 다뤄보고자 한다. 자세한 모든 화면은 이전 포스팅들을 참고. *** 지금 이 글대로 구성하면, ci server에서 jenkins data가 저장될 곳이 없어 재시작하면 전부 날아간다. 이를 고려해서, volume을 추가하는 것을 권장한다. 1. docker-compose로 GCR 위에 docker, docker 위에 jenkins, sonarqube 설치 /home/hyelie/compose/docker-compose.yml version: "3" services: jenkins: container_name:..

    [GCP] GCP 기본 설정 - SSH로 접속하기 & 포트 열기 & docker 설치 & 고정 IP

    먼저, AWS kubernetes 환경을 구성하려 했는데 AWS는 이것저것 설정할게 너무 많아서 GCP로 넘어가려 한다. 1. SSH 접속 https://ruuci.tistory.com/6 위 글을 참고했다. 먼저 C:\gcp 폴더를 만든다. 이후 vs code에서 C:\gcp에 접근해서 ssh-keygen -t rsa -f "파일 이름" -C "내 GCP 계정" 을 입력한다. 생성된 public key를 vm instance - metadata - ssh key에 복사한다. 이후 vs terminal에서 ssh -i "private key 경로.private key 파일이름" "사용자 이름"@"VM 외부 IP" 로 접속할 수 있다. 여기서 사용자 이름은 생성할 때 hyelie@postech.ac.kr ..

    EC2 Docker Jenkins Spring Gitlab 자동 빌드 - 6. 수정사항, ECR push

    1. 수정사항 원래는 docker 안에 jenkins가 있고, jenkins에서 docker로 접속하는 방식을 택했다. 근데 ECR에 push하기 위해서는 jenkins에서 docker를 실행해야 한다. 그래서 docker-compose.yml 파일을 조금 수정한다. /home/ec2-user/compose/docker-compose.yml version: "3" services: jenkins: container_name: jenkins image: jenkins/jenkins:lts user: root ports: - "8081:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock - /home/ec2-user/compose/jenkins:/var/..

    EC2 Docker Jenkins Spring Gitlab 자동 빌드 - 5. jenkins pipeline - JUnit + SonarQube

    앞에서는 build step을 이용해서 추가했다. 그러나 jenkins에서 이걸 언제 하나하나 다 만지고 있나. 프로그래머처럼 code를 이용해서 각각의 step을 design할 수 있으며 - 이것이 jenkins pipeline이다. MSA는 빠른 배포가 목적이기 때문에 JUnit, SonarQube 등의 품질검사 pipeline을 구성한다. pipeline은 gradle build - JUnit test - SonarQube test - docker build, push - kubernetes deploy 이렇게 될 것임. pipeline으로 이것을 구성해 볼 것이다. 만약 2개 이상의 프로젝트가 있으면, 각각의 프로젝트를 jenkins project에 연결시켜서 각각 프로젝트의 image만 buil..

    [Spring + Redis] Spring Redis 연동

    dependency implementation 'org.springframework.boot:spring-boot-starter-data-redis' application.properties spring.redis.host=127.0.0.1 spring.redis.port=6379 RedisUtil.java import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; @Component ..

    [Docker] Redis + Docker + 간단한 명령어

    다른 db와 마찬가지로 docker에 올렸다. docker-compose.yml 중 일부 redis: image: redis:alpine hostname: redis-local ports: - 6379:6379 container_name: local-redis 실행 docker exec -it {container-id} redis-cli 기본적으로 redis는 key, value가 쌍으로 저장되는 database이다. key 조회 keys * 값 삽입 set {key} {value} ex) set key_one value_one key에 해당하는 value 조회 get {key} ex) get key_one 갱신 : 삽입과 동일. set {key} {value} ex) set key_one value_o..

    [JPA] JPA Join 이슈, FETCH JOIN의 사용

    Join 방향 이슈 A : B = 1 : N의 관계일 때 일반적으로 B에서 ManyToOne을 가지고 있다. 이 경우 B Join FETCH A는 되지만 A Join FETCH B를 하면 작동하지 않는다. 왜냐하면 B에서 A 정보는 있지만 A에서 B 정보는 없기 때문이다. 이를 해결하기 위해서는 - 양방향 관계를 넣던가, - B.getA()로 A 정보를 가져오던가, - SQL JOIN하듯 SELECT b FROM A a JOIN B b ON b.A = a; 이렇게 하면 된다. 그냥 INNER JOIN하는 것 처럼 된다. 다만 이러면 join을 해버리는 것이기 때문에 성능상 이슈를 생각해야 한다. Fetch Join의 사용 이유 그리고 또 하나. FETCH JOIN을 사용하는 이유를 깨달은 것 같은데. 처..

    [JPA] JPQL FROM절 subquery를 해결하는 방법 (inline view)

    문제 상황 - JPA의 FROM절에 subquery를 넣는 상황. 문제 상황은 다음과 같다. 킥보드 사용량에 대한 consumption entity가 있고, 킥보드의 이동 경로에 대한 coordinate entity가 있다. consumption : coordinate는 1 : n 관계이며, coordinate entity에 다대일 매핑만 되어 있다. @Entity @Getter @NoArgsConstructor @AllArgsConstructor @Table(name = "consumption") public class Consumption { @Id @Column(name = "consumption_id") @GeneratedValue(strategy = GenerationType.IDENTITY) ..

    [Troubleshooting] Jenkins 잘 되던 build가 안 될 때

    잘 되었던 build가 안되는 경우가 생겼다. 코드는 변함없는데. 그래서 이것저것 해보다가 용량 부족임을 알게 되었다. 쌓인 image, build log를 지우고 gcr에도 쌓인 image를 삭제하니 잘 된다. stage('Docker unused image remove'){ steps{ script{ sh 'docker image prune -a' } } } -a 옵션은 사용되지 않는 모든 image 삭제이다. build server에서는 실행중인 jenkins, mysql, sonar-qube 이외의 image는 사용되지 않기 때문에 모든 image를 삭제하게 했다.

    [Spring] DTO와 Entity 간의 변환

    Spring을 쓴다면 MVC 구조를 사용한다는 것을 전제로 깔고 갈 것이다. 따라서 Controller, Service, Repositoy, DB 순으로 flow가 이동하며, 이 과정에서 entity라는 객체와 DTO라는 객체를 사용한다. 정의를 먼저 살펴보자면, entity는 DB의 row 하나와 매핑되는 객체인 반면, DTO는 Data Transfer Object, 데이터를 옮기는 데 사용하는 객체이다. DTO의 필요성 DTO의 필요성에 대해서는 말할 필요도 없다. 만약 DTO가 없다고 가정해 보자. 그러면 entity를 사용자에게 노출시켜야 하는데, entity는 DB의 모든 column에 대한 정보를 가지고 있기 때문에 이를 사용자에게 노출시키는 것은 좋지 않다. 또한 entity에 내용이 부족해..

    [JPA] JPA @IdClass에 관해,,,

    JPA에서 IdClass는 entity의 key를 1개 이상의 column으로 지정할 수 있게 해 주는 기능이 있다. 구체적으로는 implements serializable 를 이용하는데, 이 idclass에 꼭 구현되어야 하는 함수가 2가지 있다. 바로 - equals : 두 객체의 내용이 같은지 equality를 비교해주는 함수 - hashCode : 두 객체가 같은 객체인지 identity를 비교해 주는 함수 이다. 이것을 구현해 주어도 되지만, @EqualsAndHashCode annotation을 사용해서 method를 생성할 수 있고, @Data annotation을 이용할 수도 있다. 왜냐하면 @Data annotation은 - @Getter - @Setter - @RequiredArgsCo..

    [DB] MySQL 등 ERD에서 id를 long으로 두는 이유

    먼저, sql table의 primary key를 id라는 이름으로, 특별한 값을 넣지 않고 long이나 int형으로 숫자로 많이 두곤 한다. sql에서 join이나 data 탐색 등의 경우의 수를 생각해 봤을 때, primary key에 유의미한, 그리고 식별이 되는 값을 넣는게 좋지 않을까? 실제로 성능은 이게 더 나올 것이다. 그러나 이렇게 하지 않는 이유는 1) 보안상의 이유 2) 확장성의 이유 크게 2가지가 있다고 생각한다. 먼저 primary key는 어떤 일이 있더라도 겹치면 안 된다는 것은 기본이다. 예를 들어서 member라는 table에 id를 member가 회원가입할 때 등록했던 id로 지정했다고 해 보자. 그러면 member.id는 varchar형태일 것이고, id는 중복이 되지 않..

    [JPA] JPA MySQL 몇 가지 이슈에 대해서,,, GenericJDBCException

    1. JPA는 맞게 짠 것 같은데 JPA가 안돌아 가는 경우. could not execute statement; nested exception is org.hibernate.exception. org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute 이런 에러가 뜨는 경우 - JPA, 즉 Spring에서 설정한 언어(UTF-8)과 mysql의 언어 셋, charset이 달라서 그렇다. 나는 docker로 mysql을 설치했다. 그런데 여기서 MySQL에서 아래 명령어를 쳐보자..

    [JPA] JPA 단방향 vs 양방향

    JPA를 이용해서 구성하고 있는데... 다대일 단방향과 양방향에 대한 고찰이다. 일반적으로 다대일을 쓰는 거라고 한다. 그러면 member - team 관계가 있다고 가정하자.. (member:team=n:1 관계) 여러 자료들을 찾아보니 다대일 관계를 가질 때, '다' 쪽에서 외래키를 가지고 다대일 단방향 관계를 구성한다고 배웠ㄷ다. 필요할 때 양방향 관계를 구성한다고 하고. 그런데 이 '필요할 때'를 잘 모르겠다. 정말 양방향 연결이 필요한가? JPA는 '다'쪽에서 '1'쪽에 대한 정보를 가지고 있고, '1'쪽에서 '다'쪽에 대한 정보는 가지고 있지 않다. member-team의 관계에서 member는 어떤 team인지 알 수 있지만, team에 어떤 member가 있는지는 알 수 없기 때문이다. 그..

    Kubernetes - 개념

    https://subicura.com/2019/05/19/kubernetes-basic-1.html https://subicura.com/k8s/guide/#%E1%84%80%E1%85%A1%E1%84%8B%E1%85%B5%E1%84%83%E1%85%B3 https://bcho.tistory.com/1256?category=731548 위 블로그를 보고, 요약했다. 1. 개념 Kubernetes란? 쿠버네티스Kubernetes - container를 관리해 주는 도구, container orchestration tool이다. 배포 방식도 여러가지가 있고, 클라우드에서 지원하기 때문에 구글의 경우 GKE, AWS의 경우 EKS, Azure의 경우 AKS를 지원하며, autoscaling과 loadbalan..

    [Utils] API 설계 백그라운드

    RESTful API 설계 가이드 https://sanghaklee.tistory.com/57 자주 사용하는 http status code https://gist.github.com/subicura/8329759 200번대 200 OK request 성공 ex) resource 목록/resource 상세/resource 수정/그외 대부분의 API 성공 성공 메시지가 날아오는 경우는 200이라고 생각해도 무방 201 Created request 성공 ex) resource 생성 성공 204 No Content request 성공 ex) resource 삭제 성공 300번대 301 move permanently 페이지 이동 307 temporary_redirect 임시 페이지 이동 400번대 400 Bad ..

    [Git] 현업에서 사용하는 git

    git master branch는 실 사용 서버와 주로 연동되며 git-jenkins hooker도 master를 주로 받아옴. 그래서 master에 바로 소스코드를 push해버리면 테스트나 품질 검사 이런 게 없이 바로 build가 되어 버림. 그래서 다른 branch, develop branch를 파서 개발이 어느 정도 되면 master branch에 merge request를 하고, 관리자가 확인 한 후에 merge하는 것이 더 좋을 것임.

    EC2 Docker Jenkins Spring Gitlab 자동 빌드 - 4. docker image push

    지난 포스팅에서 gitlab에 push하면 hook을 따와서 jenkins에서 gitlab의 소스코드를 받아와서 build하는 것을 했다. 그러면 다음으로는 docker image를 만드는 것이다. 지금 EC2 위에는 docker가 있고, docker 내부에 jenkins를 올려두었고, jenkins에서 docker image를 작성하려면 1) jenkins 내에 docker를 깔던가, 2) jenkins에서 docker로 접속할 수 있는 방법을 만들던가 2가지 방법이 있다. 나는 2)를 택하고자 한다.(jenkins bash에서 docker로 접속할 수 있게) https://skyblue300a.tistory.com/14 1. Jenkins에서 docker로 접속하기 $ docker ps CONTAIN..

    EC2 Docker Jenkins Spring Gitlab 자동 빌드 - 3. gitlab project hooker 연동

    1. gitlab project hooker로 git에 push하면 jenkins에서 받아오기 일단 new item - freestyle project 생성 소스 코드 관리는 Git으로 바꿔준다. 내 개인 repository url을 적고, 바로 위에서 작성했던 credential을 바꿔준다. 젱질 아래의 branches to build는 어떤 branch가 push되었을 때 build할 것인지에 대한 선택이다. 빌드 유발에서 gitlab webhook 뒤에 있는 url을 복사하자. 그리고 밑으로 내려보면 secret token이 있는데, generate한 후에 이 것도 복사해 두자. gitlab - settings - webhook으로 들어가서, 바로 위 사진의 url과 secret token을 복사한..

    EC2 Docker Jenkins Spring Gitlab 자동 빌드 - 2. Docker, Jenkins, gitlab 연동

    https://tape22.tistory.com/16?category=928488 위 포스팅을 많이 참고했다. 1. EC2에 Docker, docker-compose 지난 포스팅에서 VS Code로 linux EC2에 접근했다. Ctrl + `를 눌러서 docker를 EC2에 설치하자. $ sudo yum install docker $ sudo dockerd 이후에 docker ps를 치면 에러가 난다. $ docker ps Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/contain..

    EC2 Docker Jenkins Spring Gitlab 자동 빌드 - 1. EC2 instance 생성 및 VS Code SSH 접속

    이제 해보고자 하는 것은 EC2 위에 Docker를 올리고, 그 Docker에 Jenkins container를 올려 local에서 작성한 spring 코드가 gitlab에 push되었을 때 build 및 pipeline을 거치면서 JUnit test, SonarQube 등 정적 검사를 거치고 docker image로 build하는 것을 목표로 한다. 1. EC2 instance 생성 먼저 EC2에 들어가서 인스턴스 시작 클릭 프리티어 이용 가능한 것을 선택 마찬가지로 프리티어 이용 가능한 것을 선택 다음으로 검토 버튼을 눌러서 검토를 본다. 보면 메노리가 1GiB로 상당히 적어, 추후에 swapfile 세팅을 해 주어야 한다. (OS에서 배우는 것, 스토리지를 ram처럼 사용할 수 있게 해 줌. 그리고..

    MSA란? Docker와 Kubernetes, Container와 VM, Jenkins란?

    http://book.interpark.com/product/BookDisplay.do?_method=detail&sc.shopNo=0000400000&sc.prdNo=293915007&sc.saNo=003002001&bid1=search&bid2=product&bid3=title&bid4=001 위 책을 읽고 느낀점을 정리함. 1. MSA가 뭘까? 더 빠른 개발을 위해서는 수정사항이 빨리빨리 반영되어야 한다. 그런데 기존의 monolithic한 개발 방식으로는 배포하는 데도 시간이 걸리고, 빌드하는 데도, 심지어 한 어플리케이션들의 열려있는 message들과 그 형식을 모두 맞춰야 하기 때문에 agile하지 못하다. 그래서 MS와 MSA가 나타나게 되었다. MicroService란 큰 App을 작은 s..