개요
사실 이번 시간은 트러블 슈팅이라기 보다는 내 개인적인 의문으로 공부를 한 시간이라고 할 수 있다.
한창 TCP 멀티 서버를 구축하고 테스트해보던 중... 문득 이런 생각이 들었다.
현재 내가 만든 서버에 접속 가능한 클라이언트가 몇 명 정도 될까?
나의 궁금증이 해소되는 데에는 그리 오랜 시간이 필요하지 않았다. 왜냐...?
이미 미래시를 가지고 있는 튜터님께서 테스트를 해주셨거든... 대충 200명에서 250명 사이에서 서버가 터지는 걸 확인했다. 하지만 여기서 끝내면 그저 궁금증에 지나지 않는다. 만약 서버에 더 많은 유저가 접속을 시도했을 때, 어떻게 하면 부하를 줄이고 유저를 더 수용할 수 있는지 알아보자!!!
로드 밸런싱
물론 나는 이론적으로 이미 공부를 했었던 내용이다. 바로 로드 밸런싱!!!!! 서버 부하를 줄이기 위해 서버를 분산시키는 방법! 내가 아는 내용은 대충 이 정도... 따라서 이번 시간에는 이론에 그치지 않고 로드 밸런서를 구현해보는 시간을 가져보겠다!
로드 밸런서는 클라이언트 요청을 여러 서버로 자동 분배하여 서버의 부하를 줄이고 서비스 가용성을 높인다. 주로 사용되는 로드 밸런싱 방식은 라운드 로빈, 최소 연결 및 IP 해시 방식이 있다. 그리고 대표적인 로드 밸런서 종류로는 Nginx, HAProxy, AWS ELB (Elastic Load Balancer) 등이 존재하는데, 이번 시간에는 Nginx를 이용해 라운드 로빈 방식으로 서버를 분산해보자.
Nginx 설치 후 설정 파일(nginx.conf)을 열기.
http {
upstream backend_servers {
server 127.0.0.1:3000;
server 127.0.0.2:3000; // 예시
server 127.0.0.3:3000; // 예시
}
server {
listen 80;
location / {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
위 설정에서는 세 개의 백엔드 서버 (127.0.0.1, 127.0.0.2, 127.0.0.3)에 요청을 분배하는 기본 라운드 로빈 방식으로 동작한다. 만약 공부가 아닌, 제대로 구현해볼거면 ec2와 같은 사이트에서 서버를 여러 개 빌려서 진행해야겠죠?
nginx를 재시작.
sudo systemctl restart nginx
서버 클러스터링 설정.
서버 클러스터링은 여러 서버가 하나의 그룹처럼 작동하게 하여 부하를 분산하고 장애 조치(Failover)를 제공하는 기술로, 일반적으로 서버 클러스터링은 상태 공유와 장애 조치를 위해 세션 데이터를 공유해야 한다.
- Redis와 같은 메모리 캐시 서버를 사용하여 클러스터 내 서버들 간 세션 데이터를 공유할 수 있다.
- Consul이나 Etcd와 같은 분산 키-값 저장소를 사용하여 서버 상태 및 헬스 체크 정보를 관리할 수 있다.
Redis 설치 및 설정 과정을 거친 후, 미들웨어를 활용해 세션을 Redis에 저장한다.
import session from 'express-session';
import connectRedis from 'connect-redis';
import { createClient } from 'redis';
const RedisStore = connectRedis(session);
const redisClient = createClient({
host: 'localhost',
port: 6379
});
redisClient.on('error', (err) => console.error('Redis Client Error', err));
const sessionMiddleware = session({
store: new RedisStore({ client: redisClient }),
secret: 'secret_key',
resave: false,
saveUninitialized: false
});
export default sessionMiddleware;
이렇게 설정하면, 여러 서버가 Redis에 세션을 저장하고 이를 공유하여 클라이언트가 어느 서버로 이동하더라도 세션이 유지된다.
서버 상태 모니터링 및 오류 조치.
서버 간 상태 정보를 공유하고 장애 발생 시 이를 자동으로 감지하여 조치하려면, Consul이나 Etcd를 사용할 수 있다. 이를 통해 각 서버의 상태를 모니터링하고, 로드 밸런서가 비정상적인 서버로의 트래픽을 자동으로 차단하도록 할 수 있다.
Consul 설치 및 실행: 각 서버에 Consul을 설치하고, 서버 간에 통신할 수 있는 하나의 클러스터로 구성한다.
consul agent -server -bootstrap-expect=3 -node=server1 -bind=192.168.1.101 -data-dir=/tmp/consul
서버 상태 등록: 각 서버는 Consul의 헬스 체크 기능을 통해 자신이 정상적으로 동작하는지를 등록한다. 나는 localhost 서버에 헬스 체크를 등록했다.
{
"service": {
"name": "web",
"tags": ["primary"],
"port": 3000,
"check": {
"http": "http://localhost:3000/health",
"interval": "10s"
}
}
}
만약 비정상 상태로 판정된 서버가 감지된다면, Consul에서 해당 서버에 대해 자동으로 트래픽을 차단할 것이다. 서버가 장애 상태에 빠질 경우, 스크립트를 작성해 서버를 재시작하거나 대체 서버를 추가하는 방식으로 복구를 자동화할 수도 있다. AWS Lambda나 Kubernetes의 오토스케일링 기능을 이용하면 서버의 복구 및 스케일링을 자동화할 수 있을 것이다.
'Side Projects' 카테고리의 다른 글
redis cluster 사용해보기 (1) | 2024.11.27 |
---|---|
redis / ioredis 패키지 비교 (1) | 2024.11.18 |
ORM / Low-Level Query (0) | 2024.10.29 |
Protocol Buffers? (4) | 2024.10.24 |
Text-RPG(CLI) - 트러블슈팅 (1) | 2024.10.22 |