1. 프록시(Proxy)
- 대리자를 의미한다
- 실제 객체나 서버 대신에 요청을 받아 대신 처리하거나, 그 요청을 전달하는 역할을 하는 중간 객체
- 즉, 대리인처럼 실제 작업을 대신하는 객체이다 ~!
2. 프록시를 사용하는 이유
1. 접근 제어: 어떤 객체에 대한 접근을 제어하고, 필요 시에 권한을 검사할 수 있다
2. 성능 최적화: 실제 객체가 무겁거나 시간이 많이 걸릴 경우, 프록시가 작업을 지연시키거나 캐싱하는 방법이 있다
3. 로깅과 보안: 실제 객체가 호출되기 전에 요청을 로깅하거나, 보안 처리를 할 수 있다.
4. 리모트 객체: 네트워크를 통해 접근할 수 없는 객체를 마치 로컬 객체처럼 사용할 수 있게 해준다.
3. 프록시 패턴(Proxy Pattern)
- 대리 객체(Proxy)를 통해 실제 객체에 접근하는 구조를 제공하는 디자인 패턴이다.
- 프록시 객체는 실제 객체와 동일한 인터페이스를 제공하면서, 실제 객체에 대한 접근을 제어하는 역할이다.
4. 프록시 패턴의 종류
1. 가상 프록시(Virtual Proxy)
- 실제 객체의 생성 비용이 크거나 시간이 많이 걸릴 경우, 객체를 지연 로딩하여 성능을 최적화하는 프록시.
- ex) 큰 이미지를 로딩할 때, 처음에는 작은 미리보기 이미지만 보여주고 실제 큰 이미지는 필요할 때 로딩
2. 보호 프록시(Protection Proxy)
- 객체에 대한 접근 권한을 제어하거나 보안을 강화하는 프록시. > 특정 사용자만 접근하게 제한 하는 등 접근 제어 역할
- ex) 사용자의 권한에 따라 시스템에서 민감한 데이터나 기능에 접근할 수 있도록 하는 경우
3. 리모트 프록시(Remote Proxy)
- 실제 객체가 네트워크를 통해 원격으로 위치할 때, 이를 로컬 객체처럼 사용할 수 있게 해주는 프록시.
- ex) 원격 서버에 있는 객체에 네트워크를 통해 접근하거나, 분산 시스템에서 사용됨
4. 캐싱 프록시(Caching Proxy)
*캐시(Cache): 데이터를 빠르게 접근할 수 있도록 미리 저장해 두는 공간
즉, 자주 사용하는 데이터를 빠르게 조회할 수 있도록 임시로 저장
- 자주 사용되는 데이터나 객체의 결과를 *캐시하여 성능을 최적화하는 프록시. > 동일한 요청에 대해 반복적인 처리 없이 캐시된 값을 반환하여 성능을 향상
- ex) 웹 애플리케이션에서 자주 요청되는 데이터나 페이지를 캐시하여 응답 속도를 빠르게 하는 경우
5. Java의 프록시 패턴 예시
// 실제 객체 인터페이스
interface RealSubject {
void request();
}
// 실제 객체
class RealSubjectImpl implements RealSubject {
@Override
public void request() {
System.out.println("RealSubject: Handling request."); // 실제 객체의 출력내용
}
}
// 프록시 객체
class Proxy implements RealSubject {
private RealSubjectImpl realSubject; // 실제 객체의 참조
@Override
public void request() {
if (realSubject == null) { // 실제 객체가 아직 생성되지 않았다면
realSubject = new RealSubjectImpl(); // 실제 객체 생성
}
System.out.println("Proxy: Delegating request to RealSubject."); // proxy의 출력내용
realSubject.request(); // 실제 객체의 메서드 호출
}
}
public class ProxyPatternDemo {
public static void main(String[] args) {
RealSubject proxy = new Proxy();
proxy.request(); // 프록시를 통해 실제 객체의 메서드를 호출
}
}
코드 분석
1. RealSubjectImpl: 실제 객체를 구현하는 클래스.
2. Proxy: 프록시 객체. RealSubject 인터페이스를 구현하면서, 실제 객체에 대한 접근을 제어하는 역할. > 실제 객체를 지연 생성(Lazy Initialization)하고, 실제 메서드를 호출하기 전에 프록시가 대신 호출하도록 함
3. ProxyPatternDemo: Proxy 객체를 사용해서 실제 객체에 요청을 전달하는 방식. > 프록시 패턴을 테스트
동작 흐름
1. 프록시 객체가 처음 생성될 때, Proxy 객체 생성
2. 그 후, proxy.request() 메서드를 호출하면서 Proxy 클래스 안의 request() 메서드가 실행 > realSubject == null일 경우, 실제 객체인 RealSubjectImpl가 생성 !
3. 생성된 실제 객체의 request() 메서드가 호출되면서 "RealSubject: Handling request"가 출력
4. 한번 실행되면 실제 객체는 캐시된다.
***헷갈린 부분
- 지연 생성: 실제 객체를 즉시 만들지 않고, 필요한 시점에 만들어서 사용 > 필요한 시점 ??
> 예를 들자면 웹페이지에 접속 시, 프록시 객체는 작은 이미지를 즉시 보여줌과 동시에 실제 객체(큰 이미지)를 생성한다. 그래서 지연 생성은 실제 객체의 생성을 미루는 것이지만, 미리 준비해 두는 과정이기 때문에 사용자 입장에서는 큰 이미지를 볼 때 빠르게 느껴진다.
> 두번째 호출부터는 이미 생성된 객체가 재사용되므로, 빠르게 큰 이미지를 보여줄 수 있음
> 지연 생성이라는 말이 늦어진다는 부정적인 느낌이 있어서 뭐가 좋은거지 싶었음
> 즉, 큰 이미지(실제 객체)를 클릭하지 않으면, 실제 객체(큰 이미지)는 생성되지만 사용되지 않고 계속 작은 이미지(프록시 객체)만 표시되며, 실제 객체의 메서드(큰 이미지를 화면에 출력하는 메서드)는 호출되지 않는다.
6. 프록시 서버(Proxy Server)
- 중간 서버로, 클라이언트와 서버 간의 요청을 대신 처리하는 역할.
- 웹 페이지를 요청하면, 프록시 서버가 요청을 받고 해당 웹사이트에 접근한 뒤, 받은 정보를 사용자에게 전달하는 방식
- 즉, 클라이언트가 서버에 직접 요청하지 않고, 프록시 서버를 거쳐서 요청하는 구조.
7. 프록시 서버의 종류
1. 웹 프록시(HTTP Proxy)
- 주로 HTTP 요청을 처리하는 프록시 서버
- 클라이언트가 웹페이지를 요청하면 프록시 서버가 대신 해당 페이지를 서버로부터 요청, 응답을 클라이언트에게 전달
2. 익명 프록시(Anonymous Proxy)
- 클라이언트의 IP 주소를 숨기고 요청을 서버로 전달하는 프록시 서버
- 프라이버시 보호에 유용
3. 리버스 프록시(Reverse Proxy)
*로드 밸런싱(Load Balancing): 네트워크 또는 서버에 가해지는 부하 트래픽을 분산시켜주는 기술
- 서버 측에서 요청하는 프록시
- 클라이언트는 리버스 프록시에 요청을 보내고, 리버스 프록시는 서버에 요청을 전달
- 주로 *로드 밸런싱이나 보안을 위해 사용
4. 캐싱 프록시(Caching Proxy)
- 자주 요청되는 웹 콘텐츠나 데이터를 캐싱하여 성능을 최적화 하는 프록시
- 서버에서 자주 요쳥되는 이미지나 파일을 프록시 서버에 저장하고, 같은 요청이 들어오면 프록시 서버에서 바로 응답
5. 포워딩 프록시(Forwarding Proxy)
- 클라이언트의 요청을 다른 서버로 전달하는 프록시
- 네트워크 보안이나 접근 제어를 위해 사용
- 클라이언트와 서버 사이에서 요청을 대신 처리
8. CloudFlare
- 인터넷 보안과 성능 최적화를 제공하는 클라우드 기반 서비스
- 웹사이트 보호, 콘텐츠 배달, DDOS 공격 방어 등 제공
9. CloudFlare 사용 전후 차이
CloudFlare 사용 전
*DDOS(Distributed Dnial of Service): 여러 대의 컴퓨터나 서버를 이용해 특정 서버나 네트워크에 과도한 트래픽을 보내 서비스를 마비시
키거나, 서버를 다운시키는 공격방식
> 사용자, 크롤러, 공격자가 직접 서버로 트래픽 전달 > *DDOS 공격, 느린 로딩 속도, 높은 대역폭 사용
CloudFlare 사용 후
*CDN(Content Delivery Netword): 각 사용자가 인터넷에 접속하는 곳과 가까운 곳에서 컨텐츠를 캐싱 또는 배포하는 서버 네트워크
즉, 사용자가 웹 서버로부터 컨텐츠를 다운로드하는 시간을 줄여줌
> 사용자, 크롤러, 공격자가 CloudFlare의 *CDN, 보안 레이어, 캐싱을 거쳐서 서버에 전달 > 서버 보호, 속도 향상, 대역폭 최적화
9. CORS(Cross-Origin Resource Sharing)
*오리진(Origin): 도메인, 프로토콜, 포트를 모두 포함하는 개념
ex) 'https://example.com:443/zajinmori' 에서 오리진은 'https://example.com:443' 이다
- 웹 페이지가 다른 도메인이나 포트, 프로토콜에서 제공하는 리소스를 요청할 수 있도록 하는 브라우저 보안 정책
- 즉, *다른 출처(Origin)의 리소스를 안전하게 공유하는 방법을 정의한 매커니즘
10. CORS가 필요한 이유
*동일 출처 정책(Same-Origin Policy): 한 출처(Origin)에서 로드된 웹 페이지가 다른 출처의 리소스에 접근하는 것을 제한
- 브라우저는 보안상 웹 페이지가 다른 출처의 리소스를 요청하는 것을 제한하는 *동일 출처 정책을 따른다
- 그러나! 웹 애플리케이션에서 API 서버가 다른 도메인에 있을 때는 클라이언트 웹 애플리케이션에서 다른 출처의 리소스를 요청해야 할 필요가 있어서 CORS가 필요하다
11. Java의 CORS 설정
- @CrossOrigin 어노테이션 사용
> 메서드나 클래스에만 CORS 설정하는데 사용되며, 간단한 설정에 유용
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
// 특정 출처만 허용
@CrossOrigin(origins = "https://example.com")
@GetMapping("/data")
public String getData() {
return "Hello from Spring Boot!";
}
// 모든 출처 허용
@CrossOrigin
@GetMapping("/all")
public String getAllData() {
return "Anyone can access this!";
}
}
- WebMvcConfigurer 사용
*엔드포인트(Endpoint): 클라이언트와 서버 간 통신에서 특정한 URL 경로나 인터페이스를 의미
주로 API 서버와의 요청-응답에서 사용되며, HTTP 메서드와 결합하여 각 요청에 대한 동작을 정의
ex) 'https://example.com/api/user'에서 엔드포인트는 '/api/user'이다.
> 전역적으로 CORS를 설정할 때 사용
> 애플리케이션의 모든 *엔드포인트에 CORS 적용
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 모든 엔드포인트에 대해 CORS 설정
registry.addMapping("/**")
.allowedOrigins("https://example.com", "https://anotherdomain.com") // 허용할 출처
.allowedMethods("GET", "POST", "PUT", "DELETE") // 허용할 메서드
.allowedHeaders("Content-Type", "Authorization") // 허용할 헤더
.allowCredentials(true) // 자격 증명 허용 (쿠키, 인증 헤더 등)
.maxAge(3600); // 프리플라이트 요청의 응답을 캐시할 시간 (초)
}
}
12. 결론
프록시 패턴은 대리 객체를 사용하여 실제 객체에 대한 접근을 제어하는 디자인 패턴이다.
실제 객체의 생성 비용을 줄이거나, 접근 권한을 제어할 수 있으며 특히 대규모 시스템에서 중요하게 활용된다
CORS는 웹 애플리케이션이 다른 출처의 리소스를 안전하게 요청할 수 있도록 해주는 브라우저의 보안 매커니즘이다
CloudFlare와 같은 CDN 및 보안 서비스는 웹사이트의 성능 최적화와 보안 강화에 매우 중요한 역할을 한다.
'Computer Science > Design Pattern' 카테고리의 다른 글
| 노출모듈 패턴(Revealing Module Pattern) (1) | 2025.03.24 |
|---|---|
| 이터레이터 패턴(Iterator Pattern) (0) | 2025.03.21 |
| 옵저버 패턴(Observer Pattern) (1) | 2025.03.19 |
| 전략 패턴(Strategy Pattern) (1) | 2025.03.18 |
| 팩토리 패턴(Factory Pattern) (0) | 2025.03.17 |
