웹 서버 (Web Server)

  • HTTP 기반으로 동작
  • 정적 리소스 제공, 기타 부가기능
  • 정적 HTML, CSS, JS, 이미지, 영상
  • 에) NGINX, APACHE

 

웹 애플리케이션 서버 (WAS)

  • HTTP 기반으로 동작
  • 웹 서버 기능 포함
  • 프로그램 코드를 실행해서 애플리케이션 로직 수행
    • 동적 HTML, HTTP API (JSON)
    • 서블릿, JSP, 스프링 MVC

  • 예) 톰캣, Jetty, Undertow

 

웹 서버와 WAS 의 차이

웹 서버는 정적 리소스를, WAS는 애플리케이션 로직을 포함한 동적 리소스 처리한다.

사실 둘의 용어도 경계도 모호하다.

  • 웹 서버도 애플리케이션 로직을 실행하는 기능을 포함하기도 함
  • WAS도 웹 서버의 기능을 수행 가능

 

자바에서는 서블릿 컨테이너 기능을 제공하면 WAS 라고 하며 WAS는 애플리케이션 코드를 실행하는데 더 특화돼있다.

 


웹 서버와 WAS를 분리하는 이유는?

WAS는 정적 리소스, 애플리케이션 로직 모두 제공 가능하므로 WAS, DB 만으로도 시스템 구성이 가능하다.

그러나 주로 서버 구성 시에 웹 서버와 WAS를 분리하여 구성한다. 그 이유에 대해 알아보자.

 

1. WAS가 너무 많은 역할을 담당하면 서버 과부하 우려가 있다.

WAS 단독으로 사용시 정적 리소스 때문에 가장 중요한 애플리케이션 로직의 수행이 어려울 수 있다.

또한 WAS 장애 시 오류 화면 출력이 불가능하다.

 

2. 물리적으로 분리하여 보안을 강화한다.

WAS에는 실제 Web Application이 올라가 있기 때문에 외부와 직접 연결이 되어 있다면

중요한 설정 파일이나 리소스들이 외부로 노출될 수 있다.
이를 막기 위해서 서버 WAS앞단에 배치해서 리소스를 안전하게 보호할 수 있다.

 

3. 유연한 로드밸런싱이 가능하다.

 

정적 리소스는 웹 서버가 처리하고, WAS가 애플리케이션 로직같은 동적인 처리를 전담한다.

이에 따라 효율적인 리소스 관리가 가능해진다.

  • 정적 리소스가 많이 사용되면 웹 서버 증설
  • 애플리케이션 리소스가 많이 사용되면 WAS 증설

 

 

결론

웹 서버는 정적인 리소스를 제공하는 서버이고, WAS는 동적인 리소스를 제공하는 서버이다.

WAS 단독으로도 시스템 구성이 가능하지만 웹 서버WAS를 분리하여 구성하는 가장 큰 이유는 로드밸런싱.

'네트워크' 카테고리의 다른 글

[네트워크] JWT 란  (2) 2023.10.04
x-www-form-urlencoded와 json  (0) 2023.09.21
[네트워크] HTTP 요청 데이터  (0) 2023.07.25
[네트워크] REST API 란?  (0) 2023.03.27
[네트워크] API 란?  (0) 2023.03.27

SELECT

프로그래머스 레벨2짜리 SQL 문제이다. 문제 링크

GROUP BY의 동작에 대해 좀 더 익혀둬야겠다.

이번 문제를 통해 HAVING, COUNT 도 배울 수 있었다.

이번 문제에서 배운 점은 아래와 같다.

  • GROUP BY, HAVING, COUNT 쿼리
  • COUNT로 조건에 맞는 행의 갯수를 알 수 있음

풀이

SELECT user_id, product_id
FROM online_sale
GROUP BY user_id, product_id
HAVING COUNT(product_id) > 1
ORDER BY user_id ASC, product_id DESC

MSA(Microservice Architecture) 란

모듈화 되어 작고, 독립적으로 배포 가능한 각각의 기능을 수행하는 서비스로 구성된 프레임워크이다.
하나로 통합된 프로그램인 '모놀리식 아키택쳐'에서 서비스가 커져감에 따라 부분적인 Scale-out이 어렵고,

부분 장애가 서비스 전체 장애로 이어질 수 있는 등의 문제점이 발생하면서 떠오르는 서비스 아키택쳐이다.

장점

  • 각각의 서비스 모듈끼리는 API로 통신하기 때문에 다양한 언어와 기술로 서비스를 구축할 수 있다.
  • 서비스의 부하에 따라 개별적으로 Scale-out이 가능하다.

단점

  • 모놀리식에 비해 통합테스트가 어렵고 개발환경과 실제 운영환경을 동일하게 가져가기가 어렵다.
  • 서비스가 분산돼 있기 때문에 내부 시스템의 통신을 어떻게 가져가야 할지 정해야 해서 복잡하다.
  • 통신 장애나 서버의 부하 등이 있을 경우 어떻게 transaction을 유지할지 정하고 구현해야 한다.

 

참고 자료

 

[MSA] MSA란 무엇인가? 개념 이해하기

MSA가 무엇인지 자세하게 알고싶어 개인적으로 정리하는 포스팅입니다. MSA? MicroService Architecture의 줄임말 👉🏻 마이크로서비스 아키텍처에 대한 정확한 정의는 없다. 하지만 마이크로서비스란

wooaoe.tistory.com

 

'CS' 카테고리의 다른 글

Process 와 Thread  (0) 2023.10.05
클라이언트와 서버  (0) 2023.04.03
의존성 주입(Dependency Injection) 이란?  (0) 2023.03.28
OOP 3: SOLID 객체 지향 설계 5원칙  (0) 2023.03.28
OOP 2: 객체 지향 프로그래밍의 특징  (0) 2023.03.27

의존성 주입(DI, Dependency Injection) 이란

애플리케이션 실행 시점(런타임)에 외부에서 실제 구현 객체를 생성하고 클라이언트에 그 참조값을 전달하여

클라이언트와 서버의 실제 의존 관계가 연결 되는것이다.

여기서 클라이언트란 인터넷 브라우저를 뜻하는게 아닌 DI를 주입받는 객체를 의미한다.

 

의존성 주입의 장점

DI를 사용하면 구현체가 아닌 추상화에 의존하여 클라이언트의 코드를 변경하지 않고

클라이언트가 호출하는 대상의 타입 인스턴스를 변경할 수 있어서 유지보수에 유리하다

 

의존성 주입의 방법

필드, getter/setter, 생성자 주입이 있다

객체 지향 설계 5원칙(SOLID)

1. 단일 책임 원칙 (SRP, Single Responsibility Principle)

  • 하나의 클래스는 단 하나의 책임만 가져야 한다.
  • 변경을 기준으로 변경 시 파급효과가 적으면 단일 책임 원칙을 잘 따르는 것이다.

2. 개방-폐쇄 원칙 (OCP, Open/Closed Principle)

  • 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
  • 기능을 변경하거나 확장할 수 있으면서 기능을 사용하는 코드는 수정하지 않는다.
  • 다형성을 활용하여 구현체가 아닌 추상화에 의존한다.

3. 리스코프 치환 원칙 (LSP, Liskov Substitution Principle)

  • 프로그램 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
  • 상위 타입의 객체를 하위 타입의 객체로 치환해도, 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
  • 엑셀을 바꿨는데 엑셀 밟을때 앞으로 가야지 발 뗐을때 가서는 안된다.

4. 인터페이스 분리 원칙 (ISP, Interface Segregation Principle)

  • 범용 인터페이스 하나보다 특정 클라이언트를 위한 여러 개의 인터페이스로 구성하는 것이 좋다.
  • 범용 인터페이스를 클라이언트가 필요로 하는 개별의 인터페이스로 분리함으로써 각 클라이언트가 사용하지 않는 인터페이스에 변경이 있어도 영향을 받지 않도록 만들어야 한다.
  • 읽기와 쓰기 전용 인터페이스를 분리한다면 변경에 대한 영향을 더욱 세밀하게 제어할 수 있다.

5. 의존관계 역전 원칙 (DIP, Dependency Inversion Principle)

  • 추상화에 의존해야지 구체화에 의존하면 안된다.
  • 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안되고 저수준 모듈은 고수준 모듈에서 정의한 추상 타입에 의존해야 한다.
  • 비즈니스와 관련된 부분이 세부 사항에 의존하지 않는 설계 원칙

객체 지향 설계 5원칙인 SOLID가 얘기하는 핵심은 결국 추상화와 다형성이다. 구체 클래스에 의존하지 않고 추상 클래스(또는 인터페이스)에 의존함으로써 우리는 유연하고 확장가능한 애플리케이션을 만들 수 있는 것이다.

 

 

참고 자료

 

[OOP] 객체지향 프로그래밍의 5가지 설계 원칙, 실무 코드로 살펴보는 SOLID

이번에는 객체 지향 프로그래밍의 5가지 핵심 원칙인 SOLID에 대해 알아보고자 합니다. 실제로 애플리케이션을 개발할 때 어떻게 적용할 수 있을지 구체적인 예시를 들어 살펴보고자 합니다. 아

mangkyu.tistory.com

 

객체 지향 프로그래밍의 특징

1. 추상화

  • 객체에서 공통된 속성과 행위를 추출 하는 것
  • 추상화는 불필요한 정보는 숨기고 중요한 정보만을 표현함으로써 프로그램을 간단하게 만드는 것

생성일자 ,수정일자 ,생성자, 수정자는 대부분의 엔티티에 필요한 'BaseEntity'에 해당된다. BaseEntity 라는 추상화 집합을 만들어두고 BaseEntity가 가진 공통적인 특징들을 만들어서 활용한다.

 

추상화가 왜 필요할까?

  • 개발을 하면서 추가 기능이 요구되어 엔티티가 추가될 수도 있다. 이때 추상화로 'BaseEntity'를 구현 해놓았다면 추상화 된 공통된 정보 외에 추가할 정보만 입력해주면 된다.
  • 중복 코드의 양을 줄일 수 있다.

2. 캡슐화

  • 데이터 구조와 데이터를 다루는 방법들을 결합 시켜 묶는 것 (변수와 함수를 하나로 묶는 것을 뜻함)
  • 낮은 결합도를 유지할 수 있도록 설계하는 것

 

 

접근제어자를 활용하면 getter/setter 혹은 객체의 내부 메서드를 통해서만 외부에서의 접근이 가능하도록 제한하여 정보은닉을 활용 할 수도 있다. 

(무분별하게 Setter를 열어두는건 좋지 않지만 예시로 사용하고자 한다.)

 

@Entity
@Table(name = "orders")
@Getter @Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)  
public class Order {

==============================윗부분 생략==============================

//==생성 메서드==//  여기서 주문 생성 관련을 완결해놔서 나중에 추가할게 생겨도 이 부분만 바꾸면 됨
    public static Order createOrder(Member member, Delivery delivery, OrderItem... orderItems) {
        Order order = new Order();
        order.setMember(member);
        order.setDelivery(delivery);
        for (OrderItem orderItem : orderItems) {
            order.addOrderItem(orderItem);
        }
        order.setStatus(OrderStatus.ORDER);
        order.setOrderDate(LocalDateTime.now());
        return order;
    }

    /**
     * 주문 취소
     */
    public void cancel() {
        if (delivery.getStatus() == DeliveryStatus.COMP) {
            throw new IllegalStateException("이미 배송완료된 상품은 취소가 불가능합니다.");
        }
        this.setStatus(OrderStatus.CANCEL);
        for (OrderItem orderItem : orderItems) {
            orderItem.cancel();
        }
    }

 

Order 엔티티 내에서 createOrder나 cancel과 같은 내부 메서드를 만들어서

객체 내부의 동작을 외부로의 노출을 최소화하여 각 객체의 자율성을 높이고, 객체 간 결합도를 낮추어 변경이 용이한 객체 지향의 핵심적인 이점을 잘 살리는 방법으로 프로그램을 설계할 수 있다.

3. 상속

  • 클래스의 속성과 행위를 하위 클래스에 물려주거나 하위 클래스가 상위 클래스의 속성과 행위를 물려받는 것을 말한다
  • 새로운 클래스가 기존의 클래스의 데이터와 연산을 이용할 수 있게 하는 기능

상속을 하게 된다면 장단점이 존재하는데 이는 다음과 같다.

 

장점                                                                               단점

- 재사용으로 인한 코드가 줄어든다
- 범용적인 사용이 가능하다
- 자료와 메서드의 자유로운 사용 및 추가가 가능하다
- 상위 클래스의 변경이 어려워진다
- 불필요한 클래스가 증가할 수 있다
- 상속이 잘못 사용될 수 있다


4. 다형성

  • 하나의 변수명, 함수명이 상황에 따라 다른 의미로 해석 될 수 있는 것
  • 어떠한 요소에 여러 개념을 넣어 놓는 것

객체 지향 프로그래밍은 하나의 클래스 내부에 같은 이름의 행위를 여러개 정의하거나 상위 클래스의 행위를 하위 클래스에서 재정의하여 사용할 수 있기 때문에 다형성이라는 특징을 갖는다.

 

오버라이딩

  • 상위 클래스가 가지고 있는 메소드를 하위 클래스가 재정의해서 사용하는 것

오버로딩

  • 같은 이름의 메서드가 인자의 개수나 자료형에 따라 다른 기능을 하는 것
  • 생성자 오버로딩을 생각하면 쉽다

다형성의 본질

  • 인터페이스를 구현한 객체 인스턴스를 실행 시점유연하게 변경할 수 있다
  • 클라이언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있다

객체 지향 프로그래밍

OOP(Object-Oriented Programming)란 프로그램 설계방법론이자 개념의 일종이다.

프로그램을 단순히 데이터와 처리 방법으로 나누는 것이 아니라,

프로그램을 수많은 '객체(object)'라는 기본 단위로 나누고 이들의 상호작용으로 서술하는 방식이다.

객체

객체는 프로그램에서 사용되는 데이터 또는 식별자에 의해 참조되는 공간을 의미하며

하나의 역할을 수행하는 '메소드와 변수(데이터)'의 묶음라고 할 수 있다.

레고에 빗대 표현하자면 객체는 레고의 조각이고 레고를 조립해서 무언가를 만들어 내는 것이 객체 지향 프로그래밍이라고 할 수 있다.

 

 

객체 지향 프로그래밍의 특징

객체 지향 프로그래밍은 크게 추상화, 캡슐화 ,상속 ,다형성 의 네가지 특징을 가진다.

SOLID (객체 지향 설계 원칙)

객체 지향적으로 설계하기 위해 SOLID 라 불리는 다섯 가지 원칙이 있다.

 

1. 단일 책임 원칙 (SRP, Single Responsibility Principle)

2. 개방-폐쇄 원칙 (OCP, Open/Closed Principle)

3. 리스코프 치환 원칙 (LSP, Liskov Substitution Principle)

4. 인터페이스 분리 원칙 (ISP, Interface Segregation Principle)

5. 의존관계 역전 원칙 (DIP), Dependency Inversion Principle)

 

REST 란

REST(Representational State Transfer)란 네트워크 아키텍처 스타일이다.

여기서 '네트워크 아키텍처 스타일'란 네트워크 자원을 정의하고 처리하는 방법 전반을 일컫는다.

 

즉, REST는 HTTP를 잘 활용하기 위한 원칙이라고 할 수 있고
REST API는 이 원칙을 준수해 만든 API이다.

 

그렇다면 HTTP를 잘 활용하기 위한 원칙은 무엇인가?

Representational State Transfer
자원의 표현으로 상태를 전달하는 것

 

URI로 자원을 표현하는 데에 집중하고, HTTP METHOD로 자원의 상태(행위)를 정의하는 것이

REST한 API를 설계하는 중심 규칙이다.

 

RESTful한 설계의 중심 규칙

  • URI로 자원(리소스)을 표현해야 한다.
  • 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE)로 표현된다.

 

예시를 통해 살펴보도록 하자.

 GET /members/delete/1

위와 같은 방식은 REST를 제대로 적용하지 않은 URI이다. URI는 자원을 표현하는데 중점을 두어야 한다.

delete와 같은 행위에 대한 표현은 HTTP Method를 통해 표현한다.

위의 잘못된 URI를 HTTP Method를 통해 수정해 보면 아래와 같이 수정할 수 있다.

DELETE /members/1

 

회원정보 조회는 GET, 회원 추가를 표현하고자 할 때는 POST METHOD를 통해 표현한다.

 

회원정보를 조회하는 URI

GET /members/show/1     (x)
GET /members/1          (o)

 

회원을 추가할 때

GET /members/insert/2   (x) 
POST /members/2         (o)

 

 

추가 지식)

사실 요즘 사용하는 REST API 라는 용어는 HTTP API와 거의 같은 의미라고 한다.

본래 REST API는 HTTP 프로토콜을 따르면서 아래의 4가지 가이드 원칙을 지켜야 한다.

 

  1. 자원의 식별
  2. 메세지를 통한 리소스 조작
  3. 자기서술적 메세지
  4. 애플리케이션의 상태에 대한 엔진으로서 하이퍼미디어(HATEOAS)

 

이러한 제약 조건들을 완벽하게 지키면서 개발하는 것을 RESTful API라고 하는데

실무에서 이런 방법으로 개발하는 것은 현실적으로 어렵고 개발비용 대비 효과가 있는 것도 아니다.

(4번째 원칙이 특히나 구현하기 어렵다.)

그런데 이미 많은 사람들이 이 조건들을 지키지 않아도 REST API라고 하기 때문에 HTTP API와 같은 의미로 사용하고 있다.

하지만 엄밀하게는 위 제약 조건들을 모두 지켜야 REST API라고 말할 수 있다.

좀 더 알고싶다면 해당 유튜브 영상을 한 번 보는것도 괜찮을것 같다.

 

참고 자료)

https://bentist.tistory.com/37

 

API, HTTP API, REST API 차이

기상청 날씨정보 API, 증권 API, 지도 API 등등 막연하게 API란 단어를 들어왔다. API를 가져다 써, API로 개발한다 등등 개념은 제대로 모르며 사용 해왔기에 이번엔 API에 대해 개념적으로 정리해보고

bentist.tistory.com

 

'네트워크' 카테고리의 다른 글

[네트워크] JWT 란  (2) 2023.10.04
x-www-form-urlencoded와 json  (0) 2023.09.21
[네트워크] HTTP 요청 데이터  (0) 2023.07.25
웹 서버(WS)와 WAS 및 분리 이유  (0) 2023.04.03
[네트워크] API 란?  (0) 2023.03.27

+ Recent posts