Eksekusi Tugas Asinkron Menggunakan Redis dan Spring Boot

Pada artikel ini, kita akan melihat cara menggunakan Spring Boot 2.x dan Redis untuk melakukan tugas asinkron, dan kode lengkapnya akan mendemonstrasikan langkah-langkah dalam posting ini.





Sepatu Musim Semi / Musim Semi

Spring  adalah framework paling populer untuk mengembangkan aplikasi Java. Dengan demikian, Spring memiliki salah satu komunitas open source terbesar. Selain itu, Spring menyediakan dokumentasi ekstensif dan terkini yang mencakup cara kerja bagian dalam kerangka kerja dan proyek sampel di blognya, dan ada lebih dari 100 ribu  pertanyaan dan jawabandi  StackOverflow





Pada awalnya, Spring hanya mendukung konfigurasi berbasis XML dan menjadi sasaran banyak kritik karena hal ini. Kemudian Spring memperkenalkan konfigurasi berbasis anotasi yang mengubah segalanya. Spring 3.0 adalah versi pertama yang mendukung konfigurasi berbasis anotasi. Pada tahun 2014, Spring Boot  1.0 dirilis  , benar-benar mengubah cara kita melihat ekosistem framework Spring. Penjelasan lebih rinci tentang sejarah Musim Semi dapat ditemukan di  sini





Redis

Redis adalah salah satu database dalam memori NoSQL yang paling populer. Redis mendukung berbagai jenis struktur data. Redis mendukung berbagai jenis struktur data seperti Set, tabel Hash, Daftar, pasangan nilai kunci sederhana, dan masih banyak lagi. Latensi panggilan Redis kurang dari milidetik, dukungan kumpulan replika, dan sebagainya. Latensi operasi Redis kurang dari milidetik, membuatnya semakin menarik bagi komunitas developer.





Mengapa Eksekusi Tugas Asynchronous





Panggilan API tipikal memiliki lima langkah:





  1. Menjalankan satu atau lebih kueri database (RDBMS / NoSQL)





  2. Satu atau lebih operasi sistem caching (In-Memory, Distributed, dll.)





  3. Beberapa perhitungan (ini mungkin pemrosesan data saat melakukan beberapa operasi matematika)





  4. Memanggil layanan lain (internal / eksternal)





  5. ,    





. , - 7 .  , . 





, , API. , 1K , API, API .  API, , . 





, , cron, .  , , crontab UNIX, Chronos, Spring,    Scheduled ❤️. 





cron , , , , .    , , /.    ,  .  , .  , - , - .  , , /.  —  , .    , .  / , , SQS, , 15 , , ​​ 7 7 . .





Rqueue

Rqueue — ,  Spring,  Redis . Rqueue Redis, Redis , Kafka, SQS.  - Redis .   8,4% - Redis.





, Kafka/SQS, , , , , Rqueue Redis.





, Kafka, , , , Redis, , / Redis Rqueue. Rqueue





Rqueue , .    Rqueue.





, :





  1. IDE





  2. Gradle 





  3. Java





  4. Redis 





 Spring Boot .  Gradle Spring Boot  https://start.spring.io/.





:  





  1. Spring Data Redis





  2. Spring Web





  3. Lombok





/ :





  Rqueue  . Rqueue — Spring , , Spring Redis.





spring boot starter  Rqueue com.github.sonus21:rqueue-spring-boot-starter:2.0.0-RELEASE :





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.0.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 Boot.  WEB MVC.





application :





@SpringBootApplication
@EnableRedisRepositories
@EnableWebMvc
public class AsynchronousTaskExecutorApplication { 
  public static void main(String[] args) { 
    SpringApplication.run(AsynchronousTaskExecutorApplication.class, args);
  }
}
      
      







Rqueue .   RqueueListener



.  RqueuListener



, .  deadLetterQueue



.  .  , ,  . numRetries







Java  MessageListener



:





@Component
@Slf4j
public class MessageListener {

  @RqueueListener(value = "${email.queue.name}") (1)
  public void sendEmail(Email email) {
    log.info("Email {}", email);
  }

  @RqueueListener(value = "${invoice.queue.name}") (2)
  public void generateInvoice(Invoice invoice) {
    log.info("Invoice {}", invoice);
  }
}
      
      



Email



Invoice



- .  .





Invoice.java:





import lombok.Data;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Invoice {
  private String id;
  private String type;
}
      
      







Email.java:





import lombok.Data;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Email {
  private String email;
  private String subject;
  private String content;
}
      
      



  RqueueMessageSender



 bean-. , .  enqueue, enqueueIn.





 RqueueMessageSender



bean-.





  . 





-, 30 .  30000 () .  , , .  GET, sendEmail



  generateInvoice



, POST. 





@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class Controller {
  private @NonNull RqueueMessageSender rqueueMessageSender;

  @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");
    rqueueMessageSender.enqueu(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");
    rqueueMessageSender.enqueueIn(invoiceQueueName, new Invoice(id, type), invoiceDelay);
    return "Invoice would be generated in " + invoiceDelay + " milliseconds";
  }
}
      
      



application.properties :





email.queue.name=email-queue
invoice.queue.name=invoice-queue
# 30 seconds delay for invoice
invoice.queue.delay=300000
      
      



.   .





, :





30 :





http://localhost:8080/invoice?id=INV-1234&type=PROFORMA





Sekarang kita dapat menjadwalkan tugas menggunakan Rqueue tanpa banyak kode tambahan! Pertimbangan dasar untuk menyiapkan dan menggunakan perpustakaan Rqueue telah disediakan. Satu hal penting yang perlu diingat adalah bahwa terlepas dari apakah tugas tersebut merupakan tugas yang menunggu keputusan atau tidak, defaultnya adalah menganggap bahwa tugas harus diselesaikan sesegera mungkin.





Kode lengkap dari posting ini dapat ditemukan di repositori  di  GitHub





Bacaan tambahan

Spring Boot: Membuat Metode Asinkron Menggunakan Anotasi @Async





Musim Semi dan Utas: Asinkron





Eksekusi dan Penjadwalan Tugas Terdistribusi di Java, Didukung oleh Redis
























































All Articles