产品issue 诊断:Java CPU/Memory- Caused by JAX-WS Client

【信息科学与工程学】【数据中心】第二十四篇 数据中心DaaS场景及算法 Flink, Kafka Streams, 时序数据库。Flink, Kafka Streams, 流处理引擎。Presto, ClickHouse, 查询加速引擎。Presto, ClickHouse, 查询加速引擎。延迟<50ms,可用性>99.99%,QPS>10K。REST API, GraphQL, API网关。Tableau, Power BI, 自助BI。Tableau, Power BI, 可视化库。Spark, Hadoop, 分布式计算框架。Spark, Hadoop, 分布式计算。 阅读详情

Background

我们有个组件使用JAX-WS client来call另外一个组件的web service。新的release发布后,立马出现了cpu issue。

Cpu issue

截图如下(来自Cacti)

cpu goes to 100%


经调查发现,是因为我们的Stub对象创建过于频繁所致。每次API调用,都会新建一个Stub对象(创建代码如下)。而JAX-WS Stub对象的创建是cpu-sensitive的过程 

static String SERVICE_URL = ...;
static String NAMESPACE_URI = ...;

public static MyService getMyService()
{ 
  String endpoint = "http://" + SERVICE_URL + "/ws/MyService.wsdl";
  URL url = new URL(endpoint);
  QName qname = new QName(NAMESPACE_URI, "MyServiceService");

  MyServiceService service = new MyServiceService (url, qname);
  MyService port = service.getPort(MyService.class); 
  BindingProvider bp = (BindingProvider) port ;
  bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint);
 
  return port;
}

很显然,我们必须重用stub对象,而不能每次重新创建。但问题是:

Is JAX-WS client thread-safe

如果你有google过这个问题,你一定很恼火Sun的JAX-WX RI的开发人员。

很多人希望有个官方回答,但只有非官方的线索。Stackoverflow,CXF,JBOSS

“根据JAX-WS的Spec, client proxy 是非线程安全”

经过考虑后,我们有几种方案:

  1. 创建一个全局的Stub。我们有程序员认为(未验证)Stub中全局共享的context变量在创建后并没有被修改,其他的都是每次调用生成的局部对象。所以单个Stub是线程安全的。
  2. 使用ThreadLocal,每个线程cache一个Stub对象
  3. 使用ObjectPool,类似于ThreadLocal,但不委托于Tomcat的Thread pool来管理对象的生命周期,而是自己来申请/释放
  4. 不使用JAX-WS,使用在其他项目中得到检验的Axis2的client包
  5. 从代码change的范围来讲,1~4排列,从小到大。1是将自己放在推测上,舍弃;于是用2

修改上线后,CPU下降显明,我们过了几天好日子。


左图为每次重新创建Stub,右图为重用Stub对象。(来自JConsole)

Memory Issue

截图如下(来自jvisualvm),使用的内存缓慢上升;运行几天后,内存被耗尽(2G),开始频繁的GC,导致CPU再次相当繁忙。


通过对Heap-Dump(来自MAT)的分析,我们发现占用Heap的对象为线程对象。


java.lang.Thread @ 0x75426748 http-8930-1 - 4,353,584 (1.02%)bytes.



Thread中retained对象是ThreadLocal,而ThreadLocal中cache了Stub对象, 每个Stub对象为1M左右。由于Tomcat默认线程池大小是200个,

我们的应用中每个线程会cache三个Stub对象,所以理论上Stub占用的内存为600M。

注意在我们的Tomcat中部署了多个应用,这些应用共享Tomcat的线程池,所以线程空闲的机会很少,所以线程被销毁的机会也就恨小。

在产品环境,我们发现内存占用可达到1.8G,与理论里不符。

在检查了该组件的内存使用历史记录后,我们发现这个组件在使用JAX-WS client之前内存使用也一直很高。

JAX-WS Client成了压垮它的最后一根稻草。


关于ThreadLocal + ThreadPool的组合, 网上有文说it's a bad idea,至少要慎用

Second Fix

在Memory issue出现后,我们又重新从头到审查这个issue。
我们发现在stub的创建过程,耗时操作在Service的创建上,而Port(Stub)的创建相对要轻量很多,于是我们作了如下的Fix:
全局共享一个Service对象,Port对象每次API调用重新生成。

static String SERVICE_URL = ...;
static String NAMESPACE_URI = ...;

static MyServiceService service = null;

static 
{

 String endpoint = "http://" + SERVICE_URL + "/ws/MyService.wsdl";
  URL url = new URL(endpoint);
  QName qname = new QName(NAMESPACE_URI, "MyServiceService");

  MyServiceService service = new MyServiceService (url, qname);
}

public static MyService getMyService()
{ 
 
  MyService port = service.getPort(MyService.class); 
  BindingProvider bp = (BindingProvider) port ;
  bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint);
 
  return port;
}

Still issue

产品上最终CPU/Memory没有问题。

但关于JAX-WS client stub(port)是否为线程安全,目前还没给出Final conclusion.

有人说,it's thread-safe

【雕爷学编程】Arduino动手做(111)---震动提醒模块 37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来---小小的进步或是搞不掂的问题,希望能够抛砖引玉。 阅读详情

相关推荐

Scratch(四十一):升级版垃圾分类

哈喽,大家好!之前给大家展示过“Scratch(二十四):垃圾分类”。今天呢,给大家展示的Scratch是`升级版垃圾分类`。接下来,我们一起看一下效果吧。

我可以很大侠的博客 6863

jax-ws之webservice security(安全)教程第三天

前言: 在今天的学习中,我们讲开始过渡到一个真正的websecurity例子。 第二天中我们知道了如何使用handler来处理客户端提交上来的用户名与密码,而在今天的学习中,我们将会使用服务端预先配置的用户名与密码来authenticate客户端提交上来的值。 相对于第二天的学习,如果客户端提交的用户名与密码输错,但还是能够与服务端建立http连接来说,第三天中的例子的安全性则更高,当客户端...

fulerbakesi 452

从0到1做AI漫剧:即梦+豆包+剪映+红果全流程实战

AI视频生成正在重塑内容创作的生产方式,它让原本高门槛的影视制作,变成了一条由文本、画面、剪辑与分发环节协同的流水线。理解其底层原理,在于将大模型的语义理解、图像生成与视频合成能力,与工程化的流程管理相结合,从而实现从创意到成片的自动化输出。这种技术的价值,不仅体现在降低制作成本,更在于让个人创作者能够独立完成高质量短剧,并快速迭代内容。在短剧、短视频、广告营销等场景中,利用即梦生成画面、豆包编写剧本、剪映完成剪辑、红果进行分发的组合,已成为一种被广泛验证的实践路径。本文聚焦AI漫剧制作,从环境准备、分镜设

weixin_34072637的博客 380

Java issues

<br />issue1:NPE.COND<br />Null pointer dereference of ftpClient where null comes from condition <br /> <br />A NullPointerException is thrown in case of an attempt to dereference a null value. The dereference may be a function call, a read or write of a

Be a smart person 1398

【YOLO11改进 - C3k2融合】C3k2融合DWRSeg二次创新C3k2_DWR:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目标检测

【YOLO11改进 - C3k2融合】C3k2DWRSeg二次创新C3k2_DWR:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目标检测

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 1054

传导案例:某医疗仪器传导骚扰整改案例

紫外线光疗仪是一种专业的医疗设备,主要用于治疗银屑病、白癜风等皮肤疾病。该设备采用物理治疗技术,通过特定波长的紫外线照射人体来达到治疗效果。自1984年窄谱中波紫外线(NB-UVB)应用于临床以来,该技术已成为治疗早期蕈样肉芽肿(MF)的有效方法之一。作为二类医疗器械,紫外线光疗仪必须符合严格的电磁兼容性(EMC)标准,这不仅关系到设备自身的稳定运行,更关乎患者的使用安全和治疗效果。紫外线光疗仪传导骚扰整改案例充分展示了系统性EMC设计的重要性。

m0_56451176的博客 338

java issue

使用logger.error(‘xxx’,e)的方式代替e.printStackTrace()记录错误日志

xiaoqidela的博客 642

optee技术简介

OP-TEE(Open Portable Trusted Execution Environment)是一种开源的可信执行环境(TEE),专为ARM TrustZone架构设计。TEE是一种独立的执行环境,运行在主操作系统之外,为敏感任务提供安全的计算空间,如加密、身份验证、密钥管理等。

baron-周贺贺-代码改变世界ctw 1279

java中issueCall的用法_Java魔法堂:注解用法详解——@SuppressWarnings

一、前言编码时我们总会发现如下变量未被使用的警告提示: 上述代码编译通过且可以运行,但每行前面的“感叹号”就严重阻碍了我们判断该行是否设置的断点了。这时我们可以在方法前添加@SuppressWarnings("unused")去除这些“感叹号”。二、@SuppressWarings注解作用:用于抑制编译器产生警告信息。示例1——抑制单类型的警告: @SuppressWarnings("unc...

weixin_39778393的博客 294

黑猫带你学eMMC协议第4篇:eMMC概述

1 前言 声明: 本文依据eMMC JEDEC5.1协议及个人工作经验整理而成,如有错误请留言。 文章为个人辛苦整理,付费内容,禁止私自转载。 本文大约3000字,从emmc的内部结构框架、供电、总线、寄存器等各方面进行框架性的介绍,本章节内容不需要深入研究,读完本篇文章,只要能对emmc有个框架下的了解,就可以了。 2 内部结构框架 由图可以看出,emmc内部由两块组成:控制器 + 存储介质。emmc内部存储介质绝大部分为nand flash。 众所周知,我们需要存储数据到nand flash中,并

黑猫奥利奥的博客 3340

Python爬取公交线路信息及站点shp数据 文末附数据下载地址

三、现在已经获取到了各个线路名称、链接,以及所途径的上下行站点,那么接下来就应该对开始对第三页url进行信息采集,即本次爬虫的最终目的:爬取所有站点的GPS坐标数据。但坑就坑在,二环一号线属于环线,所以只有左侧有站点数据,而其他非环线车次的站点数据分有上下行,如果用正则匹配,则分不清楚到底哪些是上行站点哪些是下行站点。以前爬过百度地图,当时用的是API平台,加上网站比较规范,所以标签节点什么的都比较清晰,但这次由于特殊原因所选择的网站为公交网,废话不多说直接开始吧。checi=二环一号线。

J_Giser的博客 1316

Issue的分类和定义

Issue的分类和定义:将产品需求进行细粒度拆分,输入到项目部,达到快速开发、验证和交付的目标。 Issue共有5种分类:Story /NewFeather/Task/Sub_Task/Bug

u012456282的专栏 4813

【温室气体数据集】CAMS 发布的温室气体(GHG)数据集总结

【温室气体数据集】CAMS 发布的温室气体(GHG)数据集总结

WW、forever的博客 554

java中issueCall的用法_Javascript中call的两种用法实例

用法一(常见用法):表现形式为:一个对象.方法.call(另一个对象),意义是用另一个对象代替当前对象,执行当前对象的方法。先看示例:function Class1(){this.name = "class1";this.showName = function(){alert(this.name);}}function Class2(){this.name = "class2";}var c1 =...

weixin_30411455的博客 325

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Java issue

读取XML配置文件可使用Digester

rjw的专栏 582

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Java JDK version issue

Sometimes we are using JDK1.8 in Desktop envionment , But 1.6 or 1.7 on Server, so we need to deploy project on lower version to fit with server.Please Note there are 2 place for version setting! Proje

heavenluu的专栏 366

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Java GC 调试手记

摘要 本文记录GC调试的一次实验过程和结果。 GC知识要点回顾 问题1:为什么要调试GC参数? 在32核处理器的系统上,10%的GC时间导致75%的吞吐量损失。所以在大型系统上,调试GC是以小博大的不错选择。'small improvements in reducing such a bottleneck can produce large gains in performance.'

FireCoder的专栏 3万+

mybatis (Ibatis ibator) generator - 1 mysql 分页插件(page/paging/pagination plugin)

前言在线文档,参考 http://ibatis.apache.org/docs/tools/ibator/由于ibatis转移为mybatis,所以参考mybatis 最新文档:http://code.google.com/p/mybatis/wiki/Downloads?tm=2下载的MyBatis Generator Tool中有文档说明http://ibatis.apache.org/docs/tools/ibator/reference/pluggingIn.html将plugin的生命周期和怎么扩

FireCoder的专栏 1万+

JAX-WS Provider (JAXB) 的加载顺序

Problem项目中使用JAX-WS 2.1.4,抛出以下错误 Caused by: java.lang.ClassCastException: com.sun.xml.bind.v2.runtime.JAXBContextImpl cannot be cast to com.sun.xml.internal.bind.api.JAXBRIContext      at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.(SOAPFaultBuilder.java

FireCoder的专栏 1万+

Hilbert 曲线

问题 一POI(Point of Interest)数据库每天都有增量的数据更新进来,对每个新增的poi必须进行dedup(去重)。即在已有库中查找是否有匹配的poi。 解决 找是否匹配的POI,当然不可能把所有的数据(几千万的点)全部取出来一一匹配。所以通用的做法是按距离进行过滤,只取当前点一定范围内的点。这是一个典型的空间索引的问题(Spatial index)。空间索引有R-Tree,

FireCoder的专栏 1万+

java finalize 方法引发的内存泄露

java finalize 方法引发的内存泄露 Posted: Mon, 11 Mar 2013 java 内存dump 内存dump后,大量的内存(>5G) 被 java.lang.ref.Finalizer hold 住(见图1)。 而这些内存是BDB占用,怀疑是BDB有内存泄露(见图2)。 java finalizer 机制 为什么会是 java

FireCoder的专栏 1万+

maven java.lang.NoClassDefFoundError: org/codehaus/plexus/util/DirectoryScanner

org/codehaus/plexus/util/DirectoryScanner在反复搜索无果之后,我将本来的repository plexus-utils 进行了清空/home/lee/.m2/repository/org/codehaus/plexus/plexus-utils然后一切OKmvn install我对plexus 究竟是啥很好奇,搜了一下,原来是另外一个IOC容器http://www.bluedash.net/spaces/Plexus,Spring之外的IoC容器提到IOC,不得不说号

FireCoder的专栏 8991

Cassandra 源码解析汇总

<br />Cassandra 源码解析Cassandra 源码解析 1:网络通信Cassandra 源码解析 2: 文件流传输 对象序列化Cassandra 源码解析 3: 分布式hashtable(DHT) 和 LocatorCassandra 源码解析 4: GMS 集群管理Cassandra 源码解析 5: MerkleTreeCassandra 源码解析 6: Storage Engine (DB Layer)<br /> <br /> <br /> <br /> <br /> 

FireCoder的专栏 8244

七种武器:apache commons : commons-lang

前言有人说apache 就是丐帮,各种开源项目鱼龙混杂,参差不起。今天试着梳理下commons包,首先是commons-lang。看了一眼之后,一个字:杂,有如瑞士军刀,无数用途。如何organize这种类JDK util代码?1) the most interesting in design or implementation2) the most useful 3) see how other developer uses, wrap, rewrite JDK正文 lang.builder.*解决了一个

FireCoder的专栏 7825

Happy Apache Cassandra 2: File Store Format

h3. Model Review Cassandra data model Column Family Super Column Family h3. File Format h4. Keyspace Each Keyspace(Eg. Lobs)in separated directoryEach ColumnFamily(Eg. obje

FireCoder的专栏 7274

Cassandra 源码解析 1:网络通信

org.apache.cassandra.thrift -  Server 端入口CassandraDaemon: 启动类CassandraServer implements org.apache.cassandra.thrift.Cassandra.Iface : 接口类,类似于web service中的skeletonCustomTThreadPoolServer extends  org.apache.thrift.server.TServer :监听类,监听thrift client请求

FireCoder的专栏 7203
上一篇: An introduction to Java-concurrency
下一篇: java generic super/extends (java 泛型中的super/extends)
FireCoder
博客等级 码龄17年 65粉丝 100原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FireCoder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值