목록전체 글 (39)
csct3434
https://github.com/orgs/community/discussions/25651 Github secret truncated after "$" · community · Discussion #25651Hello, I found a bug in github secrets. If the secret contains “$”, for example “hello$world”. Then when used in github actions, we will only get “hello” and everything after and including the doll...github.comGithub Actions Workflow에서 '$'는 특수한 목적으로 사용되는 문자입니다.이로 인해 Github Actions..
인트로작년 11월 구름에서 주최한 해커톤에 참가하여 24절기를 테마로 한 일기 서비스를 개발했습니다.해커톤 당시에는 데모 수준에 그쳤지만, 팀의 좋은 분위기로 인해 해커톤 이후로도 약 3개월 간 추가로 서비스를 개발하며 서비스를 정식으로 출시했습니다.장애 대응백엔드 개발자로서 서비스 출시를 앞두고 가장 우려되는 부분은 트래픽 증가로 인한 장애 발생이었습니다.오프라인 행사와 온라인 플랫폼(에브리타임, 인스타그램 광고)에서 홍보를 동시에 진행할 예정이었기에, 어느 정도로 부하가 발생할 지 예측하기 힘든 상황이었습니다. 이에, 비용이 많이 발생하더라도 최대한 안정적으로 서버를 운영할 수 있도록 인프라를 재구성했습니다.WASWAS의 경우 AWS ALB와 EC2 Auto Scaling을 활용하여 부하에 따라 수평..
인트로 친구 게시글 조회 기능에서의 페이지네이션을 구현하기에 앞서, LIMIT-OFFSET과 NO-OFFSET 방식의 성능을 비교해 보았습니다. 게시글 테이블에 1억 건의 더미 데이터를 추가한 후, MySQL의 EXPLAIN 명령어와 Query Profiling을 활용하여 첫번째 페이지와 마지막 페이지에 대한 쿼리 실행 계획 및 쿼리 성능을 분석했습니다. LIMIT-OFFSET 방식 쿼리문 쿼리 실행 계획 첫번째 페이지에서는 클러스터드 인덱스를 사용하지만, 마지막 페이지에서는 Full Table Scan이 발생함을 확인할 수 있었습니다. 쿼리 실행 시간 첫번째 페이지 : [ 156.68s ] , 마지막 페이지 : [ 295.17s ] 첫번째 페이지와 마지막 페이지의 조회 시간은 약 2배 정도의 차이를 보..
서론 자바, 스프링, 스프링부트 프레임워크에서의 의존성 주입 메커니즘에 대해 살펴본다. (이미지 출처 : https://rudaks.tistory.com) 왜 조립까지 신경 써야 할까? 모든 의존성이 안쪽으로, 애플라케이션의 도메인 코드 방향으로 향해야 도메인 코드가 바깥 계층의 변겨응로부터 안전하다 한 클래스가 필요로 하는 모든 객체를 생성자로 전달할 수 있다면 실제 객체 대신 목을 전달할 수 있고, 이렇게 되면 격리된 단위 테스트를 생성하기가 쉬워진다 우리의 객체 인스턴스를 생성할 책임은 누구에게 있을까? 그리고 어떻게 의존성 규칙을 어기지 않으면서 그렇게 할 수 있을까? 설정 컴포넌트 아키텍처에 중립적이고 인스턴스 생성을 위해 모든 클래스에 의존성을 가지는 설정 컴포넌트가 그 책임을 갖는다 설정 컴..
서론 각 계층의 모델을 매핑하는 전략에 대해 살펴본다. 이미지 출처 : https://rudaks.tistory.com ‘매핑하지 않기’ 전략 모든 계층이 동일한 모델을 사용하는 매핑 전략이다. 문제점 도메인 모델에서 비즈니스가 아닌 웹이나 영속성과 관련된 특수한 요구사항을 모두 다뤄야 한다. 단일 책임 원칙을 위반한다 (변경해야 할 이유가 많아진다). 각 계층이 도메인 모델에 특정 커스텀 필드를 두도록 요구한다면, 오로지 한 계층에서만 필요한 필드들을 포함하는 파편화된 도메인 모델로 이어질 수 있다. 모든 계층이 정확히 같은 구조의, 정확히 같은 정보를 필요로 한다면 ‘매핑하지 않기’ 전략은 완벽한 선택지다. 하지만 애플리케이션 계층이나 도메인 계층에서 웹과 영속성 문제를 다루게 되면 곧바로 다른 전략..
서론 육각형 아키텍처에서의 테스트 전략에 대해 이야기한다. 아키텍처의 각 요소들을 테스트할 수 있는 테스트 유형에 대해 논의할 것이다. 테스트 피라미드 위 그림은 몇 개의 테스트와 어떤 종류의 테스트를 목표로 해야 하는지 결정하는데 도움을 준다 테스트 피라미드에 따르면 비용이 많이 드는 테스트는 지양하고 비용이 적게 드는 테스트를 많이 만들어야 한다 여러 개의 단위와 단위를 넘는 경계, 아키텍처 경계, 시스템 경계를 결합하는 테스트는 만드는 비용이 더 비싸지고, 실행이 더 느려지며, 깨지기 더 쉬워진다. 테스트 피라미드는 테스트가 비싸질수록 테스트의 커버리지 목표는 낮게 잡아야 한다는 것을 보여준다. 그렇지 않으면 새로운 기능을 만드는 것 보다 테스트를 만드는 데 시간을 더 쓰게 된다 단위 테스트 피라미..
서문 1장에서 계층형 아키텍처에서는 모든 것이 영속성 계층에 의존하게 되어 데이터베이스 주도 설계가 된다고 이야기 했다. 이번 장에서는 이러한 의존성을 역전시키기 위해 영속성 계층을 애플리케이션 계층의 플러그인으로 만드는 방법을 살펴본다. 의존성 역전 위 그림은 영속성 어댑터가 애플리케이션 서비스에 영속성 기능을 제공하기 위해 어떻게 의존성 역전 원칙을 적용할 수 있을지 보여준다. 애플리케이션 서비스에서는 영속성 기능을 사용하기 위해 아웃고잉 포트 인터페이스를 호출한다 포트는 사실상 애플리케이션 서비스와 영속성 코드 사이의 간접적인 계층이다 영속성 계층에 대한 코드 의존성을 없애기 위해 이러한 간접 계층을 추가해서 사용한다 포트가 계약을 만족하는 한, 코어에 영향을 미치지 않으면서 영속성 코드를 마음껏 ..
서문 웹 인터페이스를 제공하는 어댑터의 구현 방법을 살펴본다. 의존성 역전 웹 어댑터 관련 아키텍처 요소 자세히 보면 의존성 역전 원칙이 적용된 것을 발견할 수 있다. 포트 인터페이스를 거치지 않고 어댑터가 서비스를 직접 호출할 수도 있다. 그럼에도 불구하고 어댑터와 유스케이스 사이에 포트 인터페이스를 넣는 이유는 애플리케이션 코어가 외부 세계와 통신할 수 있는 곳에 대한 명세가 코어이기 때문이다. 포트를 적절한 곳에 위치시키면 외부와 어떤 통신이 일어나는지 정확히 파악할 수 있고, 이는 유지보수에 있어 매우 소중한 정보이다 포트 인터페이스가 필요한 이유는 상호작용이 많이 일어나는 애플리케이션에서 더욱 명확해진다. 애플리케이션에서 웹 소켓을 통해 실시간 데이터를 사용자의 브라우저로 보내는 시나리오에서는 ..
구현 순서 도메인 → 유스케이스 → 포트 → 어댑터 도메인 모델 구현하기 Account package buckpal.domain; @AllArgsConstructor(access = AccessLevel.PRIVATE) public class Account { @Getter private final AccountId id; @Getter private final Money baselineBalance; @Getter private final ActivityWindow activityWindow; // 생성자 생략 public Money calculateBalance() { return Money.add( this.baselineBalance, this.activityWindow.calculateBalan..
송금하기 유스케이스 계층으로 구성하기 domain : 도메인 계층 / persistence : 영속성 계층 / web : 웹 계층 domain 패키지에 AccountRepository 인터페이스를 추가하고, persistence 패키지에 AccountRepositoryImpl 구현체를 둠으로써 의존성을 역전함 문제점 애플리케이션의 기능 조각이나 특성을 구분 짓는 패키지 경계가 존재하지 않는다. 서로 연관되지 않은 기능들끼리 엉망진창으로 묶여 예상하지 못한 부수효과를 일으킬 가능성이 크다 애플리케이션이 어떤 유스케이스들을 제공하는지 파악할 수 없다. AccountService가 어떤 유스케이스를 구현하는지 패키지 구조만으로는 파악할 수 없다 특정 기능을 찾기 위해서는 어떤 서비스가 이를 구현했는지 추측해야..