WebSphere环境下iText 5.5.6处理超长文本卡顿耗时问题排查
遗留应用HTML转PDF超长单词卡顿问题
环境与问题概述
- 应用技术栈:iText 5.5.6、Java 1.8.0_171 64位
- 部署环境:WebSphere Application Server ND 9.0.5.13、Windows Server 2016 Standard 1607 64位
- 核心功能:实现HTML转PDF
- 问题表现:当输入3万字符的超长单词(如连续的"aaaaaaaa...")时,代码在
document.add(myPdfPTable)行出现卡顿,无异常抛出;相同场景在Tomcat服务器下无此问题
相关代码
生成PDF核心方法
public Document generatePDF(String fontPath,String html) throws Exception { com.itextpdf.text.Document document = new com.itextpdf.text.Document(PageSize.A4, 20, 20, 100, 50); ByteArrayOutputStream baos = new ByteArrayOutputStream(); pdfWriter = PdfWriter.getInstance(document, baos); pdfWriter.setPageEvent(ppaHeaderFooter); pdfWriter.setViewerPreferences(PdfWriter.PageModeUseOC); pdfWriter.setPdfVersion(PdfWriter.VERSION_1_5); document.open(); document.addAuthor(authorName); document.addCreator(authorName); document.addSubject(filename); document.addCreationDate(); document.addTitle(filename); Font arabicFont = FontFactory.getFont(fontPath, BaseFont.IDENTITY_H, 14); FontFactory.register(fontPath); Font bold = FontFactory.getFont(fontPath, BaseFont.IDENTITY_H, 14f, Font.BOLD); Font regularfont = FontFactory.getFont(fontPath, BaseFont.IDENTITY_H, 10); List<Element> pdfElements = getElementsFromHtml(html, fontPath); PdfPTable contentTable = new PdfPTable(1); contentTable.setRunDirection(PdfWriter.RUN_DIRECTION_RTL); contentTable.setSplitLate(false); contentTable.setWidthPercentage(90); contentTable.setExtendLastRow(true); for (Element element : pdfElements) { PdfPCell cell = new PdfPCell(); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setVerticalAlignment(Element.ALIGN_CENTER); cell.setBorder(Rectangle.NO_BORDER); cell.setArabicOptions(ColumnText.DIGITS_EN2AN); cell.addElement(element); contentTable.addCell(cell); } document.add(contentTable); return document; }
HTML转PDF元素解析方法
public ArrayList<Element> getElementsFromHtml(final String html, String fontPath) throws IOException { final ElementList elements = new ElementList(); StringBuilder stylefile = new StringBuilder(); stylefile.append("body {font-size: 14pt;font-family:MyCustomFont;line-height: 1.5;dir:rtl}"); stylefile.append("table{padding: 0px;border-spacing: 0px;font-size: 14pt;}"); stylefile.append("td{height:30px;}"); CSSResolver cssResolver = new StyleAttrCSSResolver(); CssFile cssFile = XMLWorkerHelper.getCSS(new ByteArrayInputStream(stylefile.toString().getBytes())); cssResolver.addCss(cssFile); XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS); fontProvider.register(fontPath, "MyCustomFont"); CssAppliers cssAppliers = new CssAppliersImpl(fontProvider); HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers); htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory()); final ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null); final HtmlPipeline htmlPipeline = new HtmlPipeline(htmlContext, end); final CssResolverPipeline cssPipeline = new CssResolverPipeline(cssResolver, htmlPipeline); final XMLWorker worker = new XMLWorker(cssPipeline, true); final XMLParser p = new XMLParser(worker, Charset.forName("UTF-8")); final String resolvedHtml = "<body>" + html + "</body>"; p.parse(new ByteArrayInputStream(resolvedHtml.getBytes(Charset.forName("UTF-8"))), Charset.forName("UTF-8")); return new ArrayList<Element>(elements); }
UPDATE1:线程挂起栈信息
启用WebSphere挂起线程检测后,定位到线程挂起的调用栈:
ThreadMonitor W WSVR0605W: Thread "WebContainer : 4" (00003bed) has been active for 672628 milliseconds and may be hung. There is/are 1 thread(s) in total in the server that may be hung. at com.ibm.tivoli.itcam.gdc.data.GDCInstanceDataManager.resetProvisional(GDCInstanceDataManager.java:489) at com.ibm.tivoli.itcam.gdc.GDCMethodProbePoint.customProbeEndEvent(GDCMethodProbePoint.java:1691) at com.ibm.tivoli.itcam.toolkit.ai.boot.callbacks.generic.CustomProbeCallback.customProbeAfterCallbackInstance(CustomProbeCallback.java:450) at com.ibm.tivoli.itcam.toolkit.ai.boot.callbacks.generic.CustomProbeCallback.customProbeAfterCallback(CustomProbeCallback.java:409) at com.itextpdf.text.pdf.PdfFont.width(PdfFont.java:138) at com.itextpdf.text.pdf.PdfChunk.getCharWidth(PdfChunk.java:961) at com.itextpdf.text.pdf.BidiLine.processLine(BidiLine.java:383) at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:1068) at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:990) at com.itextpdf.text.pdf.ColumnText.goComposite(ColumnText.java:1523) at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:996) at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:990) at com.itextpdf.text.pdf.PdfPCell.getMaxHeight(PdfPCell.java:1044) at com.itextpdf.text.pdf.PdfPTable.getFittingRows(PdfPTable.java:2141) at com.itextpdf.text.pdf.ColumnText.goComposite(ColumnText.java:1753) at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:996) at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:990) at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:978) at com.itextpdf.text.pdf.PdfDocument.addPTable(PdfDocument.java:2673) at com.itextpdf.text.pdf.PdfDocument.add(PdfDocument.java:750) at com.itextpdf.text.Document.add(Document.java:278)
UPDATE2:性能差异对比
- WebSphere环境:最终PDF可生成,但耗时约15分钟(文件大小350KB,共280页)
- Tomcat 9+Java 8环境:相同请求仅需30秒,问题与WebSphere环境强相关
UPDATE3:JVM配置信息
JVM参数
-Dcom.ibm.jsse2.overrideDefaultProtocol=TLSv12 -Dcom.ibm.jsse2.overrideDefaultTLS=true -DFileNet.WSI.AutoDetectLTPAToken=true -Dcom.filenet.authentication.token.userid=sso:ltpa -Dam.wasserver=server1 -Dam.wasnode=MyNode01 -Dam.wasprofile=AppSrv01 -Dam.wascell=MyNode01Cell -Dcom.ibm.tivoli.itcam.ai.runtimebuilder.inputs=${ITCAMDCHOME}/runtime/AppSrv01.MyNode01Cell.MyNode01.server1.DCManualInput.txt -Dws.bundle.metadata=${ITCAMDCHOME}/runtime/wsBundleMetaData -Djava.security.policy=${ITCAMDCHOME}/itcamdc/etc/datacollector.policy -Xbootclasspath/p:${ITCAMDCHOME}/toolkit/lib/bcm-bootstrap.jar -Dsun.rmi.transport.connectionTimeout=300000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Dsun.rmi.dgc.client.gcInterval=3600000-verbosegc -Xgc:allocationSamplingGranularity=10000 -Xhealthcenter:transport=jrmp,level=inprocess -agentlib:am_ibm_16=${WAS_SERVER_NAME} -Djava.net.preferIPv6Addresses=false -Djava.net.preferIPv4Stack=true -Dcom.ibm.cacheLocalHost=true -Djaxws.payload.highFidelity=true -Djava.security.auth.login.config=C:\FileNet\AE\config\jaas.conf.WebSphere -agentlib:getClasses
JVM自定义属性
![JVM自定义属性截图]
内容的提问来源于stack exchange,提问作者Mahmoud Saleh
相关产品推荐
相关产品推荐

