Skip to content

Commit 0f0cc31

Browse files
committed
merge: feature/performance-test into develop
2 parents 78caede + 60ce7b9 commit 0f0cc31

File tree

8 files changed

+406
-203
lines changed

8 files changed

+406
-203
lines changed

Dockerfile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# 1. OpenJDK 기반 이미지 사용
2+
FROM eclipse-temurin:21-jdk
3+
4+
# 2. JAR 복사 (경로는 실제 빌드 결과물 위치에 따라 다름)
5+
COPY build/libs/*.jar app.jar
6+
7+
# 3. 실행 명령
8+
ENTRYPOINT ["java", "-jar", "/app.jar"]

build.gradle.kts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ dependencies {
3232
implementation("org.springframework.boot:spring-boot-starter-security")
3333
implementation("org.springframework.boot:spring-boot-starter-validation")
3434
implementation("org.springframework.boot:spring-boot-starter-web")
35-
implementation("org.springframework.boot:spring-boot-starter-data-redis")
35+
// implementation("org.springframework.boot:spring-boot-starter-data-redis")
3636
implementation("mysql:mysql-connector-java:8.0.33")
3737

3838
implementation ("org.antlr:antlr4-runtime:4.10.1")
@@ -75,6 +75,9 @@ dependencies {
7575
// AWS
7676
implementation(platform("software.amazon.awssdk:bom:2.31.11"))
7777
implementation("software.amazon.awssdk:s3")
78+
79+
implementation("org.springframework.boot:spring-boot-starter-actuator")
80+
implementation("io.micrometer:micrometer-registry-prometheus")
7881
}
7982

8083
tasks.withType<Test> {

docker-compose.perf.yml

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
services:
2+
spring:
3+
build:
4+
context: .
5+
dockerfile: Dockerfile
6+
container_name: spring
7+
ports:
8+
- "8080:8080" # 외부에서 접속할 경우 필요 (선택)
9+
environment:
10+
- SPRING_PROFILES_ACTIVE=docker # profile 설정 (application-docker.yml)
11+
depends_on:
12+
- mysql
13+
deploy:
14+
resources:
15+
limits:
16+
cpus: '1.0'
17+
memory: 1024M
18+
reservations:
19+
cpus: '1.0'
20+
memory: 1024M
21+
22+
mysql:
23+
image: mysql:8.0.33
24+
container_name: log4u_mysql
25+
deploy:
26+
resources:
27+
limits:
28+
cpus: '1.0'
29+
memory: 1024M
30+
reservations:
31+
cpus: '1.0'
32+
memory: 1024M
33+
restart: always
34+
environment:
35+
TZ: Asia/Seoul
36+
MYSQL_ROOT_PASSWORD: root
37+
MYSQL_USER: dev
38+
MYSQL_PASSWORD: devcos4-team08
39+
MYSQL_DATABASE: log4u
40+
ports:
41+
- "3307:3306"
42+
command:
43+
- --character-set-server=utf8mb4
44+
- --collation-server=utf8mb4_unicode_ci
45+
volumes:
46+
- mysql_data:/var/lib/mysql
47+
48+
prometheus:
49+
image: prom/prometheus
50+
container_name: prometheus
51+
volumes:
52+
- ./prometheus.yml:/etc/prometheus/prometheus.yml
53+
ports:
54+
- "9090:9090"
55+
restart: always
56+
57+
grafana:
58+
image: grafana/grafana
59+
container_name: grafana
60+
ports:
61+
- "3000:3000"
62+
restart: always
63+
depends_on:
64+
- prometheus
65+
privileged: true
66+
67+
postgres:
68+
image: postgis/postgis:15-3.3
69+
container_name: log4u_postgres
70+
environment:
71+
POSTGRES_DB: gis_db
72+
POSTGRES_USER: postgres
73+
POSTGRES_PASSWORD: 1234
74+
ports:
75+
- "5432:5432"
76+
volumes:
77+
- pgdata:/var/lib/postgresql/data
78+
- ./docker/init.sql:/docker-entrypoint-initdb.d/init.sql
79+
80+
mysql-exporter:
81+
image: prom/mysqld-exporter
82+
container_name: mysql-exporter
83+
ports:
84+
- "9104:9104"
85+
command:
86+
- "--mysqld.username=dev:devcos4-team08"
87+
- "--mysqld.address=log4u_mysql:3306"
88+
depends_on:
89+
- mysql
90+
91+
postgres-exporter:
92+
image: prometheuscommunity/postgres-exporter
93+
container_name: postgres-exporter
94+
ports:
95+
- "9187:9187"
96+
environment:
97+
DATA_SOURCE_NAME: "postgresql://postgres:1234@log4u_postgres:5432/gis_db?sslmode=disable"
98+
depends_on:
99+
- postgres
100+
101+
k6:
102+
image: grafana/k6:latest
103+
ports:
104+
- "6565:6565"
105+
volumes:
106+
- ./performance-test.js:/performance-test.js
107+
command: run /performance-test.js
108+
109+
volumes:
110+
pgdata:
111+
mysql_data:
112+

performance-test.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import http from 'k6/http';
2+
import { check, sleep, group } from 'k6';
3+
4+
export const options = {
5+
stages: [
6+
{ duration: '1m', target: 50 }, // 1분 동안 VU 50명 유지
7+
{ duration: '1m', target: 100 }, // 1분 동안 VU 100명 유지
8+
{ duration: '1m', target: 200 }, // 1분 동안 VU 200명 유지
9+
{ duration: '1m', target: 300 }, // 1분 동안 VU 300명 유지
10+
{ duration: '1m', target: 500 }, // 1분 동안 VU 500명 유지
11+
{ duration: '1m', target: 0 }, // 점진적 종료
12+
],
13+
};
14+
15+
const BASE_URL = 'http://spring:8080';
16+
17+
export default function () {
18+
// 강북구 고정 좌표
19+
const bounds = {
20+
south: 37.6335,
21+
north: 37.6535,
22+
west: 127.0011,
23+
east: 127.0211,
24+
};
25+
26+
const url = `${BASE_URL}/maps/diaries/marker?south=${bounds.south}&north=${bounds.north}&west=${bounds.west}&east=${bounds.east}`;
27+
28+
group('Get Diary Markers (Gangbuk-gu fixed bounds)', () => {
29+
const res = http.get(url, {
30+
headers: {
31+
'Content-Type': 'application/json',
32+
},
33+
});
34+
35+
check(res, {
36+
'status is 200': (r) => r.status === 200,
37+
});
38+
39+
sleep(1); // 사용자당 요청 간격
40+
});
41+
}

prometheus.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
global:
2+
scrape_interval: 15s
3+
evaluation_interval: 15s
4+
5+
scrape_configs:
6+
- job_name: "prometheus"
7+
static_configs:
8+
- targets: ["localhost:9090"]
9+
10+
- job_name: "mysql-exporter"
11+
static_configs:
12+
- targets: ["mysql-exporter:9104"]
13+
14+
- job_name: "java_application"
15+
metrics_path: '/actuator/prometheus'
16+
scrape_interval: 5s
17+
static_configs:
18+
# - targets: ["host.docker.internal:8080"]
19+
- targets: ["spring:8080"] # spring = docker-compose 서비스 이름
20+
21+
- job_name: 'postgres-exporter'
22+
static_configs:
23+
- targets: [ 'postgres-exporter:9187' ]

src/main/java/com/example/log4u/common/config/MySqlConfig.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
1717
import org.springframework.transaction.PlatformTransactionManager;
1818

19+
import com.zaxxer.hikari.HikariDataSource;
20+
1921
@Configuration
2022
@EnableJpaRepositories(
2123
basePackages = {
@@ -40,9 +42,21 @@ public class MySqlConfig {
4042
@Primary
4143
@ConfigurationProperties(prefix = "spring.datasource")
4244
public DataSource mysqlDataSource() {
43-
return DataSourceBuilder.create().build();
45+
HikariDataSource dataSource = DataSourceBuilder.create()
46+
.type(HikariDataSource.class)
47+
.build();
48+
49+
// Hikari 커넥션 풀 설정
50+
dataSource.setMaximumPoolSize(10); // 최대 커넥션 수
51+
dataSource.setMinimumIdle(10); // 최소 유휴 커넥션
52+
dataSource.setIdleTimeout(30000); // 유휴 커넥션 유지 시간 (30초)
53+
dataSource.setConnectionTimeout(3000); // 커넥션 대기 시간 (3초)
54+
dataSource.setMaxLifetime(1800000); // 커넥션 최대 수명 (30분)
55+
56+
return dataSource;
4457
}
4558

59+
4660
@Bean(name = "mysqlEntityManagerFactory")
4761
@Primary
4862
public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory() {

src/main/java/com/example/log4u/common/oauth2/jwt/JwtAuthenticationFilter.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,20 @@ private boolean shouldSkipFilter(String requestUri) {
8484
}
8585

8686
private String extractAccessTokenFromCookie(HttpServletRequest request) {
87-
// 쿠키에서 access 토큰 추출
8887
String accessToken = null;
8988
Cookie[] cookies = request.getCookies();
90-
for (Cookie cookie : cookies) {
91-
if (cookie.getName().equals("access")) {
92-
accessToken = cookie.getValue();
89+
90+
if (cookies != null) {
91+
for (Cookie cookie : cookies) {
92+
if (cookie.getName().equals("access")) {
93+
accessToken = cookie.getValue();
94+
}
9395
}
9496
}
9597
return accessToken;
9698
}
9799

100+
98101
private boolean validateTokenExpiration(
99102
HttpServletResponse response,
100103
String accessToken

0 commit comments

Comments
 (0)