접속자 대기열 시스템 #5- Redis를 이용한 대기열 관리 및 웹페이지 진입 API 구현

2024. 10. 10. 16:30·프레임워크/자바 스프링

이번 포스팅에서는 사용자 접속 대기열 시스템을 구축하기 위한 API 구현을 다룹니다. 목표는 사용자들이 웹페이지에 진입할 수 있는지 여부를 확인하고, 대기열 관리 로직을 통해 접속을 허용하거나 대기시킵니다. 이를 위해 Redis의 SortedSet 데이터 타입을 활용하여 사용자 대기열을 관리하고, 접속이 허용된 사용자들은 허용 목록에 추가합니다.

1. 대기열 관리 로직 설계

  • 대기열 등록: 사용자가 접속 대기열에 등록될 때, Redis의 SortedSet에 userId를 Unix 타임스탬프와 함께 추가합니다.
  • 접속 허용: 일정한 수의 사용자가 대기열에서 제거되며, 이 사용자는 접속이 허용된 목록에 추가됩니다.
  • 접속 가능 여부 확인: 사용자가 접속이 허용된 상태인지 확인하고, 대기열에서 진입이 허용된 경우에는 대기열에서 제거합니다.

2. UserQueueService 구현

UserQueueService는 Redis의 SortedSet 데이터 구조를 이용해 사용자 대기열을 관리합니다. 이 서비스 클래스는 사용자를 대기열에 등록하거나 허용된 사용자 목록에 추가하고, 사용자가 접속 가능한지 여부를 확인하는 등의 기능을 제공합니다. 주요 메서드들을 하나씩 살펴보겠습니다.

allowUser

public Mono<Long> allowUser(final String queue, final Long count) {
    // 진입을 허용하는 단계
    return reactiveRedisTemplate.opsForZSet()
            .popMin(USER_QUEUE_WAIT_KEY.formatted(queue), count) // 대기열에서 우선 순위가 가장 낮은 count개의 사용자 제거
            .flatMap(member -> reactiveRedisTemplate.opsForZSet()
                    .add(USER_QUEUE_PROCEED_KEY.formatted(queue), member.getValue(), Instant.now().getEpochSecond())) // 제거된 사용자를 허용 목록에 추가
            .count(); // 허용된 사용자 수 반환
}

1. reactiveRedisTemplate.opsForZSet().popMin(USER_QUEUE_WAIT_KEY.formatted(queue), count):

  • Redis의 SortedSet에서 대기열의 사용자 데이터를 제거합니다.
  • 대기열에서 count개의 요소를 우선순위가 낮은 순서대로 제거하며, 가장 오래된 사용자들이 우선적으로 제거됩니다.
  • 제거된 데이터는 member로 전달되며, 이 데이터는 사용자 ID와 등록 시점의 타임스탬프입니다.

2. flatMap(member -> reactiveRedisTemplate.opsForZSet().add(USER_QUEUE_PROCEED_KEY.formatted(queue), member.getValue(), Instant.now().getEpochSecond())):

  • 제거된 사용자는 USER_QUEUE_PROCEED_KEY에 해당하는 허용된 사용자 목록에 추가됩니다.
  • member.getValue()는 사용자의 ID를 나타내며, 이를 SortedSet의 키로 사용합니다.
  • 현재 시각의 Unix 타임스탬프를 score로 저장하여 허용된 시점을 기록합니다.

3. count():

  • 이 메서드는 허용된 사용자 수를 반환합니다. 만약 count개를 허용하려 했지만 실제로는 그보다 적은 수의 사용자가 대기열에 있었다면, 해당 숫자만큼 반환됩니다.

isAllowed

public Mono<Boolean> isAllowed(final String queue, final Long userId) {
    return reactiveRedisTemplate.opsForZSet().rank(USER_QUEUE_PROCEED_KEY.formatted(queue), userId.toString())
            .defaultIfEmpty(-1L)
            .map(rank -> rank >= 0); // 허용 목록에 있는지 여부를 Boolean으로 반환
}

1. reactiveRedisTemplate.opsForZSet().rank(USER_QUEUE_PROCEED_KEY.formatted(queue), userId.toString()):

  • 허용된 사용자 목록 (USER_QUEUE_PROCEED_KEY)에서 주어진 userId의 순위를 조회합니다.
  • 사용자가 허용 목록에 있을 경우, 해당 사용자의 순위를 반환합니다.

2. defaultIfEmpty(-1L):

  • 사용자가 허용 목록에 없을 경우, 반환 값이 비어있게 됩니다. 이를 -1L로 대체하여 처리합니다.

3. map(rank -> rank >= 0):

  • 사용자가 허용 목록에 존재할 경우 순위는 0 이상의 값이 됩니다.
  • 이를 기반으로 접속 가능 여부를 Boolean 값으로 반환합니다. true라면 허용된 사용자, false라면 아직 허용되지 않은 사용자임을 나타냅니다.

이러한 로직을 통해, allowUser 메서드는 대기열에서 지정된 수의 사용자를 허용 목록에 추가하며, isAllowed 메서드는 특정 사용자가 현재 접속 가능한 상태인지 판단할 수 있게 합니다.

3. UserQueueController 구현

UserQueueController는 UserQueueService를 사용하여 REST API를 제공합니다. 이 컨트롤러는 사용자 등록, 사용자 허용, 그리고 접속 허용 여부를 확인하는 API를 정의합니다. 각 API의 동작을 구체적으로 살펴보겠습니다.

3.1 사용자 허용 API

@PostMapping("/allow")
public Mono<AllowUserResponse> allowUser(
        @RequestParam(name = "queue", defaultValue = "default") String queueNm,
        @RequestParam(name = "count") Long count
) {
    return userQueueService.allowUser(queueNm, count)
            .map(allowed -> new AllowUserResponse(count, allowed));
}

1. 기능 설명:

  • 이 API는 대기열에서 특정 수의 사용자를 허용 목록에 추가합니다.
  • 지정된 수만큼의 사용자들이 대기열에서 제거되며, 이후 허용된 사용자 목록에 추가됩니다.

2. 매개변수:

  • @RequestParam(name = "queue", defaultValue = "default") String queueNm: 허용할 사용자가 대기 중인 대기열의 이름입니다. 기본값은 "default"입니다.
  • @RequestParam(name = "count") Long count: 허용할 사용자의 수입니다. 대기열에 등록된 사용자가 요청된 수보다 적을 경우, 허용 가능한 최대 수만큼 허용됩니다.

3. 작동 방식:

  • userQueueService.allowUser(queueNm, count): UserQueueService의 allowUser 메서드를 호출하여 지정된 수만큼의 사용자를 대기열에서 허용 목록으로 이동시킵니다.
  • .map(allowed -> new AllowUserResponse(count, allowed)): 요청된 허용 수와 실제로 허용된 수를 기반으로 AllowUserResponse 객체를 생성하여 클라이언트에 응답합니다.

3.2 접속 허용 여부 확인 API

@GetMapping("/allowed")
public Mono<AllowedUserResponse> isAllowedUser(
        @RequestParam(name = "queue", defaultValue = "default") String queueNm,
        @RequestParam(name = "user_id") Long userId
) {
    return userQueueService.isAllowed(queueNm, userId)
            .map(AllowedUserResponse::new);
}

1. 기능 설명:

  • 이 API는 특정 사용자가 접속 가능한 상태인지 여부를 확인합니다.
  • 사용자가 허용된 사용자 목록에 존재하는지를 검사하여 접속 여부를 반환합니다.

2. 매개변수:

  • @RequestParam(name = "queue", defaultValue = "default") String queueNm: 사용자가 접속 허용 여부를 확인할 대기열의 이름입니다. 기본값은 "default"입니다.
  • @RequestParam(name = "user_id") Long userId: 접속 허용 여부를 확인할 사용자의 ID입니다.

3. 작동 방식:

  • userQueueService.isAllowed(queueNm, userId): UserQueueService의 isAllowed 메서드를 호출하여 사용자가 허용 목록에 있는지를 검사합니다.
  • .map(AllowedUserResponse::new): 허용 여부를 기반으로 AllowedUserResponse 객체를 생성하여 클라이언트에 응답합니다.

이러한 방식으로 UserQueueController는 사용자 등록, 허용, 그리고 접속 허용 여부를 확인하는 API를 제공하며, 이를 통해 대기열 시스템을 관리할 수 있습니다.

3.3 QnA

Q1. allowUser API는 어떤 경우에 사용되나요?

A1. allowUser API는 대기열에서 사용자를 차례대로 허용할 때 사용됩니다. 예를 들어, 웹사이트에서 많은 사용자가 한꺼번에 접속하는 경우, 제한된 수의 사용자만 서버에 접속할 수 있도록 대기열을 구성하고, 순차적으로 접속을 허용할 수 있습니다. 이 API는 대기열에서 사용자를 허용 목록으로 이동시켜 실제 접속을 가능하게 합니다.

Q2. allowUser API에서 count 매개변수가 어떤 역할을 하나요?

A2. count 매개변수는 허용할 사용자의 수를 나타냅니다. 대기열에 있는 사용자 중에서 count 개수만큼 허용 목록으로 이동시키며, 만약 대기열에 등록된 사용자가 count보다 적다면 허용 가능한 최대 수만큼만 이동됩니다. 이를 통해 요청된 수만큼의 사용자를 허용할 수 있습니다.

Q3. isAllowedUser API는 언제 사용하나요?

A3. isAllowedUser API는 특정 사용자가 접속이 허용된 상태인지 확인할 때 사용합니다. 예를 들어, 사용자가 웹페이지에 접속을 시도할 때 해당 사용자가 대기열을 통과했는지, 즉 허용된 사용자 목록에 포함되어 있는지를 이 API를 통해 검사할 수 있습니다.

Q4. allowUser와 isAllowedUser API의 차이점은 무엇인가요?

A4. allowUser API는 대기열에서 사용자를 허용 목록으로 이동시키는 역할을 합니다. 반면, isAllowedUser API는 특정 사용자가 이미 허용된 상태인지 확인하는 역할을 합니다. 즉, allowUser는 사용자를 허용하도록 상태를 변경하는 작업을 수행하고, isAllowedUser는 사용자가 이미 허용된 상태인지 여부를 단순히 확인하는 데 사용됩니다.

Q5. AllowUserResponse와 AllowedUserResponse는 어떻게 다르나요?

A5. AllowUserResponse는 허용 요청 시 요청된 허용 수(count)와 실제로 허용된 수(allowed)를 포함하는 응답 객체입니다. 반면, AllowedUserResponse는 특정 사용자의 접속이 허용되었는지(Boolean allowed)를 나타내는 응답 객체입니다. 두 클래스는 서로 다른 역할을 수행하며, 하나는 허용 작업에 대한 결과를 반환하고, 다른 하나는 허용 상태를 검사한 결과를 반환합니다.

Q6. queue 매개변수의 기본값이 "default"인 이유는 무엇인가요?

A6. queue 매개변수의 기본값을 "default"로 설정하면, 별도로 대기열 이름을 지정하지 않은 경우에도 기본적으로 "default"라는 이름의 대기열에서 사용자를 관리할 수 있습니다. 이를 통해 API 호출 시 대기열 이름을 생략할 수 있으며, 기본 대기열을 사용하는 환경에서 편리하게 사용할 수 있습니다.

Q7. 대기열에 등록된 사용자가 없는 경우 allowUser API의 동작은 어떻게 되나요?

A7. 대기열에 등록된 사용자가 없는 경우, allowUser API는 아무도 허용할 수 없으므로, 결과로 0을 반환합니다. 이를 통해 대기열이 비어 있는 상태에서의 허용 요청이 안전하게 처리됩니다.

Q8. @RequestParam을 사용하여 매개변수를 받는 이유는 무엇인가요?

A8. @RequestParam은 HTTP 요청 파라미터를 메서드 매개변수로 전달받을 수 있게 해줍니다. 이를 사용하면 클라이언트가 전달한 URL 쿼리 파라미터나 폼 데이터를 컨트롤러 메서드에서 손쉽게 접근할 수 있습니다. 예를 들어, isAllowedUser API에서는 사용자 ID와 대기열 이름을 HTTP 요청 파라미터로 받아 해당 정보를 기반으로 작업을 수행합니다.

4. 테스트 환경 설정 및 검증

테스트 환경에서 대기열 로직을 검증하기 위해 EmbeddedRedis를 설정하고, UserQueueServiceTest를 통해 다양한 시나리오를 테스트합니다. 이를 통해 대기열에 사용자를 등록하고, 허용된 사용자를 관리하는 로직을 검증할 수 있습니다.

4.1 EmbeddedRedis 설정

@TestConfiguration
public class EmbeddedRedis {
    private final RedisServer redisServer;

    public EmbeddedRedis() throws IOException {
        this.redisServer = new RedisServer(63790);
    }

    @PostConstruct
    public void start() throws IOException {
        this.redisServer.start();
    }

    @PreDestroy
    public void stop() throws IOException {
        this.redisServer.stop();
    }
}

1. 설명:

  • EmbeddedRedis 클래스는 테스트 환경에서 Redis 서버를 임베디드로 실행하기 위한 설정을 정의합니다.
  • @TestConfiguration 어노테이션을 사용하여 테스트 환경에서만 활성화됩니다.

2. 주요 메서드:

  • start(): 테스트 시작 전에 Redis 서버를 시작합니다. 이 메서드는 @PostConstruct 어노테이션을 통해 객체가 생성된 후 자동으로 호출됩니다.
  • stop(): 테스트가 완료된 후 Redis 서버를 중지합니다. 이 메서드는 @PreDestroy 어노테이션을 통해 객체가 소멸되기 전에 자동으로 호출됩니다.

3. 포트 설정:

  • 임베디드 Redis 서버는 테스트 환경에서 충돌을 방지하기 위해 포트 63790을 사용합니다. 이 포트를 application.yml의 테스트 프로파일에서도 일치시켜야 합니다.

4.2 UserQueueServiceTest

UserQueueServiceTest는 UserQueueService의 기능을 검증하는 테스트 클래스입니다.

@SpringBootTest
@Import(EmbeddedRedis.class)
@ActiveProfiles("test")
class UserQueueServiceTest {

    @Autowired
    private UserQueueService userQueueService;

    @Autowired
    private ReactiveRedisTemplate<String, String> reactiveRedisTemplate;

    @BeforeEach
    public void beforeEach() {
        var con = reactiveRedisTemplate.getConnectionFactory().getReactiveConnection();
        con.serverCommands().flushAll().subscribe();
    }

    @Test
    void registerWatingQueue() {
        StepVerifier.create(userQueueService.registerWatingQueue("default", 100L))
                .expectNext(1L)
                .verifyComplete();
        StepVerifier.create(userQueueService.registerWatingQueue("default", 101L))
                .expectNext(2L)
                .verifyComplete();
    }

    @Test
    void alreadyRegisterWatingQueue() {
        StepVerifier.create(userQueueService.registerWatingQueue("default", 100L))
                .expectNext(1L)
                .verifyComplete();
        StepVerifier.create(userQueueService.registerWatingQueue("default", 100L))
                .expectError(ApplicationException.class)
                .verify();
    }

    @Test
    void emptyAllowUser() {
        StepVerifier.create(userQueueService.allowUser("default", 3L))
                .expectNext(0L)
                .verifyComplete();
    }

    @Test
    void allowUser() {
        StepVerifier.create(userQueueService.registerWatingQueue("default", 1L)
                    .then(userQueueService.registerWatingQueue("default", 2L))
                    .then(userQueueService.registerWatingQueue("default", 3L))
                    .then(userQueueService.allowUser("default", 3L)))
                .expectNext(3L)
                .verifyComplete();
    }
}

1. 설명:

  • UserQueueServiceTest는 Spring Boot의 통합 테스트를 위해 @SpringBootTest를 사용하며, EmbeddedRedis를 임포트하여 테스트 시 임베디드 Redis를 실행합니다.
  • @ActiveProfiles("test")를 통해 테스트 프로파일을 활성화합니다.

2. Redis 초기화:

  • @BeforeEach 메서드는 각 테스트가 실행되기 전에 Redis 데이터를 초기화하여 독립적인 테스트 환경을 보장합니다. flushAll() 명령을 통해 모든 데이터를 제거합니다.

3. 테스트 메서드 설명:

  • registerWatingQueue(): 새로운 사용자를 대기열에 성공적으로 등록하는지 확인합니다. 각 호출마다 반환되는 대기열 순번이 증가해야 합니다.
  • alreadyRegisterWatingQueue(): 동일한 사용자를 다시 대기열에 등록하려고 할 때 예외(ApplicationException)가 발생하는지 검증합니다.
  • emptyAllowUser(): 대기열이 비어 있을 때 사용자를 허용하는 요청을 처리했을 때, 허용된 사용자가 0명인지 확인합니다.
  • allowUser(): 여러 사용자를 대기열에 등록하고, 요청한 수만큼 사용자가 허용되었는지 검증합니다.

4. 테스트 방식:

  • StepVerifier를 사용하여 리액티브 스트림의 결과를 검증합니다. 예상되는 결과와 실제 결과를 비교하여 테스트가 성공적으로 완료되는지 확인합니다.

4.3 QnA

Q1. 왜 Redis를 사용하여 대기열을 관리하나요?

A1. Redis는 인메모리 데이터 저장소로 빠른 읽기와 쓰기 속도를 제공합니다. 대기열 시스템에서는 사용자 순번 관리와 실시간 상태 업데이트가 중요하므로, 성능이 뛰어난 Redis를 사용하면 대기열 처리를 효율적으로 할 수 있습니다. 또한, Redis의 SortedSet 데이터 구조는 대기열과 같은 순번 기반 데이터 관리에 적합합니다.

Q2. EmbeddedRedis를 사용하는 이유는 무엇인가요?

A2. EmbeddedRedis를 사용하면 테스트 환경에서 실제 Redis 서버 없이도 테스트를 실행할 수 있습니다. 이렇게 하면 테스트 환경 설정이 간단해지고, 테스트가 더 독립적이며 재현 가능한 상태로 유지됩니다. 임베디드 Redis는 로컬 환경에서 Redis 서버를 쉽게 시작하고 종료할 수 있도록 도와줍니다.

Q3. registerWatingQueue 메서드가 반환하는 값의 의미는 무엇인가요?

A3. registerWatingQueue 메서드는 대기열에 등록된 사용자의 순번을 반환합니다. 순번은 대기열에서의 위치를 나타내며, 새롭게 등록된 사용자가 몇 번째인지 확인할 수 있습니다. 예를 들어, 반환 값이 1이면 해당 사용자가 대기열에서 첫 번째라는 뜻입니다.

Q4. allowUser 메서드에서 popMin을 사용한 이유는 무엇인가요?

A4. popMin은 Redis의 SortedSet에서 가장 낮은 순위(즉, 가장 오래된 사용자)를 제거하고 반환합니다. 대기열에서는 가장 오래 기다린 사용자부터 허용해야 하므로, 이와 같은 방식으로 대기 순서를 관리합니다. 이렇게 하면 사용자 경험이 공정해지고, 대기 시간이 오래 걸린 사용자가 먼저 입장할 수 있습니다.

Q5. StepVerifier는 어떤 역할을 하나요?

A5. StepVerifier는 리액티브 스트림의 결과를 검증하는 테스트 도구입니다. 이를 사용하여 비동기적인 리액티브 코드의 결과를 단계별로 예상하고, 예측된 결과와 실제 결과가 일치하는지 확인합니다. expectNext()나 expectError()와 같은 메서드를 통해 각 단계의 기대 결과를 명확하게 정의할 수 있습니다.

Q6. 테스트 시 flushAll()을 사용하는 이유는 무엇인가요?

A6. flushAll()은 Redis 데이터베이스의 모든 데이터를 삭제하여, 테스트가 항상 동일한 초기 상태에서 시작되도록 보장합니다. 이를 통해 이전 테스트의 데이터가 현재 테스트에 영향을 미치지 않도록 하며, 각 테스트가 독립적으로 실행될 수 있습니다.

Q7. @ActiveProfiles("test")의 역할은 무엇인가요?

A7. @ActiveProfiles("test")는 테스트 실행 시 활성화할 스프링 프로파일을 지정합니다. 이를 통해 테스트 전용 설정(application-test.yml)을 사용할 수 있으며, 예를 들어 테스트 환경에서 다른 Redis 포트를 사용하는 등의 구성을 적용할 수 있습니다.

Q8. 왜 대기열에 사용자를 등록할 때 ApplicationException이 발생하나요?

A8. 동일한 사용자가 이미 대기열에 등록된 경우, ApplicationException을 발생시켜 중복 등록을 방지합니다. 이를 통해 동일한 사용자가 여러 번 대기열에 등록되는 상황을 방지하고, 대기열 상태를 정확하게 유지할 수 있습니다.

5. application.yml 설정

application.yml 파일은 Spring Boot 애플리케이션의 설정을 관리하는 곳입니다. 여기서는 Redis 서버 설정을 포함하여 프로파일 기반의 구성 방식을 설명합니다.

5.1 기본 설정

server:
  port: 9010

spring:
  data:
    redis:
      host: 127.0.0.1
      port: 6379

1. 서버 포트 설정:

  • server.port: 9010은 애플리케이션이 HTTP 요청을 수신할 포트를 지정합니다. 여기서는 기본적으로 9010 포트를 사용하도록 설정되어 있습니다.

2. Redis 설정:

  • spring.data.redis.host: 127.0.0.1은 애플리케이션이 Redis 서버와 통신할 때 사용할 호스트 주소를 설정합니다. 여기서는 로컬 Redis 서버를 사용하기 때문에 127.0.0.1로 설정했습니다.
  • spring.data.redis.port: 6379은 Redis 서버의 기본 포트를 지정합니다. 일반적으로 로컬 Redis 서버는 포트 6379에서 실행됩니다.

5.2 테스트 프로파일 설정

---
spring:
  config:
    activate:
      on-profile: test
  data:
    redis:
      host: 127.0.0.1
      port: 63790

1. 프로파일 기반의 설정:

  • spring.config.activate.on-profile: test는 이 블록의 설정이 test 프로파일이 활성화된 경우에만 적용된다는 의미입니다.
  • Spring Boot는 서로 다른 환경(예: 개발, 테스트, 프로덕션)에 대해 다른 설정을 제공할 수 있도록 프로파일 기능을 지원합니다.

2. 테스트 환경 Redis 설정:

  • 테스트 프로파일에서는 Redis 포트를 63790으로 설정하여 기본 포트 6379와 충돌하지 않도록 합니다.
  • 이를 통해 테스트 시 임베디드 Redis 서버를 사용하거나, 별도로 실행 중인 테스트용 Redis 서버와 통신할 수 있습니다.

5.3 QnA

Q1. application.yml에서 프로파일 기반 설정을 사용하는 이유는 무엇인가요?

A1. 프로파일 기반 설정은 애플리케이션의 환경에 따라 다른 구성을 제공할 수 있게 해줍니다. 예를 들어, 로컬 개발 환경, 테스트 환경, 프로덕션 환경에서 각기 다른 설정을 적용해야 하는 경우가 많습니다. Spring Boot의 프로파일 기능을 사용하면 application.yml 파일에서 환경에 맞는 설정을 손쉽게 정의하고 관리할 수 있습니다.

Q2. 테스트 프로파일에서 Redis 포트를 63790으로 설정하는 이유는 무엇인가요?

A2. 일반적으로 로컬 Redis 서버는 기본 포트 6379에서 실행됩니다. 그러나 테스트 환경에서는 기존의 Redis 서버와 충돌을 방지하기 위해 다른 포트를 사용합니다. 임베디드 Redis 서버를 테스트 시에 실행하는 경우, 포트를 63790으로 설정하면 테스트 실행 중에 기존 Redis 설정과 충돌하지 않게 됩니다.

Q3. spring.config.activate.on-profile의 역할은 무엇인가요?

A3. spring.config.activate.on-profile은 특정 프로파일이 활성화될 때 해당 설정이 적용되도록 하는 역할을 합니다. 예를 들어, test 프로파일이 활성화되면 해당 프로파일에 대한 설정이 적용됩니다. 이를 통해 프로파일에 따라 다른 설정을 적용할 수 있습니다.

Q4. 기본 설정과 프로파일 기반 설정의 우선순위는 어떻게 되나요?

A4. Spring Boot는 프로파일 기반 설정이 기본 설정보다 우선적으로 적용됩니다. 즉, 특정 프로파일이 활성화된 경우 해당 프로파일의 설정이 기본 설정을 덮어쓰게 됩니다. 예를 들어, test 프로파일이 활성화되면 기본적으로 설정된 Redis 포트 6379 대신 63790이 적용됩니다.

Q5. 테스트 환경에서 spring.config.activate.on-profile을 사용하지 않으면 어떻게 되나요?

A5. spring.config.activate.on-profile을 사용하지 않으면, 테스트 프로파일에 대한 설정이 적용되지 않습니다. 이 경우, 모든 설정이 기본 설정을 따르게 되어 테스트 환경을 분리하여 구성할 수 없습니다. 테스트 환경에서 특정 설정을 적용하려면 해당 프로파일을 명시적으로 활성화해야 합니다.

Q6. server.port를 9010으로 설정한 이유는 무엇인가요?

A6. 포트 9010은 이 예제에서 웹 애플리케이션이 클라이언트 요청을 수신할 포트로 지정된 값입니다. 기본적으로 Spring Boot는 포트 8080에서 실행되지만, 애플리케이션 간의 포트 충돌을 피하기 위해 다른 포트를 사용하는 것이 일반적입니다. 이 예제에서는 테스트 및 실습을 위한 목적에서 9010을 사용하고 있습니다.

이와 같이 application.yml을 통해 다양한 환경에서 Redis와 애플리케이션 설정을 관리할 수 있으며, 이를 통해 개발, 테스트, 프로덕션 환경 간의 설정 관리가 용이해집니다.

결론

이번 포스팅에서는 Redis의 SortedSet을 이용한 대기열 관리 로직과 관련 API 구현 방법을 다뤘습니다. 이 접근 방식은 높은 성능과 유연성을 제공하며, 특히 접속 허용 여부를 빠르게 조회할 수 있는 장점이 있습니다.

저작자표시

'프레임워크 > 자바 스프링' 카테고리의 다른 글

접속자 대기열 시스템 #7- 대기열 스케줄러 개발  (0) 2024.10.10
접속자 대기열 시스템 #6- 접속 대기 웹페이지 개발  (1) 2024.10.10
접속자 대기열 시스템 #3- 셋업  (2) 2024.10.10
접속자 대기열 시스템 #4- 대기열 등록 API 개발  (6) 2024.10.09
BlockHound: Java 비동기 애플리케이션에서 블로킹 호출을 감지하는 도구  (6) 2024.10.08
'프레임워크/자바 스프링' 카테고리의 다른 글
  • 접속자 대기열 시스템 #7- 대기열 스케줄러 개발
  • 접속자 대기열 시스템 #6- 접속 대기 웹페이지 개발
  • 접속자 대기열 시스템 #3- 셋업
  • 접속자 대기열 시스템 #4- 대기열 등록 API 개발
hyeseong-dev
hyeseong-dev
안녕하세요. 백엔드 개발자 이혜성입니다.
  • hyeseong-dev
    어제 오늘 그리고 내일
    hyeseong-dev
  • 전체
    오늘
    어제
    • 분류 전체보기 (282) N
      • 여러가지 (107)
        • 알고리즘 & 자료구조 (72)
        • 오류 (4)
        • 이것저것 (29)
        • 일기 (1)
      • 프레임워크 (39)
        • 자바 스프링 (39)
        • React Native (0)
      • 프로그래밍 언어 (38)
        • 파이썬 (30)
        • 자바 (3)
        • 스프링부트 (5)
      • 운영체제 (0)
      • DB (17)
        • SQL (0)
        • Redis (17)
      • 클라우드 컴퓨팅 (2)
        • 도커 (2)
        • AWS (0)
      • 스케쥴 (65)
        • 세미나 (0)
        • 수료 (0)
        • 스터디 (24)
        • 시험 (41)
      • 트러블슈팅 (1)
      • 자격증 (0)
        • 정보처리기사 (0)
      • 재태크 (4) N
        • 암호화폐 (4) N
        • 기타 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    DP
    ecs
    자바
    프로그래머스
    AWS
    그리디
    WebFlux
    Docker-compose
    celery
    EC2
    reactor
    java
    RDS
    항해99
    Spring Boot
    완전탐색
    mybatis
    spring
    Spring WebFlux
    #개발자포트폴리오 #개발자이력서 #개발자취업 #개발자취준 #코딩테스트 #항해99 #취리코 #취업리부트코스
    파이썬
    Python
    OOP
    SAA
    백준
    docker
    Redis
    FastAPI
    시험
    취업리부트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
hyeseong-dev
접속자 대기열 시스템 #5- Redis를 이용한 대기열 관리 및 웹페이지 진입 API 구현
상단으로

티스토리툴바