Redis 및 Spring을 사용한 비동기 작업(시작)

16561 단어 spring
이 문서에서는 Spring boot 2를 어떻게 사용하는지 살펴봅니다.x와 Redis는 비동기 작업을 수행합니다. 마지막 코드는 여기 기술한 절차에 따라 작성됩니다.

스프링/스프링 부츠


Spring은 Java 플랫폼에서 가장 유행하는 프레임워크입니다.Spring은 오픈 소스 분야에서 가장 큰 커뮤니티 중 하나입니다.이 밖에도 스프링은 프레임워크의 내부 작업 원리를 포함하는 광범위한 최신 문서를 제공하고 그들의 블로그에 예시 항목을 제공했다. Stack Overflow에 관해서는 10만여 개의 문제가 있다.
Spring 3.0은 주석 기반 구성을 지원하는 첫 번째 버전으로, 2014년 늦게 Spring boot 1.0이 발표되면서 Spring 프레임워크 생태계에 대한 우리의 견해를 완전히 바꾸었고 상자를 열면 바로 사용할 수 있는 설정과 더 많은 것을 제공했다.타임라인

레디스


Redis는 가장 유행하는 소스 오픈 NosQL 메모리 데이터베이스 중 하나입니다.Redis는 집합, 해시 테이블, 목록, 간단한 키 값 쌍 등 다양한 유형의 데이터 구조를 지원합니다.Redis 호출 지연은 복사본 세트 등을 지원하는 밀리초입니다.

비동기적으로 작업을 수행하는 이유


일반적인 API 호출은 다섯 부분으로 구성됩니다.
  • 하나 이상의 데이터베이스(RDBMS/NosQL) 쿼리 수행
  • 일부 캐시 시스템(메모리, 분산 등)에서 하나 이상의 작업
  • 일부 계산(일부 데이터 처리로 수학 연산을 할 수 있음)
  • 추가 서비스 콜(내부/외부)
  • 은 나중에 또는 백그라운드에서 하나 이상의 작업을 수행하도록 스케줄링합니다.
  • 여러 가지 이유로 주문 작성 또는 주문 발송 7일 후에 청구서를 생성해야 하는 등 나중에 작업을 예약할 수 있습니다. 즉, 지금 이메일/알림을 보내지 않아도 됩니다. 그렇지 않으면 지연될 수 있습니다.때때로 우리는 API 응답 시간을 줄이기 위해 비동기적인 작업을 수행해야 한다. 예를 들어 한 번에 1K+ 기록을 삭제해야 한다. 만약에 우리가 같은 API 호출에서 모든 기록을 삭제한다면 API 응답 시간은 반드시 증가할 것이다. API 응답 시간을 줄이기 위해 우리는 백엔드에서 하나의 작업을 실행해서 이 기록을 삭제할 수 있다.

    지연 대기열


    우리는 cron 작업으로 스케줄링 작업을 실행할 수 있고, 다른 방법으로cron 작업을 스케줄링할 수 있다. 예를 들어 UNIX 스타일의crontab, Chronos 등이다. 만약에 우리가 Spring 프레임워크를 사용한다면, 이것은 기존의 스케줄링 주석이다❤️. 대부분의 스케줄링 메커니즘에 확장 문제가 존재하기 때문에 우리는 데이터베이스를 스캔해서 관련 줄/기록을 찾을 것이다.많은 경우, 이것은 매우 나쁜 전체 테이블 스캔을 실행할 수 있다.실시간 응용 프로그램이 이 일괄 처리 시스템과 같은 데이터베이스를 사용하는 상황을 상상해 보세요.타이머가 예정된 시간에 도달하면 작업이 트리거되는 경우 지연 대기열을 사용할 수 있습니다.많은 줄 서기 시스템/소프트웨어를 사용할 수 있지만, 예를 들어 SQS는 7시간이나 7일 같은 임의의 지연이 아니라 15분의 지연을 제공한다.

    Rqueue


    Rqueue은spring 프레임워크를 위한 에이전트로 데이터를 Redis에 저장하고 임의로 작업 실행을 지연시키는 메커니즘을 제공합니다.Rqueue는 리디스가 지원하는데 리디스가 카프카, SQS 등 광범위하게 사용되는 줄 서기 시스템보다 장점이 있기 때문이다.대부분의 웹 응용 프로그램 백엔드에서 Redis는 캐시 데이터나 다른 용도로 사용됩니다.현재 세계에서 8.4%개의 웹 응용 프로그램이 Redis 데이터베이스를 사용하고 있다.

    일반적으로, 대기열에 대해, 우리는 Kafka/SQS 또는 다른 시스템을 사용합니다. 이러한 시스템은 서로 다른 차원에서 추가 비용을 가져올 수 있습니다. 예를 들어, Rqueue와 Redis를 사용하면 돈을 0으로 줄일 수 있습니다.
    비용을 제외하고 만약에 우리가 Kafka를 사용한다면 우리는 인프라 시설의 설정, 유지보수, 즉 더 많은 조작을 해야 한다. 대부분의 응용 프로그램이 Redis를 사용하고 있기 때문에 우리는 조작 비용이 들지 않는다. 사실상 Rqueue는 같은 Redis 서버/그룹을 사용할 수 있다.Rqueue는 임의의 지연 시간 지원
    메시지 전달
    Rqueue는 데이터가 Redis에서 삭제되지 않는 한 최소한 한 번의 메시지 전달을 보장합니다.자세한 내용은 Introducing Rqueue으로 문의하십시오.
    필요한 도구:
  • 모든 IDE 2그레델 3번지.Java 4.레디스
    간단하게 보기 위해서, 우리는 Spring boot을 사용할 것입니다. 우리는 Spring boot 초기값 설정 항목 https://start.spring.io/에서Gradle 프로젝트를 만들어서 우리가 필요로 하는 의존 항목에 사용할 것입니다
  • 스프링 데이터 Redis 2.봄그물용목산과 다른 어느 곳이든
  • 디렉토리/폴더 구조는 다음과 같습니다.

    Rqueue 라이브러리를 사용하여 어떠한 작업도 지연시킬 것입니다.Rqueue는 스프링 기반 비동기 작업 수행기로서 어떠한 지연에도 작업을 수행할 수 있으며, 스프링 메시지 전달 라이브러리에 기반을 두고 있으며, Redis가 지원한다.
    com을 사용하여 Rqueue spring 이니시에이터 종속성을 추가합니다.github.sonus21: rqueue spring 이니시에이터: 2.7.0-REASE
    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-data-redis'
        implementation 'org.springframework.boot:spring-boot-starter-web'
        implementation 'com.github.sonus21:rqueue-spring-boot-starter:2.7.0-RELEASE'
        compileOnly 'org.projectlombok:lombok'
        annotationProcessor 'org.projectlombok:lombok'
        providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
        testImplementation('org.springframework.boot:spring-boot-starter-test') {
            exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
        }
    }
    
    테스트를 위해 Redis spring 부트 기능을 활성화해야 하며 WEB MVC도 활성화합니다.
    응용 프로그램 파일 업데이트
    @SpringBootApplication
    @EnableRedisRepositories
    @EnableWebMvc
    public class AsynchronousTaskExecutorApplication {
       public static void main(String[] args) {
          SpringApplication.run(AsynchronousTaskExecutorApplication.class, args);
      }
    }
    
    Rqueue를 사용하여 작업을 추가하는 것은 매우 간단합니다. 우리는 Rqueue Listener로 방법을 설명하기만 하면 됩니다.Rqueu Listener 주석에는 여러 필드가 있습니다. 예를 들어 deadLetterQueue를 설정하면 작업이 다른 대기열로 전송됩니다. 그렇지 않으면 작업이 실패할 때 버려집니다.또한numRetries 필드를 사용하여 작업을 재시도해야 하는 횟수를 설정할 수도 있습니다.
    Java 파일 이름인 MessageListener를 만들고 작업을 수행하는 방법을 추가합니다.
    import com.github.sonus21.rqueue.annotation.RqueueListener;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    
    @Component
    @Slf4j
    public class MessageListener {
    
      @RqueueListener(value = "${email.queue.name}")
      public void sendEmail(Email email) {
        log.info("Email {}", email);
      }
    
      @RqueueListener(value = "${invoice.queue.name}")
      public void generateInvoice(Invoice invoice) {
        log.info("Invoice {}", invoice);
      }
    }
    
    전자 우편과 영수증 종류는 각각 전자 우편과 영수증 데이터를 저장해야 한다.간단하게 보기 위해서, 클래스는 소수의 몇 개의 필드만 있다.
    영수증활용단어참조
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Invoice {
      private String id;
      private String type;
    }
    
    전자 우편.활용단어참조
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Email {
      private String email;
      private String subject;
      private String content;
    }
    

    작업 제출

    RqueueMessageEnqueuer bean을 사용하여 퀘스트를 제출할 수 있습니다.이것은 여러 가지 방법으로 용례에 따라 임무를 줄을 서는데, 예를 들어 재사용, 재시험 계수, 지연 임무의 지연 등이다.
    우리는 RqueueMessageEnqueuer을 자동으로 연결하거나 구조 함수를 사용하여 이 bean을 주입해야 한다.
    테스트를 위한 컨트롤러 만들기:
    우리는 앞으로 30초 안에 영수증을 생성할 계획이며, 이를 위해 영수증 대기열에 30000밀리초 지연된 작업을 제출할 것입니다.또한 백그라운드에서 이메일을 보내려고 합니다.이를 위해 GET 메서드 sendEmailgenerateInvoice을 두 가지 추가하고 POST를 사용할 수 있습니다.
    @RestController
    @RequiredArgsConstructor(onConstructor = @__(@Autowired))
    @Slf4j
    public class Controller {
      private @NonNull RqueueMessageEnqueuer rqueueMessageEnqueuer;
    
      @Value("${email.queue.name}")
      private String emailQueueName;
    
      @Value("${invoice.queue.name}")
      private String invoiceQueueName;
    
      @Value("${invoice.queue.delay}")
      private Long invoiceDelay;
    
      @GetMapping("email")
      public String sendEmail(
          @RequestParam String email, @RequestParam String subject, @RequestParam String content) {
        log.info("Sending email");
        rqueueMessageEnqueuer.enqueue(emailQueueName, new Email(email, subject, content));
        return "Please check your inbox!";
      }
    
      @GetMapping("invoice")
      public String generateInvoice(@RequestParam String id, @RequestParam String type) {
        log.info("Generate invoice");
        rqueueMessageEnqueuer.enqueueIn(invoiceQueueName, new Invoice(id, type), invoiceDelay);
        return "Invoice would be generated in " + invoiceDelay + " milliseconds";
      }
    }
    
    응용 프로그램에 다음 내용을 추가합니다.속성 파일
    전자 우편.줄을 서다.대기열 이름 = 전자 메일
    영수증줄을 서다.name = 청구서 대기열

    청구서 지연 시간 30초


    영수증줄을 서다.지연 시간 = 300000
    스프링 boot 프로그램을 시작할 때가 되었습니다. 프로그램이 성공적으로 시작되면 탐색
    http://localhost:8080/[email protected]&subject=%22test%20email%22&content=%22testing%20email%22
    로그에서, 우리는 작업이 백그라운드에서 실행되고 있는 것을 볼 수 있다

    30초 후 청구서 일정
    http://localhost:8080/invoice?id=INV-1234&type=PROFORMA

    한마디로 우리는 보일러 코드가 많이 필요하지 않고 Rqueue를 사용하여 임무를 스케줄링할 수 있다.Rqueue 라이브러리를 구성하고 사용할 때 고려해야 할 사항이 있습니다.그 중 중요한 문제는 임무가 지연 임무인지 여부이다.기본적으로 임무가 가능한 한 빨리 실행되어야 한다고 가정합니다.
    전체 코드는 내 Github 계정 https://github.com/sonus21/rqueue-task-exector에서 찾을 수 있습니다.
    Rqueue 라이브러리 코드: https://github.com/sonus21/rqueue
    만약 당신이 이 문장이 매우 도움이 된다고 생각한다면, 모두 공유하고 엄지손가락을 치켜세워 주십시오.

    좋은 웹페이지 즐겨찾기