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

Tomcat 线上调优记录

原始Tomcat配置

  • 启动参数

Plaintext
-Xms256m -Xmx512m -XX:MaxPermSize=128m

  • Tomcat 参数配置

XML
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
 maxThreads="1500" minSpareThreads="50" maxIdleTime="600000"/>
    <Connector
               port="8801" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
               connectionTimeout="20000" URIEncoding="UTF-8"
               enableLookups="false"
               sendReasonPhrase="true"
               useBodyEncodingForURI="true"  maxThreads="500"
               compression="on" compressionMinSize="2048"
               compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
               acceptCount="1200" disableUploadTimeout="true"/>

第一次修改

问题表现

  • Tomcat 接口重启,tomcat 线程飙升到1000+,短时间内出现大量OOM,表现出的现象数据库连接不可用,数据查询超时等。进而导致服务不可用

Plaintext
?[m?[1;35m2022-04-13 19:01:42 ERROR [http-nio2-8803-exec-500] (ResultInterceptor.java:172) [result exception...msgType : 3, code : 99, msg : Could not get JDBC Connection; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 10656, active 18, maxActive 24, creating 0, error: com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1775)       
com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:1427)       
com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:5059) ]

Plaintext
?[m?[1;35m2022-04-13 19:05:26 ERROR [http-nio2-8812-exec-303] (ResultInterceptor.java:172) [result
?[mognl.MethodFailedException: Method "handleMsg" failed for object friendGame.action.HandleMsgAction@31aa0e68 [java.lang.OutOfMemoryError: GC overhead limit exceeded]
        at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1932)
        at ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68)
        at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethodWithDebugInfo(XWorkMethodAccessor.java:98)
        at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethod(XWorkMethodAccessor.java:90)
        at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1996)

  • 短暂的出现大量memcached 的连接

推测问题原因

  • Tomcat 线程数配置的过高,减少tomcat的最大线程配置,调大tomcat 的初始线程数
  • 服务中过度依赖memcached ,一个登录操作可能存在几十个查询操作,memcached响应过慢时,会导致tomcat 导致创建大量线程
  • 基于 xmemcached 作为memcached连接SDK 其底层消息响应机制基于java.util.concurrent.CountDownLatch 实现,过多使用会导致cpu 使用率增高

程序修改点

  • 启动参数

堆最大小统一为512MB ,移除jdk7的永久代参数配置,新增新生代配置

Plaintext
 -Xms512m -Xmx512m -Xmn256m

Tomcat  参数配置

  • 移除Executor 线程池配置减少冗余线程
  • Connector maxThreads修改为500,新增  minSpareThreads="50" 初始化线程为50

Plaintext
<!--    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"-->
<!--        maxThreads="1500" minSpareThreads="50" maxIdleTime="600000"/>-->

    <Connector
               port="8801" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
               connectionTimeout="20000" URIEncoding="UTF-8"
               enableLookups="false"
               sendReasonPhrase="true"
               useBodyEncodingForURI="true"
minSpareThreads="50" maxThreads="500"
               compression="on" compressionMinSize="2048"
               compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
               acceptCount="1200" disableUploadTimeout="true"/>

优化点

  • 限制tomcat 的线程数,避免重启时(瞬时高峰)导致线程创建过多
  • 修改堆的最大最小值,降低堆内存的动态变化的性能影响
  • 项目中对应公共不变的数据,采用本地缓存(Caffeine )
  • 接口服务对接PinPoint 进行监控

仍存在的问题

  • 重启时Tomcat 仍创建到了 线程池限制的最大值
  • 短时间出现memcached 连接超时大量减少,但极少连接超时信息
  • 重启时客户端能看到短时间的卡顿

第二次修改

问题表现

  • 项目下午三点更新,晚七点高峰期开始收到服务器资源预警,CPU和内存使用暴增,观察接口出现大量数据连接异常和OOM 日志
  • 观察PinPoint 上日志记录 更新后tomcat 线程持续保持在最大值附近,jvm频繁的出现full gc
  • 查看历史的升级记录,每次升级tomcat 线程都是保持到最大值持续到第二天凌晨开始降低

推测问题原因

  • 对比其它项目组的jvm内存配置,jvm 堆内存设置偏小
  • 运维的通过监听tomcat端口号的限流策略存在不合理处。在端口号启动后将有半分钟左右的服务不可用空窗期,大量的消息堆积导致至服务可用时,tomcat 的处理线程被压满,因为tomcat 的线程销毁策略是60s内没有被使用。故tomcat 的线程数目在凌晨左右开始降低

程序修改点

  • 启动参数
  • 提升JVM 的堆内存为1g
  • 设置元空间的初始大小与最大值
  • 设置JVM 发生OOM 时保存堆信息到指定文件

Plaintext
-Xms1g
-Xmx1g
-Xmn512m
-XX:MetaspaceSize=128m
-XX:MaxMetaspaceSize=320m
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/home/gcweb/jdk_dump

优化点

  • 扩大堆的内存限制,增大服务器资源的使用
  • 设置新生代的的初始值,避免在未达到初始值前提下每次扩增时带来的FullGC
  • 记录OOM的堆信息况
  • 运维人员使用新的重启放流策略,采用监控url 方式取代端口监听。 重启时限制nginx 发送消息到接口,监控接口服务检测url 地址 是否可用,第一次可用时延期1min 再次检测是否可用。两次可用时,nginx 开始放流
  • 修改接口重启时各项指标保持在正常水平,客户端没有明显的卡顿感

第三次修改

问题表现

  • pinpoint上观察堆使用明显偏高,full gc 的一天有三四次,在12,19 点高峰期尤为明显

推测问题原因

  • 本地保持与线上相同的tomcat配置,压测接口。并通过visualvm 观察jvm 堆信息。
  • 压测后发现 s1,s0 逐渐变小,eden 开始变大,导致 eden  gc时 s0,s1容量无法承受eden  的对象信息,导致大量对象进入老年代,进而fullgc 比较频繁

程序修改点

  • 启动参数
  • 指定CMS GC 算法

Plaintext
-Xms1g
-Xmx1g
-Xmn512m
-XX:MetaspaceSize=128m
-XX:MaxMetaspaceSize=320m
-XX:+UseConcMarkSweepGC
-XX:+UseCMSCompactAtFullCollection
-XX:CMSInitiatingOccupancyFraction=70
-XX:+CMSParallelRemarkEnabled
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:SurvivorRatio=8
-XX:-OmitStackTraceInFastThrow
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/home/gcweb/

优化点

  • 指定CMS 作为 老年代的GC 算法,并开启GC 后压缩UseCMSCompactAtFullCollection
  • 通过指定CMS 禁用了 UseAdaptiveSizePolicy 新生代的内存动态变化策略,避免过多数据进入老年代

开启UseAdaptiveSizePolicy

高并发访问后

重点关注

  • Tomca 线程数目最大值设置数目过大,瞬时高峰导致创建过多线程可能导致OOM
  • Tomcat 业务处理线程,并非启动时创建。是在第一个http 请求到来时开始创建(最多一次创建50个线程。未达到核心线程时,第二次访问再创建),故前端开始放流时,会出现短暂的CPU使用率增高
  • GC 算法选择,不推荐使用默认的 -XX:+UseAdaptiveSizePolicyJdk5 默认开启) 其目的为了增大JVM 吞吐量。开启后 新生代 egen:s0:s1 不再遵守指定的比例大小(4:1:1)而是采用JVM自己动态变化的新生代的分层大小。故开启后 s1,s2 很可能被压缩的很小,导致youngGc时,大量的对象被压倒 老年代 ,进而产生频繁full gc 推荐使用Jdk8 推荐 CMSJdk9+ 使用G1 jdk9 g1商用化)
  • Jvm 内存大小设置,推荐堆的总体大小1g+ ,新生代不少于堆总体一半,s1,s2 的容量不要过小,避免 yongGc 时因对象过大,而直接进入老年代

监控工具

  1.  pinpoint (运维部门已支持),可以监控jvm 的大至堆使用,fullgc 的频率
  1. Arthas 用于堆使用详情,gc的详情,以及动态修改jvm 部分参数
  1. visualVm 用于开发环境测试(推荐 安装 visualgc 插件,监控gc详情)

visualVm  本机使用观察注意项

下载 不推荐 Oracle jdk8 自带的。

推荐下载的插件

Java 启动的参数信息

仪表盘信息,总体介绍 jvm 使用信息

当前线程使用情况

支持sample 支持监控特定时间的 java 的内存cpu 使用情况

profile  可用监控 项目中 sql 的使用信息,cpu,锁 等信息监控,(开源版存在,Oracle版无)

常用jdk8 JVM参数

Plaintext

-Xmx1g
-Xms1g
:初始堆大小直接等于最大堆大小
-Xmn512m         新生代大小
-XX:MetaspaceSize=128m        元空间初始大小
-XX:MaxMetaspaceSize=320m         元空间最大值
-XX:+UseConcMarkSweepGC        尽量使用CMS收集器,降低GC停顿时间
-XX:+UseCMSCompactAtFullCollection        使用并发收集器时,开启对年老代的压缩.
-XX:CMSInitiatingOccupancyFraction        使用cms作为垃圾回收使用70%后开始CMS收集
-XX:+CMSParallelRemarkEnabled        降低标记停顿
-XX:SoftRefLRUPolicyMSPerMB=0 避免元空间fullgc时 class被清理 导致重新加载
-XX:SurvivorRatio=8 新生代 内存分区 6:1:1
-verbose:gc 在控制台输出GC情况
-XX:+PrintGCDetails 在控制台输出详细的GC情况
-XX:+PrintGCDateStamps GC的打印基于日期的时间戳
-XX:-OmitStackTraceInFastThrow  避免打印同样错误日志到一定次数就会被jvm默认优化掉。
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=C:/Users/liaojinlong/Downloads/dump/heap/(文件路径-保证目录存在)

-XX:+UseStringDeduplication 合并重复字符串
-XX:+DisableExplicitGC 禁用代码中System.gc()
-XX:-UseAdaptiveSizePolicy 关闭内存分配策略自适应 保证 edgen:s1:s2 8L1:1

相关文章:

Tomcat 线上调优记录

原始Tomcat配置 启动参数Plaintext-Xms256m -Xmx512m -XX:MaxPermSize128m Tomcat 参数配置XML<Executor name"tomcatThreadPool" namePrefix"catalina-exec-" maxThreads"1500" minSpareThreads"50" maxIdleTime"600000&q…...

学习 Python 之 Pygame 开发坦克大战(四)

学习 Python 之 Pygame 开发坦克大战&#xff08;四&#xff09;坦克大战添加音效1. 初始化音效2. 加入游戏开始音效和坦克移动音效3. 添加坦克开火音效4. 添加装甲削减音效5. 添加坦克爆炸音效6. 添加子弹击中边界音效坦克大战添加音效 我的素材放到了百度网盘里&#xff0c;…...

New和Malloc的使用及其差异

1&#xff0c;new的使用关于new的定义&#xff1a;new其实就是告诉计算机开辟一段新的空间&#xff0c;但是和一般的声明不同的是&#xff0c;new开辟的空间在堆上&#xff0c;而一般声明的变量存放在栈上。通常来说&#xff0c;当在局部函数中new出一段新的空间&#xff0c;该…...

2023年细胞生物学复习汇总

细胞分化 1.什么是细胞分化&#xff1f;细胞分化的特点是什么&#xff1f; 答&#xff1a;&#xff08;1&#xff09;细胞分化&#xff08;cell differentiation&#xff09;是指同一来源的细胞逐渐产生出形态结构、功能特征各不相同的细胞类群的过程&#xff0c;其结果是在空间…...

光伏VSG-基于虚拟同步发电机的光伏并网逆变器系统MATLAB仿真

采用MATLAB2021b仿真&#xff01;&#xff01;&#xff01;仿真模型1光伏电池模块&#xff08;采用MATLAB自带光伏模块&#xff09;、MPPT控制模块、升压模块、VSG控制模块、电流滞环控制模块。2s时改变光照强度 &#xff01;&#xff01;&#xff01;VSG输出有功功率、无功功率…...

高可用 - 02 Keepalived_VRRP工作原理

文章目录Keepalived VS HeartbeatKeepalived的用途VRRP与工作原理物理路由器和虚拟路由器Keepalived VS Heartbeat Keepalived是Linux下一个轻量级的高可用解决方案&#xff0c;它与Heartbeat、RoseHA实现的功能类似&#xff0c;都可以实现服务或者网络的高可用&#xff0c;但…...

vue实现xml在线编辑功能

先看效果 避免误会 这是一个在线编辑器 我们可以在这上面随意的编写xml代码格式 我们修改上面的内容之后 就可以在控制台输出内容 如果这正是您想要的东西 那就可以先创建一个vue项目 我们先引入依赖 npm install brace -S npm install element-ui -S npm install vue-cli…...

GitHub Workflow

GitHub Workflow 基本流程 把远程仓库克隆到本地 git clone xxxx.git在本地切换至新的分支 git checkout -b new_branch修改本地仓库的文件 项目修改完成后&#xff0c;查看修改的内容 git diff上传修改之后的内容到本地暂存区 git add modified_files将本地暂存区的代码更新…...

vue学习

vue 其实你只要安装一个vue-cli 就可以了 vue-cli 你可以用比较高的版本 这 当然是 可以滴...

Windows使用ssh协议远程连接ubuntu linux系统

Windows使用ssh协议远程连接ubuntu linux系统一、Windows远程连接ubuntu linux系统二、开启ubuntu ssh服务三、获取ubuntu子系统的ip地址四、从windows上通过ssh连接到ubuntu子系统五、设置ubuntu系统ssh自启动&#xff08;18.04&#xff09;一、Windows远程连接ubuntu linux系…...

大数据处理 - Overview

本文主要介绍大数据处理的一些思路。何谓海量数据处理?所谓海量数据处理&#xff0c;无非就是基于海量数据上的存储、处理、操作。何谓海量&#xff0c;就是数据量太大&#xff0c;所以导致要么是无法在较短时间内迅速解决&#xff0c;要么是数据太大&#xff0c;导致无法一次…...

12-Composer的配置与使用详解

1、自定义类与非类的自动加载与测试 # composer> php 包管理工具 &#xff0c;类似npm1.自己写的类&#xff0c;函数&#xff0c;接口&#xff0c;常量等全局成员&#xff0c;通过自动加载来实现按需加载 2.自己写的代码&#xff0c;有哪些依赖&#xff0c;用到了哪些外部成…...

RK3566开启wifi自适应

系统:linux(buildroot) 一、修改Makefile,使能RTW_ADAPTIVITY 文件路径:..\x3566_linux_v1.2.0\kernel\drivers\net\wireless\rockchip_wlan\rtl8821cs\Makefile 第74行&#xff1a; CONFIG_RTW_ADAPTIVITY_EN disable 改为&#xff1a; CONFIG_RTW_ADAPTIVITY_EN enab…...

shell编程之变量定义

typora-copy-images-to: pictures typora-root-url: …\pictures 文章目录typora-copy-images-to: pictures typora-root-url: ..\..\pictures一、SHELL介绍㈠ 什么是shell脚本&#xff1f;㈡ 什么时候用到脚本?㈢ shell脚本能干啥?㈣ 如何学习shell脚本&#xff1f;㈤ 学习s…...

Spring Cloud Alibaba 微服务简介

微服务简介 1 什么是微服务 2014年&#xff0c;Martin Fowler&#xff08;马丁福勒 &#xff09; 提出了微服务的概念&#xff0c;定义了微服务是由以单一应用程序构成的小服务&#xff0c;自己拥有自己的进程与轻量化处理&#xff0c;服务依业务功能设计&#xff0c;以全自动…...

【调试】GDB使用总结

启动 在shell下敲gdb命令即可启动gdb&#xff0c;启动后会显示下述信息&#xff0c;出现gdb提示符。 ➜ example gdb GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1 Copyright (C) 2018 Free Software Foundation, Inc. License GPLv3: GNU GPL v…...

基于Spring、Spring MVC、MyBatis的招聘管理系统

文章目录项目介绍主要功能截图&#xff1a;首页账户管理招聘建议部分代码展示设计总结项目获取方式&#x1f345; 作者主页&#xff1a;Java韩立 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 …...

软件测试基础

文章目录前言一、软件测试入门1.什么是软件测试&#xff1f;2.测试和开发的区别3.调试和测试的区别4.一些常问面试题5.测试人员需要具备的素质二、软件测试基础1.需求2.测试用例3.Bug4.软件的生命周期5.开发模型三、Bug1.如何创建bug2.Bug的级别3.Bug的生命周期4.跟开发产生争执…...

【算法基础】链表

一、单链表例题&#xff1a;实现一个单链表&#xff0c;链表初始为空&#xff0c;支持三种操作&#xff1a;向链表头插入一个数&#xff1b;删除第 k个插入的数后面的数&#xff1b;在第 k&#xfffd; 个插入的数后插入一个数。现在要对该链表进行 M次操作&#xff0c;进行完所…...

[AUTOSAR][Fls模块] Flash Driver Module

Flash Driver Module--jianqiang.xue一、 简介二、 措施方式一&#xff1a;将FLASH操作程序作为Bootloader组件的一部分固化在存储器中方式二&#xff1a;通过通讯口将该部分代码从上位机下载到指定的RAM方式三&#xff1a;将Flash功能函数作为数据运行(推荐&#xff01;&#…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...