37 posts
리액티브 시리즈 - 2. Spring WebFlux

💡 Intro 앞에서 리액티브 프로그래밍에 대해서 다뤘었다. 한마디로 리액티브 프로그래밍에 대해서 정의하자면 비동기/논블로킹 이벤트 드리븐 개발과 배압을 통해 적은 수의 쓰레드로 생상자가 소비자를 압도하지 못하며 확장성있는 개발이 가능하게 하는 프로그래밍 기법이라고 할 수 있다. 리액티브 프로그래밍은 가용성(CPU utilization이라고 볼 수 있는 영역)과 응답성(오류가 생겨도 빠르게 응답 가능)을 향상시키므로 프로그램의 효율성과 성능을 높인다. 함수형 프로그래밍도 관련 중요 키워드이다. 리액티브 프로그래밍은 함수형 프로그래밍(선언형, 함수 조합, 등등)을 활용한다. Spring WebFlux는 Spring Framework5에서 추가된 모듈이다. 스프링이 리액티브 스택 웹 어플리케이션을 구축할 수 있도록 리액티브 스트림 API를 지원해 논블로킹/비동기식으로 동작할 수 있도록 한다. 🌩 Spring WebFlux 란? 기존의 Spring Web MVC는 Servlet API,…

December 04, 2021
스프링
리액티브 시리즈 - 1. 리액티브 프로그래밍 기본

💡 Intro 트래픽이 증가하고 사용자가 기대하는 요청시간은 더 빠른 응답을 원하게 되면서 리액티브 프로그래밍이라는 개념이 대두가 되기 시작했다. Java 진영에서는 물론이고 현재 공부하고 있는 스프링 어플리케이션에서도 리액티브 개념을 구현한 모듈이 추가되고 활용되고 있다. 리액티브 프로그래밍을 키워드 중심으로 알아본다. (선언형, 리액티브 스트림, pub-sub 구조, 비동기, 옵저버 패턴 등등) 리액티브 프로그래밍이 주요 개념이 된 이유에 대해서 고민해본다. 🌩 리액티브 프로그래밍이란? ReativeX ReativeX는 옵저버 스트림을 활용한 비동기 프로그래밍을 위한 API이다. 그리고 이것을 구현한 여러 구현체들이 있다. 나 같은 경우는 자바 언어를 주로 사용하는데 자바 진영에서도 리액티브 API를 구현한 RxJava가 있고, 자바9 부터 리액티브 프로그래밍을 구현할 수 있는 Flow 클래스를 제공한다. Reactive - 무엇에 반응한다는 것인가? Reactive는 반응하다…

November 30, 2021
스프링
스프링 3대 개념 - IoC/DI, AOP, PSA

💡 Intro 스프링에서 어느날 등장한 개념은 아니고 어떠한 이름으로든 사용이 되고 있던 기술인데 스프링에서 더 잘 사용되도록 특정 형태를 부여했다. 이 3가지 기술들이 그 자체로 스프링이기보다 POJO 기반 엔터프라이즈 개발을 편하게 해줄 수 있는 일종의 도구이다. 즉, 객체지향적인 구현에 충실하면서 자연스럽게 등장하게 된 결과라고 할 수 있다. 스프링에서 제공하는 PSA, AOP만 사용하는 것이 아니라 그 개념을 차출하여 객체지향적 구현을 하는 것이 중요하다. 🌩 IoC/DI AOP, PSA도 IoC/DI에 바탕을 두고 있는 기술이다. 느슨한 결합을 위해 인터페이스를 두고 실제 구현체를 DI를 통해 외부에서 주입하는 것이다. 왜 강한 결합보다 느슨한 결합이 나은가? 유연한 확장이 가능하게 하기 위해서 → OCP 변경에 닫혀있다는 것은 재사용이 가능하다 라는 뜻이다. A → B 의존관계일 때 B가 변경이 되어도 A가 아무 영향을 받지 않으면 A 입장에서는 폐쇄이며 B 관점에서는 …

November 16, 2021
스프링
스프링, POJO 프레임워크가 무슨 뜻일까

💡 Intro POJO에 대해서 ‘그냥 자바 객체요!’라고 말하는 것 이상으로 이해해보자. POJO기반 프레임워크란 무엇인지 이해해보고 스프링에서 POJO는 어떠한 형태를 띄는지 알아보자 스프링이 개발의 복잡도를 낮춰주고 효과적으로 프로그래밍을 할 수 있도록 구체적으로 어떻게 가능하게 하는지 공부해보자. 🌩 POJO 란? 유명한 스프링의 삼각형으로 기본 컨텍스트를 맞추고 설명을 시작해보자. 스프링은 POJO에 주요기술인 IoC/DI, AOP, PSA를 사용한 코드와 POJO가 어떻게 관계를 맺고 동작하는지 정의한 설계정보로 구분된다. 스프링에서 DI는 유연하게 확장 가능한 오브젝트를 만들고, 그 관계를 외부에서 dynamic하게 설정해주는 것이며 스프링에서는 이 아이디어를 전반에 걸쳐서 적용한다. POJO는 EJB처럼 복잡하고 제한이 많은 기술로 엔터프라이즈 애플리케이션의 비지니스 로직을 구현하는 것보다 순수 자바 객체를 사용하여 비지니스 로직을 구현하는 것이 더 좋다고 생각하여 …

November 15, 2021
스프링
스프링의 싱글톤 레지스트리

💡 Intro 왜 하필 스프링 인가? 라는 질문을 던지게 되면서 스프링이 가지고 있느 장점에 대해서 고민해보았다. 그 중 기존의 싱글톤 패턴의 한계를 뛰어넘은 스프링 싱글톤 레지스트리를 알게 되었다. 이전에 단순히 스프링이 싱글톤 scope으로 객체를 관리하여 여러 요청이 동시에 들어오는 환경에서 안정적으로 서비스할 수 있다는 장점을 들었지만 싱글톤 패턴과 어떻게 다른지 알지 못했다. 그래서 알아보자 🙌 🌩 싱글톤 패턴이란? 왜 싱글톤 패턴이어야 할까 하나의 서버에 초당 수많은 요청이 도착하고 처리되어야 한다. 요청이 올 때마다 서버에서 관련 객체를 생성하는 것은 굉장히 큰 오버헤드이다. 어떤 오버헤드가 발생할 수 있을까 ? 주로 서버는 여러 계층의 레이어를 지나고 여러 비지니스 오브젝트들이 협력하여 요청을 처리한다. 요청 하나당 대충 5개 정도의 오브젝트가 생성되고, 초딩 300개의 요청, 1분에 18000개의 요청이 발생한다면 18000 * 5 만큼의 새로운 오브젝트가 생성된다…

November 10, 2021
스프링
넷플릭스에서 60000ms 만에 리눅스 서버 성능을 진단하는 방법 10가지

이 글은 다음 링크를 번역하며 공부한 글입니다 🙌 💡 Intro 성능 테스트에 관련한 공부 및 적용을 하면서 좋은 아티클을 추천 받았다. (Thanks to 제리 👍) 관련 명령어들에 대해서 공부하고 각 칼럼이 의미하는 os 및 네트워크 기초 지식을 메꾸보자. 1. uptime 실행되기를 기다리는 프로세스의 갯수를 출력한다. 리눅스 시스템에서는 CPU를 기다리는 프로세스와 uninterruptible I/O (disk I/O) 에 의해 프로세스가 막혀있을 수 있다. 따라서 이 수치를 통해서 리소스 부하를 간편하게 확인 할 수 있다. 위 세개의 번호는 각각 1분, 5분, 15분 간 실행되지 못하고 대기 중인 프로세스 갯수를 나타낸다. 시간 추이에 따른 부하 상태를 통해 상황을 유추할 수도 있다. 2. dmesg | tail 마지막 10개의 시스템 메세지를 출력한다. 여기서 성능에 이슈를 일으킨 에러 메세지를 확인할 수 있다. oom-killer나 TCP 요청 드랍 같은 경우를 확인할…

October 15, 2021
성능테스트
K6를 활용한 성능테스트 경험기 1 - 홈피드 조회 기능 향상

💡 Intro 진행 중인 프로젝트에서 구현한 웹 어플리케이션이 어느 정도의 부하를 견딜 수 있는지에 대한 성능테스트를 진행했다. 프로젝트는 개발자를 타켓으로 한 깃헙 레포지토리를 연동한 게시물을 업로드하여 개발자들이 자신의 작업을 공유하고 다른 이들의 프로젝트를 캐줄얼하게 엿볼 수 있는 SNS형 웹 어플리케이션이다. 웹 어플리케이션에 들어가자마자 최신순으로 정렬된 게시물 피드를 볼 수 있다. (비로그인/로그인 모두 가능) 홈피드 게시물 조회 성능테스트를 진행, 병목 지점을 분석하고 개선하는 과정을 따라가보자. 🌩 사전 작업 테스트 더미 데이터 입력 테스트를 진행하기 위해서는 실제 운영환경과 최대한 유사한 환경에서 테스트하는 것이 중요하다. 운영환경과 유사한 환경이라고 하면 크게 1) 인프라 구조 2) 데이터 두 가지가 있다. 먼저 대량의 더미 데이터를 입력하도록 한다. (팀원 케빈이 수고해주었다 !! 👍) MariaDB 쿼리 캐시 끄기 왜 쿼리 캐시를 껐을까? 실제 어플리케이션에서…

October 15, 2021
프로젝트
성능테스트
데이터베이스
K6를 활용한 성능테스트 경험기 2 - 홈피드 조회 기능 향상

💡 Intro 이전 포스트에서 진행한 프로젝트에서 홈피드 게시물 조회 성능 테스트에 대한 결과를 보고 개선대상을 파악하고 개선한다. 개선 후 테스트를 재진행하여 결과를 비교한다. 🌩 쿼리 진단 이전 포스트에서 진행한 성능 테스트를 통해 DB 쿼리 쪽 병목이 있다는 것을 알아냈다. 구체적으로 쿼리를 자세히 살펴보면서 어떤 문제가 있는지 확인해보자. 홈피드 게시물을 반환할 때 발생하는 slow query 현재는 포스트 조회하는 쿼리가 최대값으로는 3.62 초가 소요된다. 쿼리의 실행계획을 확인해서 문제점을 파악해보니 100만건의 데이터를 거의 다 훑으면서 filesort를 하고 있었다. 게시물을 최신순으로 정렬하여 상위 10개를 가지고 오는 Pagination을 적용하고 있기 때문이다. 🌩 개선하기 createt_At 칼럼에 인덱스를 추가하여 데이터가 정렬되도록 한다. 인덱스를 건 후 실행계획을 확인해보니 filesort가 제거되었고 훑는 row 수가 대폭 줄어들었다. 🌩 개선 후 성…

October 15, 2021
프로젝트
성능테스트
데이터베이스
대규모 서비스를 지탱하는 기술 - 실전 기술

다음은 웹 개발자를 위한 대규모 서비스를 지탱하는 기술을 읽고 정리한 내용입니다 🙌 1. 작업큐(Job-Queue) 시스템 웹 서비스와 요청 본래 웹 서비스의 요청은 동기적으로 실행이 되었는데, 데이터가 축적되어 처리가 무거워지면서 작업큐 시스템을 통해서 나중으로 미뤄도 되는 처리를 비동기로 실행하도록 한다. 예) 특정 url을 북마크 할 때 해당 url의 개요를 얻고 키워드를 추출하고, 카테고리를 판정하는 작업들을 비동기로 처리한다. 그렇지 않으면 북마크를 추가할 때마다 긴 시간이 소요된다. 작업큐 시스템 입문 비동화 하는 방법 → 해당 처리를 독립된 스크립트로 어플리케이션 내부에서 호출한다. 이 방법은 대량의 비동기 처리시 그 수만큼의 프로세스를 실행시키므로 성능상 단점이 될 수 있다. 스크립트 시작과 초기화의 오버헤드가 커서 성능이 좋지 않다. 소규모 어플리케이션에서만 진행하는 것이 좋다. 작업큐와 워커를 세트로 작업큐 시스템을 사용하는 것이 일반적이다. 작업큐에 실행하고자 …

September 29, 2021
인프라
성능테스트
대규모 서비스를 지탱하는 기술 - 웹 서비스와 네트워크

다음은 웹 개발자를 위한 대규모 서비스를 지탱하는 기술을 읽고 정리한 내용입니다 🙌 규모가 커지면서 트래픽이 커지면 문제가 발생한다. → 라우터의 성능 관점에서는 bps보다 패킷 단위인 pps가 더 중요하다. 사용하고 있는 라우터에서 감당하는 이상의 패킷이 송수신되면 문제가 발생한다. 또한 호스트 수가 500을 넘어가면서 하나의 서브넷을 구성하면 여러 패킷 손실등이 발생하기도 한다. 글로벌 서비스로 확장하면 데이터 센트럴 한군데 두었을 때 latency도 한계에 다다를 수 있다. [강의38] 네트워크 분기점 1Gbps의 한계 - PC 라우터의 한계 1Gbps 는 30만pps → 한계치이다. 이것을 해결하기 위해서는 PC 라우터를 여러 대 병렬화 하던지, 고가의 라우터를 사용해야 한다. 500호스트의 한계 - 1서브넷 ARP 테이블에서의 한계 스위치의 ARP(Address Resolution Protocol table)에서 한계가 있다. ARP는 IP주소와 MAC 주소간의 관계를 나…

September 29, 2021
인프라
성능테스트
대규모 서비스를 지탱하는 기술 - 효율 향상 전략

다음은 웹 개발자를 위한 대규모 서비스를 지탱하는 기술을 읽고 정리한 내용입니다 🙌 다중화로 어느정도 문제를 해결할 수 있지만 규모가 작으면 다중화를 했을 경우 전체적인 리소스 사용률이 떨어지면서 효율이 떨어진다. 가상화로 전체적인 리소스 사용률을 높일 수 있다. [강의36] 가상화 기술 가상화 기술의 도입 왜 가상화 기술을 사용하나 확장성 → 오버헤드 최소화 비용대비 성능 → 리소스 사용률 향상, 운용의 유연함 고가용성 → 환경 격리 가상화 기술의 효용 IPMI를 대체하는 하이퍼바이저 호스트 OS : 서버에서 최초에 기동하는 OS 하드웨어 간 차이 흡수 → 환경 추상화 준 가상화 사용 리소스 소비 제어 과부하 경고 부하 조정 가상화 서버 구축정책 하드웨어의 이용효율을 높이기 위해 남아있는 리소스를 사용하는 게스트 OS를 투입하는 것이다. 예를 들어 CPU 리소스가 남이있으면 웹 서버, I/O 리소스가 남아있으면 DB 서버, 메모리 용량이 남아있으면 캐시 서버를 투입한다. 리소스 …

September 28, 2021
인프라
성능테스트
대규모 서비스를 지탱하는 기술 - 다중성 확보, 시스템 안정화

다음은 웹 개발자를 위한 대규모 서비스를 지탱하는 기술을 읽고 정리한 내용입니다 🙌 가동률을 100%로 끌어올려 시스템이 멈추지 않도록 하는 것 여기서 중요한 것은 SPOF (Single Point of Failure) 단일장애점을 제거하는 것이다. [강의33] 다중성 확보 다중성 확보 - WAS 서버 중요한 것은 여러대의 서버가 있을 때 몇대의 서버가 정지하더라도 서비스가 정상적으로 처리될 수 있는 상태를 만드는 것이다. 로드밸런서에서 failover를 처리할 수 있다. 고장난 서버를 분리시키고 정상적인 서버로 요청을 보내는 것 연결된 서버들에 대한 주기적인 헬스체크 failback 고장난 서버를 복구하고 다시 복귀시키는 것 다중성 확보 - DB 서버 마찬가지로 여러대의 DB 서버가 있을 때 몇대가 고장나더라도 요청을 정상적으로 처리할 수 있어야 한다. Master도 다중화 하면 좋다 → 하지만 어렵다. 책의 예시에서는 멀티 마스터를 사용하고 있다. 양쪽이 서로 slave 관계이…

September 28, 2021
인프라
성능테스트
대규모 서비스를 지탱하는 기술 - 확장성 확보에 필요한 사고방식

다음은 웹 개발자를 위한 대규모 서비스를 지탱하는 기술을 읽고 정리한 내용입니다 🙌 [강의31] 계층과 확장성 확장성에 대한 요구 - 서버 1대에서 처리할 수 있는 트래픽 한계 (업데이트가 필요한 정보이다) 이 때 당시에 서버 한대로 처리할 수 있는 트래픽은 월 100만 PV 정도, 최고사양으로 100만 ~200만 까지도 감당할 수 있었다. 수천 ~1만 건/분 정도의 요청을 처리할 수 있는 정도이다. 더 대규모는 서버1대로 동작할 수 없다. 계층별 확장성 WAS는 상태를 가지고 있지 않으므로 단순히 대수를 늘리는 것으로 요청을 확장할 수 있다. 로드밸런서에 새로운 서버를 추가하면 된다. DB는 다른 방법으로 (쓰기, 읽기가 나뉘어져 있으므로) 더 많은 요소들을 고려하면서 확장해야한다. [강의32]부하 파악, 튜닝 부하 파악 - 관리화면 시각화의 중요성 각각의 서버에 관해서 그래프화 하는 것이 중요하다. 부하 측정을 위한 항목 Load Average, 메모리, CPU Load Ave…

September 28, 2021
인프라
성능테스트
대규모 서비스를 지탱하는 기술 - 대규모 데이터 처리를 지탱하는 서버/인프라 입문

다음은 웹 개발자를 위한 대규모 서비스를 지탱하는 기술을 읽고 정리한 내용입니다 🙌 [강의29] 엔터프라이즈 vs. 웹 서비스 엔터프라이즈 vs. 웹 서비스 - 응용범위로 보는 차이 웹 서비스의 특징 - 엔터프라이즈와 비교 트래픽 - 엔터프라이즈에 대규모 트래픽이 일어날 일은 많이 없지만 웹 서비스에서는 대규모 트래픽이 일어나고는 한다. 성장성 - 비즈니스와 연관된 엔터프라이즈는 급격히 성장하지는 않는다. 웹 서비스와 같은 경우는 폭팔적 성장이 가능하다. 신뢰성 - 사람의 목숨이나 돈에 관련된 일이 많기 때문에 높은 신뢰성이 요구된다. 웹 서비스는 인명이나 돈과 깊게 관련 없는 경우가 더 많기 때문에 그정도의 신뢰성이 중요하지는 않다. 트랜잭션 - 신뢰성과 비슷한 맥락의 이야기지만 더 DB에 한정되서 이야기 한다. 엔터프라이즈는 데이터의 정합성이 매우 중요하다. (은행에서 돈 예시) 웹 서비스는 (블로그와 같이) 정합성이 일치하지 않아도 큰 문제가 생기지 않는다. 웹 서비스의 인프…

September 28, 2021
인프라
성능테스트
대규모 서비스를 지탱하는 기술 - 알고리즘 실용화

다음은 웹 개발자를 위한 대규모 서비스를 지탱하는 기술을 읽고 정리한 내용입니다 🙌 [강의19] 알고리즘과 평가 데이터 규모와 계산량 차이 데이터가 클 수록 알고리즘이나 데이터 구조 선택이 속도에 영향을 미친다. ex. 선형탐색 vs. 이분탐색 알고리즘이란? 알고리즘은 값의 집합을 입력, 다른 값의 집합을 출력으로 하고 명확하게 정의된 계산절차이다. 유한한 자원인 CPU나 메모리를 어떻게 활용하여 문제를 해결해야 할까? 적절한 데이터구조를 사용하여 알고리즘을 구현해야지 효과가 있다. 결국 측정이 중요하다 !! 알고리즘을 활용한 데이터 처리 과도한 알고리즘이 항상 더 효율이 좋은 것은 아니다. 때로는 간단한 알고리즘이 더 시간을 줄여줄 때가 있다. 과도한 알고리즘의 경우 전처리에 많은 시간이 소요되기도 한다. 항상 측정이 중요하다. 단순이 데이터가 ‘적다’, ‘많다’ 라는 것으로 판단하는 것은 좋지 않다. 데이터 압축과 속도 - 전체적인 처리량을 높이기 위한 사고방식 압축이라는 것이…

September 27, 2021
인프라
성능테스트
대규모 서비스를 지탱하는 기술 - 대규모 데이터 처리 실전 입문

다음은 웹 개발자를 위한 대규모 서비스를 지탱하는 기술을 읽고 정리한 내용입니다 🙌 이전에는 미들웨어를 살펴보면서 운용에 대한 생각을 했다면 이제는 개발에 대한 생각을 하면서 어플리케이션 개발시 고려해야할 급소들에 대해서 살펴보도록 한다. 대량의 데이터에 액세스 (그리고 이러한 데이터들을 특정 부분을 절단하기 어려운 경우가 대부분이다)를 할 대 RDBMS, MySQL등에서 처리할 수 없는 규모의 데이터를 계산하고자 할 경우를 살펴본다. [강의14] 용도특화형 인덱싱 인덱스와 시스템 구성 - RDBMS가 한계를 보일 때 지나치게 많은 데이터를 다루는 경우 (검색 등) RDBMS로는 한계가 있다. 그렇다면 해결 방법은 ? 배치 처리로 RDBMS에서 대량의 데이터를 추출 별도의 인덱스 서버와 같은 것에 데이터를 보관 웹 어플리케이션에서 RPC(Remote Procedure Call)등으로 액세스 하도록 처리 RPC, 웹 API DB 가 정기적으로 데이터를 추출해서 인덱스 서버로 넘긴다.…

September 27, 2021
인프라
성능테스트
대규모 서비스를 지탱하는 기술 - 전문 검색기술

다음은 웹 개발자를 위한 대규모 서비스를 지탱하는 기술을 읽고 정리한 내용입니다 🙌 검색엔진의 노하우를 알아두면 용도특화형 인덱스를 직접 만들어서 대규모 데이터에 대한 문제를 해결할 수 있다. [강의24] 전문 검색기술의 응용범위 키워드 역 인덱스 전문 검색의 종류 grep 형 전부 읽어가면서 검색하는 것 시간이 오래 걸린다. 즉시성이 좋다 → 문서가 갱신되더라도 바로 검색할 수 있으며 검색누락이 없다. 병렬화 하기가 간단하다 → 분할해서 검색하기 편리하다 suffix 형 검색 가능한 형태로 검색 대상 전문을 보유한다. 구현이 어렵다. 역 인덱스형 단어와 문서를 연관짓는 것 문서와 별도로 역 인덱스를 만들어야 한다. → 즉 전처리가 필요하다. 즉시성이 떨어진다. 인덱스를 압축함으로 컴팩트하게 가져갈 수 있다. 대규모화 하기 가 쉽다. [강의26]검색엔진의 내부구조 역 인덱스의 구조 - Dictionary + Postings 어떠한 단어 (dictionary 형태)에서 연결되어 있는…

September 27, 2021
인프라
성능테스트
대규모 서비스를 지탱하는 기술 - OS 캐시와 분산

다음은 웹 개발자를 위한 대규모 서비스를 지탱하는 기술을 읽고 정리한 내용입니다 🙌 [강의8] OS 캐시 구조 OS의 캐시 구조를 알고 애플리케이션 작성하기 - 페이지 캐시 OS는 메모리를 이용해서 캐시 구조를 갖추고 디스크 액세스를 줄인다. Linux(x86) 페이징 구조 OS는 가장 메모리 구조를 가지고 있는데 논리적인 선형 어드레스를 물리적인 어드레스로 변환한다. 가상 메모리 구조 기본적인 OS 구조를 보면 OS에서 관리하고 있는 메모리 구조 있고, OS가 있으며 OS에서 돌아가는 프로세스가 존재한다. 프로세스에서 메모리가 필요한 경우 메모리에 직접 접근해서 주소를 가져오는 것이 아니라, OS를 통해서 비어있는 주소와 다른 주소를 반환한다. 왜 가상 주소를 반환할까? 개별 프로세스가 실제로 메모리의 어느 부분을 사용하는지 스스로 알고 있을 필요가 없고, 특정 번지에서 통일해서 시작하는 것으로 다루면 더 쉽기 때문이다. 예) 유닉스에서 공유 라이브러리는 프로세스 내에서 지정된 …

September 24, 2021
인프라
성능테스트
대규모 서비스를 지탱하는 기술 - 분산을 고려한 MySQL 운용

다음은 웹 개발자를 위한 대규모 서비스를 지탱하는 기술을 읽고 정리한 내용입니다 🙌 이번장은 레이어를 DB로 옮겨서 DB의 스케일아웃 전략에 대해서 살펴본다. [강의11] 인덱스 올바르게 운용하기 분산을 고려한 MySQL 운용, 세 가지 포인트 OS 캐시 활용 인덱스를 적절하게 설정 확장을 전제로 한 설계 OS 캐시 활용 전체 데이터 크기가 물리 메모리보다 가능한 적도록 유지한다. 상황: 대규모 서비스일 경우 (3억건의 데이터), 테이블에 칼럼을 한 개 (약 8바이트)를 추가하더라도 3GB 가 추가된다. → 스키마도 신경써서 설계해야한다. 따라서 테이블의 레코드를 컴팩트하게 설계해야한다. (int형 32비트, 문자열 8비트 같은 수치에 대한 감각 필요) DB 테이블의 데이터를 정규화하는 것은 ? 예를 들어서 필수적으로 필요한 데이터만 테이블에 남기고, flag로 사용되는 데이터들을 테이블 분리하여 필요할 때만 사용할 수도 있다. 대규모 데이터인 경우 이것만 분리를 하더라도 엄청난 …

September 24, 2021
인프라
성능테스트
대규모 서비스를 지탱하는 기술 - 대규모 데이터 처리

다음은 웹 개발자를 위한 대규모 서비스를 지탱하는 기술을 읽고 정리한 내용입니다 🙌 [강의4] 어느정도가 대규모 데이터인가 ? 이때 당시의 수치임을 감안하고 보자 !! 하테나의 경우 레코드 건수 1500만, 5000만 entry 테이블이 3기가, bookmark 데이블이 5.5기가 등등 html 텍스트 데이터 압축 후 200 기가 이정도가 중규모 ~ 대규모 디비 규모가 기가바이트면 굉장히 많은 것이다. 인덱스 사용 안했을 때 1건 검색시 200초 소요 [강의5] 대규모 데이터는 어떤 점이 어려운가 한마디로 말하면 ‘메모리 내에서 계산할 수 없다’ 데이터가 너무 많으면 메모리 내에서 계산할 수 없으므로 디스크를 검색하면 읽어야하는데 디스크를 읽는 것은 계산량도 지나치게 많아지고 시간도 많이 소요된다. (I/O 시간) 메모리와 디스크 속도 차이는 10만 ~ 100만배 정도 디스크는 왜 늦나 디스크의 경우 헤드의 이동과 원반의 회전이라는 두 가지 물리적인 이동이 수반되며 속도가 저하된다…

September 23, 2021
인프라
성능테스트
대규모 서비스를 지탱하는 기술 - 오리엔테이션

다음은 웹 개발자를 위한 대규모 서비스를 지탱하는 기술을 읽고 정리한 내용입니다 🙌 어느 정도가 대규모 인가 ? 이것은 이 책이 쓰여졌을 당시의 상황이다. 전혀 감이 없으니 이때 당시의 대규모 정도를 숫자로 파악해보자. 등록 사용자 100만 명 이상, 1500만 UU 서버 500대 이상 피크시 회선 트래픽 430Mbps [강의1] 소규모 서비스와 대규모 서비스의 차이 확장성 확보, 부하분산 필요 1대의 서버로 처리 할 수 없는 부하를 어떻게 처리할 것인가 ? 스케일 아웃 → 서버 대수를 늘림으로 스스템 처리능력을 높임 스케일 업 → 하드웨어 성능을 높여 처리 능력을 끌어올림 여러대의 서버를 사용했을 때 파생되는 문제 데이터 동기화, 네트워크 통신 지연시간, 다중성 확보 특정 서버가 고장이 나도 서비스를 계속 할 수 있어야 함 스케일아웃은 서버의 고장율이 올라가고 하나가 고장났다고 전체가 정지해버릴 순 없다. 시스템이 고장나면 다른 시스템이 자동으로 처리를 인계받는 시스템 설계가 …

September 23, 2021
인프라
성능테스트
쿠키와 세션 알아보기

INTRO HTTP는 Stateless 무상태성을 가지고 있다. 따라서 데이터를 상태로 저장하지 않는다. HTTP가 무성태성이기 때문에 클라이언트에 대한 데이터를 유지하고 싶을 때는 쿠키 또는 세션을 이용한다. (이전에 요청을 보낸 동일한 사용자임을 확인하고 싶은 경우 등등) 쿠키는 클라이언트가 정보를 가지고 브라우저에서 저장 및 관리한다. 세션은 서버가 데이터를 가지고 저장 및 관리한다. Cookie 쿠키는 클라이언트가 정보를 가지고 브라우저에서 해당 정보를 저장한다. 따라서 요청을 보낼 때마다 브라우저에서 저장된 쿠키 데이터를 HTTP 헤더에 추가하여 서버에 보낼 수 있다. HTTP 메세지 자체는 무상태성이기 때문에 매번 쿠키값을 보내주어야 한다. 쿠키에 저장되는 값의 형태는 text 이다. 쿠키의 단점 클라이언트가 관리하는 것이기 때문에 데이터가 쉽게 훼손 될 수 있다. 실제로 크롬 브라우저에서 개발자 도구 -> Application 탭에 가면 쿠키 데이터를 저장하는 저장소를…

September 04, 2021
OAuth 알아보기

1. INTRO 많은 어플리케이션에서 소셜 로그인을 지원하는데, 이때 사용되는 것이 OAuth 2.0 이다. 간단하게 이야기하면 OAuth 2.0 이란 사용자의 정보에 대한 권한을 부여하는 의 일종이다. (정의) 제 3의 앱이 자원의 소유자인 서비스 이용자를 대신하여 서비스를 요청할 수 있도록 자원 접근 권한을 위임하는 방법 출처: 금융보안원 “OAuth 2.0 개요 및 보안 고려사항” 보안연구부-2015-030 즉, 정보 소유자 (서비스 이용자)를 대신하여 앱이 다른 서비스에 등록되어 있는 자원에 대한 접근을 요청하는 권한을 위임한다. 아래 글은 링크 원문을 번역하고 일부 요약한 것이다. 2. OAuth 주요 개념 리소스 소유자 (Resource Owner) - 어플리케이션이 인가 요청을 하는 정보의 소유자이다. 즉, 그 정보를 소유하고 있는 ‘사용자’를 말한다. 클라이언트 (Client) - 리소스 소유자의 정보를 요청하는 어플리케이션이다. 리소스 서버 (Resource Se…

September 03, 2021
클래식한 스프링 웹 어플리케이션 구조

다음 글은 [링크](Understanding Spring Web Application Architecture: The Classic Way)에 기술되어 있는 스프링 웹 어플리케이션 구조에 대한 글을 번역 한 내용이다. 좋은 architecture를 위한 두 기둥 The SoC(Separation of Concerns) 원칙 A design principle for separating a computer program into distinct sections, which each section addresses a separate concern. 출처 SoC에서 신경써야 할 부분은 두가지이다. 고려해야 할 concerns가 무엇인지 어디서 해당 concern을 다루고 싶은지 SoC를 준수하게 된다면 각각의 layer와 해당 layer의 책임에 대해서 자연스럽게 정의할 수 있도록 도와준다. The KISS(Keep It Simple Stupid) 원칙 Most systems work…

June 26, 2021
스프링
HandlerMethodArgumentResolver 내부동작 원리 알아보기

INTRO 는 Spring framework에서 제공하는 인터페이스로 request에서 메소드의 parameters를 해당하는 인자값으로 변환 혹은 바인딩 하는 resolver이다. 인터페이스 내용 에는 두가지 메소드가 있다. 첫번째, Parameter가 해당 resolver를 지원하는 여부 확인 [참고] 아래 설명은 가 붙은 인자의 경우를 보는 것이므로 그 구현체가 의 예시로 설명한 것이다. Parameter가 있는 수만큼 → 안에서 for문을 돌면서 해당 parameter에 대한 argument resolve를 한다. 이때 resolve를 하기 위해서 현재 클래스가 가지고 있는 가 해당 parameter 지원 하는지 여부를 확인한다. → 확인하는 로직은 안에 있는 resolver들의 배열을 돌면서(한번 찾으면 캐싱함) 해당 parameter를 지원하는 resolver를 찾아서 반환하고, null인지 여부를 체크해 boolean을 반환한다. 이때 메소드가 수행된다.…

June 25, 2021
스프링
초간단 Interceptor 알아보기

개요 Handler interceptors는 어떤 요청들에 대한 특정 기능을 적용하고 싶을 때 사용이 되는데, 특히 어떤 조건 및 원칙들을 검증하는데 많이 사용된다. Interceptor 구성 Interceptor를 구현하기 위해서는 HandlerInterceptor를 구현해야 한다. 해당 인터페이스에는 interceptor가 실행되는 3가지 경우에 대한 메소드가 정의되어 있다. handler가 실행되기 이전 handler가 실행된 이후 전체 요청 처리가 모두 수행된 이후 이것들 중 handler 실행 이전에 수행되는 메소드인 은 boolean 값을 반환한다. 과 은 void를 반환한다. 위 세가지 메소드 모두 공통된 인자로 Servlet에 의해서 생성된 , , (Object 타입)을 받는다. 따라서 void 반환타입인 경우 HttpServletResponse에 후처리를 할 수 있다. (의 경우에는 를 은 을 속성으로 받는다) preHandle() 동작원리 은 와 를 execu…

June 23, 2021
스프링
대칭키와 비대칭키 비교하기

Intro 암호화(encryption)에는 3가지 기술이 있다. Symmetric encryption - 대칭키 Asymmestric encryption - 비대칭키 Hash functions(keyless) - 해싱 여기서는 대칭키, 비대칭키에 대해서만 다룰 것인데 둘다 각각의 장단점이 있다. 대칭키와 비대칭키의 간단한 차이점 우선 모두 key를 사용해서 데이터를 encrypt/decrypt 한다. 대칭키의 경우 동일한 key를 가지고 암호화/복호화를 하기 때문에 사용하기가 쉽다. 비대칭키의 경우 public key를 사용해서 데이터를 암호화하고, private key를 사용해서 복호화한다. Symmetric encryption 대칭키? 대칭키를 사용하면 데이터의 암호화/복호화 모두 하나의 key를 사용한다. 그리고 해당 키를 수령인과 공유한다. (수령인이 암호화된 데이터를 받았을 때 복호화를 위해서 필요) 대칭키 장단점 장점 세팅이 쉽고 간단하다. (jiffy 순간적으로 처…

June 21, 2021
Hash와 Salt

들어가기 전에 암호화(Encryption)과 해싱은 다른 개념 암호화 - 양방향이므로 복호화가 가능 해싱 - 단방향이므로 복호화가 불가능 단방향 해시 함수 (One-Way Hash Function) 기본적으로 패스워드 등의 보안의 문제가 걸린 정보를 DB에 저장할 때 평문으로 저장하지 않고 해싱한 값을 저장한다. (평문으로 저장할 경우 DB가 해킹되었을 때 심각한 문제가 발생한다) 단방향 해시 함수를 사용해서 원본 내용을 완전히 새로운 내용으로 다이제스트(digest)로 매핑한다. 이때 매핑하는 것을 해시라고 한다. 이것은 단방향이므로 복호화할 수 없다. 해시 함수 종류 SHA MD HAS WHIRLPOOL 한계점 Rainbow Table 동일한 데이터를 동일한 해시 함수로 연산한 다이제스트는 동일한 값을 가진다. 따라서 여러 값들에 대한 다이제스트를 모아놓은 Rainbow Table이라는 것이 존재하고 이것을 통해서 원본 데이터를 유추할 수 있다. Brute-force 해싱 …

June 21, 2021
자바
스프링부트의 Exception handling

Spring Boot Spring boot 자체에서 핸들링 되지 않은 error 에 대한 대비책을 마련해 두었다. 먼저, Spring boot 자체에서 에 대한 매핑을 찾아서 해당 URL에 대해서 동일한 이름을 가진 뷰를 매핑 한다. 해당 뷰는 을 반환한다. (해당 뷰는 Thymeleaf template인데, 만일 JSP를 사용한다면 를 반환하도록 에서 변경할 수 있다) 실질적인 매핑은 ViewResolver에서 담당한다. 만일 에 대해 그 어떠한 view-resolver도 매핑이 되어 있지 않다면 spring boot는 내부적으로 가지고 있는 대체 에러 페이지인 “Whitelabel Error Page”를 가지고 있다. 이때 만일 RESTful request에 대한 응답이라면 Spring boot는 자체적인 JSON 형태로 “Whitelabel Error Page”의 응답을 받은 error 정보를 반환한다. Spring boot는 컨테이너에 대한 디폴트 error-page…

June 19, 2021
스프링부트
스프링
JWT (JSON Web Token) 알아보기

JWT(JSON Web Token) 배경 이전에 인증 절차를 거치려면 사용자의 해싱값을 DB에 저장하고 매번 요청이 있을 때마다 해당 해싱값을 검증해야한다. 검증시 DB에 접근하는 쿼리가 실행되어야하는데 성능면에서 좋지 않다. 따라서 JWT가 등장하게 되고 위와 같은 절차를 거치지만 DB 접근 쿼리가 필요하지 않게 된다. JWT 정의: A string that is sent in the HTTP request (from client or server) to validate the authenticity of the client. It is saved on the client-side only. 출처 JWT 특징 compact self-contained digitally signed : it is signed using a secret key(HMAC algorithm) or public/private key pair using (RSA or ECDSA) sgined 토큰 이라면 c…

June 13, 2021
Dispatcher Servlet 알아보기

Servlet 개념 및 구조 Servlet은 웹 서버를 구현한 자바의 프로그램이며 interface이다. 서블릿이 하는 일은 다음과 같다. Servlet은 웹 클라이언트로부터 요청을 받아서 응답을 반환한다. Servlet 인터페이스는 servlet을 초기화하고, 서비스를 요청하고, servlet을 서버에서 제거하는 메소드를 제공한다. (이걸 life-cycle 메소드라고 말한다) 메소드를 통해서 서블릿이 구축된다. 클라이언트에서 호출된 메소드가 수행된다. 수행된 서블릿이 에서 제거되고 메소드를 통해서 소멸된다. 추가로 Servlet 초기세팅 정보를 에 담아서 반환하는 와, Servlet 정보를 반환하는 메소드도 존재한다. HttpServlet 구조 을 확장하고 인터페이스를 구현한다. 웹 환경에 최적화되어 있어서 HTTP 메소드를 지원한다. 즉, HttpServlet 에서는 를 override 할 이유가 거의 없다. 왜냐햐면 이미 정의되어 있는 Http 요청들을 수행하…

June 03, 2021
Bean Scope 종류 알아보기

스프링 프레임워크에서 사용되는 Bean scope에 6가지 종류가 있다. 일반적으로 많이 쓰이는 scope은 싱글톤이다. Singleton scope 스프링 빈이 singleton scope을 가지고 있다면, 컨테이너가 빈의 단 하나의 인스턴스를 해당 빈이 필요할 때마다 캐싱된 빈을 리턴한다. 빈 객체를 수정하면 해당 빈을 참조하고 있는 모든 곳에 반영이 된다. 싱글톤 스콥은 스프링의 기본값이다. Prototype scope 프로토타입 스콥은 빈 요청이 있을때마다 매번 다른 인스턴스를 컨테이너로부터 반환한다. 설정방법은 다음과 같다. Web Aware Scopes 앞에 두 개의 범위를 제외하고 4개의 범위가 더 존재한다. 하지만 조건이 있는데, web-aware application 맥락에서만 적용이 될 수 있는 범위이다. Request Scope Request scope은 하나의 HTTP request 당 하나의 빈을 생성한다. 이 scope을 사용할 때는 proxyMode 속성…

May 30, 2021
스프링
젠킨스를 활용한 CI/CD 적용기

자바 + 스프링 MVC 프로젝트 배포과정 (별도 인스턴스 활용) 이번에 몇몇 크루들과 미션을 진행하면서 웹을 처음으로 호스팅 해보았다. 웹을 배포 할 때 더욱 편리하다는 DevOps의 꽃 ci/cd를 학습해보기 위해서 6명이 모여서 한번 적용해보았다. 적용하면서 밟은 단계들을 기록해둔다. 아래와 같이 그대로 적용하다가 본 프로젝트에 맞게 어느정도 커스텀하여 다르게 설정한 것도 있다. 특히 버전같은 것들은 좀 outdated 된 정보일 수 있다. 추후에 진행할 팀 프로젝트에 큰 도움이 될 것 같다. docker 설치 EC2에서 Jenkins key 받기 및 적용 Jenkins 포트 번호 변경 젠킨스는 내부적으로 톰캣 서버를 이용하므로 기본포트 8080을 이용한다. 대부분의 스프링 프로젝트도 8080 톰캣 포트를 이용하기 때문에 젠킨스의 포트번호를 변경해야한다. Jenkins 홈 디렉토리 Jenkins 기본 설정파일 & 로그 파일 포트 변경 후 재시작 Jenkins 접속 및 설정 Je…

May 19, 2021
운영
CI/CD란 무엇일까

CI/CD 의 필요성 개발 후 운영을 하기까지 다음 그림의 프로세스가 반복해서 진행된다. 즉, 개발 프로세스(Dev)의 일종으로 개발을 하여 빌드를 하고 운영 프로세스(Ops)의 일종으로 릴리즈, 배포, 모니터링이 반복된다. 점점 이것을 짧은 쥐기로 반복하는 DevOps가 등장하면서 CI/CD가 중요해졌다. CI - Continuous Integration 정의: 지속적으로 퀄리티 컨트롤을 적용하는 프로세스를 실행하는 것 어플리케이션 코드에 변경이 생기더라도 정기적인 빌드와 테스트를 통과하여 하나의 레포지토리에 관리가 되는 것 예시: SCM(Source Code Management): 깃헙 레포 하나로 소스코드를 머지하고 충도를 처리하는 과정 테스트 코드를 통해서 유효성을 검증하는 과정 장점: 소스코드를 Ready-to-run 상태로 유지할 수 있다. 이 부분은 혼자 개발할 경우 장점을 느끼기 어렵지만 주로 여러명이서 협업하여 개발을 하기 때문에 중간에 합류한 그 누구도 빌드가…

May 17, 2021
운영
@Transactional

트랜잭션을 사용하는 이유 트랜잭션을 사용하면 각각의 단위로 나누어져있는 작업의 단위를 하나로 합칠 수 있다. 즉, 일련의 연산들을 하나의 독립된 작업 단위로 보고 하나로 취급하기 위해서 사용하는 것이다. 언제 일련의 연산들을 하나로 봐야 할 때가 생길까? 예를 들어서 돈을 송금하는 시스템이 있다고 가정해보자. 계좌A에서 계좌B로 돈을 송금해야 할 때, 계좌A에 충분한 잔액이 있는 것을 확인하고 돈을 송금하기 위해서 돈을 차감했다. 그리고 계좌B에 입금을 하려고 하는 순간 예외가 발생하면서 입금을 하지 못했다. 그런데 계좌A에서는 여전히 돈이 차감된 상태이다. 중간에 송금하려고 했던 돈이 사라지게 된 것이다. 이때, 위의 과정을 로 관리를 하게 된다면 위의 여러 작업들을 하나의 단위로 보고 중간에 예외가 발생한다면 위에서 실행중이던 작업을 한꺼번에 롤백해준다. 트랜잭션 기본 방법 2개 이상의 쿼리를 하나의 커넥션으로 묶어 DB에 전송하고, 에러가 발생할 경우 자동으로 모든 과정…

May 10, 2021
스프링부트
데이터베이스
DIP 의존관계 역전의 원칙

스프링 강의 중 DAO vs. Repository의 차이점에 대해서 논의하다가 다음과 같은 표현이 나왔다. Repository의 추상 인터페이스는 Domain Layer에 속하며 Domain 객체들을 관리하고 생애주기를 같이한다. 그 구현체인 SimpleJpaRepository는 Infrastructure에 속한다. 추상화된 repository 인터페이스를 사용하면서 추상에 의존하고 구체에 의존하지 않도록 구성(DIP) 하여 유연성 있는 시스템을 구성한다. 여기서 나오는 DIP는 무엇이고 위와 같은 구성이 어떻게 우연성을 제공하는 걸까? DIP 요약 Dependency Inversion Principle의 약자이다. 본래 객체는 상위 계층이 하위 계층에 의존한다. DIP는 그 관계를 역전시켜서 상위 계층이 하위 계층의 구현에서 독립하도록 한다. 그러기 위한 원칙 두가지는 다음과 같다. 상위 모듈과 하위 모듈이 서로 의존하는 것이 아니라 모두 추상화에 의존한다. 추상화가 구현에 의존…

March 13, 2021
스프링
웹 Layers에 대해

데이터의 흐름 또는 코드가 책임지는 부분의 유사도에 따라서 계층별로 나누어서 대규모 웹 어플리케이션을 구현한다. 이때의 이점은 각 계층이 담당하고 있는 책임을 알 수 있기 때문에 대량의 코드에서도 필요한 부분을 찾아서 수정하기 다소 쉽다. 또한 구조적으로 정리되어 있는 이점이 있다. 웹 어플리케이션을 구현할 때 이러한 계층들에 대한 제대로 된 정의를 가지고 각자가 담당하는 기능을 구현하는 것이 좋다. 함께 일하는 동료 개발자나 이후에 레거시 코드로 받을 다른 개발자들과의 의사소통 비용을 크게 감소하고 쉽게 코드와 구조를 이해할 수 있기 때문이다. 총 5개의 계층이 있다. Presentation Layer 식당에서 역할 UI를 담당하는 계층이다. User에게 보여지는 화면 담당 User의 입력을 받는 담당 입력에 따른 결과를 서버로부터 받아서 다시 화면에 띄우는 담당 다른 계층과의 접촉이 없고 Control layer를 통해서 다른 계층과 협업한다. 따라서 presentatio…

March 05, 2021