面试题答案
一键面试连接池管理
- 建立连接池:
- 措施:使用Node.js中的
http
或https
模块结合连接池库(如http-proxy-agent
等)来创建连接池。在应用启动时初始化一定数量的HTTP(S)连接,例如:
const http = require('http'); const httpProxyAgent = require('http-proxy-agent'); const agent = new httpProxyAgent({ maxSockets: 10, // 最大连接数 keepAlive: true, // 保持连接 keepAliveMsecs: 1000 // 保持连接的时间 }); const options = { hostname: 'api.example.com', port: 80, path: '/endpoint', method: 'GET', agent: agent }; const req = http.request(options, (res) => { // 处理响应 }); req.end();
- 原理:连接池可避免每次请求都重新建立TCP连接,减少了三次握手和四次挥手的开销。TCP连接建立需要一定时间,重用已有的连接可以显著提高请求效率。
- 措施:使用Node.js中的
- 连接复用与回收:
- 措施:配置连接池使其能够复用空闲连接,并在连接长时间未使用或出现错误时进行回收。例如在
http-proxy-agent
中,通过设置maxSockets
和maxFreeSockets
等参数来管理连接的复用与回收。 - 原理:复用空闲连接可以快速响应新的请求,而回收长时间未使用或出错的连接可以释放资源,防止资源泄漏,确保连接池中的连接都是可用且有效的。
- 措施:配置连接池使其能够复用空闲连接,并在连接长时间未使用或出现错误时进行回收。例如在
请求并发控制
- 限制并发请求数:
- 措施:使用队列和计数器来控制并发请求数量。例如,可以使用
async
库的queue
方法。
const async = require('async'); const requests = [/* 多个请求的配置数组 */]; const q = async.queue((request, callback) => { // 发起请求 const req = http.request(request, (res) => { // 处理响应 callback(); }); req.end(); }, 5); // 最大并发数为5 requests.forEach((request) => { q.push(request); });
- 原理:过多的并发请求可能会耗尽系统资源(如文件描述符、带宽等),导致性能下降。限制并发数可以保证系统有足够的资源处理每个请求,避免因资源竞争而产生的延迟。
- 措施:使用队列和计数器来控制并发请求数量。例如,可以使用
- 优先级处理:
- 措施:根据请求的重要性或业务需求为请求分配优先级。例如,对于一些关键业务的请求(如用户登录验证请求),可以优先处理。可以在请求队列中实现优先级排序逻辑,优先处理高优先级的请求。
- 原理:确保关键业务请求能够快速得到响应,提高整体业务的可用性和用户体验,同时合理分配系统资源,避免低优先级请求占用过多资源影响关键请求。
数据处理优化
- 减少数据传输量:
- 措施:与API提供方协商,只请求必要的数据字段,避免请求过多冗余数据。例如,如果API返回一个包含大量字段的JSON对象,而应用只需要其中几个字段,可以使用查询参数来指定返回字段,如
https://api.example.com/endpoint?fields=field1,field2
。 - 原理:减少数据传输量可以降低网络带宽消耗,缩短数据传输时间,尤其是在网络环境不佳的情况下,对提高响应速度效果显著。
- 措施:与API提供方协商,只请求必要的数据字段,避免请求过多冗余数据。例如,如果API返回一个包含大量字段的JSON对象,而应用只需要其中几个字段,可以使用查询参数来指定返回字段,如
- 缓存处理:
- 措施:在应用端实现缓存机制,对于一些不经常变化的数据进行缓存。可以使用内存缓存(如
node-cache
库)或分布式缓存(如Redis)。例如,对于一些配置信息、静态数据等,可以先从缓存中获取,如果缓存中不存在再请求API,并将获取的数据存入缓存。
const NodeCache = require('node-cache'); const myCache = new NodeCache(); const getApiData = async () => { const cachedData = myCache.get('apiData'); if (cachedData) { return cachedData; } const response = await httpRequestToApi(); myCache.set('apiData', response.data); return response.data; };
- 原理:缓存可以避免重复请求相同的数据,直接从本地缓存中获取数据,大大提高了响应速度,同时也减轻了API服务器的压力。
- 措施:在应用端实现缓存机制,对于一些不经常变化的数据进行缓存。可以使用内存缓存(如
- 异步处理与流操作:
- 措施:在处理API响应数据时,使用异步操作和流处理。例如,在Node.js中,可以使用
stream
模块来处理大文件或大量数据的响应。
const http = require('http'); const fs = require('fs'); const req = http.request({ hostname: 'api.example.com', port: 80, path: '/largeFile', method: 'GET' }, (res) => { const writeStream = fs.createWriteStream('localFile'); res.pipe(writeStream); }); req.end();
- 原理:异步操作可以避免阻塞主线程,提高应用的响应能力。流操作可以逐块处理数据,而不是等待整个数据都下载完成,减少内存占用,提高处理效率,尤其适用于处理大数据量的场景。
- 措施:在处理API响应数据时,使用异步操作和流处理。例如,在Node.js中,可以使用