-
Notifications
You must be signed in to change notification settings - Fork 0
[Feature] Config Server, Database per Service, Circuit Breaker 구현 #8
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
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # MySQL Database Credentials | ||
| # IMPORTANT: Copy this file to .env and change the values before deploying! | ||
| # cp .env.example .env | ||
|
|
||
| # MySQL Root Password | ||
| # Use a strong password with at least 16 characters including uppercase, lowercase, numbers, and special characters | ||
| MYSQL_ROOT_PASSWORD=your-strong-root-password-here | ||
|
|
||
| # MySQL User Password | ||
| # Use a strong password with at least 16 characters including uppercase, lowercase, numbers, and special characters | ||
| MYSQL_USER_PASSWORD=your-strong-user-password-here |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
api-gateway/src/main/java/com/example/gateway/FallbackController.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| package com.example.gateway; | ||
|
|
||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
| import org.springframework.http.HttpStatus; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| import java.time.LocalDateTime; | ||
| import java.util.HashMap; | ||
| import java.util.Map; | ||
|
|
||
| /** | ||
| * Circuit Breaker가 OPEN 상태일 때 실행되는 Fallback 컨트롤러 | ||
| * 서비스 장애 시 사용자에게 적절한 응답 제공 | ||
| */ | ||
| @RestController | ||
| @RequestMapping("/fallback") | ||
| public class FallbackController { | ||
| private static final Logger log = LoggerFactory.getLogger(FallbackController.class); | ||
|
|
||
| /** | ||
| * User Service 장애 시 Fallback 응답 | ||
| */ | ||
| @GetMapping("/user-service") | ||
| public ResponseEntity<Map<String, Object>> userServiceFallback() { | ||
| return createFallbackResponse("user-service", | ||
| "User 서비스가 일시적으로 사용 불가능합니다. 잠시 후 다시 시도해주세요."); | ||
| } | ||
|
|
||
| /** | ||
| * Order Service 장애 시 Fallback 응답 | ||
| */ | ||
| @GetMapping("/order-service") | ||
| public ResponseEntity<Map<String, Object>> orderServiceFallback() { | ||
| return createFallbackResponse("order-service", | ||
| "Order 서비스가 일시적으로 사용 불가능합니다. 잠시 후 다시 시도해주세요."); | ||
| } | ||
|
|
||
| /** | ||
| * 공통 Fallback 응답 생성 메서드 | ||
| * | ||
| * @param serviceName 서비스 이름 | ||
| * @param message 사용자에게 표시할 메시지 | ||
| * @return Fallback 응답 | ||
| */ | ||
| private ResponseEntity<Map<String, Object>> createFallbackResponse(String serviceName, String message) { | ||
| log.warn("Circuit breaker activated for service: {}", serviceName); | ||
|
|
||
| Map<String, Object> response = new HashMap<>(); | ||
| response.put("status", "SERVICE_UNAVAILABLE"); | ||
| response.put("message", message); | ||
| response.put("timestamp", LocalDateTime.now()); | ||
| response.put("service", serviceName); | ||
|
|
||
| return ResponseEntity | ||
| .status(HttpStatus.SERVICE_UNAVAILABLE) | ||
| .body(response); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| # Multi-stage build for optimization | ||
| FROM gradle:8.5-jdk21 AS builder | ||
| WORKDIR /app | ||
|
|
||
| # Copy Gradle files | ||
| COPY build.gradle settings.gradle ./ | ||
| COPY gradle ./gradle | ||
|
|
||
| # Copy source code | ||
| COPY config-server ./config-server | ||
|
|
||
| # Build the application | ||
| RUN gradle :config-server:bootJar --no-daemon | ||
|
|
||
| # Runtime stage | ||
| FROM eclipse-temurin:21-jre | ||
| WORKDIR /app | ||
|
|
||
| # Install curl for healthcheck | ||
| RUN apt-get update && \ | ||
| apt-get install -y curl && \ | ||
| apt-get clean && \ | ||
| rm -rf /var/lib/apt/lists/* | ||
|
|
||
| # Create non-root user for security | ||
| RUN addgroup --system spring && adduser --system --ingroup spring spring | ||
| USER spring:spring | ||
|
|
||
| # Copy JAR from builder | ||
| COPY --from=builder /app/config-server/build/libs/*.jar app.jar | ||
|
|
||
| EXPOSE 8888 | ||
| ENTRYPOINT ["java", "-jar", "app.jar"] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| plugins { | ||
| id 'org.springframework.boot' version '3.1.5' | ||
| } | ||
|
|
||
| dependencies { | ||
| implementation 'org.springframework.cloud:spring-cloud-config-server' | ||
| implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' | ||
| implementation 'org.springframework.boot:spring-boot-starter-actuator' | ||
| } |
13 changes: 13 additions & 0 deletions
13
config-server/src/main/java/com/example/configserver/ConfigServerApplication.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package com.example.configserver; | ||
|
|
||
| import org.springframework.boot.SpringApplication; | ||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
| import org.springframework.cloud.config.server.EnableConfigServer; | ||
|
|
||
| @SpringBootApplication | ||
| @EnableConfigServer // Config Server 활성화 | ||
| public class ConfigServerApplication { | ||
| public static void main(String[] args) { | ||
| SpringApplication.run(ConfigServerApplication.class, args); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| server: | ||
| port: 8888 | ||
|
|
||
| spring: | ||
| application: | ||
| name: config-server | ||
| cloud: | ||
| config: | ||
| server: | ||
| native: | ||
| search-locations: classpath:/config | ||
|
|
||
| management: | ||
| endpoints: | ||
| web: | ||
| exposure: | ||
| include: health,info | ||
| endpoint: | ||
| health: | ||
| show-details: always | ||
|
|
||
| eureka: | ||
| client: | ||
| service-url: | ||
| defaultZone: http://eureka-server:8761/eureka/ # Docker 환경용 | ||
| instance: | ||
| prefer-ip-address: true | ||
|
|
||
| logging: | ||
| level: | ||
| org.springframework.cloud.config: DEBUG |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| server: | ||
| port: 8888 # Config Server 포트 | ||
|
|
||
| spring: | ||
| application: | ||
| name: config-server | ||
| profiles: | ||
| active: native # 파일 시스템 기반 설정 사용 (Git도 가능) | ||
| cloud: | ||
| config: | ||
| server: | ||
| native: | ||
| search-locations: classpath:/config # 설정 파일 위치 | ||
|
|
||
| management: | ||
| endpoints: | ||
| web: | ||
| exposure: | ||
| include: health,info | ||
| endpoint: | ||
| health: | ||
| show-details: always | ||
|
|
||
| eureka: | ||
| client: | ||
| service-url: | ||
| defaultZone: http://localhost:8761/eureka/ | ||
| instance: | ||
| prefer-ip-address: true | ||
|
|
||
| logging: | ||
| level: | ||
| org.springframework.cloud.config: DEBUG |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| server: | ||
| port: 8080 | ||
|
|
||
| spring: | ||
| cloud: | ||
| gateway: | ||
| routes: | ||
| # User Service 라우팅 | ||
| - id: user-service | ||
| uri: lb://user-service # lb = load balanced (Eureka로 찾기) | ||
| predicates: | ||
| - Path=/api/users/** | ||
| filters: | ||
| - name: CircuitBreaker | ||
| args: | ||
| name: userServiceCircuitBreaker | ||
| fallbackUri: forward:/fallback/user-service | ||
| - RewritePath=/api/users/(?<segment>.*), /$\{segment} | ||
|
|
||
| # Order Service 라우팅 | ||
| - id: order-service | ||
| uri: lb://order-service | ||
| predicates: | ||
| - Path=/api/orders/** | ||
| filters: | ||
| - name: CircuitBreaker | ||
| args: | ||
| name: orderServiceCircuitBreaker | ||
| fallbackUri: forward:/fallback/order-service | ||
| - RewritePath=/api/orders/(?<segment>.*), /$\{segment} | ||
|
|
||
| discovery: | ||
| locator: | ||
| enabled: true | ||
| lower-case-service-id: true | ||
|
|
||
| eureka: | ||
| client: | ||
| service-url: | ||
| defaultZone: http://localhost:8761/eureka/ | ||
| instance: | ||
| prefer-ip-address: true | ||
|
|
||
| # Resilience4j Circuit Breaker 설정 | ||
| resilience4j: | ||
| circuitbreaker: | ||
| configs: | ||
| default: | ||
| registerHealthIndicator: true | ||
| slidingWindowSize: 10 # 최근 10개 요청 기준으로 판단 | ||
| minimumNumberOfCalls: 5 # 최소 5번 호출 후 동작 | ||
| failureRateThreshold: 50 # 실패율 50% 이상이면 OPEN | ||
| waitDurationInOpenState: 10000 # OPEN 상태에서 10초 대기 | ||
| permittedNumberOfCallsInHalfOpenState: 3 # HALF_OPEN에서 3번 테스트 | ||
| slowCallDurationThreshold: 2000 # 2초 이상이면 느린 호출 | ||
| slowCallRateThreshold: 50 # 느린 호출 50% 이상이면 OPEN | ||
| instances: | ||
| userServiceCircuitBreaker: | ||
| baseConfig: default | ||
| orderServiceCircuitBreaker: | ||
| baseConfig: default | ||
|
|
||
| timelimiter: | ||
| configs: | ||
| default: | ||
| timeoutDuration: 3s # 3초 타임아웃 | ||
|
|
||
| logging: | ||
| level: | ||
| org.springframework.cloud.gateway: DEBUG | ||
| io.github.resilience4j: DEBUG |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| server: | ||
| port: 8082 | ||
|
|
||
| spring: | ||
| datasource: | ||
| url: jdbc:mysql://mysql-order:3306/orderdb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC | ||
| driverClassName: com.mysql.cj.jdbc.Driver | ||
| username: user | ||
| password: password | ||
yesrin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| jpa: | ||
| hibernate: | ||
| ddl-auto: update | ||
| show-sql: true | ||
| properties: | ||
| hibernate: | ||
| dialect: org.hibernate.dialect.MySQLDialect | ||
| format_sql: true | ||
|
|
||
| eureka: | ||
| client: | ||
| service-url: | ||
| defaultZone: http://localhost:8761/eureka/ | ||
| instance: | ||
| prefer-ip-address: true | ||
|
|
||
| logging: | ||
| level: | ||
| com.example: DEBUG | ||
|
|
||
| # 추가 설정: 비즈니스 로직 관련 | ||
| app: | ||
| order: | ||
| max-order-amount: 1000000 | ||
| delivery-fee: 3000 | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.