REST API responsif kinerja tinggi, koneksi DB
REST API responsif kinerja tinggi, koneksi DB
[ad_1]
Pemrograman Responsif
Pemrograman reaktif adalah paradigma pemrograman yang mengelola aliran data asinkron dan secara otomatis menyebarkan perubahan, memungkinkan sistem bereaksi terhadap peristiwa secara real time. Hal ini berguna untuk membangun API reaktif dan aplikasi berbasis peristiwa, yang sering diterapkan pada pembaruan UI, umpan data, dan sistem waktu nyata.
Fluks Web
WebFlux dirancang untuk aplikasi dengan kebutuhan konkurensi tinggi. Dia mengeksploitasi Proyek Reaktor Dan Aliran responsifyang memungkinkannya menangani permintaan dalam jumlah besar secara bersamaan dengan penggunaan sumber daya minimal.
Fitur utama
- Pemrograman Responsif menggunakan tipe reaktif seperti
Mono
yang mengelola data 0..1, danFlux
yang menangani 0..N data, untuk memproses aliran data secara asinkron. - I/O tanpa pemblokiran dibangun di server non-pemblokiran seperti Netty, mengurangi overhead dan memungkinkan pemrosesan throughput tinggi.
- Model fungsional dan berbasis anotasi mendukung perutean fungsional dan pengontrol berbasis anotasi tradisional.
R2DBC (Konektivitas Basis Data Reaktif)
R2DBC
(Konektivitas Basis Data Relasional Reaktif) adalah API non-pemblokiran untuk berinteraksi dengan basis data relasional dengan cara yang sepenuhnya reaktif dan asinkron. Ini dirancang untuk aplikasi reaktif, memungkinkan manajemen operasi database yang efisien dalam aliran data real-time, terutama dengan kerangka kerja seperti Spring WebFlux.
Ikhtisar Solusi
Pendekatan ini ideal untuk aplikasi yang memerlukan scalable
interaksi real-time dengan sumber data. Aliran Web Musim Semi memungkinkan konfigurasi API yang asinkron dan non-pemblokiran, sementara R2DBC
menyediakan koneksi responsif ke database relasional, seperti PostgreSQL
Atau MySQL
yang secara tradisional memerlukan pemblokiran I/O dengan JDBC. Kombinasi ini menciptakan sistem yang transparan dan berbasis peristiwa, memanfaatkan aliran reaktif untuk mengelola aliran data dari klien ke database tanpa menunggu operasi pemblokiran.
Komponen utama
- Jawa17 atau lebih baru akan menjalankan solusi ini karena logging Java yang digunakan.
- Sepatu bot musim semi Perpustakaan digunakan sebagai konfigurasi layanan portabel.
- APO musim semi Pendekatan deklaratif berarti bahwa masalah ditambahkan secara dinamis pada saat runtime, bukan di-hardcode ke dalam aplikasi, sehingga lebih mudah untuk melakukan penyesuaian tanpa mengubah kode yang sudah ada.
- Aliran Web Musim Semi: Kerangka web responsif yang menyediakan sepenuhnya
non-blocking
API dioptimalkan untuk aplikasi responsif dan fungsionalitas web real-time - R2DBC: API yang responsif dan non-pemblokiran untuk konektivitas database, menggantikan API
blocking
perilaku JDBC dengan tumpukan yang sepenuhnya reaktif - StrukturPeta: Digunakan untuk mengubah kueri menjadi lapisan akses data
Servlet WebFlux
WebFlux
mendukung berbagai server seperti Netty
, Tomcat
, Jetty
, Undertow
dan wadah Servlet. Mari kita definisikan Netty dan container servlet dalam contoh ini.
Struktur proyek
Konfigurasi
logging:
level:
org:
springframework:
r2dbc: DEBUG
server:
error:
include-stacktrace: never
spring:
application:
name: async-api-async-db
jackson:
serialization:
FAIL_ON_EMPTY_BEANS: false
main:
allow-bean-definition-overriding: true
r2dbc:
password: 123456
pool:
enabled: true
initial-size: 5
max-idle-time: 30m
max-size: 20
validation-query: SELECT 1
url: r2dbc:mysql://localhost:3306/test
username: root
Web Flux Netty: proses fungsional
Kerangka web fungsional Spring (ProductRoute.java
) memperlihatkan fungsionalitas perutean, seperti membuat a RouterFunction
menggunakan API gaya konstruktor yang dapat ditemukan, untuk membuat RouterFunction
diberikan a RequestPredicate
Dan HandlerFunction
dan untuk melakukan subrouting tambahan pada fungsi routing yang ada. Selain itu, kelas ini dapat mengubah a RouterFunction
di sebuah HttpHandle
.
package com.amran.async.controller.functional;
import com.amran.async.constant.ProductAPI;
import com.amran.async.handler.ProductHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import static org.springframework.web.reactive.function.server.RequestPredicates.DELETE;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
import static org.springframework.web.reactive.function.server.RequestPredicates.PUT;
/**
* @author Md Amran Hossain on 28/10/2024 AD
* @Project async-api-async-db
*/
@Configuration(proxyBeanMethods = false)
public class ProductRoute {
@Bean
public RouterFunction routerFunction(ProductHandler productHandler) {
return RouterFunctions
.route(GET(ProductAPI.GET_PRODUCTS).and(ProductAPI.ACCEPT_JSON), productHandler::getAllProducts)
.andRoute(GET(ProductAPI.GET_PRODUCT_BY_ID).and(ProductAPI.ACCEPT_JSON), productHandler::getProductById)
.andRoute(POST(ProductAPI.ADD_PRODUCT).and(ProductAPI.ACCEPT_JSON), productHandler::handleRequest)
.andRoute(DELETE(ProductAPI.DELETE_PRODUCT).and(ProductAPI.ACCEPT_JSON), productHandler::deleteProduct)
.andRoute(PUT(ProductAPI.UPDATE_PRODUCT).and(ProductAPI.ACCEPT_JSON), productHandler::handleRequest);
}
}
Proses permintaan non-fungsional WebFlux
- API istirahat yang dirasakan musim semi (
ProductController.java
):
package com.amran.async.controller;
import com.amran.async.model.Product;
import com.amran.async.service.ProductService;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* @author Md Amran Hossain on 28/10/2024 AD
* @Project async-api-async-db
*/
@RestController
@RequestMapping(path = "/api/v2")
public class ProductController {
private final ProductService productService;
public ProductController(ProductService productService) {
this.productService = productService;
}
@GetMapping("/product")
@ResponseStatus(HttpStatus.OK)
public Flux getAllProducts() {
return productService.getAllProducts();
}
@GetMapping("/product/{id}")
@ResponseStatus(HttpStatus.OK)
public Mono getProductById(@PathVariable("id") Long id) {
return productService.getProductById(id);
}
@PostMapping("/product")
@ResponseStatus(HttpStatus.CREATED)
public Mono createProduct(@RequestBody Product product) {
return productService.addProduct(product);
}
@PutMapping("/product/{id}")
@ResponseStatus(HttpStatus.OK)
public Mono updateProduct(@PathVariable("id") Long id, @RequestBody Product product) {
return productService.updateProduct(product, id);
}
@DeleteMapping("/product/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public Mono deleteProduct(@PathVariable("id") Long id) {
return productService.deleteProduct(id);
}
}
Kalau begitu mari kita beralih untuk melihat R2DBC
pelaksanaan. Repositori ini mengikuti paradigma reaktif dan menggunakan tipe Project Reactor yang dibangun di atasnya Reactive Streams
. Simpan dan hapus operasi dengan entitas yang memiliki atribut versi yang memicu a onError
dengan a OptimisticLockingFailureException
ketika mereka menemukan nilai versi yang berbeda di penyimpanan persistensi dibandingkan di entitas yang diteruskan sebagai argumen. Operasi penghapusan lainnya yang hanya menerima ID atau entitas tanpa atribut versi tidak menimbulkan kesalahan ketika tidak ada data yang cocok ditemukan di penyimpanan persistensi.
Penguncian optimis
Penguncian optimis dan konflik konkurensi terdeteksi saat memperbarui data. Penguncian optimis adalah mekanisme untuk menangani perubahan bersamaan dengan cara yang menjamin integritas data tanpa memerlukan kunci database eksklusif. Hal ini umumnya diterapkan dalam sistem di mana beberapa transaksi dapat membaca dan memperbarui catatan yang sama secara bersamaan.
package com.amran.async.repository;
import com.amran.async.domain.ProductEntity;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import org.springframework.stereotype.Repository;
/**
* @author Md Amran Hossain on 28/10/2024 AD
* @Project async-api-async-db
*/
@Repository
public interface ProductRepository extends ReactiveCrudRepository {
// @Query("SELECT * FROM product WHERE product_name = :productName")
// Flux findByProductName(String productName);
}
Ringkasan
Singkatnya, menggunakan Java Spring Boot WebFlux dengan R2DBC memungkinkan pengembang membuat REST API yang responsif dan berkinerja tinggi dengan koneksi database non-pemblokiran. Kombinasi ini mendukung aplikasi berlatensi rendah dan skalabel yang dioptimalkan untuk menangani permintaan bersamaan dalam jumlah besar, menjadikannya ideal untuk lingkungan cloud-native real-time.
Anda juga dapat menemukan contoh kode sumber lengkap Di Sini.
[ad_2]