Upgrade to Pro — share decks privately, control downloads, hide ads and more …

R2DBCでAPIの高速化をしようとしてやめた話

yy_yank
September 02, 2022

 R2DBCでAPIの高速化をしようとしてやめた話

FORCASというプロダクトの開発でR2DBCをやろうとしていた話です
R2DBC(MySQL) + Spring Boot + Kotlin + Kotlin Coroutines

参考リンク集
https://gist.github.com/yyYank/cbcf8074b3b3bfa0fd68d9fc00cb6e73

yy_yank

September 02, 2022
Tweet

More Decks by yy_yank

Other Decks in Programming

Transcript

  1. 自己紹介 やんく(@yy_yank) 株式会社ユーザベースのプログラマ。 Product Team 所属。 最近はNewsPicks Stage.の開発に関わっています。 Java, Kotlin,

    Goが好き。最近はRustを書いています。 過去にKotlin in Actionという本の共同翻訳をしたりしまし た。 2
  2. 10 ・R2DBC(Reactive Relational Database Connectivity)とは Based on the Reactive Streams

    specification. R2DBC is founded on the Reactive Streams specification, which provides a fully-reactive non-blocking API. Works with relational databases. In contrast to the blocking nature of JDBC, R2DBC allows you to work with SQL databases using a reactive API. Supports scalable solutions. With Reactive Streams, R2DBC enables you to move from the classic “one thread per connection” model to a more powerful and scalable approach. Provides an open specification. R2DBC is an open specification and establishes a Service Provider Interface (SPI) for driver vendors to implement and clients to consume. https://r2dbc.io/ R2DBCとSpring BootとKotlin Coroutines
  3. 20 R2DBCとSpring BootとKotlin Coroutines R2DBCを使うには? dependencies { implementation("dev.miku:r2dbc-mysql:0.8.2.RELEASE" ) //

    or implementation("com.github.jasync-sql:jasync-r2dbc-mysql:2.0.8" ) } ・R2DBCドライバ実装も必要 R2DBCのMySQLドライバ実装に関しては過去にブログに書きました https://yyyank.blogspot.com/2021/02/r2dbc2mysql.html
  4. 22 R2DBCとSpring BootとKotlin Coroutines application.yml spring: r2dbc: url: r2dbcs:pool:mysql://localhost:3306/hoge username:

    mysql-user password: mysql-password pool: initial-size: 10 max-size: 10 validation-query: "select 1"
  5. 24 R2DBCとSpring BootとKotlin Coroutines R2DBCはorg.springframework.r2dbc.core.DatabaseClientを使う @Repository class HogeRepository( private val

    dbClient: DatabaseClient ) { fun select(ids: List<String>): Flux<HogeEntity> { return dbClient.sql("select * from hoge where id in (:ids) " ) .bind("ids", ids) .map { row -> HogeEntity( id = checkNotNull(row.get("id", String::class.java)), hoge = checkNotNull(row.get("hoge", java.lang.Integer:: class.java)?.toInt()), fuga = checkNotNull(row.get("fuga", String::class.java)) ) } .all() } }
  6. 25 R2DBCとSpring BootとKotlin Coroutines R2DBCはコルーチン内で呼び出す @Service class HogeService( private val

    repository: hoge.infra.HogeRepository ) { fun fetchHoge(ids: List<String>): List<Hoge> = runBlocking { val hogeFlux = repository.select(ids) val hogeList = hogeFlux.collectList() .awaitSingle() ids.map { id -> async(context = Dispatchers.Default) { // 非同期でデカい処理 Hoge() } }.map{ it.await() } } }
  7. 26 R2DBCとSpring BootとKotlin Coroutines R2DBCはコルーチン内で呼び出す @Service class HogeService( private val

    repository: hoge.infra.HogeRepository ) { fun fetchHoge(ids: List<String>): List<Hoge> = runBlocking { val hogeFlux = repository.select(ids) val hogeList = hogeFlux.collectList() .awaitSingle() ids.map { id -> async(context = Dispatchers.Default) { // 非同期でデカい処理 Hoge() } }.map{ it.await() } } }
  8. 28 R2DBCとSpring BootとKotlin Coroutines R2DBCはコルーチン内で呼び出す @Service class HogeService( private val

    repository: hoge.infra.HogeRepository ) { fun fetchHoge(ids: List<String>): List<Hoge> = runBlocking { val hogeFlux = repository.select(ids) val hogeList = hogeFlux.collectList() .awaitSingle() ids.map { id -> async(context = Dispatchers.Default) { // 非同期でデカい処理 Hoge() } }.map{ it.await() } } }
  9. 30 R2DBCとSpring BootとKotlin Coroutines R2DBCはコルーチン内で呼び出す @Service class HogeService( private val

    repository: hoge.infra.HogeRepository ) { fun fetchHoge(ids: List<String>): List<Hoge> = runBlocking { val hogeFlux = repository.select(ids) val hogeList = hogeFlux.collectList() .awaitSingle() ids.map { id -> async(context = Dispatchers.Default) { // 非同期でデカい処理 Hoge() } }.map{ it.await() } } }