TIL - 0807

HTTP

  • 웹 구성요소들이 대화를 하기위해 만들어진 프로토콜(약속)
    • 클라이언트 - 서버
    • 상호운용성을 중요시 함 : 버젼업이 되더라도 하위호환성 있게 기존의 것은 그대로 유지
    • TCP/IP 기반 : 하지만 리소스 1개에 대한 트랜잭션 후 연결을 끊고, 다시 연결을 만들어 트랜잭션 진행(커넥션 생성 반복으로 오버헤드 발생하는 것을 대체하는 방법이 있긴 함 - keep alive), URL에 명시된 주소와 포트(80이라면 생략 - 웹 클라이언트 default)로 TCP/IP 프로토콜 메세지 작성 -> 연결 -> HTTP 통신
  • MIME 타입 : Multipurpose Internet Mail Extentions, 멀티미디어 콘텐츠의 타입 라벨(주고 받을 리소스의 타입)
    • HTTP는 .html 문서 뿐만 아니라 여러 타입 리소스를 주고 받을 수 있을 수 있음 : MIME 타입 지정해야
    • 주타입/부타입 : text/html, text/plain, image/jpeg
    • 요청, 응답 시에 명시해줘야함 : Accept, Content-Type
  • 서버 API : 서버에서 공개해놓은 인터페이스, URI와 API를 구분해서 사용할 것(리소스와 행위)
  • URI : 리소스 식별하는 방법(식별자), 두가지가 있음 URL과 URN
    • URL : 정확히 리소스가 어디있는지(접근방법, 호스트, 경로)까지 지정, 스킴://호스트:포트/경로(스킴 - 클라이언트가 리소스 접근 시 사용해야하는 방법)로 구성되어있음, 일관된 방식으로 호출할 수 있게 경로 또한 디자인해야함(uniform interface)
  • HTTP 트랜잭션(상호작용) : 리소스 요청 - 리소스 응답, HTTP 메세지를 기반 트랜잭션이 이뤄짐
    • 요청 메세지 구성 : 리퀘스트 라인(HTTP 메소드, 리소스 식별자, HTTP 버젼), 헤더, 바디
    • 응답 메세지 구성 : 리스폰스 라인(응답 코드, 응답 코드의 메세지, HTTP 버젼), 헤더, 바디
    • 직접 메세지 보내보기 : telnet(원격 접속 프로토콜, 프로토콜 기반 원격 접속 프로그램)으로 웹서버 접속해서 HTTP 요청 메세지 전송하니 응답 메세지가 옴

  • 웹 구성요소
    • 리버스 프록시 : 클라이언트 요청을 일단 모두 받는 역할, 받은 뒤 서버에 전달함, 실제 서버를 숨길 수 있음(보안)
    • 캐시
    • 게이트워이 : 프록시와 같은 역할인데, HTTP 프로토콜 통신을 다른 프로토콜 통신으로 변환하기위해 사용(다른 프로토콜로 리소스를 요청하도록 변환)
    • 에이전트 : 유저의 HTTP 요청을 만들어주는 클라이언트 프로그램(대표적으로 웹브라우져가 있음, RestTemplate로도 해당 프로그램을 만들 수 있음, 크롤러도 요청하고 응답받아 원하는 내용을 파싱하는 것이므로 에이전트)

웹서버 캐시해보기

준비하기

  • 스프링으로 만든 WAS를 배포 서버에서 run하기위해서 jre 설치하기
  • (선택)배포 자동화 스크립트 작성
    • 테스트 완료
#! /bin/zsh
JAVA="$JAVA_HOME/java"
JAVA_OPTS="$JAVA -Djava.security.egd=file:/dev/./urandom"

REPO=$HOME/java-ims
TARGET=$REPO/build/libs

cd $REPO
git fetch origin master

origin=$(git rev-parse imjinbro)
remote=$(git rev-parse origin/imjinbro)

if [[ $origin == $remote ]]; then
   exit 0
fi

git merge origin imjinbro

CURRENT_PID=$(pgrep -f java-ims)

if [ -n $CURRENT_PID ]; then
    kill -9 $CURRENT_PID
    sleep 5
fi

#build gradle
./gradlew build -x test

if [ ! -d $TARGET ]; then
    exit 1
fi

cd $TARGET
java -jar java-ims-*.jar & > /dev/null 2>&1
  • 웹서버(nginx) 설치 및 리버스 프록시 설정
    • WAS 포트 번호는 외부에서 접근하지못하도록 열어놨던 설정을 닫아야함 : 80 포트를 통해서 요청이 전해지도록
    • 디렉토리(우분투 기준) : /etc/nginx (찾기 : sudo find / -name nginx.conf)
    • 설정 파일 : nginx.conf(기본설정, 건들지않고 수정할 수 있음), sites-avaliable(파일명.conf 파일 만들고 설정 후 sites-enable에 링크 만들기)
    • 설정 후 : sudo service nginx reload(리로드 해줘야함)
    • http 블록 : 상위 블록, 여기서 설정한 값이 하위블록에서 적용, nginx.conf에 있음
    • server 블록 : 하나의 웹사이트에 대한 처리 방법 설정
    • location 블록 : 특정 URL에 대한 처리 방법 설정
    • nginx.conf에 전역 값(http)을 지정해두고 sites-available에 서버에 대한 설정하기(꼭 굳이 안그래도 되지만… 서버마다 지정해도 되고) - 테스트 완료
/* nginx.conf */
http {
   .
   .
   .
   
   ##
   # 캐시 설정
   ##
   proxy_cache_path /data/cache/nginx/cache/ levels=1:2 keys_zone=cache_zone:100m inactive=7d max_size=100m;   
   
   .
   .
   .
}

/* reverse_server.conf */
server {
    listen 80;

    server_name localhost;
    charset utf-8;

    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    location ~* \.(?:css|js|gif|png|jpg|jpeg)$ {
        proxy_pass http://127.0.0.1:8080;
        proxy_cache_valid 200 60m;
        proxy_cache cache_zone;
        expires 1y;
        access_log off;
        add_header X-Proxy-Cache $upstream_cache_status;
    }

    location / {
        proxy_pass http://127.0.0.1:8080;
    
}
  • 실습해본 결과

내일 해봐야할 것

  • 만료기간이 지나지 않았음에도 WAS에서는 파일이 변경되었는데, nginx는 캐시된 파일이 있고 브라우저는 캐시된 정보가 있어서 캐시 정보가 응답될텐데 어떻게?
    • 파일명을 변경하면 브라우저는 패스별로 캐시를 하기때문에 내려받도록 할 수 있음 : 그렇다면 기존 캐시된 파일은 nginx에서 계속 캐시하고 있을텐데 이건 어떻게 되나?

자료구조

링크드리스트

  • 객체 간의 연결
  • 연결은 되어있지만 연속된 메모리 공간에 위치하는게 아니라 각각 떨어져있는 애들을 연결만 시켜두는 것 - 사용하는 쪽에서는 헤드 노드만 가지고 있고 헤드에서 다음 노드로 옮겨가면서 탐색
    • 단순연결리스트 단점 : 순차탐색은 상관없지만, 특정 위치의 요소에 가려면 굉장히 비효율적인 자료구조
    • 단순연결리스트 장점 : 배열과는 삽입할 떄는 좋음, 중간에 삽입할 때는 배열에 비해서는 좋음(거기까지 찾아들어가야하지만, 최악의 경우 n회 다 들어가야) - 중간에 끊고 연결해주면 되니깐, 밀지않아도 됨
  • 종류
    1. 단순연결리스트 : 다음 노드만 연결되어있음
    2. 이중연결리스트 : 양 노드가 모두 연결(prev, next), 탐색할 때 한방향이 아니라 두 방향으로 갈 수 있음(메모리 공간은 더 쓰나 탐색할 때 단순연결리스트보다는 효율)
  • 내일 다시 이어서 하기 : 이중, 원형 구현 / 연결리스트 어디서 활용할까?