모든 메서드 호출 로깅하기

목표 mocking 한 객체들의 메서드 호출들을 모두 로깅하도록 한다. MockSettings 일반적으로 mockito를 이용해서 목킹할 때 mock(MyClass.class) 형태로 목칭을 하지만, 두번째 인자로 목킹할 때 추가적인 설정을 할 수 있다. MockSettings customSettings = withSettings().defaultAnswer(new CustomAnswer()); MyList listMock = mock(MyList.class, customSettings); MockSettings에는 invocationListeners를 등록할 수 있고, 이는 목킹한 객체에 메서드 호출이 발생할 때 동작하는 리스너다. List mockWithListener = mock(MyList.class, withSettings().invocationListeners(new YourInvocationListener())); Mockito-Kotlin 도 이를 지원하고 있고, 이를 통해서 호출된 메서드가 무엇인지 로깅할 수 있다....

2024-09-15 · 1 min · 86 words

모든 ip에서 사용가능한 계정 만들기

create user [username]@'%' identified by '[password]';

2024-09-15 · 1 min · 6 words

명령어로 특정 클래스만 테스트 하는 법

gradle test --tests SomeClass https://stackoverflow.com/questions/22505533/how-to-run-only-one-unit-test-class-using-gradle

2024-09-15 · 1 min · 5 words

리플리케이션(Replication)

사용자가 많은 Database는 많은 쿼리를 모두 처리하기 힘들어, CUD를 위한 데이터베이스(master)와 read를 위한 database를(slave) 따로 나눈다. 참고 자료 https://kwonnam.pe.kr/wiki/springframework/transaction https://nesoy.github.io/articles/2018-02/Database-Replication

2024-09-15 · 1 min · 20 words

리눅스에서 로그 파일 열기

배경 용량이 큰 로그 파일을 vim이나 cat으로 열게 된다면, 파일 내용을 RAM에 모두 올리면서 OOM 에러가 발생할 수 있다. less less [파일명] 이 명령어를 통해 파일을 열면 내용을 청크로 잘라서 조금씩 볼 수 있기 때문에 OOM이 발생하지 않는다. 참고 자료 https://jmseo.tistory.com/69

2024-09-15 · 1 min · 41 words

로드 밸런싱

L4와 L7 2가지가 있다. L4는 TCP, UDP 정보(특히 포트 넘버)기반으로 로드 밸런싱을 수행한다. L7는 애플리케이션 계층의 프로토콜 정보를 기반으로 수행한다. Nginx에서 수행하는 리버스 프록시가 유사한 기능을 가지고 있다. 한 서버에 장애가 발생했을 때, 다른 서버를 통해 서비스를 제공할 수 있다. 동일한 서비스를 다수의 서버에 부하를 분산시킨다.

2024-09-15 · 1 min · 46 words

로깅 테스트하기

logback 구현체를 통해서 appender를 추가해서 테스트를 진행할 수 있다. ListAppender를 사용하면 로깅 내용을 메모리로 저장할 수 있다. class ReflectionsTest { private static final Logger log = (Logger) LoggerFactory.getLogger(ReflectionsTest.class); private static final ListAppender<ILoggingEvent> listAppender = new ListAppender<>(); static { listAppender.setContext((LoggerContext) LoggerFactory.getILoggerFactory()); log.setLevel(Level.DEBUG); log.addAppender(listAppender); listAppender.start(); } @Test void someTest() { //... assertThat(result).contains("[DEBUG] examples.QnaController", "[DEBUG] examples.MyQnaService", "[DEBUG] examples.JdbcUserRepository", "[DEBUG] examples.JdbcQuestionRepository"); } } 참고 자료 https://www.baeldung.com/junit-asserting-logs

2024-09-15 · 1 min · 62 words

디플로이먼트 파드 전체 재시작

목표 디플로이먼트에 속한 파드 전체를 재시작한다. 방법 kubectl rollout restart <resource> 예시 kubectl rollout restart deployment/nginx 참고 자료 https://kubernetes.io/docs/reference/kubectl/generated/kubectl_rollout/kubectl_rollout_restart/

2024-09-15 · 1 min · 19 words

디렉토리 경로와 파일이름 합치기

import os os.path.join(dirname, filename) 참고 자료 https://wikidocs.net/39

2024-09-15 · 1 min · 7 words

두 리스트가 순서 상관없이 동일한지 비교

assertThat(a).containsExactlyInAnyOrderElementsOf(b); 참고 자료 https://www.baeldung.com/java-assert-lists-equality-ignore-order

2024-09-15 · 1 min · 4 words

동등성 비교

assertThat(fido).isEqualToComparingFieldByFieldRecursively(fidosClone); 참고 자료 https://www.baeldung.com/introduction-to-assertj

2024-09-15 · 1 min · 4 words

도커 스웜을 이용한 스케일 아웃

기존에 내가 진행하던 프로젝트는 WAS가 한 대 뿐이었다. 이번에 성능 향상을 목적으로 스케일 아웃을 진행하기로 결정했다. 스케일 아웃을 진행하면서 처리해야될 작업들에는 다음이 있었다. 서버가 여러 대인 점을 이용한 무중단 배포 WAS가 늘어나면서 NGINX에서 요청을 전달한 WAS 선택 방법 (로드 밸런싱) 이를 해결하기 위해서 나는 도커 스웜을 사용해보기로 결정했다. 그 이유는 다음과 같다. 도커 스웜은 자체적으로 롤링 업데이트를 지원하며, 매우 간단하게 사용할 수 있다. ingress 네트워크를 통해 NGINX에 추가적인 설정을 하지않아도, ingress의 로드 밸런서가 라운드 로빈 방식을 사용해서 WAS의 트래픽을 분산시킬 수 있다....

2024-09-15 · 3 min · 620 words

데이터베이스 생성시 UTF-8 설정

CREATE DATABASE db_name DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

2024-09-15 · 1 min · 9 words

단방향 OneToMany 연관관계 매핑의 문제점

단방향 연관관계 매핑을 사용하면 insert 이후에, FK를 저장하기 위해 update 쿼리를 한 번더 실행하는 문제가 있다. @Entity public class Menu { //... @OneToMany(cascade = CascadeType.PERSIST) @JoinColumn(name = "menu_id") private final List<MenuProduct> menuProducts; //... } @Entity public class MenuProduct { //... } 위 상황의 경우 MenuProduct 엔티티의 menu_id라는 FK가 저장된다. 하지만 Menu 를 저장할 때, MenuProduct에 FK 값을 지정하기 위해서 update 쿼리가 한 번더 실행되기 때문에 성능상 좋지않다. 단방향 OneToMany를 사용하는 것 보다는 양방향 ManyToOne을 사용하는 것이 좋다....

2024-09-15 · 1 min · 80 words

다음 라인 실행하기 전에 n초 기다리기

5초동안 잠시 멈추려면 아래와 같이 작성하면 된다. setTimeout(function () { // 5초 뒤 실행할 코드 }, 5000); 참고 자료 https://stackoverflow.com/questions/14226803/wait-5-seconds-before-executing-next-linehttps://www.w3schools.com/jsref/met_win_settimeout.asp

2024-09-15 · 1 min · 20 words

다른 서버의 별칭 설정

매번 ip를 입력하기엔 너무 불편하다. vi /etc/hosts [서비스용IP] [별칭]

2024-09-15 · 1 min · 9 words

논리적 삭제를 하고 있는 Entity가 지연 로딩

문제 상황 @EntityListeners(AuditingEntityListener.class) @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity public class Room { @OneToMany(mappedBy = "room") private final List<Session> sessions = new ArrayList<>(); //... } @EntityListeners(AuditingEntityListener.class) @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity public class Session { @Column(nullable = false) private boolean deleted = false; //... public void delete() { if (user.isLinkedSession(this)) { user.unLinkSession(this); } if (room.containsSession(this)) { room.exitSession(this); } deleted = true; } } Session은 논리적 삭제를 사용하고 있는데, Room의 sessions필드가 지연로딩 될 때, 논리적 삭제를 사용하고 있는 것을 모르기 때문에 모든 session을 가지고 오는 문제가 있었다....

2024-09-15 · 1 min · 148 words

날짜 필드

@Temporal(TemporalType.DATE) private Date date; // date date 생성 @Temporal(TemporalType.TIME) private Date time; // time time 생성 @Temporal(TemporalType.TIMESTAMP) private Date timestamp; // timestamp timestamp 생성 @Temporal 를 생략할 경우 TIMESTAMP 로 컬럼을 만든다. Java 8의 경우에서 나온 LocalDate, LocalTime, LocalDateTime 등은 별도의 어노테이션을 붙일 필요가 없다. 참고 자료 https://www.baeldung.com/hibernate-date-time

2024-09-15 · 1 min · 48 words

그림으로 배우는 Http Network Basic

웹과 네트워크의 기본에 대해 알아보자 웹은 HTTP로 나타낸다 웹 브라우저는 웹 브라우저 주소 입력란에 지정된 URL에 의지해서 웹 서버로부터 리소스라고 불리는 파일 등의 정보를 얻는다. 서버에 의뢰하는 웹 브라우저 등을 클라이언트라고 부른다. 클라이언트에서 서버까지 일련의 흐름을 결정하고 있는 것은 웹에서 HTTP라고 불리는 프로토콜이다. 프로토콜이라는 의미는 “약속”이다. HTTP는 이렇게 태어났고 성장했다 1989년에 CERN의 팀 비너스 리 박사는 멀리 떨어져 있는 동료 연구자와 지식을 공용하게 할 수 있도록 시스템을 고안하였다. 최초로 고안한 것은 여러 문서를 상호간에 관련 짓는 하이퍼텍스트에 의해 상호간에 참조할 수 있는 WWW의 기본 개념이 되었다....

2024-09-15 · 42 min · 8759 words

그룹 별 상위 n개 가져오기

배경 어떤 테이블에 대해서 컬럼 A 기준으로 group을 만들고 그룹 내에서 컬럼 B 기준으로 상위 n개를 가져와야 되는 목적이 생겼다. 해결 방법 예시를 들어 설명을 한다. 아래와 같이 테이블과 행이 존재한다. create table player ( user_id bigint auto_increment primary key, team_id bigint not null, score bigint not null ); 다음과 같이 데이터가 존재하고, team_id 별로 상위 2등까지 플레이어를 확인하고 싶다면 아래와 같이 작성하면된다. SELECT * FROM( SELECT *, RANK() OVER (PARTITION BY player....

2024-09-15 · 1 min · 129 words