【高并发优化手段】基于Springboot项目(一)

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 【高并发优化手段】基于Springboot项目

🌟 一、概述

Spring Boot是基于Spring Framework的快速开发框架,它提供了许多自动化的配置方法,使得开发者可以更加专注于业务逻辑的实现。

在高并发场景下,Spring Boot的配置也是非常重要的,需要对服务器、Tomcat、线程池等进行优化配置,以达到最优的性能。本文将介绍如何对Spring Boot进行优化配置,在高并发场景下实现最佳的性能表现。

场景如下:提供30秒内2万用户每秒5次请求的10万并发服务支持。

🌟 二、服务器配置

🍊 1. 选择合适的机器

在高并发场景下,选择合适的机器是非常重要的。首先,需要根据业务需求和预期QPS(每秒请求数)选择合适的机型,例如CPU、内存、硬盘、网络带宽等。

其次,为了提高性能,建议选择高并发优化的系统。例如,针对Java应用,可以选择专门针对Java应用优化的Linux操作系统,例如CentOS、Ubuntu等。

🍊 2. 配置服务器参数

在服务器上,可以根据实际情况调整以下参数:

🎉 (1)TCP网络层参数

可以设置以下参数,以提高服务器网络性能和稳定性:

①. TCP握手队列长度:默认为128,可以设置为1024,以处理更多的TCP连接请求。

②. TCP连接超时时间:默认为2小时,可以设置为3秒,以加快连接失败的响应速度。

③. TCP连接重试次数:默认为10次,可以设置为3次,以加快连接失败的响应速度。

📝 如何配置

在CentOS 7上,可以使用以下命令来配置TCP网络层参数:

  1. 打开配置文件/etc/sysctl.conf:
sudo vi /etc/sysctl.conf
  1. 添加或编辑以下参数:
# 设置虚拟内存超配值为 1,可以允许分配比实际物理内存更多的内存空间,从而提高应用程序性能,但可能导致 OOM 错误。为 0 时表示内存空间不足时直接拒绝申请
vm.overcommit_memory = 1
# 设置系统脏页(未写入磁盘的页面)达到多少字节时可以开始写入磁盘
vm.dirty_background_bytes = 8388608
# 设置系统脏页达到多少字节时必须写入磁盘
vm.dirty_bytes = 25165824
# 设置可以在后台写入磁盘的脏页占总脏页的比例(即总脏页数的2%)
vm.dirty_background_ratio = 2
# 设置当系统脏页占总内存的比例超过5%时,系统必须开始写入磁盘
vm.dirty_ratio = 5
# 设置系统判定一个脏页需要写入磁盘的时间,单位为centisecond,即2000分之一秒
vm.dirty_expire_centisecs = 2000
# 设置最小内存分配单位(单位为KB)
vm.min_free_kbytes = 8192
# 将虚拟内存的 overcommit 比率设置为80%
vm.overcommit_ratio = 80
# 设置堆内存溢出处理方式(0表示不紧急内存压缩,1表示紧急内存压缩,2表示杀死进程)
vm.panic_on_oom = 2
# 设置发送方socket buffer大小的最大值为16MB
net.core.wmem_max = 16777216
# 设置接收方socket buffer大小的最大值为16MB
net.core.rmem_max = 16777216
# 当TCP流量控制窗口溢出时,中止连接
net.ipv4.tcp_abort_on_overflow = 1
# 对于高延迟、高带宽的网络,开启窗口缩放
net.ipv4.tcp_adv_win_scale = 1
# 允许使用的TCP拥塞控制算法,可以使用cubic和reno算法
net.ipv4.tcp_allowed_congestion_control = cubic reno
# 应用程序socket buffer的大小,单位为Kbyte
net.ipv4.tcp_app_win = 31
# TCP发送数据时,自动开启corking模式
net.ipv4.tcp_autocorking = 1
# 允许使用的TCP拥塞控制算法,可以使用cubic和reno算法
net.ipv4.tcp_available_congestion_control = cubic reno
# 设置TCP数据包的最小大小,单位为byte
net.ipv4.tcp_base_mss = 512
# 发送方最多允许发送多少个SYN报文段作为challenge ack防范syn flood攻击
net.ipv4.tcp_challenge_ack_limit = 1000
# TCP使用的拥塞控制算法,可以使用cubic算法
net.ipv4.tcp_congestion_control = cubic
# 开启对方乱序数据的确认,以降低网络延迟
net.ipv4.tcp_dsack = 1
# 当检测到丢包时,提前触发重传
net.ipv4.tcp_early_retrans = 3
# 开启ECN(Explicit Congestion Notification)拥塞控制算法
net.ipv4.tcp_ecn = 2
# 使用FACK(Forward Acknowledgment)作为拥塞控制算法的一部分
net.ipv4.tcp_fack = 1
# 开启TCP Fast Open,以加快连接速度
net.ipv4.tcp_fastopen = 3
# 设置TCP Fast Open使用的密钥,可以使用随机数生成器生成
net.ipv4.tcp_fastopen_key = 6d0c41a3-123fdf85-a7f901e8-59fea180
# TCP连接关闭的超时时间,单位为秒
net.ipv4.tcp_fin_timeout = 10
# 开启TCP Fast Recovery防止网络拥塞
net.ipv4.tcp_frto = 2
# 设置TCP连接每秒允许的最大无效数据包数,超过该值则降低发送速度
net.ipv4.tcp_invalid_ratelimit = 500
# TCP保持连接的时间间隔,单位为秒
net.ipv4.tcp_keepalive_intvl = 15
# 发送TCP保持连接探测报文的次数
net.ipv4.tcp_keepalive_probes = 3
# TCP保持连接的时间,单位为秒
net.ipv4.tcp_keepalive_time = 600
# 限制发送缓存的最大空间,单位为byte
net.ipv4.tcp_limit_output_bytes = 262144
# 开启TCP低延迟模式
net.ipv4.tcp_low_latency = 0
# 操作系统允许的最大TCP半连接数
net.ipv4.tcp_max_orphans = 16384
# TCP拥塞窗口增长算法的阈值,一般设为0不使用该功能
net.ipv4.tcp_max_ssthresh = 0
# 等待建立连接请求的最大个数
net.ipv4.tcp_max_syn_backlog = 262144
# 每秒最多处理的TCP连接数,越高则占用CPU时间越多
net.ipv4.tcp_max_tw_buckets = 5000
# 设置TCP Mem,包括min、default、max三个参数,单位为page数量
net.ipv4.tcp_mem = 88053  117407  176106
# 设置发送方socket buffer大小的最小值,单位为byte
net.ipv4.tcp_min_snd_mss = 48
# 设置TCP使用的最小TSO分段数目(只有在开启TSO时生效)
net.ipv4.tcp_min_tso_segs = 2
# 开启TCP自适应窗口大小控制
net.ipv4.tcp_moderate_rcvbuf = 1
# 开启TCP MTU探测,以避免网络分片
net.ipv4.tcp_mtu_probing = 1
# 禁止保存TCP延迟测量得到的数据
net.ipv4.tcp_no_metrics_save = 1
# 无需等待发送缓存为空,就可以发送数据
net.ipv4.tcp_notsent_lowat = -1
# TCP重传数据包的最大次数
net.ipv4.tcp_orphan_retries = 0
# TCP重传数据包后允许接收的最大乱序数据包个数
net.ipv4.tcp_reordering = 3
# 启用TCP Fast Retransmit和Fast Recovery算法
net.ipv4.tcp_retrans_collapse = 1
# 第一次重传TCP数据包的次数
net.ipv4.tcp_retries1 = 3
# 第二次重传TCP数据包的次数
net.ipv4.tcp_retries2 = 15
# 拒绝与RFC1337不兼容的数据包
net.ipv4.tcp_rfc1337 = 1
# 设置TCP接收缓存大小,包括min、default、max三个参数,单位为byte
net.ipv4.tcp_rmem = 4096  87380 33554432
# 开启TCP SACK(Selective Acknowledgments)支持
net.ipv4.tcp_sack = 1
# 关闭TCP连接空闲一段时间后再次发送数据包
net.ipv4.tcp_slow_start_after_idle = 0
# 禁用TCP Socket Urgent功能
net.ipv4.tcp_stdurg = 0
# TCP SYN请求重试的最大次数
net.ipv4.tcp_syn_retries = 1
# TCP SYN/ACK请求重试的最大次数
net.ipv4.tcp_synack_retries = 1
# 开启TCP SYN Cookie防止syn flood攻击
net.ipv4.tcp_syncookies = 1
# 关闭TCP Thin Dupack
net.ipv4.tcp_thin_dupack = 0
# 关闭TCP Thin Linear Timeouts
net.ipv4.tcp_thin_linear_timeouts = 0
# 开启TCP时间戳
net.ipv4.tcp_timestamps = 1
# 设置TCP TSO窗口大小的除数,只有在开启TSO时生效
net.ipv4.tcp_tso_win_divisor = 3
# 开启TCP TIME_WAIT Socket重用机制
net.ipv4.tcp_tw_recycle = 1
# 允许将TIME_WAIT Socket重用于新的TCP连接
net.ipv4.tcp_tw_reuse = 1
# 开启TCP窗口缩放
net.ipv4.tcp_window_scaling = 1
# 设置发送方socket buffer大小,包括min、default、max三个参数,单位为byte
net.ipv4.tcp_wmem = 4096  16384 33554432
# 关闭TCP workaround signed windows(https://tools.ietf.org/html/rfc7323)
net.ipv4.tcp_workaround_signed_windows = 0
# 当使用conntrack跟踪TCP连接时,设置是否采用liberal模式
net.netfilter.nf_conntrack_tcp_be_liberal = 0
# 当使用conntrack跟踪TCP连接时,设置是否采用loose模式
net.netfilter.nf_conntrack_tcp_loose = 1
# TCP连接最大重传次数
net.netfilter.nf_conntrack_tcp_max_retrans = 3
# TCP连接关闭后,等待fin结束的时间,单位为秒
net.netfilter.nf_conntrack_tcp_timeout_close = 10
# TCP连接关闭后,进入CLOSE_WAIT状态的时间,单位为秒
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
# TCP连接已经建立时,如果长期没有数据传输,连接最长保持时间,单位为秒
net.netfilter.nf_conntrack_tcp_timeout_established = 432000
# 当关闭TCP连接时,TCP_FIN等待ACK的超时时间,单位为秒
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
# 当关闭TCP连接时,ACK等待FIN的超时时间,单位为秒
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
# TCP连接最大重传次数,以及TCP RTO
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300
# 设置 TCP SYN_RECV 状态的超时时间为 60 秒
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
# 设置 TCP SYN_SENT 状态的超时时间为 120 秒
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 120
# 设置 TCP TIME_WAIT 状态的超时时间为 120 秒
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
# 设置 TCP 未确认连接的超时时间为 300 秒
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300
# 设置 sunrpc 协议的 FIN 超时时间为 15 秒
sunrpc.tcp_fin_timeout = 15
# 设置 sunrpc 协议的最大槽位表项数为 65536
sunrpc.tcp_max_slot_table_entries = 65536
# 设置 sunrpc 协议的槽位表项数为 2
sunrpc.tcp_slot_table_entries = 2
# 设置 sunrpc 协议的传输层为 TCP,缓存区大小为 1048576 字节
sunrpc.transports = tcp 1048576
# 设置系统最大连接数为 65535
net.core.somaxconn = 65535
# 设置网络设备缓存队列最大值为 65535
net.core.netdev_max_backlog = 65535
# 设置系统的最大文件句柄数为 65535
fs.file-max = 65535
# 增加文件描述符限制
fs.nr_open = 1000000
# 设置同时为当前用户打开的 inotify 实例的最大数目为 1024
fs.inotify.max_user_instances = 1024
# 设置当前用户为每个 inotify 实例可同时监视的文件和目录数目上限为 65536
fs.inotify.max_user_watches = 65536
# 设置 inotify 实例中等待处理的事件队列的最大(未处理)长度为 16384
fs.inotify.max_queued_events = 16384
# 调整文件系统缓存参数
vfs_cache_pressure = 50
# 设置进程ID的最大值为131072
kernel.pid_max = 131072
# 设置系统支持的最大进程ID值为131072
kernel.max_pid = 131072
# 设置系统的信号量的参数,分别是512个信号量集、每个信号量集的最大值为65535、每个进程最多可以持有的信号量数量为1024、最大的信号量值为2048
kernel.sem = 512 65535 1024 2048
  1. 保存文件并退出。
  2. 使用以下命令使新配置生效:
sudo sysctl -p
  1. 使用命令行工具查看TCP网络参数的值,例如使用命令:
sysctl -a | grep tcp

可以查看到当前TCP网络参数的值,确认修改是否生效。

以上配置仅供参考,具体的参数设置应根据实际情况进行调整。在更改任何系统参数之前,请确保了解所需的配置和可能的影响。

🎉 (2)文件系统参数

可以设置以下参数,以提高服务器的文件系统性能:

①. 文件打开数:默认为1024,可以设置为65535,以支持更多的文件打开。

②. 文件描述符大小:默认为1024,可以设置为65535,以支持更大的文件。

③. 内存缓存大小:默认为32MB,可以设置为512MB,以加快磁盘访问速度。

📝 仅根据硬件配置,估算机器的最大性能

对于2核心4G内存的机器,最大的QPS和TPS取决于三个主要限制因素:

  1. CPU性能
  2. 内存大小
  3. 磁盘速度

在这个配置下,可能的最大QPS和TPS取决于这三个因素中最小的那个。

对于文件打开数和文件描述符大小的设置,655355是足够高的,不太可能成为限制因素。

对于内存缓存大小,512MB也足够大了,对性能的提升是有帮助的,但也不会明显改变最大性能。

考虑到压测的机器ESSD AutoPL云盘 40000 IOPS,可以假设磁盘速度也足够高。因此,最大性能主要取决于CPU和内存。

根据经验,一个CPU核心的最大处理能力通常在1万到10万之间。2核心4线程的CPU最大的处理能力是在2万到20万之间。这个范围是因为处理能力还取决于其他因素,如CPU主频、缓存大小、内存带宽等等。

以我本机i9-12900k为例,根据Intel官方资料,i9-12900k是一款16核32线程的处理器,其主频为3.2GHz,最大增强主频为5.2GHz。因此,其最大处理能力可以计算为:

最大处理能力 = 核心数 x 主频 x 指令执行效率

其中,指令执行效率可以用IPC(Instructions Per Cycle)来表示指令执行效率通常是通过 CPU 的性能指标来评估,例如时钟频率、IPC (Instructions Per Cycle) 等指标。在 Linux 中,可以使用一些工具来查看 CPU 的性能指标,例如 top、perf、htop 等。i9-12900k的IPC约为2。因此,i9-12900k的最大处理能力约为:

16 x 5.2GHz x 2 = 166.4万

即最大处理能力为166.4万。需要注意的是,实际应用中的性能取决于多种因素,包括软件优化程度、内存速度、硬盘速度等,因此实际性能可能会有所不同。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
15天前
|
Java 应用服务中间件
SpringBoot获取项目文件的绝对路径和相对路径
SpringBoot获取项目文件的绝对路径和相对路径
53 1
SpringBoot获取项目文件的绝对路径和相对路径
|
5天前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
17 2
|
10天前
|
分布式计算 关系型数据库 MySQL
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型 图像处理 光通信 分布式计算 算法语言 信息技术 计算机应用
32 8
|
15天前
|
缓存 监控 Java
|
1月前
|
JavaScript 前端开发 Java
解决跨域问题大集合:vue-cli项目 和 java/springboot(6种方式) 两端解决(完美解决)
这篇文章详细介绍了如何在前端Vue项目和后端Spring Boot项目中通过多种方式解决跨域问题。
340 1
解决跨域问题大集合:vue-cli项目 和 java/springboot(6种方式) 两端解决(完美解决)
|
17天前
|
JavaScript 前端开发 Java
SpringBoot项目的html页面使用axios进行get post请求
SpringBoot项目的html页面使用axios进行get post请求
40 2
|
17天前
|
前端开发 Java Spring
SpringBoot项目thymeleaf页面支持词条国际化切换
SpringBoot项目thymeleaf页面支持词条国际化切换
45 2
|
17天前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
33 1
|
19天前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
19天前
|
关系型数据库 MySQL Java
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
22 0

热门文章

最新文章