当前位置: 首页 > news >正文

Rust编程实战:Rust实现简单的Web服务,单线程性能问题

知识点

  1. tcp 服务
  2. 多线程处理

实现功能

启动web服务,访问链接获取页面内容。

单线程web服务

TcpListener

使用 TcpListener 开启服务端口

 let listener = TcpListener::bind("127.0.0.1:7878").unwrap();

处理客户端连接:

 for stream in listener.incoming() {
        println!("Connection established!");
    }

当浏览器访问 http://127.0.0.1:7878/ 就打印 “Connection established!”, 表示服务启动成功。

处理接口请求

设计2个接口:

  1. 访问 http://127.0.0.1:7878 时,显示index.html 的内容
  2. 访问 http://127.0.0.1:7878/sleep 时,做一个延迟,模拟单线程服务的问题

准备html文件

  1. index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Hello!</title>
  </head>
  <body>
    <h1>Hello!</h1>
    <p>Hi from Rust</p>
  </body>
</html>
  1. 404.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>你好!</title>
  </head>
  <body>
    <h1>很抱歉!</h1>
    <p>由于运维删库跑路,我们的数据全部丢失,总监也已经准备跑路,88</p>
  </body>
</html>

实现

  1. 实现请求路由判断
  2. 读取 html 文件内容,并且返回

请求路由判断

通过 BufReader 获取请求数据

   // 解析buffer. 获取请求的数据
    let buf_reader = BufReader::new(&mut stream);
    // 读取请求行
    let http_request: Vec<_> = buf_reader
        .lines()
        .map(|result| result.unwrap())
        .take_while(|line| !line.is_empty())
        .collect();
        

http_requset 得到数据如下:

[
    "GET / HTTP/1.1",
    "Host: 127.0.0.1:7878",
    "Connection: keep-alive",
    ...
   ]

由此数据可得,只需要判断数组第一个数据就知道请求到哪个路由了。

 let request_line =  if http_request.len( ) > 0 { &http_request[0] } else {""};
    let (status_line, filename) =  match &request_line[..] {
        "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "index.html"),
        "GET /sleep HTTP/1.1" => {
            std::thread::sleep(Duration::from_secs(5)); // 添加 5 s 延迟
            ("HTTP/1.1 200 OK", "index.html")
        }
        _ => ("HTTP/1.1 404 NOT FOUND", "404.html"),
    };

处理html文件

通过 文件 处理模块 fs 获取文件的内容。

    let contens = fs::read_to_string(filename).unwrap();

设置返回数据

获取文件的内容之后,把数据返回给客户端, 通过 write_all 方法。

 let content_length = contens.len();

    // 组合返回数据
    let response = format!(
        "{}\r\nContent-Length: {}\r\n\r\n{}",
        status_line,
        content_length,
        contens
    );

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

效果

当客户端访问 http://127.0.0.1:7878 就会看到 index.html 的内容。如果客户端先访问 http://127.0.0.1:7878/sleep 新起标签页面访问 http://127.0.0.1:7878,如下图。你会发现 http://127.0.0.1:7878 的请求并没有立即显示,而是等待 sleep 请求结束才会显示。相当于接口会存在排队的处理,这对于web服务是个不好的体验。因此需要多线程去处理这些问题。
在这里插入图片描述

处理多线程请求

将每个请求都用 thread 去处理

thread::spawn(|| {
            handle_connection(stream);
        });

效果如下,并没有发生排队的问题。这只是简单处理,实际上现在成熟的框架处理单线程的问题。
在这里插入图片描述
源码

相关文章:

  • 第八篇《九变篇》
  • android13打基础: 控件alertdialog
  • 电子电气架构 --- 拓扑架构集中的趋势及其演变
  • Linux12-TCP\HTTP
  • e2studio开发RA2E1(18)----看门狗WDT
  • SEO新手操作实战精要
  • 未来经济范式争夺战:AR眼镜为何成为下一代交互终端的制高点?
  • Compose Multiplatform+Kotlin Multiplatfrom 第四弹跨平台
  • 文件下载/文件导出---使用a标签,访问文件路径进行下载
  • 算法1-4 凌乱的yyy / 线段覆盖
  • 全星FMEA软件系统在汽车电子行业的应用介绍
  • 2024 JAVA面试题
  • CSS—flex布局、过渡transition属性、2D转换transform属性、3D转换transform属性
  • 2025-03-04 学习记录--C/C++-C语言 判断是否是素数
  • stable-diffusion-webui 加载模型文件
  • sql调优(oracle):优化响应时间(优化sql) / 优化吞吐量; 高斯调优
  • 一、OpenGL的原理解析
  • FreeRTOS 源码结构解析与 STM32 HAL 库移植实践(任务创建、删除篇)
  • Windows 10/11 系统下 Git 的详细安装步骤和基础设置指南
  • Foxglove 介绍以及入门使用教程
  • 坪山网站建设价位/长沙网站开发
  • 适合企业网站的cms/如何建立一个网站平台
  • 网站建设沟通/如何推广普通话
  • 最好的网站设计/网站构建的基本流程
  • 链接制作网站/今日新闻大事件
  • 建设集团企业网站/竞价推广出价多少合适