单机并发接口报错问题

date
Feb 23, 2023
slug
concurrent-nginx
status
Published
tags
concurrent
nginx
linux
summary
解决在高并发下由 Nginx 或 Linux 配置问题引起的接口报错
type
Post
Language

接口在并发下出现 404

在一定并发量下接口出现 404,排除网关错误,查看 nginx 错误日志如下
Errno 99: cannot assign requested address
nginx 与服务器会进行 sockets 连接,每一个连接会占用一个端口,以上错误是端口用完造成的,解决方法为修改内核参数
# 修改内核参数
sudo vim /etc/sysctl.conf
# 启用重用 TIME_WAIT 状态的端口
net.ipv4.tcp_tw_reuse=1
# 生效
sysctl -p
注意:docker 不会引用宿主机内核参数,docker-compose 配置 sysctls 传入内核参数才能生效
nginx-test:
image: nginx:1.20.1
container_name: nginx-test
privileged: true
restart: always
sysctls:
    - net.ipv4.tcp_tw_reuse=1
容易被忽略的问题:用 Python Requests 多线程模拟请求不会报错,因为 Requests 会复用 Session,会保持长连接,使用在一定并发下不会造成端口用完的情况;现代浏览器 Chrome 会采用多路复用的技术减少延迟,真实环境下不会复现问题,如 LoadRunner 等测试工具发送的短连接,如果不修改内核参数,会出现此类问题

接口在并发下出现 500

在一定并发量下接口出现 500,排除网关错误,查看 nginx 错误日志如下
worker_connections are not enough
nginx 可以同时处理的上限是 worker_processes * worker_connections,worker_processes 通常会设定为 CPU 核心数,设置为 auto 会自动获取服务器核心数,worker_connections 为同一时间的连接数 解决方法:修改 nginx 的 config 配置
worker_processes 64

events {
	worker_connections 1024
}

接口在并发下出现 500

在一定并发量下接口出现 500,排除 nginx 错误,查看业务错误日志如下
java.util.concurrent.RejectedExecutionException
一般情况下是业务使用的线程池资源被用完了,需要根据硬件参数合理配置线程池参数,主要参数为:
  • CorePoolSize 核心线程数,在 CPU 密集下使用 NCPU + 1,在 IO 密集下使用 N * CPU + 1
  • MaxPoolSize 最大线程数,线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程,CorePoolSize 必须小于 MaxPoolSize
  • QueueCapacity 用来缓冲执行任务的队列

Reference


© chobit blog 2025