2021-06-10-TIL
2021-06-10-TIL
S3에 이미지 업로드 및 스프링 연동
이미지 파일은 DB나 애플리케이션 서버 디스크 대신 S3 같은 객체 저장소에 두고, DB에는 파일의 URL(또는 키)만 저장하는 구성이 일반적이다. 서버를 여러 대로 늘려도 파일 위치가 하나로 유지되고, 정적 파일 전송을 S3(또는 앞단의 CDN)가 맡는다. Spring에서는 컨트롤러가 MultipartFile로 파일을 받고, AWS SDK의 S3 클라이언트로 putObject를 호출해 업로드한 뒤 객체 URL을 돌려준다. 접근 키를 코드나 저장소에 넣지 말고 환경 변수나 IAM 역할로 주입해야 한다.
- https://leveloper.tistory.com/46
ON DELETE CASCADE vs 비즈니스 로직상에서 순차적 삭제
성능 면에서는 ON DELETE CASCADE가 훨씬 우세하다. 하지만 안정성 및 디버깅의 용이성 같은 점을 고려해보면 비즈니스 로직 상에서 처리하는 것이 좀 더 낫다. DB 테이블에 CASCADE가 여기저기 걸려있으면 쿼리를 하나씩 추적하는것은 어렵다. 반면에, 비즈니스 로직 상에서 구현되어 있다면 디버깅을 보다 상세히 할 수 있다는 점에서 유리하다.
성능 차이가 나는 이유는 처리 위치에 있다. 외래 키의 ON DELETE CASCADE는 부모 행 하나를 지우는 문장 안에서 DB가 자식 행을 함께 지운다. 애플리케이션에서 지우면 자식들을 조회한 뒤 DELETE를 여러 번 보내야 한다. JPA의 CascadeType.REMOVE도 애플리케이션 쪽 처리라서, 자식 엔티티를 로딩해 한 건씩 삭제 쿼리를 보낸다. 반대로 DB 쪽 연쇄 삭제는 애플리케이션이 모르게 일어나므로, 영속성 컨텍스트에 남아 있는 엔티티와 DB 상태가 어긋날 수 있고 삭제 이벤트를 남기거나 감사 로그를 쓰기도 어렵다. 링크된 토론들도 이 두 관점(성능과 단순함 대 명시성과 통제)을 두고 의견이 나뉜다.
- https://stackoverflow.com/questions/19997325/sql-on-delete-cascade-vs-delete-on-business-logic
- https://dba.stackexchange.com/questions/254605/is-it-a-good-or-bad-idea-to-use-on-update-cascade-on-delete-cascade-for-foreig
Dirty Checking
save메소드로 엔티티를 저장하지 않더라도, 엔티티의 변화를 감지하여 자동으로 update쿼리가 수행되는 것
JPA는 엔티티를 영속성 컨텍스트에 처음 올릴 때 그 상태의 스냅샷을 보관한다. 트랜잭션이 커밋되면서 플러시가 일어날 때 현재 엔티티와 스냅샷을 비교하고, 바뀐 엔티티에 대해 UPDATE 문을 만들어 보낸다. 그래서 트랜잭션 안에서 조회한 엔티티의 필드만 바꿔도 반영된다. 조건이 있다. 영속 상태의 엔티티여야 하고(준영속, 비영속 엔티티는 대상이 아니다), 트랜잭션 안에서 바뀌어야 한다. Hibernate는 기본적으로 모든 컬럼을 UPDATE 문에 넣고, 바뀐 컬럼만 넣으려면 @DynamicUpdate를 쓴다.
Exception Handling
Spring Boot에서 표준 예외 응답을 구현한 예제 저장소다. README에 따르면 공통 에러 응답 객체(ErrorResponse)를 정의하고, @RestControllerAdvice에서 예외를 잡아 400 응답을 세분화하며, BusinessException 같은 커스텀 예외 계층을 두는 구성이다. 지금은 더 이상 관리하지 않고 다른 저장소로 옮겨졌다고 안내한다.
Jenkins
Jenkins는 빌드, 테스트, 배포를 자동화하는 오픈소스 CI/CD 서버다. 저장소에 변경이 생기면(웹훅이나 폴링) 정해 둔 작업을 실행하고, 파이프라인은 Jenkinsfile에 단계별로 코드로 정의할 수 있다.
- https://ict-nroo.tistory.com/31
- https://krksap.tistory.com/1377
- https://daystudy.tistory.com/734
AWS and Jenkins
EC2에 Jenkins를 설치해 운영하는 방법과, AWS CodeCommit 저장소의 변경을 Jenkins 빌드로 연결하는 방법을 다룬 자료다.
- https://krksap.tistory.com/1368
- https://aws.amazon.com/ko/blogs/devops/integrating-aws-codecommit-with-jenkins/
AWS and Kubernetes
AWS에서 Kubernetes를 운영하는 방법을 소개하는 페이지다. Amazon EKS는 Kubernetes 컨트롤 플레인을 AWS가 관리해 주는 서비스로, 사용자는 워커 노드와 애플리케이션 배포에 집중한다.
- https://aws.amazon.com/ko/kubernetes/
Jekyll
GitHub Pages와 Jekyll로 블로그를 만들고 테마를 고르고 설치하는 과정을 다룬 글들이다.
- https://www.jihyeleee.com/blog/third-designer-can-make-jekyll-blog/
- https://jetalog.net/86
- https://sh-otherlife.tistory.com/entry/Githubio%EB%A1%9C-%EB%82%98%EB%A7%8C%EC%9D%98-%EB%B8%94%EB%A1%9C%EA%B7%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0-2-Jekyll-%ED%85%8C%EB%A7%88-%EC%B0%BE%EA%B3%A0-%EC%84%A4%EC%B9%98%ED%95%98%EB%8A%94-%EB%B2%95
- https://honbabzone.com/jekyll/start-gitHubBlog/
Jacoco
JaCoCo는 Java 코드 커버리지 도구다. 테스트를 실행할 때 바이트코드에 측정 코드를 넣어 어떤 라인과 분기가 실행됐는지 기록하고, HTML이나 XML 리포트를 만든다. 우아한형제들 글은 Gradle의 jacoco 플러그인으로 리포트를 만들고, jacocoTestCoverageVerification에 최소 커버리지 규칙을 걸어 기준에 못 미치면 빌드를 실패시키는 설정을 다룬다.
- https://woowabros.github.io/experience/2020/02/02/jacoco-config-on-gradle-project.html
Mock MVC
MockMvc는 실제 서버를 띄우지 않고 Spring MVC의 요청 처리 흐름을 테스트하는 도구다. perform(get("/questions/1"))로 요청을 만들고, andExpect(status().isOk()), andExpect(jsonPath("$.title").value(...))로 응답을 검증하며, andDo(print())로 요청과 응답 내용을 출력한다.
- https://itmore.tistory.com/entry/MockMvc-%EC%83%81%EC%84%B8%EC%84%A4%EB%AA%85
댓글
아직 댓글이 없습니다