Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf : 통계 조회 성능 개선 및 nGrinder를 이용한 성능 테스트 #36

Merged
merged 5 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions api/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@ out/
/docker-compose-monitoring/grafana/volume
/docker-compose-monitoring/prometheus/volume
/docker-compose-monitoring/prometheus/config/query_log_file.log

### nGrinder ###
/docker-compose-nGrinder/ngrinder-controller
16 changes: 16 additions & 0 deletions api/docker-compose-nGrinder/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: '3.8'
services:
controller:
image: ngrinder/controller
restart: always
ports:
- "9000:80"
- "16001:16001"
- "12000-12009:12000-12009"
volumes:
- ./ngrinder-controller:/opt/ngrinder-controller
agent:
image: ngrinder/agent
restart: always
links:
- controller
68 changes: 68 additions & 0 deletions api/docker-compose-nGrinder/scripts/ReadStatisticsTest.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import static net.grinder.script.Grinder.grinder
import static org.junit.Assert.*
import static org.hamcrest.Matchers.*
import net.grinder.script.GTest
import net.grinder.script.Grinder
import net.grinder.scriptengine.groovy.junit.GrinderRunner
import net.grinder.scriptengine.groovy.junit.annotation.BeforeProcess
import net.grinder.scriptengine.groovy.junit.annotation.BeforeThread
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith

import org.ngrinder.http.HTTPRequest
import org.ngrinder.http.HTTPRequestControl
import org.ngrinder.http.HTTPResponse
import org.ngrinder.http.cookie.Cookie
import org.ngrinder.http.cookie.CookieManager

/**
* A simple example using the HTTP plugin that shows the retrieval of a single page via HTTP.
*
* This script is automatically generated by ngrinder.
*
* @author admin
*/
@RunWith(GrinderRunner)
class TestRunner {

public static GTest test
public static HTTPRequest request
public static Map<String, String> headers = [:]
public static Map<String, Object> params = [:]
public static List<Cookie> cookies = []

@BeforeProcess
public static void beforeProcess() {
HTTPRequestControl.setConnectionTimeout(300000)
test = new GTest(1, "host.docker.internal")
request = new HTTPRequest()
grinder.logger.info("before process.")
}

@BeforeThread
public void beforeThread() {
test.record(this, "test")
grinder.statistics.delayReports = true
grinder.logger.info("before thread.")
}

@Before
public void before() {
request.setHeaders(headers)
CookieManager.addCookies(cookies)
grinder.logger.info("before. init headers and cookies")
}

@Test
public void test() {
HTTPResponse response = request.GET("http://host.docker.internal:8080/api/results/v1/statistics")

if (response.statusCode == 301 || response.statusCode == 302) {
grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", response.statusCode)
} else {
assertThat(response.statusCode, is(200))
}
}
}
4 changes: 2 additions & 2 deletions api/src/main/java/org/meotppo/webti/InitData.java
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@ public void initData() {
List<Statistic> statisticData = profileData.stream()
.map(profile -> Statistic.builder()
.developerProfile(profile)
.count(100L)
.matchCount(50L)
.count(0L)
.matchCount(0L)
.build())
.collect(Collectors.toList());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.meotppo.webti.dto.result.StatisticDTO;
import org.meotppo.webti.domain.dto.result.StatisticDTO;
import org.meotppo.webti.dto.result.TestResultRequest;
import org.meotppo.webti.response.ResponseBody;
import org.meotppo.webti.service.result.ResultService;
Expand Down
19 changes: 0 additions & 19 deletions api/src/main/java/org/meotppo/webti/dto/result/StatisticDTO.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package org.meotppo.webti.service.result;

import lombok.RequiredArgsConstructor;
import org.meotppo.webti.domain.entity.mongo.result.TestResult;
import org.meotppo.webti.domain.dto.result.StatisticDTO;
import org.meotppo.webti.domain.entity.mongo.testresult.TestResult;
import org.meotppo.webti.domain.repository.jpa.statistics.StatisticRepository;
import org.meotppo.webti.domain.repository.mongo.result.TestResultRepository;
import org.meotppo.webti.dto.result.StatisticDTO;
import org.meotppo.webti.domain.repository.mongo.testresult.TestResultRepository;
import org.meotppo.webti.dto.result.TestResultRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
Expand All @@ -30,13 +29,6 @@ public void createTestResult(TestResultRequest req) {
}

public List<StatisticDTO> readStatistics() {
return statisticRepository.findAll().stream()
.map(statistic -> new StatisticDTO(
statistic.getDeveloperProfile().getResult(),
statistic.getCount(),
statistic.getMatchCount(),
statistic.getModifiedAt()
))
.collect(Collectors.toList());
return statisticRepository.findAllStatisticDtos();
}
}
20 changes: 19 additions & 1 deletion api/src/main/resources/sql/api-postgres.sql
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,22 @@ INSERT INTO web_developer_profile (created_at, modified_at, description, mbti_ty
(NOW(), NOW(), '당신은 체계적이고 조직적인 접근 방식을 통해 백엔드 시스템을 효율적으로 관리합니다. 철저한 계획과 규칙을 중시하며, 팀을 이끌어 프로젝트를 성공적으로 완수합니다. 당신의 코드는 언제나 깔끔하고 명확하며, 시스템의 신뢰성을 보장합니다.', 'ESTJ', '실행력 강한 관리자형 백엔드 개발자'),
(NOW(), NOW(), '당신은 섬세하고 창의적인 디자인 감각으로 사용자 인터페이스를 아름답게 구현합니다. 세밀한 부분까지 놓치지 않으며, 사용자가 시각적으로 즐길 수 있는 웹사이트를 만듭니다. 당신의 작업물은 예술 작품처럼 정교하고 매력적입니다.', 'ISFP', '디테일에 강한 시각 예술가형 프론트엔드 개발자'),
(NOW(), NOW(), '사용자 경험에 깊은 공감을 가지고 디자인하는 당신은, 감성적이고 창의적인 방식으로 웹 페이지를 만듭니다. 사용자와의 상호작용에서 진정성을 발휘하며, 웹사이트를 통해 따뜻한 이야기를 전합니다. 당신의 작업물은 사용자의 마음을 움직입니다.', 'INFP', '공감하는 이야기꾼형 프론트엔드 개발자'),
(NOW(), NOW(), '당신은 변화와 도전에 강하며, 문제를 해결하는 데 있어 유연하고 즉흥적인 접근 방식을 취합니다. 실용적이고 효율적인 방법을 선호하며, 빠른 결단력으로 프로젝트를 성공적으로 이끌어갑니다. 당신의 작업은 항상 실용적이고 동적입니다.', 'ESTP', '유연하고 즉흥적인 개발자형 풀스택 개발자');
(NOW(), NOW(), '당신은 변화와 도전에 강하며, 문제를 해결하는 데 있어 유연하고 즉흥적인 접근 방식을 취합니다. 실용적이고 효율적인 방법을 선호하며, 빠른 결단력으로 프로젝트를 성공적으로 이끌어갑니다. 당신의 작업은 항상 실용적이고 동적입니다.', 'ESTP', '유연하고 즉흥적인 개발자형 풀스택 개발자');

INSERT INTO statistic (created_at, modified_at, developer_profile_id, count, match_count) VALUES
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'ISTJ'), 0, 0),
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'INTJ'), 0, 0),
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'ISTP'), 0, 0),
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'INTP'), 0, 0),
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'ESTJ'), 0, 0),
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'ISFJ'), 0, 0),
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'ESFP'), 0, 0),
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'ENFP'), 0, 0),
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'ISFP'), 0, 0),
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'INFP'), 0, 0),
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'ESFJ'), 0, 0),
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'INFJ'), 0, 0),
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'ENTP'), 0, 0),
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'ENFJ'), 0, 0),
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'ENTJ'), 0, 0),
(NOW(), NOW(), (SELECT id FROM web_developer_profile WHERE mbti_type = 'ESTP'), 0, 0);
5 changes: 2 additions & 3 deletions batch/src/main/java/org/meotppo/webti/InitData.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.meotppo.webti.domain.entity.type.MbtiType;
import org.meotppo.webti.domain.entity.mongo.result.TestResult;
import org.meotppo.webti.domain.entity.jpa.developerProfile.WebDeveloperProfile;
import org.meotppo.webti.domain.entity.mongo.testresult.TestResult;
import org.meotppo.webti.domain.repository.jpa.developerType.WebDeveloperProfileRepository;
import org.meotppo.webti.domain.repository.mongo.result.TestResultRepository;
import org.meotppo.webti.domain.repository.mongo.testresult.TestResultRepository;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.annotation.Profile;
import org.springframework.context.event.EventListener;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.meotppo.webti.job;

import org.meotppo.webti.domain.entity.jpa.statistics.Statistic;
import org.meotppo.webti.domain.entity.mongo.result.TestResult;
import org.meotppo.webti.domain.entity.mongo.testresult.TestResult;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.job.builder.JobBuilder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import lombok.RequiredArgsConstructor;
import org.meotppo.webti.domain.entity.jpa.developerProfile.WebDeveloperProfile;
import org.meotppo.webti.domain.entity.jpa.statistics.Statistic;
import org.meotppo.webti.domain.entity.mongo.result.TestResult;
import org.meotppo.webti.domain.entity.mongo.testresult.TestResult;
import org.meotppo.webti.domain.repository.jpa.developerType.WebDeveloperProfileRepository;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.context.annotation.Bean;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.meotppo.webti.job.reader;

import org.meotppo.webti.domain.entity.mongo.result.TestResult;
import org.meotppo.webti.domain.entity.mongo.testresult.TestResult;
import org.springframework.batch.item.data.MongoPagingItemReader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.meotppo.webti.domain.config.jpa;

import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class QuerydslConfig {

@PersistenceContext
private EntityManager entityManager;

@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.meotppo.webti.domain.dto.result;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.querydsl.core.annotations.QueryProjection;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;

@Data
@NoArgsConstructor
public class StatisticDTO {
private String result;
private Long count;
private Long matchCount;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime modifiedAt;

@QueryProjection
public StatisticDTO(String result, Long count, Long matchCount, LocalDateTime modifiedAt) {
this.result = result;
this.count = count;
this.matchCount = matchCount;
this.modifiedAt = modifiedAt;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.meotppo.webti.domain.entity.mongo.result;
package org.meotppo.webti.domain.entity.mongo.testresult;

import lombok.AccessLevel;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.meotppo.webti.domain.repository.jpa.statistics;

import org.meotppo.webti.domain.dto.result.StatisticDTO;

import java.util.List;

public interface QuerydslStatisticRepository {
List<StatisticDTO> findAllStatisticDtos();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@

import java.util.Optional;

public interface StatisticRepository extends JpaRepository<Statistic, Long> {
public interface StatisticRepository extends JpaRepository<Statistic, Long>, QuerydslStatisticRepository {
Optional<Statistic> findByDeveloperProfile(WebDeveloperProfile developerProfile);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.meotppo.webti.domain.repository.jpa.statistics;


import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.meotppo.webti.domain.dto.result.QStatisticDTO;
import org.meotppo.webti.domain.dto.result.StatisticDTO;

import java.util.List;

import static org.meotppo.webti.domain.entity.jpa.statistics.QStatistic.statistic;

@RequiredArgsConstructor
public class StatisticRepositoryImpl implements QuerydslStatisticRepository {

private final JPAQueryFactory queryFactory;

@Override
public List<StatisticDTO> findAllStatisticDtos() {
return queryFactory
.select(new QStatisticDTO(
statistic.developerProfile.result,
statistic.count,
statistic.matchCount,
statistic.modifiedAt
))
.from(statistic)
.fetch();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.meotppo.webti.domain.repository.mongo.result;
package org.meotppo.webti.domain.repository.mongo.testresult;

import org.meotppo.webti.domain.entity.mongo.result.TestResult;
import org.meotppo.webti.domain.entity.mongo.testresult.TestResult;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface TestResultRepository extends MongoRepository<TestResult, String> {
Expand Down
Loading