STUDY/Rust

Rust - 27. 최종 프로젝트 (2) - 러스트 공식문서 끝

sinawi95 2024. 4. 7. 15:27
728x90

1회독 끝!


싱글 스레드 서버를 멀티스레드 서버로 바꾸기

use hello::ThreadPool;
use std::{
    fs,
    io::{prelude::*, BufReader},
    net::{TcpListener, TcpStream},
    thread,
    time::Duration, 
};


fn main() {
    let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
    let pool = ThreadPool::new(4);

    for stream in listener.incoming().take(2) {
        let stream = stream.unwrap();

        pool.execute(|| {
            handle_connection(stream);
        });
    }
    
    println!("Shutting down.");
}

fn handle_connection(mut stream: TcpStream) {
    let buf_reader = BufReader::new(&mut stream);
    let request_line = buf_reader.lines().next().unwrap().unwrap();

    let (status_line, filename) = match &request_line[..] {
        "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"),
        "GET /sleep HTTP/1.1" => {
            thread::sleep(Duration::from_secs(5));
            ("HTTP/1.1 200 OK", "hello.html")
        }
        _ => ("HTTP/1.1 404 NOT FOUND", "404.html"),
    };
    
    let contents = fs::read_to_string(filename).unwrap();
    let length = contents.len();

    let response = format!(
        "{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"
    );

    stream.write_all(response.as_bytes()).unwrap();

}

웹서버의 처리량을 개선하는 여러가지 방법

  • 스레드풀
  • 포크 조인 모델
  • 싱글스레드 비동기 I/O 모델
  • 멀티스레드 비동기 I/O 모델

스레드 풀(thread pool)

  • 작업 처리가 준비된 대기 중인 스레드 그룹
  • 프로그램이 새 작업을 받으면 해당 작업을 풀에 있는 스레드 중 하나에게 할당하고 해당 스레드가 작업을 처리함.
  • 스레드 개수를 제한하면 서비스 거부 공격(DoS) 으로 부터 보호 할수 있음.

워커(Worker)

  • 스레드 풀과 스레드 사이에 새로운 동작을 관리하는 데이터 구조

마지막은 뭔가 복사 붙여넣기 하면서 읽느라 어영부영 이해하고 끝나긴했다.

그래도 남은 4월동안 러스트 책 다시 읽어볼 예정이니깐 괜찮다.