| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- Azure Cosmos DB
- Azure NoSQL
- 맥 윈도우 설치
- intermediate
- RAG model
- azure
- LLM
- Django REST framework
- AI rag
- data pipeline
- Teams Web hook
- 실시간 데이터 스트리밍
- 이벤트 허브
- Azure Event Hub
- Azure 이벤트 허브
- ChatGPT
- Beginner
- Windows 가상머신
- Python
- Cloud Engineering
- Event Hub
- Data Streaming
- Azure Function App
- Azure OpenAI
- mac windows
- webhook
- DRF
- VM 설치
- Azure Cloud
- vector embedding
- Today
- Total
Seum.Lee Story
웹 서버 및 프로그램 구조 이해 (Web / DB) 본문
1. 개발 환경
하드웨어 환경 구성

실무에서 서버 환경은 크게 네 가지 역할로 나뉜다.
| 구성 요소 | 역할 | 실무 예시 |
|---|---|---|
| Web Server | HTTP 요청 처리, 정적 파일 반환 | Nginx, Apache |
| WAS | 동적 비즈니스 로직 처리 | Tomcat, Node.js |
| DB Server | 데이터 영구 저장 및 조회 | PostgreSQL, MySQL |
| File Server | 파일 저장소 역할 | NFS, S3(클라우드) |
실무에서는 이 네 가지를 반드시 물리적으로 분리하는 건 아니다. 소규모 서비스라면 Web Server와 WAS를 한 서버에서 함께 돌리기도 한다. 다만 트래픽이 커지면 각각을 분리해야 병목이 생기는 지점을 독립적으로 스케일링할 수 있다.
웹 서버의 주요 기능
웹 서버는 단순히 "요청을 받아 파일을 돌려주는 것" 이상의 역할을 한다.
- HTTP/HTTPS 지원: 보안 통신(TLS) 처리
- 통신 기록(Logging): 접근 로그, 에러 로그 관리
- 정적 파일 관리: HTML, CSS, 이미지 등 직접 반환 (WAS까지 안 보냄)
- 대역폭 제한: 트래픽 폭주 시 서버 보호
- 가상 호스팅: 하나의 서버 IP로 여러 도메인을 처리 (예:
a.com,b.com을 같은 Nginx에서 분기) - 인증: Basic Auth, SSL 인증서 기반 접근 제어
소프트웨어 환경

개발 언어 선정 기준
암기용 키워드: 적효이친범
- 적정성: 개발 목적에 맞는가
- 효율성: 처리 능력이 충분한가
- 이식성: 다른 환경에서도 동작하는가
- 친밀성: 개발팀이 익숙한가 (생산성과 직결)
- 범용성: 커뮤니티/생태계가 충분한가
실무에서는 친밀성과 범용성이 가장 현실적인 선택 기준이 된다. 아무리 성능이 좋은 언어라도 팀이 모르면 유지보수 비용이 급격히 올라간다.
2. 개발 패턴과 방법
소프트웨어 아키텍처란
SW 아키텍처는 시스템을 구성하는 요소들이 어떻게 연결되고 상호작용하는지를 표현하는 구조다. 코드를 짜기 전에 "어떤 구조로 만들 것인가"를 결정하는 설계 단계에서 핵심 역할을 한다.
품질 속성은 세 가지 측면에서 바라본다.
- 시스템 측면: 성능, 보안, 가용성, 안정성
- 비즈니스 측면: 출시 일정, 비용, 시장 요구
- 아키텍처 측면: 개념적 무결성, 정확성
아키텍처 설계 원칙
모듈화는 시스템을 기능 단위로 쪼개는 것이다. 각 모듈이 독립적일수록 수정 시 파급 범위를 줄일 수 있다.
추상화는 큰 그림부터 그리고 점차 구체화하는 방식이다. 세 가지로 나뉜다.
- 과정 추상화: "어떻게"보다 "무엇을" 하는지에 집중 (함수 시그니처 정의)
- 자료 추상화: 데이터 내부 구조를 숨김 (클래스, DTO)
- 제어 추상화: 실행 흐름의 세부 내용을 숨김 (이벤트 루프, 스케줄러)
정보 은닉은 캡슐화와 연결되는 개념이다. 모듈 내부 구현을 외부에서 직접 접근하거나 수정하지 못하도록 막는다. 실무에서는 private 메서드, 내부 패키지 분리, API 게이트웨이 같은 형태로 적용된다.
단계적 분해는 상위 개념에서 하위 개념으로 순차적으로 구체화하는 Top-Down 접근 방식이다.
상위 설계 vs 하위 설계
| 구분 | 다른 이름 | 다루는 내용 |
|---|---|---|
| 상위 설계 | 아키텍처 설계 / 예비 설계 | 전체 구조, DB 스키마, 인터페이스 정의 |
| 하위 설계 | 모듈 설계 / 상세 설계 | 컴포넌트 내부, 자료구조, 알고리즘 |
상위 설계가 "건물의 평면도"라면, 하위 설계는 "각 방의 내부 도면"에 해당한다.
협약에 의한 설계 (Design by Contract)
컴포넌트가 정상 동작하기 위한 조건을 명시적으로 계약처럼 기술하는 방식이다.
- 선행 조건(Precondition): 이 함수를 호출하기 전에 만족해야 하는 조건 (예: 입력값이 null이 아닌 것)
- 결과 조건(Postcondition): 함수 실행 후 보장되는 상태 (예: 반환값은 항상 양수)
- 불변 조건(Invariant): 실행 전후에 항상 유지되어야 하는 조건 (예: 리스트의 길이는 음수가 될 수 없음)
def withdraw(account, amount):
# 선행 조건
assert amount > 0, "출금액은 0보다 커야 한다"
assert account.balance >= amount, "잔액이 부족하다"
account.balance -= amount
# 결과 조건
assert account.balance >= 0, "잔액은 음수가 될 수 없다"
아키텍처 패턴 정리
아키텍처 패턴은 시스템 전체 구조를 어떻게 잡을지에 대한 검증된 해법이다.

| 패턴 | 핵심 구조 | 대표 사례 |
|---|---|---|
| 레이어 | 계층별로 역할 분리, 인접 계층만 통신 | Spring MVC (Presentation / Service / Repository) |
| 클라이언트-서버 | 서버 1개 + 클라이언트 N개 | 웹 서비스 대부분 |
| 파이프-필터 | 데이터가 필터를 순서대로 통과 | UNIX 쉘 파이프(` |
| MVC | Model / View / Controller 분리 | Spring, Django, Rails |
| 마스터-슬레이브 | 마스터가 작업 분배, 슬레이브가 처리 | DB 복제, 분산 연산 |
| 브로커 | 브로커가 서비스 요청자와 제공자를 중개 | Kafka, RabbitMQ |
| 피어-투-피어 | 모든 노드가 클라이언트이자 서버 | BitTorrent, 블록체인 |
| 이벤트-버스 | 퍼블리셔가 이벤트 발행, 구독자가 처리 | 푸시 알림, AWS SNS+SQS |
| 블랙보드 | 공유 저장소에 모든 컴포넌트가 접근 | 음성 인식, AI 추론 시스템 |
| 인터프리터 | 기호/언어를 파싱해 실행 | SQL 파서, 스크립트 엔진 |
시험 포인트: 파이프-필터의 대표 예시는 UNIX 쉘이다. 이벤트-버스는 퍼블리시/구독(Pub-Sub) 구조라는 점을 기억한다.
3. 객체 지향
핵심 개념 한눈에
객체 지향의 목표는 현실 세계의 사물을 소프트웨어 객체로 표현하고, 그 객체들이 서로 메시지를 주고받으며 동작하는 시스템을 만드는 것이다.

| 개념 | 한 줄 설명 | 실무 연결 |
|---|---|---|
| 객체 | 데이터 + 함수(메서드)의 묶음 | 클래스의 인스턴스 |
| 클래스 | 객체를 찍어내는 설계도 | class User { ... } |
| 메시지 | 객체에게 동작을 요청하는 것 | 메서드 호출 |
| 캡슐화 | 내부 구현 숨기고 인터페이스만 노출 | private 필드 + getter/setter |
| 상속 | 부모 클래스의 속성/메서드를 물려받음 | class Admin extends User |
| 다형성 | 같은 메서드 호출이 객체마다 다르게 동작 | 오버라이딩, 인터페이스 구현 |
// 다형성 예시
interface Shape {
double area();
}
class Circle implements Shape {
double radius;
public double area() { return Math.PI * radius * radius; }
}
class Rectangle implements Shape {
double w, h;
public double area() { return w * h; }
}
// 같은 area() 호출이지만 객체에 따라 다르게 동작
Shape s1 = new Circle();
Shape s2 = new Rectangle();
s1.area(); // 원 넓이
s2.area(); // 직사각형 넓이
객체 간 연관성
| 표현 | 의미 | 예시 |
|---|---|---|
is member of |
연관화 (상호 참조) | 학생이 동아리에 속함 |
is instance of |
분류화 (같은 클래스의 인스턴스) | 홍길동은 User 클래스의 인스턴스 |
is part of |
집단화 (전체-부분 관계) | 엔진은 자동차의 일부 |
is a |
일반화 / 특수화 | 관리자(Admin)는 사용자(User)다 |
객체 지향 분석 방법론
시험에서는 방법론별 키워드를 외우는 것이 핵심이다.
- 럼바우: 객동기 (객체 모델링 / 동적 모델링 / 기능 모델링)
- 부치: 미시적 / 거시적 개발 프로세스
- 제이콥슨: 유스케이스 중심
- 코드와 요르돈: E-R 다이어그램 활용
- Wirfs-Brock: 분석과 설계 구분 없이 진행
SOLID 원칙
SOLID는 유지보수하기 좋은 객체 지향 설계를 위한 다섯 가지 원칙이다.

| 원칙 | 이름 | 핵심 내용 |
|---|---|---|
| S | 단일 책임 원칙 (SRP) | 클래스는 하나의 책임만 가져야 한다 |
| O | 개방-폐쇄 원칙 (OCP) | 확장에는 열려 있고, 수정에는 닫혀 있어야 한다 |
| L | 리스코프 치환 원칙 (LSP) | 자식 클래스는 부모 클래스를 대체할 수 있어야 한다 |
| I | 인터페이스 분리 원칙 (ISP) | 사용하지 않는 인터페이스에 의존하지 않아야 한다 |
| D | 의존 역전 원칙 (DIP) | 구체 클래스보다 추상(인터페이스)에 의존해야 한다 |
4. 모듈
결합도와 응집도
모듈 품질을 평가하는 두 가지 축이다. 방향이 반대다.
결합도는 낮을수록, 응집도는 높을수록 좋은 설계다.
결합도 (낮은 것이 좋음): 자스제외공내

| 순서 | 종류 | 설명 |
|---|---|---|
| 1 (낮음) | 자료(Data) | 단순 데이터 값만 전달 |
| 2 | 스탬프(Stamp) | 자료구조(객체, 배열 등)를 통째로 전달 |
| 3 | 제어(Control) | 제어 플래그를 전달해 상대 모듈의 흐름을 제어 |
| 4 | 외부(External) | 외부 모듈의 변수를 직접 참조 |
| 5 | 공통(Common) | 전역 변수 공유 |
| 6 (높음) | 내용(Content) | 다른 모듈의 내부 코드/데이터를 직접 참조/수정 |
응집도 (높은 것이 좋음)

| 순서 | 종류 | 설명 |
|---|---|---|
| 1 (낮음) | 우연(Coincidental) | 아무 관계 없는 기능이 한 모듈에 묶임 |
| 2 | 논리(Logical) | 유사한 성격의 기능을 묶음 (같은 타입의 입출력 처리 등) |
| 3 | 시간적(Temporal) | 특정 시점에 함께 실행되는 것들을 묶음 (초기화 루틴 등) |
| 4 | 절차(Procedural) | 순서대로 실행되어야 하는 기능들을 묶음 |
| 5 | 교통(Communication) | 동일한 입출력 데이터를 다루는 기능들을 묶음 |
| 6 | 순차(Sequential) | 앞 기능의 출력이 다음 기능의 입력이 되는 파이프라인 구조 |
| 7 (높음) | 기능(Functional) | 단 하나의 명확한 기능만 수행 |
팬인 / 팬아웃
모듈 구조도(구조 차트)에서 모듈 간 호출 관계를 나타내는 지표다.
- 팬인(Fan-in): 해당 모듈을 호출하는 모듈의 수 (들어오는 화살표)
- 팬아웃(Fan-out): 해당 모듈이 호출하는 모듈의 수 (나가는 화살표)
팬아웃이 너무 높으면 그 모듈이 너무 많은 책임을 지고 있다는 신호다. 반대로 팬인이 높은 모듈은 재사용성이 높은 핵심 모듈일 가능성이 있다.
IPC (Inter-Process Communication)
모듈 또는 프로세스 간에 데이터를 주고받는 방식이다.

| 방법 | 특징 |
|---|---|
| 공유 메모리 | 빠르지만 동기화 필요 |
| 소켓 | 네트워크 기반, 원격 통신 가능 |
| 세마포어 | 동시 접근 제어(잠금 역할) |
| 파이프 / 네임드 파이프 | 단방향 / 양방향 데이터 스트림 |
| 메시지 큐 | 비동기 메시지 전달 (Kafka, RabbitMQ의 원형) |
5. 테스트와 코드
테스트 케이스
테스트 케이스는 소프트웨어가 요구사항을 제대로 만족하는지 확인하기 위한 시험 항목 명세서다. 단순히 "실행해서 오류 없으면 OK"가 아니라, 어떤 입력에 어떤 결과가 나와야 하는지를 사전에 정의한다.
공통 모듈 명세 기법의 기준은 다섯 가지다.
- 정확성: 실제로 구현 가능한 내용인가
- 명확성: 이중 해석의 여지 없이 단일하게 이해되는가
- 완전성: 시스템이 갖춰야 할 모든 것을 기술했는가
- 일관성: 다른 명세와 충돌하지 않는가
- 추적성: 요구사항의 출처와 이유를 역추적할 수 있는가
재사용 단위
| 단위 | 설명 |
|---|---|
| 함수 / 객체 | 가장 작은 재사용 단위 |
| 컴포넌트 | 독립적으로 배포 가능한 기능 묶음 |
| 애플리케이션 | 전체 시스템을 통째로 재활용 |
코드 체계
코드는 데이터를 식별하고 분류하기 위한 기호 체계다.
| 코드 종류 | 예시 | 특징 |
|---|---|---|
| 순차 코드 | 1, 2, 3, 4 | 단순 일련번호 |
| 블록 코드 | 1001~1100 | 범위로 구분 |
| 10진 코드 | 1000: 공학, 2000: 문학 | 십진 분류법 |
| 그룹 분류 코드 | 1-01-001: 본사-총무부-인사계 | 계층 구조 표현 |
| 연상 코드 | TV-40: 40인치 TV | 의미를 직관적으로 표현 |
| 표의 숫자 코드 | 120-720-1500: 두께×폭×길이 | 수치 자체가 의미를 가짐 |
| 합성 코드 | KE-711: 대한항공 711편 | 두 가지 이상 코드 결합 |
6. 디자인 패턴
디자인 패턴은 모듈 간 관계 및 인터페이스 설계에서 자주 반복되는 문제에 대한 검증된 해법이다. GoF(Gang of Four) 패턴이 가장 많이 쓰인다.
생성 패턴 (객체를 어떻게 만들 것인가)
| 패턴 | 핵심 |
|---|---|
| 추상 팩토리 | 관련 객체 그룹을 묶어서 생성 |
| 빌더 | 복잡한 객체를 단계별로 조립 |
| 팩토리 메소드 | 객체 생성을 서브 클래스에 위임 |
| 프로토타입 | 기존 객체를 복제해서 생성 |
| 싱글톤 | 인스턴스를 딱 하나만 유지 |
구조 패턴 (객체를 어떻게 조합할 것인가)
| 패턴 | 핵심 |
|---|---|
| 어댑터 | 호환되지 않는 인터페이스를 변환 (플러그 변환기와 같은 원리) |
| 브리지 | 기능과 구현을 분리해 독립적으로 확장 |
| 컴포지트 | 단일 객체와 복합 객체를 동일하게 다룸 (트리 구조) |
| 퍼사드 | 복잡한 서브시스템에 단순한 인터페이스 제공 |
| 플라이웨이트 | 유사 객체를 공유해 메모리 절약 |
| 프록시 | 실제 객체 앞에 대리 객체를 두어 접근 제어 |
행위 패턴은 이 자료의 범위에서는 생략한다.
7. 기타: 프레임워크와 배치
서버 개발 프레임워크
대부분의 서버 사이드 프레임워크는 MVC 구조를 기반으로 한다.
| 프레임워크 | 언어 | 특징 |
|---|---|---|
| Spring | Java | 국내 엔터프라이즈 환경에서 가장 널리 쓰임 |
| Django | Python | 빠른 개발, 배터리 포함 철학 |
| Ruby on Rails | Ruby | CoC(설정보다 관례) 원칙 |
| CodeIgniter | PHP | 경량 PHP 프레임워크 |
API와 Open API
API(Application Programming Interface)는 라이브러리나 서비스를 외부에서 사용할 수 있도록 규칙을 정의한 인터페이스다. 그 중 외부에 공개된 것을 Open API라고 부른다. 카카오 지도 API, 기상청 날씨 API 등이 대표적이다.
배치 프로그램
배치는 "정해진 시간에 대량의 데이터를 자동으로 처리"하는 프로그램이다. 실시간으로 처리하기 부담스러운 작업을 새벽 시간대에 몰아서 처리하는 방식으로 많이 쓰인다.
배치 프로그램이 갖춰야 할 요소 다섯 가지:
- 대용량 데이터 처리 능력
- 자동화: 사람이 개입하지 않아도 실행
- 견고성: 예외 상황에서도 비정상 종료 없이 처리
- 안정성 / 신뢰성: 중복 실행, 누락 없이 정확하게 처리
- 성능: 정해진 시간 내에 완료
배치 스케줄러는 세 가지를 기억한다.
| 스케줄러 | 특징 |
|---|---|
| Spring Batch | Java 기반, 대규모 배치 처리 표준 프레임워크 |
| Quartz | Java 기반, 유연한 스케줄링 |
| Cron | Unix/Linux 기반, 시간 기반 작업 자동화 (0 0 * * * 형태의 표현식) |
# Cron 표현식 예시
# 분 시 일 월 요일
0 2 * * * # 매일 새벽 2시에 실행
0 9 * * 1 # 매주 월요일 오전 9시에 실행
0 0 1 * * # 매월 1일 자정에 실행