
로드 밸런싱(Load Balancing)은 들어오는 네트워크 트래픽이나 작업 부하를 여러 서버 또는 인스턴스에 분배하여 단일 서버에 과부하가 걸리지 않도록 하는 기술입니다.
이를 통해 애플리케이션의 가용성(Availability), 신뢰성(Reliability), 반응성(Response Time)을 유지할 수 있습니다.
예를 들어, 쇼핑몰 사이트에서 블랙 프라이데이 세일이 시작되면 트래픽이 급증하는데, 이때 로드 밸런싱 없이 하나의 서버만 사용한다면 과부하로 인해 서비스가 중단될 가능성이 높습니다.
하지만 여러 서버에 부하를 나누면 서비스가 안정적으로 유지됩니다.
로드 밸런싱 방식은 크게 다음과 같이 나뉩니다.
이번 포스팅에서는 소프트웨어 기반 로드 밸런싱을 스프링 부트를 이용해 직접 구현해보겠습니다.
@SpringBootApplication
@RestController
public class ThirdPartyApplication {
@Value("${server.port}")
private int port;
@GetMapping("/test")
public String test() {
return "Response from port: " + port;
}
public static void main(String[] args) {
SpringApplication.run(ThirdPartyApplication.class, args);
}
}
server.port=8081
이 애플리케이션을 포트 8081, 8082, 8083에서 각각 실행하려면 VM 옵션을 설정하면 됩니다.
-Dserver.port=8081
-Dserver.port=8082
-Dserver.port=8083
@SpringBootApplication
@RestController
public class MainApplication {
private final List<String> serverList = Arrays.asList(
"http://localhost:8081/test",
"http://localhost:8082/test",
"http://localhost:8083/test"
);
private AtomicInteger currentIndex = new AtomicInteger(0);
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Autowired
private RestTemplate restTemplate;
@GetMapping("/load-balance")
public String loadBalance() {
int index = currentIndex.getAndIncrement() % serverList.size();
String serverUrl = serverList.get(index);
return restTemplate.getForObject(serverUrl, String.class);
}
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
server.port=8080
curl http://localhost:8080/load-balance
스프링 부트를 이용한 간단한 로드 밸런싱을 구현해보았습니다.
더 복잡한 환경에서는 Spring Cloud LoadBalancer, Spring Cloud Gateway, Netflix Ribbon 등을 활용할 수도 있습니다.
클라우드 환경에서는 AWS, GCP, Azure의 로드 밸런싱 서비스를 활용하면 더욱 효율적인 로드 밸런싱이 가능합니다.
Spring Cloud LoadBalancer 공식 문서
Spring Cloud Gateway 공식 문서
Netflix Ribbon 깃허브
AWS Elastic Load Balancing
백엔드 아키텍처 패턴 - 마틴 파울러 블로그