Spring과 동시 요청 처리

김민기·2021년 8월 11일
0

개요

나는 스프링에서 기본적으로 사용하는 Annotation(@Component, @Service, @Controller 등)을 통해 생성되는 빈들은 scope를 지정해주지 않으면 싱글톤(단 하나) 객체로 생성됨을 알고있다.
하지만 서버의 경우 여러 요청이 클라이언트로부터 오게되고 동일한 URI에 대한 요청은 하나의 Controller가 처리하게 된다.

-> 하나의 Controller는 어떻게 동시에 오는 요청을 처리하게 되는건가?
라는 의문이 들게 되어 이 글을 작성하게 되었다.

Spring boot와 내장 Tomcat

참조

먼저 스프링 부트는 서버가 아니다.
스프링 부트의 자동 설정에는 톰캣의 설정과 구동이 포함되어 있다.

TomcatServletWebServerFactory.java

public WebServer getWebServer(ServletContextInitializer... initializers) {
  ...

  Tomcat tomcat = new Tomcat();
  File baseDir = this.baseDirectory != null ? this.baseDirectory : this.createTempDir("tomcat");
  tomcat.setBaseDir(baseDir.getAbsolutePath());
  Connector connector = new Connector(this.protocol);
  connector.setThrowOnFailure(true);
  tomcat.getService().addConnector(connector);
  this.customizeConnector(connector);
  tomcat.setConnector(connector);
  tomcat.getHost().setAutoDeploy(false);
  ...

위와 같이 톰캣을 생성하고, 서블릿 및 디스패처 설정 등을 하는 코드가 있다.
즉, 자동 설정 안에 톰캣과 서블릿 등 웹 서버 기본 설정들이 포함되어 있다.

Spring boot Processing Concurrent Request

참조

Spring boot는 내장 톰캣을 가지고 있다.
그리고 톰캣은 동시 사용가능한 쓰레드를 지정하여 요청마다 쓰레드를 생성하여 처리하게 된다.
(maxThreads는 기본으로 200으로 되어있고 이는 설정을 통해 변경할 수 있다.)

=> 그렇기 때문에 동시에 여러 요청을 처리할 수 있게 된다.

그렇다면 싱글톤 객체에 여러 쓰레드가 동시에 접근하는 건가?
-> 그렇다.

톰캣에서 생성한 여러 쓰레드는 같은 인스턴스(빈, Bean)에 접근을 하게 되고, 우리가 생성한 Controller, Service, Component는 동시에 여러 쓰레드가 접근을 할 수 있도록 한다.

어찌보면 당연한 것이다.
우리가 정의했던 클래스들은 모두 동시에 접근이 가능하도록 우리는 정의를 한다.

@RestController
public class HelloController {

	@GettMapping("/hello")
    public ResponseEntity<String> hello() {
    	return ResponseEntity.ok("hello");
    }

}

동시에 접근 가능한 객체

그렇다면 동시에 접근이 가능한 객체들은 어떻게 정의를 해야하는가?
-> 상태를 갖지 말아야 한다.

Component, Service, Controller들은 상태를 기본적으로 갖지 않게 된다.
우리가 자주 사용하는 Repository는 DB에 접근을 하기 위한(실제로 Repository가 직접 접근하지는 않는다.) 클래스이지 상태를 갖지 않는다.

스프링에서 제공해주는 자동 주입을 하는 객체들 또한 우리는 상태를 갖도록 하지 않기 때문에 문제가 되지는 않는다.

결론

싱글톤 객체를 생성하고 여러 쓰레드가 이를 접근하는 것이 문제가 되는 것처럼 보일 수 있다.
하지만 우리가 사용하는 Controller, Service, Component들은 상태를 갖지 않으며, 상태를 갖도록 만들면 안된다.

profile
항상 질문하는 개발자 migni입니다!

0개의 댓글