# 질문과 답변

## Q. HAProxy

[https://d2.naver.com/helloworld/284659](https://d2.naver.com/helloworld/284659)\
[https://seokjun.kim/haproxy-and-nginx-load-balancing/](https://seokjun.kim/haproxy-and-nginx-load-balancing/)

* L4, L7 과 같은 하드웨어 로드밸런서를 대체하기 위한 오픈소스 소프트웨어
* 리버스 프록시로서 서버 앞단에서 클라이언트의 요청을 받아 로드밸런싱을 한다.
* HA는 High Availability의 약자로, 서버들의 health check가 가능하고, 한 서버에서 문제가 생기면 다른 서버로 요청을 넘겨줄 수 있다. (cf. Nginx에서는 유료 버전을 쓰지 않으면 불가능하다고...)

![image](https://user-images.githubusercontent.com/22112344/77309240-a497cb00-6d3f-11ea-91fa-33ad3b15da08.png)

#### 동작 원리

1. 클라이언트가 처음으로 요청한다. HAProxy는 어떤 서버를 골라서 이 요청을 보내준다.&#x20;
2. 서버는 응답을 내려줄 때 쿠키에 서버 정보를 같이 보내준다. 이 그림에서는 `SERVERID`가 들어갔다.
3. 클라이언트가 다시 요청한다. HAProxy는 클라이언트의 쿠키를 보고 쿠키에 있는 정보대로 서버를 골라 보내 준다.
4. 서버가 다시 응답할 때는 다시 쿠키를 설정하지 않아도 된다.

하드웨어 L4 앞에 HAProxy를 붙이는 등 확장해서 사용하는 것도 물론 가능하다고.

## Q. L4, L7 로드 밸런싱

#### L4 (Transport Layer) 스위치

* 프로토콜: TCP/UDP (OSI layer 3-4)
* `IP + 포트` 기반 로드 밸런싱

#### L7 (Application Layer) 스위치

* 프로토콜: TCP/UDP 및 HTTP, FTP, SMTP (OSI layer 3-7)
* `IP + 포트` 및 패킷 컨텐츠 내용 기반 로드 밸런싱

#### 차이점: 세션 유지 방식

> 내용 및 그림 출처: [https://medium.com/@pakss328/%EB%A1%9C%EB%93%9C%EB%B0%B8%EB%9F%B0%EC%84%9C%EB%9E%80-l4-l7-501fd904cf05](https://medium.com/@pakss328/%EB%A1%9C%EB%93%9C%EB%B0%B8%EB%9F%B0%EC%84%9C%EB%9E%80-l4-l7-501fd904cf05)

1. L4 ![image](https://user-images.githubusercontent.com/22112344/77550069-fda86000-6ef3-11ea-828a-abae6b7dd5f4.png) 클라이언트와 서버 사이에 세션을 만들고, L4 스위치는 중계한다.
2. L7 ![image](https://user-images.githubusercontent.com/22112344/77550180-1ca6f200-6ef4-11ea-94e5-2270a7679543.png) 클라이언트-스위치, 스위치-서버 간의 세션을 따로 만든다.

## Q. load balancing technique 비교

### http redirection

* HTTP redirection을 로드밸런싱으로 사용.

**defects**

* HTTP redirect 코드를 내려주기 위해서는 특정 서버로 가야 하는데, 가는 것 자체가 로드밸런싱이 필요한 일. redirecting server로 가는 게 로드밸런싱이 안되어 있다면 해당 서버는 굉장히 멀리 있을 수도 있으므로 비효율적.
* client 302를 받고 또 다른 서버로 요청을 보내야 하므로 한번의 요청에 2번의 RTT가 발생. 모든 요청이 2배의 시간이 드는 것.
* `X-Forwarded-For` 등으로 client IP address를 아는 방법이 있으므로, 장점이 크게 없다고 보인다.

### dns redirection

* 하나의 dns name에 여러개의 서버 IP address를 등록하여 DNS 서버가 해당 서버의 IP Address를 rotate 하며 요청마다 다른 IP address 를 resolve 해준다.

**defects**

* 한번 client가 특정 서버에 대하여 IP Address를 얻으면 높은 확률로 cache한다. 특히 애초에 os가 캐시할 수 있는데, 이 경우 특정 client에 대해서는 로드밸런싱이 적용되지 않음.
* 수많은 lookup이 발생할 경우, 해당 서버 IP Address에 대해 계속 rotate 하는 건 엄청난 computation power가 필요할 수도 있다.
* 동시에 여러개의 http request를 보내는 경우, 앞 요청에서 dns name resolution을 기다리거나, 요청마다 다른 IP Address를 할당받을 수 있는데, 그렇게되면 굉장히 비효율적, 불안정한 통신.

### anycast addressing

* number of hops, distance, lowest cost, latency measurements or based on the least congested route 등을 고려하여 가장 효율적인 path를 정하는 방식.
* 각 서버는 router communication protocol을 통해 근처 라우터에게 자신의 위치를 광고한다.
* experimental.

**defects**

* 서버가 근처 라우터를 알고, 특정 프로토콜을 이용해 광고해야 함. 구현 부담 증가.
* 같은 서버간 ip를 어떻게 같게 할까? 서버간 ip 구분이 안갈 경우 특정 서버로 일부러 보내고 싶어도 못보내고 backbone network에 의지할 수 밖에 없음.
* route leak 발생.

## Myunggeun's todo

### redirect loop

> 리디렉션이 너무 많이 일어나면 어떡함

#### client (browser, agent) side

* `ERR_TOO_MANY_REDIRECTS`, `The page isn’t redirecting properly`, ...
* 이 에러가 뜨는 조건?
* 안 뜨게 하는 방법?
  * 사이드 이펙트

#### server side

* 일정 이상의 리디렉션을 제어하는 여러가지 방법
