IPC(Inter Process Communication)

IPC는 프로세스 간 통신이라는 뜻으로 프로세스들 사이에 서로 데이터를 주고받는 행위 또는 방법이나 경로를 뜻한다.

 

프로세스는 독립적으로 실행되기 때문에 다른 프로세스에 영향을 받지 않는다.
반대로 스레드는 프로세스 안에서 자원을 공유하므로 영향을 받는다.

 

이런 상황에서 프로세스 간의 통신이 필요한 상황이 있을 것이다.
그런 경우에 이를 가능하게 해주는 것이 바로 IPC 통신이다.
프로세스는 커널이 제공하는 IPC 설비를 이용해 프로세스 간 통신을 할 수 있게 된다.

커널(Kernel)

운영 체제의 핵심적인 부분으로 운영 체제의 핵심 기능 및 자원 관리를 담당하며, 하드웨어와 응용 프로그램 간의 통신을 중재합니다. 대표적인 커널로 linux 커널, Window 커널, macOS 커널 등이 있다.

 

IPC에도 몇 가지 메커니즘이 존재하는데 이에 대해 알아보자.

  • 익명 파이프 (Unnamed Pipe) : 두 개의 프로세스를 연결하는 데 하나의 프로세스는 데이터를 쓰기만 하고, 다른 하나는 데이터를 읽기만 할 수 있다. 한쪽 방향으로만 통신이 가능한 반이중 통신이라고도 부른다.
  • 이름이 있는 파이프 (Named Pipe 또는 FIFO) : 통신할 프로세스를 명확히 알 수 있는 경우(ex) 부모 자식 프로세스 통신)에 사용한다. Named Pipe도 익명 파이프와 동일하게 단방향 통신 메커니즘을 갖고 있다.
  • 메시지 큐 (Message Queue) : 프로세스 간에 메시지를 비동기적으로 전달하는 데 사용된다. 메시지 큐를 통해 메시지를 보내고 받는 프로세스는 독립적으로 실행된다. 파이프와 다른 점은 데이터의 흐름이 아니라 메모리 공간이다.
  • 공유 메모리 (Shared Memory) : 데이터 자체를 공유하도록 지원하는 설비이다. 프로세스가 공유 메모리 할당을 커널에 요청하면, 커널은 해당 프로세스에 메모리 공간을 할당해 주고 이후 모든 프로세스는 해당 메모리 영역에 접근할 수 있게 된다. 중개자 없이 곧바로 메모리에 접근할 수 있어서 IPC 중에 가장 빠르게 작동한다.
  • 소켓 (Socket) : 네트워크 소켓 통신을 통해 데이터를 전송하는 데 사용되며 IPC의 확장된 형태이다. 클라이언트와 서버가 소켓을 통해서 통신하는 구조이다.

IPC는 다양한 운영 체제에서 지원되며, 프로세스 간 통신 및 협력을 허용하여 복잡한 응용 프로그램 및 시스템을 개발하는 데 중요한 역할을 한다.

이러한 IPC 통신에서 프로세스 간 데이터를 동기화하고 보호하기 위해 사용하는 게
세마포어(Semaphore) & 뮤텍스(Mutex)이다.
공유된 자원에 한 번에 하나의 프로세스만 접근시킬 때 사용한다.

 

임계 구역


세마포어와 뮤텍스를 이해하려면 임계 구역(Critical Section)을 알아야 한다.

임계 구역(Critical Section)은 다중 프로세스 또는 다중 스레드 환경에서 데이터를 공유하며 수행될 때, 각 프로세스에서 공유 데이터를 접근하는 프로그램 코드 부분이다. 다른 말로는 공유 변수 영역이라고 한다.


공유 데이터를 여러 프로세스가 동시에 접근할 때 잘못될 결과를 만들 수 있기 때문에 충돌을 방지하고 데이터 무결성을 유지하기 위한 메커니즘이다.

 

임계 구역은 다음과 같은 3가지 특성을 갖고 있다.

  1. 상호 배제(mutual exclusion) : 한 프로세스가 임계 구역에 들어가 있으면 다른 프로세스는 들어갈 수 없다.
  2. 한정 대기(bounded wating) : 프로세스가 자기의 임계구역에 진입하려는 요청을 한 후부터 그 요청이 허용될 때까지 다른 프로세스들이 그들 자신의 임계구역에 진입하도록 허용되는 횟수에 한계가 있어야 한다.
  3. 진행의 융통성(progress flexibility) : 자기의 임계구역에서 실행되는 프로세스가 없고 그들 자신의 임계구역으로 진입하려고 하는 프로세스들이 있다면, 나머지 구역에서 실행 중이지 않은 프로세스들만 다음에 누가 그 임계구역으로 진입할 수 있는지를 결정하는 데 참여할 수 있으며, 이 선택은 무한정 연기될 수 없다.

이러한 특성은 경쟁 조건(Race Condition)과 같은 문제를 방지하고 공유 자원을 안정할 수 있도록 한다.

경쟁 조건(Race Condition)은 두 프로세스가 서로 경쟁하여 데이터에 손상을 일으키는 경우를 말한다.

 

이러한 임계 구역을 만족하기 위해서 구현하는 방법들이 세마포어뮤텍스이다.

 

세마포어(Semaphore)

세마포어는 다중 프로세스 또는 다중 스레드 환경에서 동기화와 상호 배제를 관리하기 위한 동기화 도구 중 하나이다.

세마포어는 데이터나 자원에 대한 접근을 조절하는 데 사용된다.

세마포어 P, V 연산
P : 임계 구역 들어가기 전에 수행 ( 프로세스 진입 여부를 자원의 개수(S)를 통해 결정)
V : 임계 구역에서 나올 때 수행 ( 자원 반납 알림, 대기 중인 프로세스를 깨우는 신호 )

 

구현 예시

procedure P(S)   --> 최초 S값은 1임
    while S=0 do wait  --> S가 0면 1이 될때까지 기다려야 함
    S := S-1   --> S를 0로 만들어 다른 프로세스가 들어 오지 못하도록 함
end P

--- 임계 구역 ---

procedure V(S) --> 현재상태는 S가 0임
    S := S+1   --> S를 1로 원위치시켜 해제하는 과정
end V

이를 통해 한 프로세스가 P 혹은 V를 수행하고 있는 동안 프로세스가 인터럽트 당하지 않게 된다.

 

세마포어는 크게 두가지 유형으로 나뉜다.

  • 이진 세마포어 (Binary Semaphore): 값이 0 또는 1만 가질 수 있는 세마포어로, 주로 임계 구역의 이진 상태를 관리하는 데 사용됩니다. 이러한 이진 세마포어를 뮤텍스(Mutex)라고도 부른다.
  • 카운팅 세마포어 (Counting Semaphore): 값이 양수 또는 음수가 될 수 있는 세마포어로, 여러 프로세스나 스레드가 동시에 접근할 수 있는 자원의 수나 작업 허용량을 관리하는 데 사용된다.

세마포어를 사용하면 공유자원에 대한 안전한 접근을 조절하고, 다중 프로세스 또는 스레드 간의 동기화 문제를 해결할 수 있지만 올바르게 사용하려면 주의 깊은 설계와 구현이 필요하다.

 뮤텍스(Mutex)

뮤텍스는 mutual exclusion의 약자로 상호 배제라는 뜻이다. 임계 구역을 가진 스레드들의 실행 시간이 서로 겹치지 않고 단독으로 실행되게 하는 기술을 말한다.

 

해당 접근을 조율하기 위해 lock과 unlock을 사용한다

lock은 현재 임계 구역에 들어갈 권한을 얻어오며, unlock은 현재 임계 구역을 모두 사용했음을 알린다.

뮤텍스는 상태가 0,1로 이진 세마포어라고도 불린다.

 

뮤텍스는 일반적으로 단일 소유권을 가지며, 잠긴 상태에서 다른 스레드 또는 프로세스가 잠금을 얻을 수 없다. 이로써 공유 자원에 대한 동시 액세스를 방지할 수 있다.

 

뮤텍스는 다른 스레드가 뮤텍스를 이미 잠갔을 경우, 새로운 스레드는 뮤텍스가 해제될 때까지 대기한다. 이러한 특성을 통하여 경쟁 조건(Race Condition)을 방지하고 공유 자원의 일관성 유지에 도움을 준다.


lock과 unlock을 사용한 이진 세마포어 알고리즘 외에도 여러가지가 있다.

 

1. 데커 알고리즘 : flag와 turn이라는 변수로 임계 영역에 들어갈 프로세스나 스레드를 결정하는 방식이다.

flag는 프로세스 중 누가 임계 영역에 진입할 것인지를 나타내는 변수이며,
turn은 누가 임계 구역에 들어갈 차례인지 나타내는 변수이다.

while(true) {
    flag[i] = true; // 프로세스 i가 임계 구역 진입 시도
    while(flag[j]) { // 프로세스 j가 현재 임계 구역에 있는지 확인
        if(turn == j) { // j가 임계 구역 사용 중이면
            flag[i] = false; // 프로세스 i 진입 취소
            while(turn == j); // turn이 j에서 변경될 때까지 대기
            flag[i] = true; // j turn이 끝나면 다시 진입 시도
        }
    }
}

// ------- 임계 구역 ---------

turn = j; // 임계 구역 사용 끝나면 turn을 넘김
flag[i] = false; // flag 값을 false로 바꿔 임계 구역 사용 완료를 알림

2. 피터슨 알고리즘 : 데커와 유사하지만 상대방 프로세스,스레드에게 진입 기회를 양보하는 것에 차이가 있는 알고리즘

while(true) {
    flag[i] = true; // 프로세스 i가 임계 구역 진입 시도
    turn = j; // 다른 프로세스에게 진입 기회 양보
    while(flag[j] && turn == j) { // 다른 프로세스가 진입 시도하면 대기
    }
}

// ------- 임계 구역 ---------

flag[i] = false; // flag 값을 false로 바꿔 임계 구역 사용 완료를 알림

3. 제과점(Bakery) 알고리즘 : 여러 프로세스,스레드에 대한 처리가 가능한 알고리즘이다. 가장 작은 수의 변호표를 가지고 있는 프로세스가 임계 구역에 진입한다.

while(true) {
    
    isReady[i] = true; // 번호표 받을 준비
    number[i] = max(number[0~n-1]) + 1; // 현재 실행 중인 프로세스 중에 가장 큰 번호 배정 
    isReady[i] = false; // 번호표 수령 완료
    
    for(j = 0; j < n; j++) { // 모든 프로세스 번호표 비교
        while(isReady[j]); // 비교 프로세스가 번호표 받을 때까지 대기
        while(number[j] && number[j] < number[i] && j < i);
        
        // 프로세스 j가 번호표 가지고 있어야 함
        // 프로세스 j의 번호표 < 프로세스 i의 번호표
    }
}

// ------- 임계 구역 ---------

number[i] = 0; // 임계 구역 사용 종료

 

'Computer Science > Operating System(OS)' 카테고리의 다른 글

페이징 & 세그먼테이션  (0) 2023.09.05

본 내용은 해당 강의를 듣고 필요에 맞게 요약한 글입니다.

 

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8

 

스프링 핵심 원리 - 기본편 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., 스프링 핵심 원리를 이해하고, 성장하는 백엔드 개발자가 되어보세요! 📢

www.inflearn.com

 

스프링

객체 지향만으로는 OCP(개방 폐쇄 원칙), DIP(의존관계 역전 원칙)을 지킬 수 없다.

스프링은 앞에서 말한 다형성 + OCP(개방 폐쇄 원칙), DIP(의존관계 역전 원칙)을 가능하게 여러가지 기능을 제공한다.

  • Dependency Injection(의존관계 주입)
  • DI 컨테이너 제공
  • 클라이언트의 코드의 변경없이 기능 확장

먼저 간단한 예시 비즈니스 도메인을 만들었다.

역할과 구현, 책임을 잘 분리해서 설계하는 것이 중요하다.
유연하게 변경이 가능하도록 설계하는 것 또한 중요하다.

클래스 다이어그램은 클래스 간의 관계를 표현한 정적인 다이어그램이다.

 

객체 다이어그램은 실제 메모리가 할당되는 객체들의 관계를 정의한 동적인 다이어그램이다.

 

제어의 역전(IOC : Inversion of Control)

기존의 프로그램은 클라이언트 구현 객체가 스스로 필요한 서버 구현 객체를 생성하고, 연결하고 실행했다.
개발자가 원하는 대로 호출하고 생성하는 개념이 아닌 프레임워크가 내 코드를 대신 호출하여 제어권이 뒤바뀌는 것을 제어의 역전 이라고 한다. 다음 예시는 수동으로 빈을 등록하여 객체 인스턴스의 의존관계를 주입하는 예시이다.

@Configuration
public class AppConfig {
    @Bean
    public MemberService memberService(){
        return new MemberServiceImpl(memberRepository());
    }
    @Bean
    protected MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
    @Bean
    public OrderService orderService(){
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }
    @Bean
    protected DiscountPolicy discountPolicy() {
        return new RateDiscountPolicy();
    }

}

AppConfig는 프로그램에 제어 흐름 권한을 가져가며, 수동으로 빈을 등록한다. 
오더 서비스나 멤버 서비스는 어떠한 구현 객체가 생성되는지 전혀 알지 못한다.
이렇게 프로그램의 제어 흐름을 직접 제어하는 것이 아니라 외부에서 관리하는 것제어의 역전이라고 한다.

의존관계 주입 (DI : Dependency Injection)

위의 그림인 클래스 다이어그램을 보면 오더 서비스 구현 객체인 OrderServiceImpl은 할인 정책(Discount Policy) 인터페이스에 의존한다. OrderServiceImpl은 할인 정책에 어떤 구현 객체가 사용될지 모른다.
의존관계에는 정적인 클래스 의존 관계와 실행 시점에 결정되는 동적인 의존관계가 있다.

정적인 클래스 의존관계는 클래스가 사용되는 임포트 코드나 클래스 다이어그램만으로도 파악 가능하지만 실제 어떤 구현 객체가 주입될지는 알 수 없다.
동적인 객체 인스턴스 의존관계는 애플리케이션 실행 시점에 실제 생성된 객체의 인스턴스 참조가 연결된 의존 관계이다.

결론적으로 애플리케이션 실행 시점에 외부에서 실제 구현 객체를 생성하고, 클라이언트에 전달해서 클라이언트와 서버의 실제 의존관계가 연결되는 것을 의존관계 주입이라고 한다.

객체 인스턴스를 생성하고 그 참조값을 전달해서 연결된다. 의존관계 주입을 사용하면 정적인 클래스 의존관계를 변경하지 않고, 동적인 객체 인스턴스의 변경을 쉽게 할 수 있다.

그리고 스프링은 스프링 컨테이너로 이를 관리해준다.

 

스프링 컨테이너 ( DI 컨테이너 )

위의 예시인 AppConfig처럼 객체를 생성 및 관리하고 의존관계를 주입해주는 역할을 하는 것을  스프링 컨테이너 또는 DI 컨테이너라고 한다. 스프링 컨테이너는 AppConfig처럼 @Configuration이 붙은 컨피그 클래스를 설정 정보로 사용한다.

스프링 컨테이너를 만드는 방법

ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

ApplicationContext는 인터페이스이며, ApplicationContext를 스프링 컨테이너라고 한다.
스프링 컨테이너는 애노테이션으로 만들 수도 있고, XML 방식으로도 만들 수 있다.
AnnotationConfigApplicationContext는 ApplicationContext의 구현체이다.

스프링 컨테이너는 설정 정보를 참고해서, 의존관계를 주입한다. 위의 AppConfig를 보면 단순히 자바 코드를 호출하는 것 같지만 스프링 컨테이너는 기본적으로 싱글톤 방식으로 스프링 빈을 등록한다.

 

스프링 컨테이너에서 스프링 빈을 조회하는 방법

getBean(빈이름, 타입)을 활용하여 조회하면 된다. 다음은 멤버 서비스 빈을 조회하는 예시이다.

MemberService memberService = ac.getBean("memberService",MemberService.class);

타입이 둘 이상이면 다음과 같은 방식으로 조회 가능하다.

Map<String, MemberRepository> beansOfType = ac.getBeansOfType(MemberRepository.class);

스프링 빈을 조회 시, 부모 타입으로 조회하면 자식 타입도 함께 조회한다. 만약 부모의 자식이 둘 이상이면NoUniqueBeanDefinitionException이 발생하므로 빈 이름을 지정해주어야한다.

 

BeanFactory와 ApplicationContext

BeanFactory는 스프링 컨테이너의 최상위 인터페이스로, 스프링 빈을 관리하고 조회하는 역할을 한다.
ApplicationContext는 BeanFactory의 기능을 모두 상속받아서 제공하며,추가로 여러가지 부가 기능을 제공한다.

  • 메시지소스를 이용한 국제화 기능
    - 예를 들면 한국에서 들어오면 한국어로, 영어권에서 들어오면 영어로 출력하는 기능
  • 환경 변수
    - 로컬, 운영, 개발 등을 구분해서 처리
  • 애플리케이션 이벤트
    - 이벤트를 발행하고 구독하는 모델을 편리하게 지원
  • 편리한 리소스 조회
    - 파일, 클래스패스, 외부 등에서 리소스를 편리하게 조회

정리하면 ApplicationContext는 BeanFactory의 기능을 상속받아 사용하며, 빈 관리 기능 외에도 추가적인 기능을 제공한다.
BeanFactory나 ApplicationContext을 스프링 컨테이너라고 한다.
ApplicationContext는 또한 애노테이션, xml, Groovy 등 다양한 설정 정보를 지원하게끔 구현 객체를 가지고 있다.

 

스프링 빈 설정 메타정보

스프링이 이렇게 다양한 설정 정보를 지원할 수 있는 이유는 BeanDefinition이라는 추상화 덕분이다.

 

BeanDefinition을 빈 설정 메타정보라고 하며, 스프링 컨테이너는 이 메타정보를 기반으로 스프링 빈을 생성한다.
@Bean 애노테이션 하나에 각각 하나씩 메타 정보가 생성된다.

더 자세히 들어가자면
1. AnnotationConfigApplicationContext AnnotatedBeanDefinitionReader 사용해서 AppConfig.class 읽고 BeanDefinition 생성한다.

2. GenericXmlApplicationContext는 XmlBeanDefinitionReader를 사용해서 appConfig.xml 설정 정보를 읽고 BeanDefinition 생성한다.

3.새로운 형식의 설정 정보가 추가되면, XxxBeanDefinitionReader 만들어서 BeanDefinition 생성하면 된다. 

BeanDefinition의 정보

  • BeanClassName: 생성할 빈의 클래스 명(자바 설정 처럼 팩토리 역할의 빈을 사용하면 없음)
  • factoryBeanName: 팩토리 역할의 빈을 사용할 경우 이름, 예) appConfig
  • factoryMethodName: 빈을 생성할 팩토리 메서드 지정, 예) memberService
  • Scope: 싱글톤(기본값)
  • lazyInit: 스프링 컨테이너를 생성할 때 빈을 생성하는 것이 아니라, 실제 빈을 사용할 때 까지 최대한 생성을 지연 처리 하는지 여부
  • InitMethodName: 빈을 생성하고, 의존관계를 적용한 뒤에 호출되는 초기화 메서드 명
  • DestroyMethodName: 빈의 생명주기가 끝나서 제거하기 직전에 호출되는 메서드 명
  • Constructor arguments, Properties: 의존관계 주입에서 사용한다. (자바 설정 처럼 팩토리 역할의 빈을 사용하면 없음) 

 

 

프레임워크 VS 라이브러리

프레임워크가 내가 작성한 코드를 제어하고, 대신 실행하면 그것은 프레임워크이다.
ex) 자바 테스트로 활용하는 Junit이 대표적인 예시이다. 나는 테스트 코드만 짤뿐 실제 실행이 어떤 프로세스로 흘러가는 지 알 수 없다.

 

반면에, 내가 작성한 코드가 직접 제어의 흐름을 담당한다면 그것은 라이브러리이다.

 

 

'Back-End > Spring' 카테고리의 다른 글

빈 생명주기 콜백  (0) 2023.09.08
컴포넌트 스캔  (0) 2023.09.08
싱글톤 패턴과 싱글톤 컨테이너  (0) 2023.09.08
스프링 핵심 원리 요약 - 1  (0) 2023.08.20
스프링 입문 요약  (0) 2023.08.14

로드 밸런싱

로드 밸런싱(Load Balancing)은 네트워크나 서버 시스템에서 발생하는 트래픽을 여러 대의 서버나 자원 사이에 균등하게 분산시켜 주는 기술이다. 이를 통해 각 서버나 자원에 가중치가 일정하게 분산되어 작업 부하를 균형 있게 분담할 수 있다.

 

로드 밸런싱의 장점

로드 밸런싱은 애플리케이션 서버와 방문자 또는 클라이언트 간의 인터넷 트래픽을 지시하고 제어한다.
결과적으로 애플리케이션의 가용성, 확장성, 보안성능이 향상된다.

1. 애플리케이션 가용성

서버 장애 또는 유지 관리로 인해 애플리케이션 가동 중지 시간이 늘어 방문자가 애플리케이션을 사용할 수 없게 될 수도 있다. 로드 밸런서는 서버 문제를 자동으로 감지하고 클라이언트 트래픽을 사용 가능한 서버로 리디렉션 하여 시스템의 내결함성을 높인다.
로드 밸런싱을 사용하면 이런 문제를 방지할 수 있고, 애플리케이션의 가동 중지 없이 애플리케이션 서버 유지 관리 또는 업그레이드를 실행할 수 있다.

2. 애플리케이션 확장성

로드 밸런서를 사용하여 여러 서버 간에 네트워크 트래픽을 지능적으로 전달할 수 있다.
로드 밸런싱은 한 서버의 트래픽 병목 현상을 방지하고, 필요한 경우 다른 서버를 추가하거나 제거할 수 있도록 애플리케이션 트래픽을 예측한다. 다음과 같은 특성을 활용하면 수천 개의 클라이언트 요청을 처리할 수 있다.

3. 애플리케이션 보안

로드 밸런서에는 인터넷 애플리케이션에 또 다른 보안 계층을 추가할 수 있는 보안 기능이 내장되어 있다. 이는 공격자가 서버 장애를 일으키는 수백만 개의 동시 요청으로 애플리케이션 서버를 가득 채우는 분산 서비스 거부 공격을 처리하는 데 유용한 도구이다. 또한 트래픽을 모니터링하고, 악성 콘텐츠를 차단하며, 공격 트래픽을 여러 백엔드 서버로 자동으로 리디렉션 하여 영향을 최소화한다. 추가 보안을 위해 네트워크 방화벽 그룹을 통해 트래픽을 라우팅 한다.

4. 애플리케이션 성능

로드 밸런서는 응답 시간을 늘리고 네트워크 지연 시간을 줄여 애플리케이션 성능이 향상된다.
서버 간의 로드를 균등하게 배포하여 애플리케이션 성능을 향상하고, 클라이언트 요청을 지리적으로 더 가까운 서버로 리디렉션 하여 지연 시간을 단축시킬 수도 있다. 물리적 및 가상 컴퓨팅 리소스의 신뢰성과 성능을 보장한다.

 

이러한 장점들은 현대 애플리케이션이 갖춰야 할 속성을 정의한 리액티브 선언과도 굉장히 잘 맞다고 느낀다.

리액티브 선언은 현대의 소프트웨어 시스템의 아키텍처 및 설계 원칙에 관한 문서로, 2014년 Jonas Bonér, Dave Farley, Roland Kuhn 등 여러  소프트웨어 개발자 및 아키텍트들이 공동으로 작성한 선언문으로 4가지 특성을 강조한다.

  • 응답성(Responsive) : 사용자에게 신뢰성 있는 응답을 빠르고 적절하게 제공하는 것
  • 탄력성(Resilient) : 장애가 발생하거나 부분적으로 고장 나더라도 시스템 전체가 고장 나지 않고 빠르게 복구하는 능력
  • 유연성(Elastic) : 시스템의 사용량에 변화가 있더라도 균일한 응답성을 제공하는 것 (시스템의 사용량에 비례해서 자원을 늘리거나 줄이는 능력)
  • 메시지 기반(Message Driven) : 비동기 메시지 전달을 통해 위치 투명성, 느슨한 결합, 논블로킹 통신을 지향하는 것

로드 밸런싱은 이러한 특성을 지키기 위한 중요한 기술 중 하나로 볼 수 있다.

 

로드 밸런싱 알고리즘

  • 라운드 로빈 로드 밸런싱(Round Robin Load Balancing)
    이 유형은 들어오는 요청을 순서대로 각 서버에 번갈아가며 분배한다. 각 서버는 동등한 부하를 갖게 되지만, 서버 간의 성능 차이나 부하 상태를 고려하지 않는다.
  • 최소 연결 수 로드 밸런싱(Least Connections Load Balancing)
    연결 수가 가장 적은 서버에 새로운 요청을 보내는 방식입니다. 현재 연결 수가 적은 서버에 부하를 분산시켜 성능을 최적화할 수 있다.
  • IP 해시 로드 밸런싱(IP Hash Load Balancing)
    클라이언트의 IP 주소를 해시하여 특정 서버에 할당하는 방식이다. 동일한 IP 주소는 항상 같은 서버로 연결되므로 세션 유지를 위한 경우에 유용하다.
  • 가중치 순환 로드 밸런싱(Weighted Round Robin Load Balancing)
    서버마다 가중치를 할당하여 부하를 분산시키는 방식이다. 가중치가 높은 서버일수록 더 많은 요청을 처리하게 된다.
  • 가중치 최소 연결 수 로드 밸런싱(Weighted Least Connections Load Balancing)
    연결 수에 가중치를 적용하여 연결 수가 적은 서버에 부하를 분산시키는 방식이다.
  • 세션 유지(스티키 세션) 로드 밸런싱(Session Persistence (Sticky Session) Load Balancing)
    특정 클라이언트의 요청을 항상 같은 서버로 보내는 방식으로, 클라이언트의 세션 정보나 쿠키를 기반으로 연결을 유지한다.
  • 콘텐츠 기반 로드 밸런싱(Content-Aware Load Balancing)
    요청의 내용이나 URL을 분석하여 특정 서버로 보내는 방식이다. 특정 URL 패턴에 따라 다른 서버로 요청을 전달할 수 있다.
  • 글로벌 서버 로드 밸런싱(Global Server Load Balancing (GSLB))
    여러 데이터 센터나 지역에 분산된 서버 사이의 부하를 조절하고, 사용 가능한 데이터 센터로 요청을 보내는 방식이다.

로드밸런싱 기술 유형

1. 하드웨어 로드 밸런서

하드웨어 로드 밸런서는 전용 하드웨어 장비로, 네트워크 트래픽을 관리하고 분산시키는 역할을 한다.
주로 대규모의 데이터 센터나 기업 환경에서 사용된다.

 

장점

  • 고성능: 전용 하드웨어를 사용하므로 대량의 트래픽을 효율적으로 처리할 수 있다.
  • 안정성: 하드웨어 장비는 특화된 운영체제를 사용하며, 높은 가용성과 안정성을 제공합니다.
  • 확장성: 대규모 환경에서 서버를 추가할 때도 높은 성능을 유지할 수 있습니다.

단점

  • 비용: 하드웨어 로드 밸런서는 전용 장비를 필요로 하며, 비용이 상대적으로 높을 수 있다.
  • 유지보수: 하드웨어 장비의 유지보수 및 업그레이드가 복잡할 수 있다.

2. 소프트웨어 로드 밸런서

소프트웨어 로드 밸런서는 서버 내에서 소프트웨어로 구현된 로드 밸런싱 기능을 사용하는 방식이다.
가상 머신, 컨테이너, 클라우드 환경 등에서 사용된다.

 

장점

  • 비용 효율성: 추가적인 하드웨어 장비 없이 소프트웨어로 구현되므로 비용이 낮을 수 있다.
  • 유연성: 가상 환경에서 쉽게 배포되며, 클라우드 기반 환경에서도 운영될 수 있다.
  • 관리 용이성: 소프트웨어 업데이트와 유지보수가 상대적으로 간단할 수 있다.

단점

  • 성능 한계: 고성능 요구사항을 처리하기 어려울 수 있으며 하드웨어 로드 밸런서보다 성능이 낮을 수 있다.
  • 가용성 : 소프트웨어 로드 밸런서 자체의 가용성에 의존하므로, 단일 서버 장애 시 문제가 발생할 수 있다.

요약하자면 하드웨어 로드 밸런서는 대규모 환경에서 안정적인 성능을 추구할 때 적절하며, 소프트웨어 로드 밸런서는 상대적으로 훨씬 유연하며, 클라우드 컴퓨팅 환경과 호환이 잘되는 장점이 있다.

 

참조(Reference)

https://aws.amazon.com/ko/what-is/load-balancing/

 

로드 밸런싱이란 무엇인가요? - 로드 밸런싱 알고리즘 설명 - AWS

로드 밸런싱은 애플리케이션을 지원하는 리소스 풀 전체에 네트워크 트래픽을 균등하게 배포하는 방법입니다. 최신 애플리케이션은 수백만 명의 사용자를 동시에 처리하고 정확한 텍스트, 비

aws.amazon.com

 

'Computer Science > Network' 카테고리의 다른 글

HTTP의 특징  (0) 2023.09.19
URI 와 웹 브라우저 요청 흐름  (0) 2023.09.19
HTTP 웹 기본 지식  (2) 2023.09.18
SSL/TLS HandShake  (0) 2023.08.29
HTTP와 HTTPS  (0) 2023.08.28


SSL/TLS 핸드셰이크는 데이터를 보호하기 위해 정보를 암호화하고 해독하는 과정을 포함하고 있다.
아래의 단계를 통해 핸드셰이크 과정을 거친다.

  1. 클라이언트 시작 (Client Hello): 클라이언트가 서버에 접속할 때, 클라이언트는 서버에게 자신이 지원하는 암호화 방법들을 말하면서 "안녕하세요!"라고 인사를 한다.. 이때 클라이언트는 랜덤한 데이터를 생성한다.
  2. 서버 응답 (Server Hello): 서버는 클라이언트의 메세지를 받으면서, 클라이언트가 지원하는 암호화 방법 중 하나를 선택하고, 서버 자신도 사용할 랜덤한 데이터를 생성하여 "안녕하세요!"라고 응답한다.
    이때 서버는 디지털 인증서를 함께 보낸다. 이 인증서는 서버의 신원을 확인하는 데 사용된다.
  3. 클라이언트 인증서 확인 (Client Certificate): 클라이언트는 서버로부터 받은 디지털 인증서를 확인하고, 클라이언트 자신의 디지털 인증서를 서버로 보내어 자신의 신원을 확인시킨다. 이 단계는 선택적일 수도 있다.
  4. 사전 마스터 시크릿 생성 (Pre-Master Secret): 클라이언트는 두 개의 랜덤한 데이터와 미리 정해진 규칙에 따라 '사전 마스터 시크릿'을 만든다. 마스터 시크릿은 데이터 암호화에 사용되는 중요한 열쇠 같은 역할을 한다.. 클라이언트는 이 사전 마스터 시크릿을 서버의 공개키로 암호화해서 서버에게 보낸다.
  5. 서버에서 마스터 시크릿 생성: 클라이언트가 생성한 사전 마스터 시크릿과 서버가 생성한 사전 마스터 시크릿을 조합하여 '마스터 시크릿(대칭키)'을 만든다. 이 키는 데이터의 대칭키 암호화에 사용된다.
  6. 세션 키 생성 (Session Keys): 클라이언트와 서버는 각각 자신의 랜덤한 데이터와 마스터 시크릿을 기반으로 '세션 키'들을 생성한다. 이 세션 키들은 데이터를 암호화하고 복호화하는 데 사용된다.
  7. 암호화된 연결 확립 (Establishing Encrypted Connection): 클라이언트와 서버는 핸드셰이크가 완료되었음을 서로에게 알리고, 이제부터는 실제 데이터를 주고받을 때 세션 키를 사용하여 데이터를 암호화하고 해독하여 안전한 연결을 유지한다.

이렇게 SSL/TLS 핸드셰이크는 대칭키와 공개키 암호화 기술을 조합하여 안전한 통신을 구축하는 과정이다.
대칭키는 데이터의 빠른 암호화와 복호화를 담당하고, 공개키는 서버의 신원을 확인하고 키 교환을 안전하게 수행한다.

 

사진 출처
https://aws-hyoh.tistory.com/39

 

HTTPS 통신과정 쉽게 이해하기 #3(SSL Handshake, 협상)

고대 그리스에서는 타인에게 노출되어서는 안 될 중요한 정보를 보낼 때, 전달하는 이(사자)의 머리를 빡빡 깎아서 중요한 정보를 적은 후 머리가 자라서 글이 보이지 않으면 그제야 상대방에게

aws-hyoh.tistory.com

해당 블로그에 설명도 잘 돼있어서 참고하면 좋을 것으로 보인다.

'Computer Science > Network' 카테고리의 다른 글

HTTP의 특징  (0) 2023.09.19
URI 와 웹 브라우저 요청 흐름  (0) 2023.09.19
HTTP 웹 기본 지식  (2) 2023.09.18
로드 밸런싱(Load Balancing)  (0) 2023.08.29
HTTP와 HTTPS  (0) 2023.08.28

+ Recent posts