MSA(마이크로 서비스 아키텍처) 라는 말을 들으면 대부분의 개발팀에서 하는 말이 있습니다.

"이게 우리팀에 꼭 필요해?"

 

네. 저도 이렇게 생각합니다. MSA는 꼭 필요하지 않아요.

오히려 대부분의 스타트업과 작은 프로젝트에는 모놀리식 아키텍처가 합리적입니다.

 

1. 모놀리식 아키텍처는 실패인가?

 > 아닙니다. 많은 성공한 서비스들이 초기에는 모놀리식 아키텍처를 사용해왔습니다.

   MSA로 전환한것은 그 이후 필요해졌을 때입니다.

 

2. 모놀리식 아키텍처의 장점

 1) 개발속도 : 초기 개발이 빠르다

 2) 배포 단순화 : 한 번에 배포

 3) 운영 비용 : 서버 1~2대로 시작 가능

 4) 디버깅 : 문제 추적이 직관적

 

3. MSA로 전환이 필요한 상황

 1) 단일 서버에서는 트래픽이 감당 불가능한 수준일 때

 2) 팀 규모가 클 때 (코드충돌, 의존성으로 인한 병목 방지)

 3) 개발 속도가 중요하지 않고 안정성/보안이 최우선일 때

 4) 서로 다른 기술 스택 필요시

 5) 부분 장애를 피하기 위해

 

결론 : 

상황을 먼저 파악하고 결정한다.

 

분명 MSA를 사용할때의 확실한 이점이 있겠지만 

각 파트를 따로 처리할정도의 충분한 팀 규모가 없다면 의미가 없어질 가능성이 높고,

여러개 서버 상태를 추적해야하므로 디버깅도 복잡해질 것입니다.

 

팀 규모가 작다면, 모놀리식으로 충분합니다. 개발 속도에 집중하세요.

비즈니스가 성공해서 정말 필요해졌을 때, 그 때 아키텍처를 고민하면 됩니다.

'IT' 카테고리의 다른 글

크롬 https 자동 변환 해제  (0) 2026.01.07

특정도메인이 필요한 에디터의 기능 확인을 위해 hosts파일에 등록후 접속했으나

크롬에서 자동으로 https로 변환시키며 접속에 실패했다.

 

이 경우에는 크롬에서 해당 도메인의 hsts정책을 삭제한다.

 

1. 크롬 주소창에 입력후 접속

chrome://net-internals/#hsts

 

2. Delete domain security policies 에 해당 도메인 입력 후 삭제

 

이것도 귀찮으면 크롬 시크릿 모드로 접속하면 된다.

'IT' 카테고리의 다른 글

MSA를 꼭 써야하나요?  (0) 2026.01.20

Spring Boot와 JPA를 쓰면서 대량의 데이터를 넣을 때(Bulk Insert), 무작정 saveAll()을 믿었다가 낭패를 보는 경우가 있다. 특히 MySQL/MariaDB 환경에서 자주 겪는 성능 이슈와 OOM(Out Of Memory)의 원인, 그리고 해결책을 정리한다.

1. 문제상황
시나리오: 로그 데이터 10만 건을 repository.saveAll(list)로 저장 시도.
현상: 서버 메모리가 급증하고(GC 과부하), 쿼리 속도가 예상보다 훨씬 느림.

2. 왜 느릴까?
  1) 영속성 컨텍스트의 메모리 점유
    - JPA는 저장하는 모든 엔티티를 1차 캐시(영속성 컨텍스트)에 보관한다.
    - 10만 개의 객체가 트랜잭션이 끝날 때까지 메모리를 차지하고 있으니, 당연히 OOM 위험이 커진다.
  2) Identity 전략과 Batch Insert의 충돌
    - 보통 MySQL/MariaDB에서는 PK 생성 전략으로 GenerationType.IDENTITY(Auto Increment)를 많이 쓴다.
    - 하지만 JPA(Hibernate)는 IDENTITY 전략을 쓸 때 Batch Insert(묶음 저장)를 비활성화한다.
      [이유] Auto Increment는 DB에 실제로 INSERT를 해야만 PK 값을 알 수 있다.
      [결과] JPA는 PK를 미리 알 수 없으니 "묶어서 보내기(Write-Behind)"를 포기하고, 10만 번의 INSERT 쿼리를 하나씩 날린다.

3. 해결책
  1)  JdbcTemplate 사용하기
    - JPA의 영속성 컨텍스트를 우회해서, JDBC 레벨에서 직접 쿼리를 날리는 것이 가장 깔끔하고 빠르다.

jdbcTemplate.batchUpdate(
    "INSERT INTO event_history (col1, col2) VALUES (?, ?)",
    new BatchPreparedStatementSetter() {
        @Override
        public void setValues(PreparedStatement ps, int i) throws SQLException {
            ps.setString(1, list.get(i).getCol1());
            ps.setString(2, list.get(i).getCol2());
        }
        @Override
        public int getBatchSize() {
            return list.size(); // 한 번에 보낼 크기
        }
    }
);


  2) 굳이 JPA를 써야 한다면 끊어서 저장하기
    - 비즈니스 로직상 엔티티가 꼭 필요하다면, 리스트를 1,000개 정도씩 끊어서 저장하고 영속성 컨텍스트를 비워준다.

for (int i = 0; i < list.size(); i++) {
    repository.save(list.get(i));
    if (i % 1000 == 0) { // 1000건마다 비우기
        entityManager.flush();
        entityManager.clear();
    }
}


주의) 이 방법은 메모리 문제는 해결해주지만, Identity 전략으로 인한 속도 저하(건별 Insert)는 해결하지 못한다.

가장 최근 커밋 1개를 취소하고 되돌리는 방법.

Reset 3가지 모드

git reset [모드] HEAD~1 로 사용.


모드 옵션 동작 활용
Soft --soft 커밋만 취소 (변경분은 Staging에 남음) 메시지만 고쳐서 바로 재커밋할 때
Mixed (기본) 커밋 취소 + Unstage (변경분은 파일에 남음) 파일을 다시 골라 담을 때 (add 다시 하려고)
Hard --hard 싹 다 삭제 (파일 내용도 날아감) 작업 내용을 아예 버릴 때

 

상황 A: 커밋 메시지만 수정 (--soft)

코드는 그대로 두고 커밋만 풀기

[bash]
git reset --soft HEAD~1
git commit -m "수정된 메시지"

 

상황 B: 파일 다시 골라 담기 (Mixed)

커밋 풀고 Staging도 해제해서 원하는 것만 다시 add

 
[bash]
git reset HEAD~1
git add 원하는_파일
git commit -m "재커밋"

 

주의사항

  1. Push한 커밋은 Reset 금지: 팀원들 코드 꼬임. 이미 올렸으면 git revert 써야 함.
  2. Hard Reset 조심: 파일 내용까지 다 지워짐. 복구 힘드니까 신중하게.

'GIT' 카테고리의 다른 글

[Git command] Local Storage 브랜치 삭제  (0) 2024.05.26

주로 데이터베이스 쿼리에서 반환된 결과가 너무 많을 때 발생한다.

1. 잘못된 조건: 데이터베이스 쿼리에 잘못된 조건이 포함되어 있어서 예상보다 많은 결과를 반환하는 경우
- ex) 1개의 데이터가 반환되어야 하지만 내가 짠 쿼리의 조건으로는 2개의 데이터가 반환될 때

2. 중복된 데이터: 쿼리 결과에 중복된 데이터가 포함되어 있어서 예상보다 많은 결과가 반환되는 경우
- 이 경우 데이터 중복을 방지하거나 적절한 DISTINCT나 GROUP BY 절을 사용하여 해결할 수 있다.

3. 조인 문제: 쿼리에 잘못된 조인이 포함되어 있어서 결과가 예상치 못하게 확장되는 경우
- 각 조인이 맞는 방향으로 걸려있는지 확인한다.

'DB' 카테고리의 다른 글

[Dbeaver] MariaDB 드라이버 설치불가  (0) 2024.05.26
MSSQL MERGE INTO문  (0) 2024.05.26

[에러상황] MariaDB 연결중 MariaDB 드라이버 다운로드 불가.

 

[에러코드] Network error

이유: Network unavailable due to a certificate issue. Try changing the setting Use Windows trust store in Preferences->Connections and restart DBeaver. It might help if you haven't overridden the trust store. javax.net.ssl.SSLHandshakeException:PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

 

[조치법] 상단 [윈도우]메뉴 - 설정 - 연결 -> Use Windows trust store 해제

'DB' 카테고리의 다른 글

TooManyResultException 에러 해결  (0) 2024.05.28
MSSQL MERGE INTO문  (0) 2024.05.26

Sourcetree, GitHub Desktop 등 UI에서 브랜치삭제에 문제가 생겼을 때 강제로 삭제하는 방법이다.

 

1. git branch -> Local 브랜치명 검색

2. git branch -D [브랜치명]

 

'GIT' 카테고리의 다른 글

[Git Command] commit 실수 되돌리기  (0) 2025.02.21

MERGE INTO란?

데이터가 있으면 UPDATE, 없으면 INSERT를 한 번에 처리하는 SQL 문법. UPSERT(Update + Insert)라고도 함.

 

쿼리 예시

MERGE INTO 게시판 AS a
USING (SELECT 1 AS dual) AS b
ON (a.SEQ = 100)
WHEN MATCHED THEN
UPDATE SET CONTENT = '수정된 내용'
WHEN NOT MATCHED THEN
INSERT(TITLE, CONTENT, CREATE_AT)
VALUES('새 제목', '새 내용', '2026-01-05');

 

각 부분 설명

MERGE INTO 게시판 AS a UPDATE 또는 INSERT할 대상 테이블
USING (SELECT 1 AS dual) AS b 비교할 데이터 소스 (다른 테이블 안 쓸 때 더미 사용)
ON (a.SEQ = 100) 조건식 (SEQ가 100인 데이터 존재 여부 판단)
WHEN MATCHED THEN UPDATE 조건 (데이터 존재)일 때 UPDATE 실행
WHEN NOT MATCHED THEN INSERT 조건 거짓(데이터 없음)일 때 INSERT 실행

 

핵심 포인트

테이블명은 MERGE INTO 옆에 한 번만 작성

ON 조건식으로 데이터 존재 여부 판단

한 쿼리로 UPDATE와 INSERT 동시 처리 가능

 

실무 활용

USING 절에 다른 테이블이나 서브쿼리 사용 시 대량 데이터 병합 가능

DELETE도 WHEN MATCHED THEN DELETE WHERE 조건으로 추가 가능

'DB' 카테고리의 다른 글

TooManyResultException 에러 해결  (0) 2024.05.28
[Dbeaver] MariaDB 드라이버 설치불가  (0) 2024.05.26

+ Recent posts