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

一次 web 请求响应中,通常那个部分最耗时?

文章目录

  • 一次Web请求的完整旅程
    • 1. DNS解析
    • 2. TCP连接建立
    • 3. 发送HTTP请求
    • 4. 服务器处理
    • 5. 服务器响应
    • 6. 浏览器渲染
  • 哪个环节通常最耗时?
    • 1. 数据库查询
    • 2. 外部API调用
    • 3. 复杂的业务逻辑
  • 如何优化各个环节?
    • 1. 数据库优化
    • 2. 缓存策略
    • 3. 异步处理
  • 总结

一次Web请求的完整旅程

当用户在浏览器地址栏输入网址并按下回车,到最终看到页面内容,这中间经历了什么?我们来拆解一下这个过程:

1. DNS解析

浏览器首先要把域名转换成IP地址。比如把"www.baidu.com"转换成"120.5.5.46"。这个时间取决于DNS服务器的响应速度、是否有DNS缓存还有良好的网络环境。

2. TCP连接建立

找到IP地址后,浏览器需要和服务器建立TCP连接,这就是三次握手,主要受网络延迟影响。

3. 发送HTTP请求

连接建立后,浏览器发送HTTP请求到服务器,这个过程通常很快,除非请求数据很大。

4. 服务器处理

服务器接收到请求后,开始处理业务逻辑。这通常是最"邪门"的环节。

5. 服务器响应

服务器将处理结果发送回浏览器。主要取决于响应数据的大小和网络带宽。

6. 浏览器渲染

浏览器接收到HTML后,开始解析、渲染页面,时间取决于加载的库、脚本等需要网络的组件的数量的网络消耗。

哪个环节通常最耗时?

答案:通常是服务器处理时间

在大多数情况下,服务器处理时间是最大的性能瓶颈。为什么这么说?

1. 数据库查询

现在的Web应用大多需要查询数据库:

-- 一个复杂的查询可能需要几百毫秒甚至几秒
SELECT u.name, p.title, COUNT(c.id) as comment_count
FROM users u
JOIN posts p ON u.id = p.user_id
LEFT JOIN comments c ON p.id = c.post_id
WHERE u.created_at > '2023-01-01'
GROUP BY u.id, p.id
ORDER BY comment_count DESC
LIMIT 20;

如果没有合适的索引,这样的查询轻松就能花掉几秒钟。

2. 外部API调用

很多应用需要调用第三方服务:

  1. 支付接口调用
  2. 地图服务API
  3. 短信发送服务

每个外部调用都可能增加几百毫秒的延迟,而且还可能失败重试。

3. 复杂的业务逻辑

  1. 服务之间的调用(RPC)
  2. 复杂的业务逻辑(电商的价格计算)
  3. 数据处理(格式转换与序列化)
  4. 上传大文件、文件压缩(Zip)
  5. 权限校验(用户身份认证)
  6. 记录日志(操作日志持久化到磁盘)
    这些操作都要销毁大量的时间,耗时比较久。

如何优化各个环节?

1. 数据库优化

-- 给常用查询字段加索引
CREATE INDEX idx_user_id ON posts(user_id);-- 用JOIN替代循环查询
SELECT p.title, u.name 
FROM posts p JOIN users u ON p.user_id = u.id;

索引是一种高效的数据结构,可以提高数据的查询效率。

2. 缓存策略

@Service
public class ProductService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Autowiredprivate ProductMapper productMapper;public List<Product> getHotProducts() {String cacheKey = "hot_products";// 先查缓存List<Product> cached = (List<Product>) redisTemplate.opsForValue().get(cacheKey);if (cached != null) {return cached;}// 缓存没有,查数据库List<Product> products = productMapper.getHotProducts();// 存入缓存,5分钟过期redisTemplate.opsForValue().set(cacheKey, products, 5, TimeUnit.MINUTES);return products;}
}

热点数据被频繁查询,每次都查数据库会把数据库拖垮。缓存后,100个用户访问只需要查1次数据库,这样不仅提高的数据的查询,还减少了磁盘IO,缩短了时间。

3. 异步处理

@RestController
public class OrderController {@Autowiredprivate OrderService orderService;@Autowiredprivate AsyncTaskService asyncTaskService;@PostMapping("/order")public ResponseEntity<?> createOrder(@RequestBody OrderRequest request) {// 先快速创建订单并响应Order order = orderService.createOrder(request);// 异步处理耗时任务asyncTaskService.sendOrderEmail(order.getId());asyncTaskService.updateInventory(order.getItems());return ResponseEntity.ok(Map.of("orderId", order.getId(), "status", "processing"));}
}@Service
public class AsyncTaskService {@Asyncpublic void sendOrderEmail(Long orderId) {// 发送订单确认邮件(耗时操作)emailService.sendOrderConfirmation(orderId);}@Async  public void updateInventory(List<OrderItem> items) {// 更新库存(可能需要调用多个服务)inventoryService.updateStock(items);}
}

主线程专注处理核心业务,耗时操作放到后台慢慢处理,整体吞吐量大大提升。

总结

所以一次Web请求响应中最耗时的大多数情况下是服务器处理时间,特别是数据库查询和外部API调用。

http://www.lryc.cn/news/606081.html

相关文章:

  • Flutter module 是如何被原生 Android 项目通过 Gradle 引入的
  • Flutter Chen Generator - yaml配置使用
  • 原生安卓与flutter混编的实现
  • 是否需要买一个fpga开发板?
  • 嵌入式硬件学习(十)—— LED驱动+杂项设备驱动
  • 【Unity】实现小地图
  • TDengine 中 TDgp 中添加算法模型(异常检测)
  • 【大模型理论篇】跨语言AdaCOT
  • Flutter 页面跳转及传参总结
  • 8.2-使用字符串存储 UTF-8 编码文本
  • RAG:让AI更聪明的“外接大脑“ | AI小知识
  • ECMAScript2023(ES14)新特性
  • C# 基于halcon的视觉工作流-章27-带色中线
  • HTM 5 的离线储存的使用和原理
  • JavaEE初阶1.0
  • 认知绞肉机:个体实践视域下认知暴力与元认知升维的活体实验研究
  • 今日做题练习
  • 记录自己使用gitee和jenkins
  • PHP 核心特性全解析:从实战技巧到高级应用(2)
  • 按键精灵iOS工具元素命令SetText:自动化输入的终极解决方案
  • .NET Core部署服务器
  • Linux网络-------3.应⽤层协议HTTP
  • Java 大视界 -- Java 大数据在智能交通公交客流预测与线路优化中的深度实践(15 城验证,年省 2.1 亿)(373)
  • 快速搭建Node.js服务指南
  • 前端核心技术Node.js(四)——express框架
  • 8,FreeRTOS时间片调度
  • RPA-重塑企业自动化流程的智能引擎
  • 《能碳宝》AI辅助开发系统方案
  • 免费语音识别(ASR)服务深度指南​
  • 深入解析域名并发请求限制与HTTP/2多路复用技术