Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
a18adf8
feat: 모듈 분리를 위한 설정 파일 추가 및 수정(websocket 모듈용 application.yml, build.gr…
waitAmhee Nov 10, 2025
29f58bf
refactor: 기존의 코드 infra 모듈에서 websocket 모듈로 이동
waitAmhee Nov 10, 2025
10cb821
feat : LiveStockPriceWebSocketService 클래스 분리
waitAmhee Nov 10, 2025
2f469b5
refactor: 필요없는 코드 삭제 및 수정
waitAmhee Nov 10, 2025
cf61267
refactor: 기존에는 같은 서버 내에서만 이벤트를 발행/구독 -> Redis Pub/Sub을 통해 서버 간 통신이 가능…
waitAmhee Nov 10, 2025
86e9d37
refactor: 서버-클라, 증권사-서버 패키지 분리
waitAmhee Nov 10, 2025
f874696
refactor: 로그정리 및 서버-클라, 증권사-서버 패키지 분리 이후 -> 자동 패키지 리팩토링된 클래스
waitAmhee Nov 10, 2025
3da425e
fix: predestroy 실행 전에 redis가 닫혀버려서 redisTemplate 접근 중 에러 발생 -> Redis …
waitAmhee Nov 10, 2025
1598640
feature: websocket 용 build.gradle파일 추가
waitAmhee Nov 10, 2025
987fc74
refactor: DockerFile 이름 변경
waitAmhee Nov 10, 2025
29e6ade
fix: ecr repository를 fintory로 통일, 태그로 구분
waitAmhee Nov 10, 2025
2947c97
fix: ecr repository를 fintory-child로 통일
waitAmhee Nov 10, 2025
13705a0
fix: application.yml -> 프로필명 통일
waitAmhee Nov 10, 2025
307d8dd
refactor: 필요없는 코드 삭제
waitAmhee Nov 10, 2025
c9be4ba
fix : EC2 간 Bean 의존성 분리 (Service/Repository 직접 참조 제거)
waitAmhee Nov 10, 2025
7ce27f3
fix : child 모듈에서 websocket 모듈 삭제
waitAmhee Nov 11, 2025
9abb802
fix : appcliation.yml 변수 활용 방식 변경
waitAmhee Nov 11, 2025
7e989e2
fix : 들여쓰기 에러 수정
waitAmhee Nov 11, 2025
9c091df
fix : 빈 의존성 수정
waitAmhee Nov 11, 2025
3743bc7
fix : WebSocket 종료 시 Redis 연결 에러 해결
waitAmhee Nov 11, 2025
58fb44c
fix : @EnableJpaAuditing 추가
waitAmhee Nov 11, 2025
eb7fa26
fix : actuator 의존성 추가 + 토큰 발급 주기 23시간 -> 8시간으로 변경
waitAmhee Nov 12, 2025
393e3ab
fix : SecurityConfig 추가 -> 그라파나 대시보드 추가를 위해서.
waitAmhee Nov 12, 2025
0d613a5
fix : dependson 제거
waitAmhee Nov 13, 2025
f3b7092
fix : redis replica 설정 해제
waitAmhee Nov 14, 2025
3b381d5
fix : redis replica 설정 추가(테스트)
waitAmhee Nov 14, 2025
f40ef53
feat: 증권사를 대체할 외부 stock data 생성기로 부터 webflux서버로 웹소켓 연결하여 실시간 데이터 받는 기…
happyAndy0412 Nov 15, 2025
0d3434f
feat: rsocket 프로토콜을 이용한 라우팅 클래스 및 설정클래스 생성
happyAndy0412 Nov 18, 2025
c726682
feat: webflux 모듈 cicd 스크립트 추가
happyAndy0412 Nov 18, 2025
bdc8720
feat: 설정 프로파일 적용
happyAndy0412 Nov 18, 2025
a7353ac
fix: 설정 파일에 rsocket추가 + 오타 제거
happyAndy0412 Nov 18, 2025
9df5a96
chore: webflux 모듈에 모니터링 메트릭용 엔드포인트 추가
happyAndy0412 Nov 18, 2025
4299d2a
fix: rsocket 포트 매핑 추가
happyAndy0412 Nov 19, 2025
e5ea4dd
fix: rsocket 서버를 모든 네트워크 인터페이스에 바인딩
happyAndy0412 Nov 19, 2025
1f67825
chore: rsocket 디버깅 로그 추가
happyAndy0412 Nov 19, 2025
10b5411
chore: 설정 파일 중복으로 인한 프로파일 미적용 오류 -> 이름 변경
happyAndy0412 Nov 19, 2025
8b4d242
chore: 설정 파일 변경에 따른 도커파일 수정
happyAndy0412 Nov 19, 2025
acd1769
fix: 오타 수정
happyAndy0412 Nov 19, 2025
68b4af3
fix: 오타 수정
happyAndy0412 Nov 19, 2025
6cd62c8
fix: 원인이 아닌 것 같아 롤백
happyAndy0412 Nov 19, 2025
22f902a
Revert "revert: 롤백"
happyAndy0412 Nov 19, 2025
e6351c7
chore: 로그 삭제
happyAndy0412 Nov 19, 2025
35362b6
feat: micrometer, actuator 의존성 추가
happyAndy0412 Nov 19, 2025
68df0af
feat: rsocket이 기본으로 micrometer를 내장하지 않아 수동으로 의존성 추가
happyAndy0412 Nov 19, 2025
e694922
fix: 실시간 전파가 목적이므로 데이터 처리 방식 변경(과거 데이터 저장 불필요)
happyAndy0412 Nov 19, 2025
6bbfeb5
chore: 서버에 너무 많은 데이터 수신 로그가 쌓여 제거
happyAndy0412 Nov 19, 2025
907c439
feat: pub과 sub용 sink리턴 메소드를 따로 정의. 백프레셔 옵션 추가
happyAndy0412 Nov 20, 2025
58bf965
chore: docker-compose 방식으로 변경
happyAndy0412 Nov 23, 2025
17db734
chore: cicd 테스트
happyAndy0412 Nov 23, 2025
b22406d
chore: env 파일 생성
happyAndy0412 Nov 25, 2025
2b5c9b8
ehm: 힙메모리 할당량 700m로 증량
happyAndy0412 Nov 25, 2025
4e85483
ehm: 메모리 초기 크기 700 -> 500
happyAndy0412 Nov 25, 2025
2fdf4d7
ehm: 메모리 최대 크기 700 -> 500
happyAndy0412 Nov 25, 2025
03d29d3
ehm: autocancel 옵션 해제
happyAndy0412 Nov 25, 2025
9826727
ehm: autocancel 옵션 롤백
happyAndy0412 Nov 25, 2025
3337c2f
ehm: 힙메모리 할당량 350m로 증량
happyAndy0412 Nov 25, 2025
2d31f08
ehm: 힙 덤프파일 생성 옵션 추가 + 네이티브 메모리 모니터링 옵션 추가
happyAndy0412 Nov 25, 2025
a801af2
chore: 모듈 별 배포 스크립트 생성 + webflux 모듈 gc(serialGC -> g1gc)
happyAndy0412 Nov 25, 2025
5094661
chore: 불필요하게 크게 예약된 네이티브 메모리 영역 크기 제한
happyAndy0412 Nov 26, 2025
45749d7
ehm: 모든 구독자가 구독을 해제할 시, 해당 싱크 객체를 map에서 제거 -> 연관된 객체(특히 mat으로 확인한 5만 …
happyAndy0412 Nov 26, 2025
89f81fb
chore: 도커 타임존 설치 명령 삭제
happyAndy0412 Nov 26, 2025
cdac8f5
chore: 도커 빌드킷 레이어 캐시 활용하기 위해 명령어 분할
happyAndy0412 Nov 26, 2025
90ec054
chore: 주석 제거
happyAndy0412 Nov 26, 2025
7fbbac2
chore: settings.gradle 인식할 수 있게 빌드 컨텍스트 루트로 변경
happyAndy0412 Nov 27, 2025
a6eb72e
chore: application-deploy-webflux.yml 파일 인식할 수 있게 경로 지정
happyAndy0412 Nov 27, 2025
4558a9d
chore: 파일 인식할 수 있게 경로 지정
happyAndy0412 Nov 27, 2025
6a28138
ehm: 캐시 마운트 + 깃액션의 휘발성을 고려하여 원격 캐시 적용
happyAndy0412 Nov 27, 2025
34252a0
chore: 누락된 도커빌드 드라이버 추가
happyAndy0412 Nov 27, 2025
097a86b
chore: jre -> jdk
happyAndy0412 Nov 27, 2025
3b38587
chore: 도커헙 푸쉬 제외
happyAndy0412 Nov 27, 2025
5845af3
chore: JAVA_OPTS 인식 위해 쉘 형식으로 ENTRYPOINT 수정
happyAndy0412 Nov 27, 2025
83e4540
test: 도커 캐시 테스트
happyAndy0412 Nov 27, 2025
d5d34f4
fix: 소스 코드 변경시 빌드는 무조건 실행되기때문에 의존성에만 캐시 마운트 설정. 빌드에는 제거
happyAndy0412 Nov 27, 2025
364c73a
test: 도커 캐시 테스트
happyAndy0412 Nov 27, 2025
5e821ac
fix: 빌드 아키텍쳐 변경
happyAndy0412 Nov 27, 2025
d6e7bc3
fix: 빌드 아키텍쳐 변경
happyAndy0412 Nov 27, 2025
025cd74
test: 소스코드 수정 사항 변경 확인용 로깅 클래스 생성
happyAndy0412 Nov 27, 2025
98aa0bd
ehm: account 데드락 디버깅
happyAndy0412 Dec 4, 2025
453c0e2
ehm: account 데드락 디버깅위해 의심 구간 제외 주석처리
happyAndy0412 Dec 4, 2025
81ada21
ehm: account 데드락 디버깅위해 의심 구간 제외 주석처리
happyAndy0412 Dec 4, 2025
57dad08
ehm: account 데드락 디버깅위해 의심 구간 제외 주석처리
happyAndy0412 Dec 4, 2025
eed16c3
ehm: account 데드락 디버깅위해 의심 구간 제외 주석처리
happyAndy0412 Dec 4, 2025
d920609
ehm: account 데드락 디버깅위해 의심 구간 제외 주석처리
happyAndy0412 Dec 4, 2025
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
90 changes: 90 additions & 0 deletions .github/workflows/deploy-webflux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Fintory Webflux Module CI/CD
on:
push:
branches: [ "dev" ]
pull_request:
branches: [ "dev" ]

env:
AWS_REGION: ap-northeast-2

jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'

- name: Grant permission to gradlew
run: chmod +x ./gradlew

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1

- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Docker build and push websocket-webflux
run: |
ECR_REGISTRY=${{ steps.login-ecr.outputs.registry }}
FINAL_IMAGE="${ECR_REGISTRY}/fintory-child:webflux-latest"
CACHE_IMAGE="${ECR_REGISTRY}/fintory-child:webflux-cache"

docker buildx build \
-t "${FINAL_IMAGE}" \
-f ./websocket-webflux/Dockerfile . \
--platform linux/amd64 \
--push \
--cache-from type=registry,ref="${CACHE_IMAGE}" \
--cache-to type=registry,ref="${CACHE_IMAGE}",mode=max

deploy-webflux:
needs: build-and-push
runs-on: ubuntu-latest
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1

- name: Deploy fintory-webflux to EC2
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.FINTORY_WEBFLUX_HOST }}
username: ubuntu
key: ${{ secrets.EC2_SSH_KEY }}
script: |
export ECR_REGISTRY=${{ steps.login-ecr.outputs.registry }}

aws ecr get-login-password --region ap-northeast-2 | \
docker login --username AWS --password-stdin ${{ steps.login-ecr.outputs.registry }}

TARGET_IMAGE="${ECR_REGISTRY}/fintory-child:webflux-latest"
docker pull ${TARGET_IMAGE}

echo "TARGET_IMAGE=${TARGET_IMAGE}" > .env

docker compose down
docker compose up -d

docker image prune -f
99 changes: 99 additions & 0 deletions .github/workflows/deploy-websocket.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
name: Fintory Websocket Module CI/CD
on:
push:
branches: [ "dev" ]
pull_request:
branches: [ "dev" ]

env:
AWS_REGION: ap-northeast-2

jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'

- name: Grant permission to gradlew
run: chmod +x ./gradlew

- name: Cache Gradle
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1

- name: Build and push websocket
run: |
./gradlew :websocket:clean build
docker build -t websocket:latest ./websocket
docker tag websocket:latest ${{ steps.login-ecr.outputs.registry }}/fintory-child:websocket-latest
docker push ${{ steps.login-ecr.outputs.registry }}/fintory-child:websocket-latest

deploy-websocket:
needs: build-and-push
runs-on: ubuntu-latest
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1

- name: Deploy fintory-websocket to EC2
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.FINTORY_WEBSOCKET_HOST }}
username: ubuntu
key: ${{ secrets.EC2_WEBSOCKET_SSH_KEY }}
script: |
export ECR_REGISTRY=${{ steps.login-ecr.outputs.registry }}
export RDS_URL=${{ secrets.RDS_URL }}
export RDS_USERNAME=${{ secrets.RDS_USERNAME }}
export RDS_PASSWORD=${{ secrets.RDS_PASSWORD }}
export AWS_REDIS_HOST=${{ secrets.FINTORY_CHILD_PRIVATE_HOST }}
export AWS_REDIS_PASSWORD=${{ secrets.AWS_REDIS_PASSWORD }}
export HANTU_APPKEY=${{ secrets.HANTU_APPKEY}}
export HANTU_APPSECRET=${{ secrets.HANTU_APPSECRET}}
export DB_APPKEY=${{ secrets.DB_APPKEY}}
export DB_APPSECRET=${{ secrets.DB_APPSECRET}}
export EOS_API_KEY=${{ secrets.EOS_API_KEY}}


aws ecr get-login-password --region ap-northeast-2 | \
docker login --username AWS --password-stdin ${{ steps.login-ecr.outputs.registry }}

docker pull ${{ steps.login-ecr.outputs.registry }}/fintory-child:websocket-latest

docker compose down
docker compose up -d

docker image prune -f

4 changes: 2 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,15 @@ jobs:
export OPENAI_MODEL=${{ secrets.OPENAI_MODEL}}
export OPENAI_TEMPERATURE=${{secrets.OPENAI_TEMPERATURE}}
export OPENAI_MAX_TOKENS=${{secrets.OPENAI_MAX_TOKENS}}
export WEBSOCKET_PRIVATE_HOST=${{secrets.WEBSOCKET_PRIVATE_HOST}}
export FIREBASE_CONFIG='${{secrets.FIREBASE_CONFIG}}'

aws ecr get-login-password --region ap-northeast-2 | \
docker login --username AWS --password-stdin ${{ steps.login-ecr.outputs.registry }}
docker login --username AWS --password-stdin ${{ steps.login-ecr.outputs.registry }}

docker pull ${{ steps.login-ecr.outputs.registry }}/fintory-child:latest

docker compose down
docker compose up -d

docker image prune -f

1 change: 1 addition & 0 deletions app-child/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ dependencies {
implementation project(':domain')
implementation project(':infra')
implementation project(':auth')
implementation project(":websocket")


/* .env 자동 로딩 */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
@SpringBootApplication(scanBasePackages = {
"com.fintory.infra",
"com.fintory.auth",
"com.fintory.child"
"com.fintory.child",
})
@ConfigurationPropertiesScan(basePackages = {
"com.fintory.auth"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
import com.fintory.domain.stock.dto.korean.response.StockSearchResponse;
import com.fintory.domain.stock.dto.websocket.MarketStatusResponse;
import com.fintory.domain.stock.service.common.CommonStockService;
import com.fintory.domain.stock.service.websocket.LiveStockPriceWebsocketService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

Expand All @@ -20,22 +21,27 @@
public class CommonStockControllerImpl implements CommonStockController {

private final CommonStockService commonStockService;
private final LiveStockPriceWebsocketService websocketService;
private final RestTemplate restTemplate;

@Value("${websocket.server.url}")
private String websocketServerUrl;


//주식 종목 검색
@Override
@GetMapping("/search")
public ResponseEntity<ApiResponse<List<StockSearchResponse>>> searchStock(@RequestParam String keyword) {
List<StockSearchResponse> stockSearchRespons = commonStockService.searchStock(keyword);
return ResponseEntity.ok(ApiResponse.ok(stockSearchRespons));
List<StockSearchResponse> stockSearchResponse = commonStockService.searchStock(keyword);
return ResponseEntity.ok(ApiResponse.ok(stockSearchResponse));
}

//장시간 리턴
@Override
@GetMapping("/opened-market")
public ResponseEntity<ApiResponse<MarketStatusResponse>> getMarketStatus(){
return ResponseEntity.ok(ApiResponse.ok(websocketService.getMarketStatus()));
String url = "http://"+websocketServerUrl+":8080" + "/api/websocket/market/status";
MarketStatusResponse response = restTemplate.getForObject(url, MarketStatusResponse.class);
return ResponseEntity.ok(ApiResponse.ok(response));
}

}

This file was deleted.

Loading
Loading