전체 글 361

대규모 서비스 - CDN을 사용하는 이유

캐시(Cache) 캐시 계층은 데이터가 잠시 보관되는 곳으로 별도의 캐시 계층을 이용해서 DB 서버나 웹 서버의 부하를 줄일 수 있습니다. 과정을 요약하면 이렇습니다. 원하는 페이지에 요청을 보냄 key를 이용해서 필요한 캐시를 가져옴 -> cache.get('key') 캐시가 존재하면 데이터를 그대로 사용하고, 그렇지 않으면 새로 서버에서 데이터를 읽고 캐시에 저장함 -> cache.set('key', 'content', expired) 따라서 아래와 같은 점들을 고려해야 합니다. 데이터 갱신은 자주 일어나지 않지만 참조는 빈번해야 함 휘발성이기 때문에, 데이터를 보관하는 역할을 하여선 안됨 (ex. 사용자 정보를 보관하는 경우 X) 장애 대처를 위해 캐시 서버는 분산되어야 함 CDN(Content D..

Master-Slave를 사용하는 이유 (Replication 장단점)

데이터베이스 다중화 많은 DBMS가 데이터베이스 다중화를 지원합니다. 보통은 Master-Slave 패턴을 자주 사용하는데, 데이터 원본은 주(Master)서버에, 사본은 부(Slave)서버에 저장하는 방식입니다. Master-Slave 쓰기(Write)는 마스터에서만 지원하고, 부(Slave)서버는 DB사본을 갱신하면서, 읽기만을 지원합니다. 통상 애플리케이션은 읽기 연산 비중이 훨씬 크기 때문에 아래와 같은 구성으로 많이 사용합니다. 즉, 설계안은 다음과 같이 동작합니다. 동작 원리 사용자는 URL로 사이트에 접속하면 로드밸런서 IP 주소를 받습니다. 사용자는 로드밸런서에 접속합니다. 사용자의 요청은 웹 서버1 또는 웹 서버2로 전달됩니다. 웹서버는 쓰기(Write)라면 MasterDB, 읽기(Rea..

Database/Server 2022.02.25

리팩토링 - 메소드 올리기 (Pull up method)

메소드 올리기 (Pull up method) 메소드 올리기는 하위 클래스들의 중복 메소드를 상위 클래스로 빼는 리팩토링 기술입니다. 아래와 같은 Dashboard 클래스가 있고, 이를 상속하는 두 클래스가 있다고 가정하겠습니다. [부모 클래스] public class Dashboard { public static void main(String[] args) throws IOException { ReviewerDashboard reviewerDashboard = new ReviewerDashboard(); reviewerDashboard.printReviewers(); ParticipantDashboard participantDashboard = new ParticipantDashboard(); parti..

MySQL - datetime("0000-00-00") 사용하면 안되는 이유! (+ 에러 임시 해결)

"0000-00-00 00:00:00" error? 이번 주 회사에서 예약 서비스를 개발하다가 발생한 문제입니다. 회사에서 mysql의 datatimes값으로 0000-00-00 00:00:00 등의 format을 많이 사용하고 있었습니다. 그런데 문제가 발생해서 이런 값 사용은 절대 지양했으면 좋겠다고 생각하게 되었는데, 이유를 말씀해드릴게요! 1. DB Error: Incorrect datetime value MySQL 8.0의 sql_mode은 기본값으로 아래 세팅들을 포함하고 있습니다. ONLY_FULL_GROUP_BY STRICT_TRANS_TABLES NO_ZERO_IN_DATE NO_ZERO_DATE ERROR_FOR_DIVISION_BY_ZERO NO_ENGINE_SUBSITUTION 저기..

Database/SQL 2022.02.20

리팩토링 - 함수 추출 (Extract function)

함수 추출 함수 추출은 함수를 정의할 때 각 기능들이 어느정도 코드가 길고 읽기가 어렵다면 그 기능을 함수로 추출하는 방법입니다. 예시는 아래와 같습니다. (읽지 않으시는 걸 추천드립니다..) 두 함수가 읽는 것에도 꽤 시간이 들어가고, 공동으로 사용하는 코드도 많은 것 같습니다. 해당 부분들을 각 함수로 추출해보겠습니다. public class StudyDashboard { private void printParticipants(int eventId) throws IOException { GitHub gitHub = GitHub.connect(); GHRepository repository = gitHub.getRepository("whiteship/live-study"); GHIssue issue =..

Javascript - Null 병합 연산자 (null, undefined 검사 후 삼항 연산자 사용 개선)

개발 상황 개발을 하다보면 뭔가 메서드의 결과가 null 또는 undefined인지에 따라 값을 반환해야 하는 경우가 많습니다. 저의 경우에는 order라는 컬럼을 기준으로 Category가 정렬되기 때문에, Category를 생성할 때 Max order에 +1한 값을 order로 설정해줬어야 했어요! const maxOrder = categoryRepository.max("order"); category.order = maxOrder + 1; categoryRepository.create(category) 하지만, 저 방식은 category가 이미 1개 이상 있을때만 안전하고, 카테고리가 없다면 max가 null을 반환하기 때문에 null + 1이 연산 되면서, 에러가 발생합니다! If문 그래서 if문..

SQL - 트랜잭션 범위 개선

트랜잭션 트랜잭션은 최소의 단위로 설정하는 것이 중요합니다. 아래 예제는 사용자가 게시판에 게시물을 작성한 후 저장 버튼을 클릭했을 때 서버의 동작을 순서대로 정리한 것입니다. 1) 처리 시작 => 데이터베이스 커넥션 생성 => 트랜잭션 시작 2) 사용자의 로그인 여부 확인 3) 사용자의 글쓰기 내용의 오류 여부 확인 4) 첨부로 업로드된 파일의 확인 및 저장 5) 사용자의 입력 내용을 DBMS에 저장 6) 첨부 파일 정보를 DBMS에 저장 7) 저장된 내용 또는 기타 정보를 DBMS에서 조회 8) 게시물 등록에 대한 알림 메일 전송 9) 알림 메일 발송 이력을 DBMS에 저장 => 트랜잭션 종료(COMMIT) => 데이터베이스 커넥션 반납 10) 처리 완료 개선 사항 1. 트랜잭션이 처리 시작과 동시에..

Database/SQL 2022.02.13

Java14 - Record (Data class) 정리

Record 자바 14 버전부터 record 키워드를 지원합니다. record를 사용하면 Data class를 훨씬 간결하게 작성할 수 있습니다. 파이썬의 dictionary, C#의 Record, 코틀린의 Data class와 유사한 역할을 합니다. 기존 Data class 클래스를 만들 때 생성자를 정의합니다. 그리고, 필드를 캡슐화하고, getter를 정의한 클래스가 있다고 가정합니다. public class UserDto { private final int name; private final int address; public User(int name, int address) { this.name = name; this.address = address; } public String getName(..

Language/Java 2022.02.12

Java - Atomic Variable (+ 동시성 제어 비교 with volatile, synchronized)

동시성 제어 in 자바 자바에서 Multi Thread 환경의 동시성을 제어를 위한 방법은 대표적으로 3가지가 있습니다. volatile synchronized Atomic variable 3가지 방법은 모두 쓰임새가 다른 데 같이 살펴보겠습니다! volatile volatile을 키워드를 사용하면 멀티 쓰레드 환경에서 변수를 공유할 수 있습니다. public class SharedObject { public volatile int counter = 0; } 단, 여러 개의 스레드가 읽을 수 있지만, write할 수 있는 쓰레드는 하나만 존재해야 합니다. Volatile 키워드는 각 스레드가 가진 CPU cache가 아닌, 공유하는 Main memory에서 읽고 Write하는 방법입니다. 즉, A클래스에..

Language/Java 2022.02.12

Java 8 - 메소드 레퍼런스(Method Reference) : 람다식 간단하게 표현하기!

메소드 레퍼런스(Method Reference) comments라는 List타입의 리스트가 있다고 가정하겠습니다. 해당 배열에 대한 내용을 하나씩 출력할 때 코드는 어떻게 작성할까요..? 아마 리팩토링 경험이 많이 없으신 분들은 아래와 같이 작성하실 수 있습니다. for(int i = 0; i < comments.size(); i++) { System.out.println(comment.get(i)); } 또는 조금 간추려서, 아래처럼 작성할 수도 있습니다. for(String comment : comments) { System.out.println(comment); } 람다식 리팩토링 경험이 조금 있으신 분들은 람다식을 사용해서 코드를 단 한 줄로 표현할 수 있습니다. comments.forEach(c..

Language/Java 2022.02.11