Server

[Springboot] web+jpa vs webflux+r2dbc 비교 (2)

hoonylab 2022. 12. 7. 09:49
728x90
반응형

이번 포스팅에서 starter-web + starter-data-jpa를 이용한 servlet-stack 방식과 starter-webflux + starter-data-r2 dbc를 이용한 reactive-stack 방식의 성능 비교를 해봤었다.

 

2022.12.04 - [Server] - [Springboot] web+jpa vs webflux+r2dbc 비교 (1)

 

[Springboot] web+jpa vs webflux+r2dbc 비교 (1)

기존의 개발 방식으로 많이 사용하는 starter-web + starter-data-jpa 라이브러리를 사용하여 servlet stack 방식을 많이 사용하고 있을것이다. 최근 webflux + r2dbc 라이브러리를 이용하여 비동기(async) & 논블

tistory.minikode.com

 

이전 포스팅에서 다른 방식으로 개선해볼 수 있을까?

이전 포스팅에서는 mariadb 를 이용해서 성능 비교를 해봤고, 이번 포스팅에서는 Nosql의 대표적인 mongodb 를 이용해서 비교를 해보려 한다.

저번 사용한 mariadb connection dependency
저번 사용한 mariadb connection dependency

mongodb connection을 이용하기 위해 

implementation("org.springframework.boot:spring-boot-starter-data-mongodb-reactive")

를 추가해준다.

mongodb dependancy
mongodb dependancy

그리고  mongodb 설정을 위해 application.yaml 설정을 추가해준다. 필자는 로컬에 mongodb를 설치해서 진행했다.

application.yaml

spring:
  data:
    mongodb:
      database: 'webflux'
#      username:
#      password:
      host: localhost
      port: 27017

또 starter-data-monogodb-reactive 라이브러리에서 지원해주는 기능을 사용하기 위해 config 설정도 필요하다.

MongoConfig.kt

import org.springframework.context.annotation.Configuration
import org.springframework.data.mongodb.config.EnableMongoAuditing
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories

@Configuration
@EnableMongoAuditing
@EnableReactiveMongoRepositories(basePackages = ["com.minikode.webflux_demo.mongo.repository"])
class MongoConfig {

}

 

이후 이전 포스팅과 마찬가지로 비교에 필요한 코드를 구성해보았다.

servlet-stack 코드

기본적인 controller, service, repository, entity를 구성

controller

import com.minikode.webflux_demo.mongo.entity.MemberEntity
import com.minikode.webflux_demo.service.MemberService
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import java.util.*

@RestController
@RequestMapping("/mg")
class MongoController(
    private val memberService: MemberService,
) {
    @PostMapping("/")
    fun save(): ResponseEntity<Mono<MemberEntity>> {
        return ResponseEntity.ok(memberService.saveMember())
    }

    @GetMapping("/")
    fun find(): ResponseEntity<Flux<MemberEntity>> {
        return ResponseEntity.ok(memberService.findMembers())
    }
}

service

import com.minikode.webflux_demo.mongo.entity.MemberEntity
import com.minikode.webflux_demo.mongo.repository.MemberRepository
import org.springframework.stereotype.Service
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import java.util.*

@Service
class MemberService(
    private val memberRepository: MemberRepository,
) {

    fun saveMember(): Mono<MemberEntity> {
        val memberEntity = MemberEntity()
        memberEntity.memberId = UUID.randomUUID().toString()
        memberEntity.name = "이름은 minikode"
        return memberRepository.save(memberEntity)
    }

    fun findMembers(): Flux<MemberEntity> {
        return memberRepository.findAll()
    }

}

repository

import com.minikode.webflux_demo.mongo.entity.MemberEntity
import org.springframework.data.mongodb.repository.ReactiveMongoRepository

interface MemberRepository : ReactiveMongoRepository<MemberEntity, String> {
}

entity

import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.Document
import org.springframework.data.relational.core.mapping.Column
import java.util.*

@Document(collection = "member")
class MemberEntity {

    @Id
    var memberId: String? = null

    var name: String? = null

}

 

위 코드로 코드를 작성했고, jMeter를 이용해서 성능 비교를 해보았다.

각 controller의 save(), find()를 각각 동시 500명이 10번 반복하도록 설정했다.

-> save() 1000번 실행 -> find() 1000번 실행

 

결과는??

Active Threads Over Time
Active Threads Over Time
Response Times Over Time
Response Times Over Time
Transactions per Second
Transactions per Second
생성된 data
생성된 data

위처럼 결과가 나왔다.

이번 결과는 은 총 2분 26초 걸렸고, 저번 mariadb로 진행했었던 reactive stack 은 4분 35초와 비교해서 2분 이상 줄어드는 결과를 알 수 있었다. 그리고 이전의 mariadb + servlet-stack 방식의 46초와 비교해서는 더 많은 시간이 소요되는 것도 알 수 있었다.

 

이전 결과와 이번 결과로 얻을수 있는 것

이번 비교로 무거운 작업이 포함될수록 servlet-stack 방식이 좀 더 나은 결과를 보여주는 걸로 생각해볼 수 있는 경험이 된 것 같다.

728x90
반응형