当前位置: 首页 > 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.dtcms.com/a/308026.html

相关文章:

  • git ETAS包 使其可以本地编辑
  • 借助于llm将pdf转化为md文本
  • PDF源码解析
  • 数据结构第4问:什么是栈?
  • CUDA系列之CUDA安装与使用
  • freeRTOS 消息队列
  • Cesium 快速入门(三)Viewer:三维场景的“外壳”
  • 【MySQL】MySQL大偏移量查询优化方案
  • 若依框架-前端二次开发快速入门简述
  • [硬件电路-109]:模拟电路 - 自激振荡器的原理,一种把直流能量转换成交流信号的装置!
  • Linux软件包管理器深度解析:从概念到实战
  • React开发依赖分析
  • TRAE 软件使用攻略
  • 快速搭建Node.js服务指南
  • python制作的软件工具安装包
  • c# net6.0+ 安装中文智能提示
  • 前端框架Vue3(二)——Vue3核心语法之OptionsAPI与CompositionAPI与setup
  • 超体积指标(Hypervolume Indicator,S 度量)详析
  • 【JMeter】性能测试脚本录制及完善
  • 辐射源定位方法简述
  • 【BUUCTF系列】[HCTF 2018]WarmUp1
  • 网络编程-IP
  • 计算机网络:什么是光猫
  • Hyperbrowser MCP:重新定义网页抓取与浏览器自动化的AI驱动工具
  • Solr升级9.8.0启动异常UnsupportedOperationException known Lucene classes
  • Tauri vs Electron 的全面对比
  • 生产管理升级:盘古IMS MES解锁全链路可控可溯,激活制造效率
  • LCM中间件入门(2):LCM核心实现原理解析
  • 牛客练习赛142 第四次忍界大战 并查集
  • 永磁同步电机无速度算法--直流误差抑制自适应二阶反推观测器