记一次web服务的调优
来源:互联网 发布:项目管理流程软件 编辑:程序博客网 时间:2024/06/03 16:54
首先,描述一下环境,简单的web服务,关键日志写入kafka,要求qps达到单机10K即可。
后面将遇到的问题、解决方案和原理记录如下:
1、内存占用过大,虽然jvm的堆内存设为1G,但进程实际内存使用量达到了12G
解决方案:程序中使用了kafka,new出kafka producer来向kafka中写日志,调整kafka参数解决,调大了batch.size和partition
原理:原因还是batch.size和partition设置过小,导致要发送的数据包过多,都堵在了producer的机器上,而kafka producer又使用了zero copy技术,使得占用了大量的内核态内存无法释放,而内核态内存又不是堆内存,不由用户控制,所以出现了进程占用内存过大的情况,kafka版本为0.8.2.2。(其实这里还存在一点疑问,网上说kafka通信时使用了zerocopy,但我实际跟进代码时,producer使用的是ByteBuffer.allocate,也就是说使用的是堆内存,而没有调用ByteBuffer.allocateDirect创建非堆内存,与网上说的有冲突。如果哪位朋友知道这个问题的原理,还请赐教)
2、长时间负载高的情况下,程序性能下降明显,查看GC情况,发现频繁进行full gc
解决方案:通过使用jmap -dump将内存中的对象信息导出到文件,使用jhat命令分析,查出是一个kafka callback对象过多,而这个Callback对象包含了一些内容较长的字符串类型的私有变量,导致字符串占了较多内存,而kafka的producer有缓存机制,就会导致Callback对象占据内存无法释放,后来通过删除了Callback的私有变量,将Callback变为单例,来减少了内存占用
3、多线程丢数据
解决方案:由于有实时性要求,所以不能阻塞,只能通过加大队列长度和子线程的数量的方式
原理:主线程向子线程分配任务时,未自己管理BlockingQueue,而是交由操作系统自己管理,向子线程分配任务时,直接分配Callable对象
// 创建线程池ExecutorService pool = newThreadPoolExecutor(threadPoolSize, threadPoolSize, 0L, TimeUnit.MILLISECONDS, newLinkedBlockingQueue<>(queueCapacity));// 向子线程分配任务pool.submit(() ->producer.send(new ProducerRecord<>(topic, null, record), kafkaCallback));
由于submit方法调用了BlockingQueue的offer方法来添加,若队列已满,则返回false,而不是阻塞,且会抛出RejectedExecutionException(RuntimeException的子类),导致抛出异常和数据丢失
若考虑使用阻塞的方式,则可修改为自己控制BlockingQueue,若不想使用阻塞的方式,则可加大queueCapacity和threadPoolSize
4、日志使用log4j记录和写kafka性能差别过大,写日志文件达到3000qps,写kafka能达到11Kqps
解决方案:改为使用log4j 2.x,或使用kafka
原理:通过跟进log4j的代码,发现log4j 1.x中使用了很多sychronized代码,导致log4j多线程下性能问题严重,改为log4j 2.x可使qps提高到10K
- 记一次web服务的调优
- 记一次docker部署web服务性能瓶颈解决过程
- 记一次Web接口开发之旅,涉及Web服务、Oracle操作、字符编码等等
- 一次web项目从Weblogic服务到oracle AS10gR2的迁移过程
- 记一次tomcat启动后无服务的问题
- 记一次HTTP 服务实战
- 记一次keepalived故障服务
- 记一次服务停止排查
- 记一次难忘的调优
- 记一次C#的web模拟登录抓取
- 记一次web端的百度地图开发
- 记一次服务发布之后,图形验证码乱码的服务排查
- 一次简单的安装FreeBSD系统+添加用户+设置网络+安装web服务+mysql+php
- 一次修复IncrediBuild Coordinator服务的经历
- 一次奇怪的调优
- Web服务的特点
- web服务的复习.
- Web服务的标准
- 问题 A: Elevator
- ubuntu下安装和配置最新版JDK8傻瓜教程
- java 泛型
- 始终灼热的坚持.
- Java设计模式--工厂模式(简单工厂+工厂方法)
- 记一次web服务的调优
- 第五周 项目5-后缀表达式
- php微信支付
- Item3 Understand decltype
- 浅析JAVA中toString方法的作用
- hiho 1383 The Book List
- 先定一个小目标
- java连接SQL Server 2005数据库教程(手把手教程)
- SAP GUI740 PATCH10 下载