#설치와동시에 #velog1일차 #바로바로기록해보기 공식 문서 → https://docs.docker.com/desktop/setup/install/windows-install/ 설치관련 유튜브 영상 : https://youtu.be/5Mfe54238xE?si=ss8tqEOexy7ooU03 (다른거 볼 필요 없다. 20분 미만, 내부 설명란에 위의 공식문서도 있음) 로그인하고 image 다운까지 내부에서 받으면 위의 캡쳐와 같이 뜬다 그 과정은 위와같이 터미널에서 인도유튜버를 그대로 따라했다. 아 그리고 처음에 도커를 깔기전 powershell에서 리눅스 설치도 필요하다. 그 이유는 다음 주차 도커에 대해서 배울때 같이 정리해보겠다.
malloc 예시: 주차장에서 자동차를 주차하는 발렛 요원의 업무 알고리즘 필요해보이는 개념: 청크, 페이지, OS 간에 상호작용 malloc 에 대한 현재 내 생각 문제의식: 컴파일 타임에 증명할 수 없는 데이터를 담기 위한 그릇이 필요하다. 현실은 아마도 카오스 세계일 것이기에 런타임의 데이터를 100% 예측할 수 없을 것이고, 단 하나의 완벽한 malloc 함수는 없을 것이다. 그래서 수십 년동안 IT 에서 이 난제를 풀기 위해 고민해왔다. 불확실한 상황에서 하드웨어 리소스를 어떻게 사용할 것인가? 메모리 활용도 높이기 (트레이드오프: Latency) 처리 속도 높이기 (트레이드오프: Fragmentation) 당연히 다양한 맥락이 있을 것이고, 특정한 맥락이 조금씩 바뀔지라도, 경향성이 패턴으로 포착되는 한, 나름의 적당한 해법(특정한 malloc 알고리즘)이 있을 것이다. 의문: malloc() 은 왜 void* 를 return 하는가? 할당해준 메모리에 호출자가 어떤 타입의 데이터를 담을지 미리 알 수 없기 때문 malloc() 입장에서 타입을 몰라도 모든 타입에 대해 범용적으로 메모리를 할당 만약 C언어에서 void*가 없었다면, 타입마다 함수를 따로 만들어야 했을 것임 malloc_int() malloc_char() malloc_struct_node() 등등... C언어 규칙상 void* 는 어떤 포인터 타입으로든 명시적인 캐스팅 없이 암묵적으로 형변환된다 (Implicit Conversion). 반환값을 임의의 특정 포인터 변수에 그대로 대입할 수 있다. int *arr = malloc(sizeof(int) * 10); char *str = malloc(sizeof(char) * 32); struct Node *node = malloc(sizeof(struct Node)); malloc() 은 타입 정보가 없기에 데이터 해석 규칙이나 크기 정보를 모른다. 순수하게 물리적 메모리 시작 위치만 건네준다. 특정 포인터의 타입은 컴파일러에게 "이 주소에서 몇 바이트를 읽어야 하는가", "포인터 연산(p + 1) 시 몇 바이트를 건너뛰어야 하는가" 를 알려준다. int *p; -> p + 1 은 4바이트 이동 double *p; -> p + 1 은 8바이트 이동 void *p; -> 가리키는 대상의 크기 정보가 없음 결론: 성공해서 정상적인 주소를 주든, 실패해서 NULL을 주든, 기계어 관점에서는 8바이트 주소 레지스터(%rax)를 쓰는 void * 타입 포인터를 반환하는 것은 고정이다.
1. 오늘의 한 줄 요약 Spring Boot를 이용한 백엔드 개발 학습을 마무리하고, 하나의 애플리케이션을 여러 개의 작은 서비스로 나누어 개발하고 운영하는 MSA(Microservice Architecture) 의 기본 개념과 Spring Cloud의 역할을 알아보았다. 2. MSA란? MSA는 하나의 애플리케이션을 비즈니스 기능에 따라 여러 개의 작은 서비스로 나누는 아키텍처다. 각 서비스는 자신이 담당하는 기능을 독립적으로 개발하고 실행하며 배포할 수 있다. 필요한 경우 다른 서비스와 REST API나 메시지 등을 통해 통신한다. 예를 들어 쇼핑몰 서비스를 다음과 같이 나눌 수 있다. Client ↓ API Gateway ├─ 회원 서비스 ├─ 상품 서비스 ├─ 주문 서비스 └─ 결제 서비스 단순히 프론트엔드와 백엔드를 분리했다고 해서 MSA가 되는 것은 아니다. MSA에서는 백엔드 내부도 회원, 상품, 주문처럼 비즈니스 기능을 기준으로 나뉜다. 3. Monolithic Architecture와 MSA Monolithic Architecture Monolithic Architecture는 여러 기능을 하나의 애플리케이션에 포함하는 구조다. 회원, 상품, 주문 기능이 하나의 프로젝트에 들어 있으므로 구조를 파악하고 실행하기 쉽다. 하지만 일부 기능만 수정해도 전체 애플리케이션을 다시 빌드하고 배포해야 할 수 있다. Microservice Architecture MSA에서는 각각의 기능을 독립된 서비스로 분리한다. 구분 Monolithic Architecture MSA 구성 모든 기능이 하나의 애플리케이션에 포함됨 기능별로 서비스가 나뉨 배포 전체 애플리케이션을 함께 배포 서비스를 독립적으로 배포 가능 확장 전체 애플리케이션을 확장 필요한 서비스만 확장 가능 장애 하나의 문제가 전체에 영향을 줄 수 있음 장애를 서비스 단위로 격리 가능 통신 같은 애플리케이션 안에서 호출 네트워크를 통한 서비스 간 통신 복잡도 비교적 단순함 운영 및 데이터 관리가 복잡함 MSA는 무조건 좋은 구조가 아니라, 서비스 규모와 운영 환경에 따라 선택해야 하는 아키텍처다. 서비스를 분리하면 결합도를 낮추고 필요한 기능만 확장할 수 있지만, 네트워크 지연, 분산된 데이터의 일관성, 장애 추적과 같은 새로운 문제도 발생한다. 4. MSA의 주요 특징 작은 서비스 하나의 서비스는 너무 많은 기능을 담당하지 않고, 명확한 비즈니스 기능에 집중해야 한다. DDD(Domain Driven Design)에서는 서비스의 경계를 나누는 개념으로 Bounded Context 를 사용한다. 예를 들어 하나의 CRM 애플리케이션을 다음과 같이 분리할 수 있다. CRM ├─ 고객 서비스 ├─ 계약 서비스 └─ VOC 서비스 독립적인 서비스 각 서비스는 가능하면 다른 서비스와 강하게 결합되지 않아야 한다. 서비스마다 독립적으로 개발, 테스트, 배포할 수 있어야 하며 한 서비스의 장애가 전체 시스템으로 확산되지 않도록 설계해야 한다. 응집도가 높은 서비스 하나의 서비스에는 서로 관련된 기능이 모여 있어야 한다. 서비스의 책임이 명확하면 코드를 이해하기 쉬워지고, 수정으로 인해 다른 기능이 영향을 받을 가능성도 줄어든다. 자율적인 서비스와 팀 MSA에서는 서비스를 담당하는 팀이 개발뿐 아니라 테스트, 배포, 운영까지 함께 책임지는 경우가 많다. 서비스와 팀이 독립적으로 움직이려면 서로 직접 코드를 공유하기보다 정해진 API 규칙을 통해 통신해야 한다. 5. Cloud Native와 MSA MSA는 Cloud Native Architecture와 함께 자주 사용된다. Cloud Native Architecture가 중요하게 생각하는 특징은 다음과 같다. 필요한 서비스만 수평으로 확장할 수 있어야 한다. 서비스가 빠르게 생성되고 배포될 수 있어야 한다. 특정 서비스의 장애가 다른 서비스로 확산되지 않아야 한다. 컨테이너를 이용해 실행 환경을 일관되게 관리한다. CI/CD를 통해 빌드, 테스트, 배포 과정을 자동화한다. 로그와 상태를 관찰할 수 있어야 한다. 결국 MSA는 단순히 프로젝트를 여러 개로 나누는 것이 아니라, 독립적인 개발과 배포, 확장, 장애 격리를 가능하게 만드는 운영 방식까지 포함하는 구조 다. 6. Spring Cloud란? Spring Boot가 각각의 서비스를 개발하는 데 사용된다면, Spring Cloud는 여러 서비스로 구성된 분산 시스템을 운영할 때 필요한 기능을 제공한다. 대표적인 기능은 다음과 같다. Spring Cloud Config : 여러 서비스의 설정을 중앙에서 관리한다. Service Discovery : 실행 중인 서비스의 위치를 등록하고 검색한다. Spring Cloud Gateway : 클라이언트의 요청을 적절한 서비스로 전달한다. Load Balancing : 요청을 여러 서비스 인스턴스에 분산한다. OpenFeign : 다른 서비스의 REST API를 편리하게 호출한다. Circuit Breaker : 특정 서비스의 장애가 다른 서비스로 퍼지는 것을 막는다. 분산 추적과 모니터링 : 여러 서비스를 거친 요청의 흐름을 확인한다. Spring Boot → 각각의 Microservice를 개발 Spring Cloud → 여러 Microservice를 연결하고 운영 오늘은 각각의 기술을 직접 구현하기보다, 앞으로 어떤 구조와 기술을 배우게 되는지 전체적인 흐름을 이해했다. Spring Boot 학습이 하나의 백엔드 애플리케이션을 만드는 과정이었다면, 앞으로는 여러 Spring Boot 애플리케이션을 독립된 서비스로 구성하고 서로 연결하는 방법을 학습하게 될 것 같다.
팀 코드를 보다가 로그인 유저 정보와 약관 모달 노출 여부를 zustand로 관리하는 구조를 알게 되어 정리합니다. 아래 코드는 구조를 설명하기 위해 새로 작성한 예제입니다. 전체 흐름 로그인 요청이 성공하면 응답의 유저 정보를 스토어에 저장합니다. 유저 정보를 저장하는 시점에 약관 동의 여부를 확인해 약관 모달을 열지 정합니다. 약관 동의 요청이 성공하면 응답으로 받은 유저 정보를 다시 저장하고, 약관 모달을 닫으면서 환영 모달을 엽니다. 스토어 구성 // authStore.ts import { create } from 'zustand'; import { useModalStore } from './modalStore'; interface User { id: number; name: string; termsAgreed: boolean | null; } interface AuthState { user: User | null; isUserLoading: boolean; setUser: (user: User | null) => void; logout: () => void; } export const useAuthStore = create<AuthState>(set => ({ user: null, isUserLoading: true, setUser: user => { set({ user, isUserLoading: false }); // 약관 미동의 상태면 약관 모달 노출 useModalStore.getState().setTermsVisible(user?.termsAgreed === null); }, logout: () => set({ user: null }), })); // modalStore.ts import { create } from 'zustand'; interface ModalState { termsVisible: boolean; welcomeVisible: boolean; setTermsVisible: (visible: boolean) => void; closeModal: (type: 'terms' | 'welcome') => void; agreeTerms: () => void; } export const useModalStore = create<ModalState>(set => ({ termsVisible: false, welcomeVisible: false, setTermsVisible: visible => set({ termsVisible: visible }), closeModal: type => set(type === 'terms' ? { termsVisible: false } : { welcomeVisible: false }), agreeTerms: () => set({ termsVisible: false, welcomeVisible: true }), })); isUserLoading 을 처음에 true 로 두고 setUser 가 호출될 때 false 로 바꾸는 부분이 눈에 띄었습니다. 유저 정보가 아직 없는 상태와 로그인하지 않은 상태를 구분할 수 있어서, 첫 렌더링에서 화면이 깜빡이는 것을 막는 데 쓸 수 있습니다. 요청은 React Query, 결과는 zustand 로그인과 약관 동의는 값을 조회하는 요청이 아니라 상태를 바꾸는 요청이라 useMutation 을 씁니다. 성공 콜백에서 응답의 유저 정보를 setUser 에 넘깁니다. const handleAgreeTerms = () => { agreeTermsMutation(undefined, { onSuccess: res => { setUser(res.data ?? null); // 동의한 내용을 유저 정보에 반영 agreeTerms(); // 약관 모달 닫고 환영 모달 열기 }, }); }; useMutation 의 결과는 그 훅을 쓴 컴포넌트 안에만 있어서, 다른 화면에서도 같은 유저 정보를 쓰려면 전역 저장소에 넣어야 합니다. 그래서 조회 데이터는 React Query, 요청 결과를 앱 전체가 공유해야 하는 값은 zustand로 나눠서 쓴 구조입니다. 모달 닫기 처리 공통 모달 컴포넌트는 닫기 버튼과 ESC 키 모두 같은 핸들러를 거칩니다. 먼저 모달 내부 상태를 바꿔 사라지는 연출을 보여주고, 300ms 뒤에 스토어 상태를 닫습니다. const handleClose = useCallback(() => { setIsVisible(false); setTimeout(() => closeModal(modalType), 300); }, [closeModal, modalType]); useCallback 으로 핸들러를 고정해서 ESC 키 이벤트가 렌더링마다 다시 등록되지 않게 하고, 언마운트 때 이벤트를 해제합니다. 이 구조의 장단점 장점은 이렇습니다. 훅 밖에서도 getState() 로 접근할 수 있어서 요청 콜백이나 다른 스토어에서 상태를 바꾸기 쉽습니다. 모달 컴포넌트가 props를 거치지 않고 스토어만 보고 열리고 닫힙니다. 아쉬운 점은 이렇습니다. 새 모달을 추가하려면 스토어의 상태와 closeModal 의 타입을 같이 고쳐야 합니다. activeModal 하나로 관리하면 분기가 늘지 않습니다. 서버에서 받은 유저 정보가 스토어에도 있어서, 서버 데이터와 어긋나지 않도록 갱신 지점을 관리해야 합니다. 주의할 점 스토어의 유저 정보는 화면을 분기하는 용도입니다. 약관 동의 같은 필수 조건을 강제하려면 서버가 미동의 상태를 거절해야 하고, 클라이언트 모달은 안내 역할만 합니다. 정리 요청은 React Query의 useMutation , 요청 결과와 UI 상태는 zustand로 분리한다. isUserLoading 으로 유저 정보를 아직 모르는 상태를 구분한다. 서버 데이터와 스토어 값이 어긋나지 않도록 유저 정보를 갱신하는 지점을 정해 둔다.
열이 회사마다 다르다 작업일보 메인 화면은 "현장 × 직종" 표다. 각 칸에 그날 단말기로 찍힌 인원과 관리자가 적은 일보 인원을 나란히 보여 준다. 문제는 가로축인 직종 이다. 직종(형틀, 철근 같은 분류)은 건설사가 직접 등록하기 때문에 회사마다 개수도 이름도 다르다. 운영 데이터를 세어 보니 업체 201곳의 직종 수는 2개부터 33개까지였고, 서로 다른 직종 목록이 82가지였다. 그래서 HTML에 <th>형틀</th> 처럼 열을 적어 둘 수 없다. 엑셀도 마찬가지다. 첫 시도: 열은 그렸는데 표가 깨졌다 열 자체는 어렵지 않았다. 그 업체의 직종 목록을 조회해서 th:each 로 돌리면 된다. 어려운 건 칸 안의 값 이었다. 집계 쿼리는 결과를 세로로 준다. 현장 직종 인원 A현장 형틀 5 A현장 철근 3 B현장 형틀 2 이걸 가로 표에 넣으려고, 처음에는 화면에서 행마다·직종마다 결과 리스트를 처음부터 다시 뒤져 맞는 값을 찾았다. <th:block th:each="row : ${countRows}"> <th:block th:each="job : ${row}"> <th:block th:each="entry : ${job}"> <th:block th:each="jobName : ${jobList}"> <!-- 직종마다 리스트를 다시 뒤진다 --> <td th:if="${entry.key == jobName}" th:text="${entry.value}"></td> 값이 없는 칸은 <td> 가 아예 안 그려지니 뒤의 칸이 앞으로 밀리고, 열 위치가 어긋났다. 그날 커밋 메시지가 이랬다. "모든 합계 쿼리를 구현했으나 화면에 뿌려주는 과정에서 화면 깨짐. 타임리프 수정 필요" 문제는 열이 아니라 칸 이었다. (현장, 직종)으로 값을 바로 꺼낼 구조가 없었다. 세로 결과를 2단 Map으로 다시 조립 그래서 서비스에서 세로 결과를 현장 → 직종 → 인원 2단 Map으로 바꿨다. Map<String, Map<String, Object>> grid = new LinkedHashMap<>(); for (Map<String, Object> row : mapper.reportedCountBySiteAndJob(p)) { Map<String, Object> bySite = grid.computeIfAbsent((String) row.get("site_name"), k -> new LinkedHashMap<>()); String job = (String) row.get("job_name"); int cnt = Integer.parseInt(row.get("count").toString()); bySite.merge(job, cnt, (a, b) -> (int) a + (int) b); // 같은 직종이 팀별로 여러 행이면 더한다 } computeIfAbsent : 현장이 처음 나오면 빈 Map을 만들고, 이미 있으면 그걸 쓴다. merge : 같은 현장·직종이 팀별로 여러 행 오면 인원을 더한다. LinkedHashMap : 쿼리에서 정렬한 현장 순서를 그대로 유지한다. HashMap 이면 화면의 행 순서가 뒤섞인다. 이제 화면은 칸마다 좌표로 한 번만 꺼내면 된다. <th th:each="job : ${jobList}" th:text="${job.name}"></th> <!-- 열: 직종 목록 --> <tr th:each="site : ${grid}"> <td th:each="job : ${jobList}" th:text="${grid[site.key][job.name] ?: 0}"></td> <!-- 칸: 좌표 1회 --> </tr> 열은 항상 직종 목록을 기준으로 돌기 때문에, 값이 없는 칸도 ?: 0 으로 0이 그려진다. 칸이 밀리지 않는다. SQL PIVOT으로 가로로 받으면 안 되나? DB에서 가로 결과를 받는 방법(PIVOT, crosstab, 동적 SQL)도 있다. 하지만 열이 회사마다 다르니, 회사마다 다른 쿼리를 만들어야 한다. PostgreSQL에서는 crosstab 확장도 필요하다. 세로로 받아서 애플리케이션에서 펴면 쿼리는 하나로 고정 되고, 열이 몇 개든 같은 코드로 그린다. 엑셀도 같은 Map으로 작업일보는 엑셀 다운로드도 있다(일간·월간 5종). 엑셀도 같은 2단 Map을 받는다. 엑셀은 빈 파일을 코드로 그리지 않고, 서식이 미리 들어 있는 템플릿 xlsx 를 읽어서 값만 채웠다. 고정 열 뒤 10번째 열부터 직종 헤더를 넣고, 합계·병합 범위는 마지막 직종 열 기준으로 계산한다. XSSFWorkbook wb = new XSSFWorkbook(new ClassPathResource("files/report.xlsx").getInputStream()); XSSFRow header = wb.getSheetAt(0).getRow(3); for (int i = 0; i < jobList.size(); i++) { header.getCell(10 + i).setCellValue(jobList.get(i).getName()); // 직종 수만큼 헤더 } int last = 10 + jobList.size() - 1; // 마지막 직종 열 sheet.addMergedRegion(new CellRangeAddress(3, 4, last + 1, last + 7)); // 그 뒤 합계 영역 글꼴이나 색 같은 서식 요청이 오면 코드를 고치지 않고 템플릿 파일만 바꾸면 된다. 정리 동적 컬럼에서 어려운 건 열이 아니라 칸이었다. 열은 직종 목록 하나로 끝나지만, 칸은 (현장, 직종) 좌표로 꺼낼 구조가 있어야 한다. 세로로 받고 2단 Map으로 폈다. 쿼리는 하나로 고정하고, 화면과 엑셀이 같은 Map을 읽는다. 열은 항상 직종 목록 기준으로 돌렸다. 값이 없는 칸도 0으로 그려서 칸이 밀리지 않는다.
오늘은 대학원 합격 데이터를 이용해 로지스틱 회귀와 규제 모델을 비교하고, 중고차 가격 데이터에 결정 트리 회귀를 적용했다. 분류에서는 정답을 맞힌 비율을, 가격 예측에서는 실제 값과 예측값의 차이를 확인했다. 대학원 합격 여부 예측 대학원 합격 데이터에서 식별용 컬럼 두 개를 제외하고, GRE·TOEFL 점수, 학점, 연구 경험 등 일곱 특성으로 합격 여부를 예측했다. 400개 행을 학습 320개와 테스트 80개로 나누고, 학습 데이터 기준으로 표준화했다. X2_train, X2_test, y2_train, y2_test = train_test_split( X2, y2, test_size=0.2, random_state=2026, stratify=y2 ) X2_train_scaled = scaler2.fit_transform(X2_train) X2_test_scaled = scaler2.transform(X2_test) lr2 = LogisticRegression() lr2.fit(X2_train_scaled, y2_train) 로지스틱 회귀의 학습·테스트 정확도는 모두 0.8875였다. predict_proba() 로 각 행의 합격 클래스 확률도 확인했다. 계수를 정렬해 보니 표준화된 특성 중 CGPA 의 계수가 가장 컸다. 같은 데이터에 선형 회귀, Ridge, Lasso도 적용했다. 이 모델들은 연속값을 반환하므로 MSE·RMSE를 계산하고, 출력값을 0.5 기준으로 나눴을 때의 분류 정확도도 별도로 확인했다. 모델 RMSE 0.5 기준 분류 정확도 LinearRegression 0.3183 0.8625 Ridge 0.3181 0.8625 Lasso 0.3183 0.8875 이번 설정에서 Lasso는 LOR 계수를 0으로 만들었다. 계수에 제약을 주는 방식에 따라 결과가 어떻게 바뀌는지 확인했지만, 이 정확도만으로 모델의 우열을 단정할 수는 없다. 중고차 가격 데이터 전처리 중고차 데이터는 301개 행에서 시작했다. 차량 이름을 제외하고 주행거리 10만 km 이상인 행을 제거하니 293개가 남았다. 연료 종류가 CNG인 행 2개도 제외하고, 연료·판매자·변속기 종류를 더미 변수로 변환했다. car_df = car_df[car_df["Kms_Driven"] < 100000].copy() car_df["Vehicle_Age"] = 2020 - car_df["Year"] car_df = car_df[car_df["Fuel_Type"] != "CNG"].copy() car_df = pd.get_dummies( car_df, columns=["Fuel_Type", "Seller_Type", "Transmission"], drop_first=True, dtype=int ) 차량 연식에서 만든 Vehicle_Age 와 원본 Year 를 동시에 넣자 두 컬럼의 상관계수가 -1이고 VIF가 매우 크게 나왔다. Year 를 제거한 뒤 다시 계산하니 나머지 특성의 VIF가 약 1.04~2.20으로 내려갔다. 파생변수를 만들었다면 원본 컬럼과 정보가 겹치는지도 확인해야 한다. 결정 트리와 선형 회귀 비교 전처리한 291개 행을 학습 232개와 테스트 59개로 나누고 판매 가격을 예측했다. 결정 트리는 특성을 기준으로 데이터를 여러 구간으로 나눈 뒤, 각 구간의 값으로 가격을 예측한다. 이번 실습에서는 두 모델 모두 표준화한 입력값으로 학습했다. dtr = DecisionTreeRegressor(random_state=2026) dtr.fit(X_train_scaled, y_train) y_pred1 = dtr.predict(X_test_scaled) rmse = root_mean_squared_error(y_test, y_pred1) 기본 결정 트리의 테스트 RMSE는 약 1.179, 선형 회귀는 약 1.107이었다. 실제 가격과 예측 가격을 산점도로 비교하고, 오차를 원래 가격과 같은 단위로 볼 수 있는 RMSE를 사용했다. 트리의 max_depth=60 , min_samples_leaf=40 을 지정해 다시 학습한 결과 RMSE는 약 2.099로 높아졌다. 분할 조건을 제한한다고 항상 성능이 좋아지는 것은 아니었다. 다음에는 깊이와 리프의 최소 샘플 수를 각각 바꿔 보며 결과를 비교해 볼 생각이다.
TIL - 2026.10.01 📌 오늘 학습한 주제 Software Architecture Cloud Native Monolithic Architecture Microservice Architecture Monolith와 MSA 비교 MSA의 장단점 Bounded Context Service Decomposition Service Ownership SOA와 MSA의 차이 Spring Cloud 💡 오늘 배운 것 — 나만의 언어로 오늘은 지금까지처럼 하나의 기능을 구현하는 수업이 아니라 서비스 전체 구조를 어떻게 설계할 것인지 에 대한 MSA를 배웠다. 지금까지 만든 Spring Boot 프로젝트를 생각해보면 회원, 게시글, 댓글 같은 기능이 하나의 Backend 안에 같이 들어 있었다. 이런 식으로 여러 기능을 하나의 Application으로 묶어서 개발하는 방식이 Monolithic Architecture이다. Monolith는 처음 만들 때는 구조가 단순하고 코드를 찾거나 Debugging하기도 편하다. 하지만 서비스가 점점 커지면 작은 기능 하나를 수정해도 전체 Application을 다시 Build하고 배포해야 할 수 있고, 특정 기능만 따로 확장하기도 어렵다. MSA는 이런 큰 Application을 업무에 맞는 작은 Service로 나누는 방식 이다. 중요한 것은 단순히 프로젝트를 여러 개 만드는 것이 아니라, 각각의 Service가 자신의 역할을 가지고 독립적으로 개발하고 실행하고 배포할 수 있도록 만드는 것 이라고 이해했다. 오늘 수업을 들으면서 MSA는 단순한 코드 분리 방법이라기보다 서비스 규모가 커졌을 때 변경과 장애를 더 잘 관리하기 위한 Architecture라는 생각이 들었다. 💻 오늘 배운 것 1 — Monolith와 MSA Monolithic Architecture Monolith는 여러 업무 기능이 하나의 Application 안에 들어 있는 구조이다. 예를 들어 하나의 쇼핑몰에 회원 상품 주문 결제 기능이 모두 들어 있고 하나의 Spring Boot Application으로 실행된다면 Monolith 구조로 볼 수 있다. 장점은 구조가 비교적 단순하다는 것이다. 처음 개발할 때 전체 코드를 한 프로젝트에서 볼 수 있고, 기능 간 호출도 같은 Application 안에서 처리할 수 있어서 이해하기 쉽다. 하지만 서비스가 커지면 단점도 생긴다. 예를 들어 주문 기능만 조금 수정했어도 전체 Application을 다시 Build하고 배포해야 할 수 있다. 또한 주문 요청만 갑자기 많아졌다고 해서 주문 기능만 따로 확장하기도 어렵다. Microservice Architecture MSA에서는 하나의 큰 Application을 여러 개의 작은 Service로 나눈다. 예를 들어 쇼핑몰이라면 회원, 상품, 주문, 결제 같은 업무를 기준으로 각각 Service를 나눌 수 있다. 여기서 중요한 것은 각 Service가 최대한 독립적으로 움직이는 것이다. 회원 Service를 수정했다고 해서 주문 Service까지 같이 배포해야 하는 구조보다는, 회원 Service만 수정하고 배포할 수 있는 방향을 목표로 한다. ✨ 이해한 점 처음에는 MSA를 그냥 “Spring Boot 프로젝트를 여러 개 만드는 것”이라고 생각하기 쉬웠다. 그런데 오늘 배운 내용을 보면 프로젝트 개수보다 더 중요한 것은 Service의 독립성 이었다. 각 Service가 독립적으로 개발되고 배포되고 필요한 부분만 확장될 수 있어야 MSA를 사용하는 의미가 생긴다. 💻 오늘 배운 것 2 — MSA가 무조건 좋은 것은 아니다 MSA를 배우기 전에는 서비스를 작게 나누면 무조건 더 좋은 구조일 것 같았다. 하지만 오늘 자료에서는 Monolith와 MSA가 각각 장단점이 있다고 설명했다. 구분 Monolith MSA 구조 하나의 Application 여러 개의 Service 개발 초기 비교적 단순 구조 설계가 더 필요 배포 전체 배포가 쉬움 Service별 독립 배포 가능 확장 전체를 기준으로 확장 필요한 Service를 따로 확장 가능 통신 같은 Application 내부 호출 Network 통신이 생김 장애 영향 범위가 커질 수 있음 Service 단위로 격리 가능 데이터 관리 비교적 단순 서비스 간 데이터 관리가 어려워질 수 있음 MSA의 장점은 Service끼리 결합도를 낮출 수 있고, 필요한 Service만 확장하거나 변경하기 쉽다는 점이다. 반대로 Service가 서로 Network를 통해 통신하기 때문에 통신 지연이나 장애를 생각해야 하고, 여러 Service에 나뉜 데이터를 어떻게 맞출 것인지도 고민해야 한다. ✨ 이해한 점 Monolith가 나쁜 구조이고 MSA가 좋은 구조라는 식으로 보면 안 될 것 같다. 작은 서비스에서는 오히려 Monolith가 더 단순하고 관리하기 편할 수 있다. MSA는 독립적인 배포나 확장이 필요한 규모가 됐을 때 장점이 생기는 구조라고 이해했다. 💻 오늘 배운 것 3 — Service를 어디까지 나눌까? MSA에서 제일 어려워 보였던 부분은 “어디까지를 하나의 Service로 볼 것인가?” 였다. Microservice라는 이름 때문에 기능을 최대한 잘게 쪼개야 할 것 같지만, 무조건 작게 만드는 것이 목적은 아니었다. 오늘은 Domain Driven Design의 Bounded Context 라는 개념도 같이 배웠다. 쉽게 이해하면 하나의 Service가 담당할 업무 범위를 정하는 경계 라고 생각했다. 예를 들어 CRM Application 안에 고객 관리, 계약 관리, VOC 관리가 있다면 이것을 하나로 묶을 수도 있지만 업무 성격에 따라 고객 Service 계약 Service VOC Service 처럼 나눌 수 있다. 그리고 하나의 Service 안에는 서로 관련 있는 기능들이 모여 있어야 한다. 고객 Service라면 고객과 관련된 기능을 모으고, 주문 Service라면 주문과 관련된 기능을 모으는 식이다. Service Decomposition Service를 나눌 때는 단순히 Class 이름이나 기술 기준으로 나누는 것이 아니라 업무를 먼저 이해하고 어떤 부분이 독립적으로 배포되고 확장되어야 하는지 판단하는 과정 이 필요하다. 그래서 오늘 자료에서는 Business Domain을 이해하고 Bounded Context를 찾은 뒤 Service 경계를 정하는 흐름을 설명했다. ✨ 이해한 점 MSA에서는 Controller Service , Repository Service 처럼 Layer 기준으로 나누는 것이 아니라, 회원 , 상품 , 주문 , 결제 처럼 업무 기준으로 Service를 나누는 것이 중요하다. 그래서 MSA는 개발 코드만 보는 게 아니라 실제 업무가 어떻게 나뉘어 있는지도 알아야 설계할 수 있다는 생각이 들었다. 📌 Service Ownership MSA에서는 Service를 나누는 것뿐 아니라 누가 그 Service를 책임지는지 도 중요했다. 한 팀이 특정 Service를 담당하면 그 팀이 기획, 개발, 테스트, 배포, 운영까지 Service의 전체 과정을 책임질 수 있다. 예를 들어 주문 Service를 맡은 팀이 주문 기능을 직접 개발하고 테스트한 뒤 배포까지 할 수 있다면 다른 팀의 작업을 계속 기다리지 않고 더 독립적으로 움직일 수 있다. 오늘 자료에서 나온 Two Pizza Team도 이런 작은 팀 단위의 Service 운영과 연결되는 내용이었다. ✨ 이해한 점 MSA는 서버를 여러 개 만드는 기술적인 문제만 있는 것이 아니라 팀을 어떻게 나누고 누가 어떤 Service를 책임질 것인지까지 연결되는 Architecture 라는 점이 기억에 남았다. 📌 Cloud Native와 지금까지 배운 내용 연결하기 오늘 MSA를 배우면서 전에 배운 Docker, CI/CD, DevOps가 다시 나왔다. Cloud Native Application을 설명할 때 Microservices Containerization Continuous Delivery DevOps 가 같이 나왔다. 전에는 각각 따로 배운 기술처럼 느껴졌는데 오늘은 왜 같이 사용되는지 조금 연결됐다. MSA에서는 Service가 여러 개로 나뉠 수 있다. 그러면 각각의 Service를 실행할 환경이 필요하고, Service마다 배포하는 과정도 많아진다. 그래서 Docker로 실행 환경을 묶고, GitHub Actions나 Jenkins 같은 CI/CD를 이용해 Build와 배포를 자동화하는 것이 중요해진다. ✨ 이해한 점 전에는 Docker나 GitHub Actions를 그냥 “배포를 편하게 하는 도구” 정도로 생각했다. 오늘 MSA를 배우고 나니 Service를 독립적으로 자주 배포하고 운영하기 위해 이런 기술들이 같이 필요한 것 이라는 점이 더 잘 이해됐다. 📌 SOA와 MSA 차이 SOA와 MSA는 둘 다 Service라는 단위로 시스템을 구성한다는 점에서 비슷하다. 하지만 수업에서는 방향의 차이를 설명했다. SOA는 공통 Service를 공유하고 재사용하는 것에 더 초점을 맞춘다. 반면 MSA는 작은 Service가 서로 낮은 결합도를 유지하면서 독립적으로 실행되는 것에 더 초점을 둔다. 쉽게 정리하면 SOA는 Service 재사용 , MSA는 Service 독립성 을 더 중요하게 보는 차이가 있다고 이해했다. 💻 오늘 배운 것 4 — Spring Cloud는 왜 필요한가? Service를 여러 개로 나누면 새로운 문제도 생긴다. 예를 들어 회원 Service, 주문 Service, 결제 Service가 각각 따로 실행되고 있다면 어떤 Service가 어디에서 실행되고 있는지 알아야 하고, 여러 Instance가 있다면 어느 곳으로 요청을 보내야 하는지도 정해야 한다. 설정도 Service마다 관리해야 하고, 하나의 Service에서 장애가 났을 때 어떻게 대응할지도 필요하다. 이런 분산 시스템에서 반복해서 필요한 기능들을 도와주는 것이 Spring Cloud 이다. 오늘은 Spring Cloud 기능을 직접 구현한 것은 아니고 전체적인 역할을 먼저 봤다. 대표적으로 Config Server: 여러 Service의 설정 관리 Service Discovery: Service 위치 찾기 Load Balancing: 요청 분산 API Gateway: 외부 요청의 입구 역할 OpenFeign: Service 간 REST 통신 Monitoring / Tracing: 요청 흐름 확인 Fault Tolerance: 장애 대응 같은 기능들이 있다는 것을 확인했다. ✨ 이해한 점 Monolith에서는 Application 하나만 잘 관리하면 됐지만 MSA에서는 Service가 많아지기 때문에 Service들을 연결하고 관리하는 기능이 추가로 필요하다. Spring Cloud는 MSA 그 자체라기보다는 이런 분산 시스템을 만들 때 필요한 기능을 제공해주는 도구라고 이해했다. ❓ 어려웠던 점 & 정리 문제 1 — 프로젝트를 여러 개 만들면 MSA인가? 처음에는 Backend 프로젝트를 회원, 주문, 결제로 여러 개 만들면 바로 MSA라고 생각하기 쉬웠다. 정리 프로젝트 수보다 중요한 것은 각각의 Service가 업무적으로 명확한 역할을 가지고 독립적으로 개발·배포될 수 있는지이다. 문제 2 — Service는 작게 만들수록 좋은가? Microservice라는 이름 때문에 기능마다 Service 하나씩 만드는 것이 좋은 줄 알았다. 정리 무조건 작게 쪼개는 것이 목적은 아니다. 업무 경계와 변경 주기, 확장 필요성 등을 보고 Service의 적절한 범위를 정해야 한다. 문제 3 — MSA가 더 복잡한데 왜 사용하는가? Service를 나누면 Network 통신도 생기고 데이터 관리도 어려워져 오히려 복잡해 보였다. 정리 독립적인 배포, 확장, 장애 격리가 필요할 정도로 서비스가 커졌을 때 MSA의 장점이 생긴다. 그래서 상황에 맞게 Architecture를 선택하는 것이 중요하다. 🧩 오늘 배운 개념 정리 개념 오늘 이해한 내용 Software Architecture 시스템의 구성 요소와 관계를 설계하는 것 Monolith 여러 기능이 하나의 Application에 들어 있는 구조 MSA 업무 단위 Service를 독립적으로 구성하는 구조 Cloud Native Cloud 환경에서 확장과 배포를 고려한 구조 Bounded Context 하나의 Service가 담당할 업무 범위 Service Decomposition 큰 Application을 Service 단위로 나누는 과정 Ownership 한 팀이 Service의 개발부터 운영까지 책임지는 구조 Fault Isolation 한 Service 장애가 다른 Service까지 퍼지는 것을 줄이는 것 Spring Cloud 분산 시스템에서 필요한 여러 기능을 제공하는 Spring 프로젝트 Service Discovery Service가 어디에서 실행되고 있는지 찾는 기능 API Gateway 외부 요청을 받아 알맞은 Service로 전달하는 입구 📌 오늘 이해한 전체 흐름 큰 Application ↓ 업무 Domain 분석 ↓ Service 경계 정하기 ↓ 각 Service 독립적으로 구성 ↓ Microservice Architecture ↓ Docker로 실행 환경 관리 ↓ CI/CD로 Build / Deploy 자동화 ↓ Spring Cloud로 Service Discovery, Gateway, 설정 등을 관리 오늘 수업을 통해 MSA는 단순히 Backend를 여러 프로젝트로 나누는 것이 아니라 업무를 기준으로 Service의 경계를 정하고, 각각을 독립적으로 운영할 수 있도록 전체 구조를 설계하는 방식 이라는 점을 이해했다. 📅 다음에 할 일 & 아직 모르는 것 실제 프로젝트에서 Bounded Context를 기준으로 Service를 나눠보기 Service Discovery가 실제 코드에서 어떻게 동작하는지 확인하기 API Gateway를 직접 구성해보기 Service별 데이터가 분리될 때 데이터 정합성을 어떻게 맞추는지 알아보기 Monolith와 MSA 중 어떤 상황에서 어떤 구조를 선택할지 다시 정리하기 ✅ 오늘 한 줄 정리 오늘은 Monolith와 MSA의 차이를 배우면서 MSA가 단순히 프로젝트를 여러 개 만드는 방식이 아니라, 업무 기준으로 Service를 나누고 각각 독립적으로 개발·배포·확장할 수 있도록 설계하는 Architecture라는 것을 배웠다. 또한 Docker, CI/CD, DevOps 같은 기술이 Cloud Native와 MSA 운영에 왜 필요한지 연결해서 이해했고, 앞으로 Spring Cloud를 이용해 여러 Microservice를 관리하는 방법을 배우게 될 것 같다. 핵심 학습 주제 MSA, Monolith, Microservice, Cloud Native, Bounded Context, Service Decomposition, Spring Cloud 태그 Java SpringBoot MSA Microservice Monolith CloudNative SpringCloud BoundedContext ServiceDecomposition Docker CICD DevOps TIL
Mumbai’s warm and humid climate makes proper ventilation important for homes and offices. However, keeping windows open can also allow mosquitoes, flies, and other insects to enter indoor spaces. A professionally fitted Window Mosquito Net in Mumbai can provide a practical barrier while allowing fresh air and natural light to enter. All Safety Net Solution offers mosquito net solutions for different window designs and property requirements. With accurate measurements and proper installation, window mosquito nets can be a convenient addition to bedrooms, kitchens, living rooms, offices, and other spaces. Why Install a Window Mosquito Net? Windows are among the common entry points for mosquitoes and insects. Keeping them closed can reduce insect entry but may also limit ventilation. A suitable mosquito net provides an alternative by covering the opening while allowing air circulation. Window mosquito nets can be useful for: Bedroom windows Kitchen windows Living room windows Balcony windows Sliding windows Casement windows Office windows Apartment windows The appropriate net design can depend on the window structure, dimensions, and frequency of use. Professional Window Mosquito Net Installation Accurate measurement is an important part of mosquito net installation. A properly fitted net can help minimize gaps around the window and provide convenient everyday operation. All Safety Net Solution can assist with selecting and installing a suitable Window Mosquito Net in Mumbai according to the requirements of the property. Professional installation can also provide a cleaner finish and help ensure that the net is securely fitted. Depending on the window design, customers may consider retractable or other convenient mosquito net options that allow the window to be used as required. Benefits of Window Mosquito Nets A mosquito net can help create a more comfortable indoor environment by providing a physical barrier against mosquitoes and other insects. At the same time, it allows windows to remain open for ventilation. Regular cleaning can help maintain airflow and visibility through the net. It is also useful to periodically inspect the net, frame, and edges for any signs of wear or damage. Choose All Safety Net Solution If you are searching for a reliable Window Mosquito Net in Mumbai, All Safety Net Solution provides solutions for residential and commercial properties. The installation can be planned according to the type, size, and location of your windows. Whether you need mosquito nets for a single bedroom window or multiple windows across your property, choosing the right design and professional installation can make everyday use more convenient. Contact All Safety Net Solution to discuss your requirements and find a suitable mosquito net solution for your Mumbai property. Visit : https://share.google/DNMYPEHt8cg35ki56 Contact : 9820095252
The Cheap Key Question Nobody Wants to Answer Search for Windows product key options online and you'll hit the same bewildering spectrum: legitimate retail licenses commanding a serious premium, and grey-market keys floating around for less than the cost of a pizza. The Windows Product Key Price gap between these two extremes tells a story most sellers would rather you didn't read. I've spent the last few months tracking licensing reports across Microsoft's official channels, industry repair shops, and user forums. Here's what the data actually says — and how platforms like aipowersolutions.in are positioning themselves to solve the mess. What the 2026 Market Data Reveals Recent industry reports paint a clear picture of the licensing landscape in India. The official retail channel — what Microsoft calls FPP (Full Packaged Product) — sits firmly at the top of the market. OEM System Builder licenses, designed for DIY builders, occupy the mid-tier. Then there's the grey market, where keys sell for next to nothing with what the same report labels as "High" risk. The pattern isn't random. It's structural — and it directly shapes every Windows Product Key Price you'll encounter. Why Cheap Keys Exist (And Why They Break) Microsoft's licensing model separates technical activation from legal entitlement. A key is just a string of characters. A license is a legal right to use the software. Grey-market sellers exploit this gap. Most heavily discounted keys trace back to one of three sources: • Volume Licensing leaks: Large organizations receive MAK or KMS keys for bulk activation. Employees or resellers illegally export these keys, selling them to unsuspecting buyers. Microsoft periodically revokes entire batches when anomaly detection flags excessive activations. • OEM key extraction: Some sellers pull keys from discarded or refurbished machines. These are hardware-bound and often fail on new motherboards. • MSDN/TechNet abuse: Developer subscription keys meant for testing get resold. They activate initially but lack any legitimate transfer rights. The short-term appeal is obvious. The long-term cost — revocation, watermark overlays, blocked security updates, and buying a second key — is where the "savings" evaporate. The Real Comparison: What Each License Type Actually Gives You License Type Market Position Transferable? Microsoft Support? Revocation Risk Official Retail (FPP) Premium tier Yes Yes None Official Upgrade (Home→Pro) Mid-tier Tied to original license Yes None OEM System Builder Budget tier No (hardware-bound) Limited Low Grey-Market Keys Rock bottom No None High Sources: 2026 industry licensing reports The table exposes the trade-off clearly. Grey-market keys aren't cheaper. They're deferred-cost purchases — you pay now, and you pay again when Microsoft's servers deactivate you. A repair technician I spoke with described the pattern bluntly: "Users buy a heavily discounted key. Three months later they're back because Windows Update broke activation. We charge them for diagnosis and then for a proper OEM license. They've spent more than if they'd bought legitimate from the start." When You Don't Need to Buy Anything Here's the insight most sellers bury: you may already own a Windows license. Since 2012, virtually every laptop sold in India with Windows pre-installed stores the product key inside the UEFI firmware chip. Reinstalling Windows from an official Microsoft ISO automatically reads this embedded key and activates without any purchase. You can check this yourself. Open Command Prompt as administrator and run: text wmic path softwarelicensingservice get OA3xOriginalProductKey If a key appears, you're covered. If not, then you need to buy. This single check prevents thousands of unnecessary purchases every year — and it's something any trustworthy licensing platform should tell you upfront. It also reframes the entire Windows Product Key Price conversation: the best deal is the one you don't have to make. The aipowersolutions.in Approach In a market where rock-bottom keys coexist with premium retail licenses, the question isn't whether to buy — it's where to buy without gambling. The emerging standard for trusted platforms involves three things: transparent license-type labeling, pre-purchase UEFI checks, and clear guidance on what each tier actually covers. Rather than pushing the cheapest possible key, the smarter approach helps users understand whether they need an OEM builder license, an upgrade path, or nothing at all. For Indian users navigating this landscape, that distinction matters. Reports indicate a significant grey-market problem specifically in India, with repair shops and online marketplaces frequently selling volume-license keys that fail within months. A platform that prioritizes diagnosis before sale — checking whether the user already has an embedded license, explaining the difference between OEM and retail, and refusing to sell grey-market keys — fills a genuine gap. Key Takeaways Before You Buy Check your UEFI first. Most laptops sold in India post-2012 already have a license. Don't buy until you've confirmed you need one. Treat ultra-cheap keys as temporary at best. They may activate today. They may fail tomorrow. The "savings" rarely survive a revocation sweep. OEM licenses are the genuine budget option. Hardware-bound activation is the legitimate floor — not the grey-market alternative. Retail licenses justify their premium through transferability. If you upgrade motherboards or rebuild systems, OEM won't follow you. Retail will. The Bottom Line The range of Windows Product Key Price options isn't a bug. It's a feature of a system where technical activation and legal licensing are deliberately separate concepts. Cheap keys exploit that separation. Legitimate platforms bridge it. Before you spend anything, run the UEFI check. If you genuinely need a license, skip the grey-market lottery. The real cost of a grey-market key isn't the sticker price — it's the second purchase you'll make when the first one dies.
PDF files are everywhere. From invoices and reports to application forms and personal documents, it is common to end up with several separate PDF files that need to be combined into one. klzth is a browser-based PDF merging tool designed to make that process simple. Instead of requiring users to install desktop software or upload their documents to an online server, klzth lets users combine PDF files directly in their browser. What Does klzth Do? At its core, klzth is a PDF merger. You can select multiple PDF files, arrange them in the order you want, and combine them into a single document. The workflow is intentionally straightforward: Select or drop your PDF files. Arrange the files in the desired order. Sort them by filename if needed. Optionally standardize different page sizes to A4. Merge the files into one PDF. This makes klzth useful for everyday tasks such as combining receipts, organizing reports, preparing application documents, or putting several related files into one document before sending or printing it. How Is klzth Different From Traditional Online PDF Tools? Many online PDF services use a cloud-based workflow. A user uploads a document, the server processes it, and the finished file is downloaded afterward. klzth takes a different approach. The PDF merging process runs directly in the browser, so users do not have to send their documents to a remote processing server simply to combine them. This can be particularly useful when working with documents that contain information you would rather keep on your own device, such as contracts, invoices, forms, financial records, or personal documents. PDF Quality Matters Merging PDFs should not mean unnecessarily converting the contents of every page. klzth combines existing PDF pages rather than rebuilding the entire document from scratch. This approach helps retain selectable text and the original quality of embedded images, making the resulting file suitable for both digital use and printing. When PDFs contain different page dimensions, users can also choose to standardize them to an A4 layout. This can be helpful when preparing a document that needs a more consistent appearance. No Account Required klzth is designed for people who need a PDF tool without wanting to create another online account. There is no registration process, no software installation, and no watermark added to merged documents. You can open the tool, complete the task, and move on. The pricing model is also designed around occasional use rather than a recurring subscription. Users can make three merges per month for free. If additional usage is needed, there are one-time options: $5.50 for 30 merges $9.90 for 100 merges There is no monthly commitment, so users only purchase additional usage when they actually need it. Who Is klzth For? klzth can be useful for a wide range of users. Students can combine assignments, reference materials, or application documents into a single PDF. Professionals can merge reports, invoices, forms, and other business documents without relying on desktop PDF software. Freelancers and small businesses can organize client documents or prepare files for sharing and printing. It can also be useful for anyone who occasionally needs to combine PDFs but does not want to install a dedicated application or sign up for another subscription service. A More Focused Approach to PDF Tools There are many PDF platforms that offer dozens of features, including editing, conversion, compression, annotation, signing, and file management. Those services can be useful when you need a complete PDF workspace. But sometimes the requirement is much simpler: you just need to put several PDF files together. That is where klzth focuses its attention. Rather than building a complicated workflow around a basic task, it provides a focused environment for combining documents while keeping the process straightforward. Conclusion So, what is klzth? klzth is a browser-based PDF merging tool that lets users combine documents locally, organize their files, and create a single PDF without uploading the original files to a cloud processing service. Its main features include file reordering, filename sorting, optional A4 formatting, and preservation of existing PDF content. With no account requirement, no watermark, and no recurring subscription, it is designed for people who need a simple PDF merger without unnecessary complexity. For occasional PDF work, klzth offers a practical approach: choose your files, put them in order, merge them, and get on with your work.