728x90
반응형

Development 39

[썬카/백엔드] AWS 없이 무료로 SSL 인증서 등록하여 HTTPS 통신하기 - HTTP -> HTTPS 리다이렉션, HSTS, Let's Encrypt, snap, certbot

HTTP에 SSL 인증서(암호화라고 보면 됨)를 적용한 것이 HTTPS 이다. 웹을 서비스하기 위해서 SSL 인증서는 필수라고 할 수 있다. SSL 인증서가 없다면 1차적으로 브라우저에 안전하지 않다는 경고가 뜨며, 데이터가 평문으로 노출되어 탈취당할 가능성이 있고, 최신 웹 프로토콜이나 기술들과 호환되지 않을 수 있다. 심지어 개인정보를 취급하는 웹 사이트의 경우 암호화 등의 보안 조치를 취하는 것이 법적으로 의무화 되어 있고, HTTPS는 암호화를 적용하는 가장 쉽고 표준적인 방법이기 때문에 적용하지 않을 이유가 없다. SSL 인증서를 적용하는 대표적인 방법은 크게 두 가지가 있다.1. AWS의 ACM, Route53, 로드 밸런서를 이용한 SSL 인증서 적용2. Let's Encrypt, 가비아(또..

[썬카/백엔드] Jenkins, Blue/Green 전략을 활용한 무중단 배포 CI/CD 파이프라인 구축과 수동 롤백 설계 + 인프라 구성도

일반적인 배포는 많이 해 봤지만, CI/CD 파이프라인 구축과 무중단 배포는 한 번도 해본 적 없었다. 개인 프로젝트 때 반드시 해 보고 싶었던 것 중 하나였기에, 이번에 직접 구축해 보았다. Jenkins와 Blue/Green 전략을 활용해서 무중단 배포 CI/CD 파이프라인을 구축했고, 문제 발생 시 한 단계 전으로 수동 롤백이 가능하도록 했다. Jenkins 설정이 약간 복잡한 듯 싶었지만 Jenkins가 복잡한 게 아니라 CI/CD와 무중단 배포 구현이 복잡한 거였다. 난 EC2 프리티어 인스턴스와 RDS 프리티어 데이터베이스를 사용했다. 글에서는 기본 배포가 이미 되어 있다고 가정한다. 나는 프리티어를 쓰는 만큼, Jenkins와 스프링 부트 애플리케이션 서버를 단일 프리티어 인스턴스 내에 두었..

[썬카/정기 회고] 스프린트 4 종료 - 테스트 코드, 프로젝트 방향성 변경

테스트 코드처음으로 테스트 코드라는 것을 작성해 보았다. 단위 테스트, 통합 테스트에 대해 공부하고 그것을 적용해 테스트 코드를 작성했다. 테스트 코드는 말 그대로 테스트이기 때문에 간단할 것이라고 생각했지만 생각보다 고려할 것이 많았다. 물론 그냥 내 맘대로 짜면 짤 수도 있었겠지만, 무엇이 좋은 테스트인가? 어떤 것을 테스트해야 하는가? 모킹은 어느 정도 수준까지 해야 하는가? 테스트 해야 할 흐름은 어떤 것들이 있는가? 즉, 최적의 테스트 라는 게 무엇인지를 깊이 탐구하는 것과, 그것을 알기 위해 테스트라는 것 자체를 깊게 이해해야 했기에 많은 시간이 걸렸던 것 같다. 테스트는 보는 이로 하여금 테스트의 의도가 명확히 전해져야 하고, 그것을 위해 조금의 불편함도 감수할 수 있어야 한다. 쓸데없이 복..

[썬카/백엔드] 커스텀 쿼리를 이용한 판매 차량 삭제 기능 구현 - Soft Delete 방식의 간접 CASCADE

일반적인 Hard Delete 방식을 사용했다면 외래키 관계를 이용한 엔티티와 DB 레벨에서의 cascade를 이용할 수 있었을 테지만, 중고차 거래 플랫폼 특성상 데이터의 신뢰도가 중요했기 때문에 Soft Delete 방식을 채용했다. 그로 인해 연쇄 삭제 기능은 서비스 레벨에서의 delete() 메서드 조합이나 QueryDsl 커스텀 쿼리를 통해 직접 구현해야 했다. 처음엔, 모든 엔티티가 상속받는 BaseEntity에 존재하는 softDelete() 메서드를 Facade 서비스 클래스에서 전부 호출해서 삭제할까 생각했다. 하지만, 그러면 제공되는 인자는 CarListing.id(판매 차량 id) 한개 뿐일텐데 이걸로 repository 조회해서 연관된 엔티티 id를 얻고 하는 일련의 작업을 서비스 ..

[썬카/백엔드] 서비스 계층 및 커스텀 리파지터리 테스트 코드 작성, 팩토리/빌더 클래스 설계와 영속성 컨텍스트, Hibernate 통계 관리(Statistics)

썬카의 기능이 조금씩 많아지니, 코드를 수정할 때마다 매번 Postman으로 api를 호출해보는 나를 발견할 수 있었다. 이 작업이 번거롭다고 느껴지는 순간, 테스트 코드를 도입할 때가 왔다고 느꼈다. 그래서 잠시 스프린트는 접어두고 테스트 코드를 도입한 후 작업에 들어가기로 했다. 처음 작성해 보는 테스트 코드였지만, 나는 말 그대로 테스트만 하는 코드인데 오래 걸리겠어? 라고 생각했다. 그러나 이렇게나 생각할 게 많고 복잡할 줄 몰랐다. 테스트의 종류도 여러 가지였고 각각 어떤 테스트인지, 어떤 상황에서 도입해야 하는지, 우선순위는 어떻게 되는지 전부 생각해야 했다. 테스트 코드 자체도 전부 처음 보는 방식, 메서드들이라 기존의 난 완전 백지 상태나 다름이 없었어서 완전히 하나하나 차근히 공부하면서 ..

스프링 부트 테스트 전략 - 단위 테스트와 통합 테스트

테스트 코드는 매우 중요하며, 개발자에게 있어 필수적인 핵심 역량이다. 서비스 규모가 작을 때야 코드를 수정한 후 api 몇 개 직접 호출하면 금방 테스트할 수 있겠지만, 규모가 커져서 api가 수백 수천 개, 메서드가 수천 수만 개 된다면 반드시 테스트 코드가 필요할 것이다. 미리 잘 짜놓은 테스트 코드는, 배포하기 전 매번 테스트를 직접 수행하는 번거로움을 줄여주며 정확히 어디에서 오류가 발생했는지 쉽게 디버깅할 수 있게 해 준다. 개발이라는 분야에 있어서 기능의 구현 만큼이나 코드의 유지보수성과 확장성이 중요하다는 것을 생각한다면, 테스트 코드는 비즈니스 로직 만큼이나 중요하다고 해도 과언은 아닐 것이다. 스프링 부트 테스트 전략은 크게 [단위 테스트, 통합 테스트, E2E/기능 테스트] 로 나뉜다..

[썬카/정기 회고] 스프린트 3 종료 - 객체지향적 설계와 쿼리 최적화

스프린트 3이 종료되었다. 스프린트 2 회고에서 차량 등록, 조회를 어떻게 구현할지 걱정했지만 훌륭히 구현해 냈다.이번에 구현한 기능은 아래와 같다.차량 등록판매 차량 상세 조회 차량 정보를 다루는 엔티티가 무려 10개였기 때문에, 백엔드 코드 작성이 매우 매우 어려웠다. 애플리케이션 레벨에서 관계는 어떻게 정의하며, repository와 service는 어떤 구조로 작성하고 관리하는지, 쿼리는 어떻게 최적화 하는지 등등… 고민해보지 못했던 문제들을 많이 만났다. 스프린트 2의 유저 관련 로직을 짤 때보다 10배는 더 어려웠던 것 같다. 이번 스프린트 3을 진행하며 가장 크게 배운 것은 객체지향적 설계와 SOLID원칙, 그리고 쿼리 최적화이다. 백엔드에서 어려웠던 점 - 객체지향적 설계와 N+1, 카테시..

[썬카/백엔드] 판매 차량 상세조회 기능 구현 - Lazy Loading, fetchJoin(), BatchSize

차량 상세조회 기능을 구현하며 차량 관련 엔티티 10개를 조회해야 했는데, 이 과정에서 Lazy Loading, fetchJoin, BatchSize를 공부하고 적용해 보았다. 백엔드에서 쿼리 짜는 게 제일 어려운 것 같다. 아래는 Lazy Loading, fetchJoin(), BatchSize에 대해 내가 정리한 글이다.https://yskisking.tistory.com/316 JPA 쿼리 최적화 - Lazy loading, fetchJoin(), BatchSize개인 프로젝트 썬카에서 차량 상세 조회 기능을 만들다가 쿼리 최적화 문제에 부딪혔다.무려 10개의 엔티티를 전부 조회해야 했고 성능 부분을 신경쓰지 않을 수 없었기에, 자연스럽게 Lazy loadingyskisking.tistory.com..

JPA 쿼리 최적화 - Lazy loading, fetchJoin(), BatchSize

개인 프로젝트 썬카에서 차량 상세 조회 기능을 만들다가 쿼리 최적화 문제에 부딪혔다.무려 10개의 엔티티를 전부 조회해야 했고 성능 부분을 신경쓰지 않을 수 없었기에, 자연스럽게 Lazy loading, fetchJoin, BatchSize에 대해서 조금 공부하게 되었다. Lazy Loading- JPA/Hibernate 에서 사용하는 데이터 로딩 전략- 연관 엔티티의 데이터를 실제로 필요한 시점까지 DB에서 조회하지 않고 지연시키는 방식 Lazy Loading - 작동 원리- 엔티티 조회 시 영속성 컨텍스트에 주 엔티티 데이터 로드- 연관 엔티티는 실제 데이터 대신 프록시 객체(참조)로 대체됨- 연관 엔티티(프록시)에 getter로 접근하는 시점에 추가 DB 쿼리가 발생함 // Lazy loading..

[썬카/백엔드] 차량 관련 Facade 서비스 인터페이스 세분화 (LSP, ISP 원칙)

차량 판매등록 기능은 카히스토리 api를 사용해 받아온 데이터를 등록해야 하지만, api를 아직 도입하지 못해서(너무 비싸..) 임시로 더미 데이터를 입력하는 방식으로 구현했다. 해당 기능은 인터페이스를 통해 구현된 facade 서비스 클래스에 존재하는데, 기존엔 배포용 차량 판매등록 기능과 더미 데이터 판매등록 기능이 하나의 인터페이스에 공존하고 있었고, 그것을 두개의 구현체로 구현했었다. 배포 때는 배포 판매등록 기능, 개발 때는 더미 판매등록 기능이 이용 되어야 하며, 두 기능은 하나의 환경에서 동시에 사용되지 않아야 한다. 따라서 하나의 인터페이스에서 파생된 두 구현체는, 사용되지 않는 메서드까지 상속받아 무의미하게 구현하고 있는 상태였다( ISP 위반 ). 또한 두 구현체는 같은 부모 인터페이스..

728x90
반응형