希望大家指出我的不足之处。
希望能帮我点上一颗 star,多谢多谢。
云压测平台在测试领域并不是陌生的名词,简单来说就是在网页/移动端执行压测操作,同时压力机是部署在云端。
如压力节点机在云南,那就是云南产生压力,在北京,那就是北京产生压力。
现阶段云压测平台挺多的,我了解到的就有收费的如阿里云的 PTS、XMeter,还有一些开源的,如 nGrinder、云集微店的 TITAN。
收费的就不提了。
开源的各种压测工具,总会面临各种问题:
同时,平台实现之后还有好处:
其实平台本身使用什么语言开发都可以,但是由于压力内核选择使用了 Jmeter,为了要调用 Jmeter 的 API,平台也选择使用 Java 开发。
优点不详述了,最重要的还是顶级项目开源,社区活跃,Java 语言性能好和跨平台。
说下缺点,我目前发现的有:
所以国内已经有余力的公司(阿里)是在改造 Jmeter,就是取其精华去其糟粕了。
平台根据前端的操作,自动拼接出一行可执行的命令,然后在指定服务器上执行这段脚本。
相当于是手工敲的命令平台帮着拼接和回车执行了。
即便是前端来生成测试脚本,也可以先保存成 jmx 文件,再脚本执行。
特点是平台和 Jmeter_Home 完全分离,带来的:
平台代码直接调用 Jmeter 的 API。
相对脚本执行的实现:
对比脚本执行的好处:
我的平台两种方式都支持,当然推荐是引用 Jmeter 的 API 方式启动,可配置。
最最基本的要求了。
如果没有在线实时监控,那和 Jmeter 自身的脚本压测甚至和 AB 等工具,就没啥区别了。
Jmeter 3 开始支持测试报告,这也是选择 Jmeter 的原因之一。
即云压测的基础。
权限管理是平台面向全公司/全网的基础。
压测需要和具体业务有关系,这个关系在平台上要可以设置。
图形监控的功能要非常丰富,比如放大缩小等。
删除是让系统文件空间可控。下载是移动办公的基础。
分布式压测的衍生需求,有了分布式节点管理,能大大减轻手工操作。同时各种提示非常人性化。
这曾经是我比较纠结的地方。
还有很多很多。
阿里的 PTS 是让在平台上写脚本代码实现最核心的功能包括断言,然后页面录入压测指标数据。
这样做如果遇到复杂的性能测试要求,问题很大:
所以我的选择很简单,上传 Jmeter 的脚本,同时上传参数化文件。
好处不说了,详细的后续会介绍。
简单来说,就是平台可以实时监控到服务器的网卡,CPU,内存,磁盘,甚至日志等等。
我放弃的原因:
其实这个话题很大,比如监控到什么程度才算合格,能否做到智能化监控与测试报告的连接,服务器指标数据和服务器日志的结合展示分析等等。
在没想好怎么做之前,我的选择是抛弃这部分需求,做不好不如不做。
平台我一直在深度使用,挺好用。
平台代码当前也比较稳定。
平台创造压力的能力和 Jmeter 的内核相同,无论是单机还是分布式,同样的支持 Grafana+InfluxDB。
后续我会慢慢介绍这个平台,当然也可以直接看我的代码,我自认为代码注释,结构等,还是很清晰的。
赞一个,不过有一条不是很能同意:
高昂的学习成本,这么复杂的脚本代码我还搞什么工具推广,工具面对的是小白怎么办
性能测试要做好,所需要的技能可能比安全测试还要宽、深(可能有些维度上深度会差异较大),这点学习成本,就不用给做性能测试的工程师们省了
平台的好处就是海纳百川,搜集足够多的信息,也能够灵活快速支持分布式压测,这都是很赞的~另外,如果从测试配置和执行、监控结果中挖掘一些基础的分析和调优建议倒是个不错的思路
我是做性能测试,说真的阿里云的 PTS 和腾讯的 WeTest 我都用了,但是功能是在太单调了,不能满足实际情况的需求。
所以我们都是自己写 Loadrunner 脚本和 Jmter 脚本,然后根据实际情况租用阿里云机器进行压测的,报告都是自己收集整理的,虽然确实繁琐,但是可以应对实际测试过程中的一些突发情况和奇奇怪怪的需求。
其实我比较想要 脚本、报告、数据等信息的管理维护,以及一个可以自动化关联测试的资源监控平台(可以应付绝大数的数据库、服务器、中间件等监控)。
了解了,压测任务确实各有不同,不过只要是使用 Jmeter 的脚本,都可以上传到这个平台上进行压测。
至少可以做到:
如果你们的测试报告都是自己整理的,那么你们可能需要完备的监控截图,而我的平台监控截图比 grafana 的清晰了不少,你们可以作为参考。
### SQL: insert into test_stress_case_file ( `case_id`, `slave_id`, `status`, `origin_name`, `file_name`, `file_md5`, `add_by` ) values ( ?, ?, ?, ?, ?, ?, ? )
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'slave_id' cannot be null
; SQL []; Column 'slave_id' cannot be null; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'slave_id' cannot be null
at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:85)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)
at com.sun.proxy.$Proxy68.insert(Unknown Source)
@zyanycall Taurus (Blazemeter reporting services ) 了解一下. 重复的轮子
额,这种提到 issue 里吧……然后堆栈完整一点儿。
看错误是比较简单的,数据库字段不能为 null。我本地是可以的,当然完整堆栈能看出是什么问题。
外国人的轮子啊……不知道也是基于 Jmeter 的吗?
我文中写了不少为什么我要再开发一套的原因,要不你参考一下,然后告诉我 Taurus (Blazemeter reporting services ) 是不是都满足了。
用了大半年的 ngrinder,社区几乎死了一样,二次开发也多半集中在数据的展示,进一步较难。
现在在重新回到 jmeter,谢谢楼主分享的方案,有启发
楼主写的还是不错,代码也比较容易看懂,可以拿过去自己再进行二次开发。
另外,我觉得既然压测的核心已经交给了 jmeter,二次开发还是聚焦在数据展示上面比较好,如果能够实现 loadrunner 那种实时数据、监控资源展示,还有报表分析的能力那就牛逼了。
多谢肯定。
实时监控的开源产品太多了,最近我还发现了一个 :
https://github.com/AsuraTeam/monitor
这方面要考虑的太多,自己实现很难专业。
另外提到的 报表分析 ,如果做出来确实很牛,就像 听云 ,但是到这步就很难开源了, 是可以赚钱的了。
正在用 go 写 jmeter 的性能测试平台 向楼主学习一下
@zyanycall 达康书记 首篇没了 第 二 第三篇呢
厉害
最近也在给团队开发这个高并发的性能测试平台,不过我是用 Python 手写的,并发可上万。可以交流一哈
pom 文件用哪个?
大佬,本地 windows 使用 IDEA 启动,生成报告会报 The JMETER_HOME environment variable is not defined correctly
This environment variable is needed to run this program
我就是 win10 啊。
mac 成功了,win10 不成功,那先检查配置呗……主要是 Jmeter_home 的路径,目录下是这样的:
可能是我的 apache-jmeter-4.0 有问题,我换成 apache-jmeter-5.0 的,然后把 pom 里的依赖换成 5.0 就好了
兄弟,linux 上 mvn package,然后 java -jar renren-fast.jar,运行报错
基于 Jmeter 的轻量级云压测平台的原理与实现 (一):开篇 (改)
大牛,二和三呢?
您好 我用 jmeter 压测,请求数比较多,中间有出现 502 504 500 的错误,我怎么捕获这些呢。本来我想着用 python 写个结果分析文件,但结果太大了,jmeter3.0 能设置只要这些的结果吗
感谢使用。
第三方的 jar 包要写到 pom 文件里,相当于平台加载的三方 jar 包,然后重启平台使用。
这方面目前没有什么好办法。
请问下您这个性能平台支持 dubbo 接口的性能测试吗?
RPC 的接口吗?这个没尝试过。
我们平台是 Jmeter 内核的,如果 Jmeter 可以测,那平台就可以。
嗯..用了...也拜读了你的代码... 确实很清晰易懂... 但是有个建议反馈给楼主:
jmeter master 和 slave 之间用的 RMI 协议进行通讯的,网络开销很大..在进行超大 TPS 压测时,master 的网卡时常会成为瓶颈.及时不成为瓶颈,经过在压测中数次验证, Master*1 Slave*3 架构可以发出的压力一般都是小于 Master *4 的... 在实战中,我都是使用多个 Master 的模式压测的... Master-Slave 的基本不用
还是被说出来了啊……其实这个坑我也是深有体会的。文中我也提了。
这个坑,属于 Jmeter 的缺陷,但你的多 master 的方式也有问题,主要就是测试数据的监控收集和测试报告的整合及生成。
我想的解决方式,应该还是给 Jmeter 写插件,不要实时发送数据,而是固定间隔发送数据给 master。
当然目前我没心急火燎的解决这个问题,因为实际上,master-slave 的结构能产生的压力还凑合。
我这边是有数据的,master 是 1G 网卡的情况下,多 slave 能产生接近 8 万的 TPS 压力。
这个压力的数值,已经可以了。
通俗点儿说,这个压力我认为已经满足绝大多数的压力需求了。
这个问题我已经想着呢,会实现。
楼主,M-S 模式和多 M 模式各有优劣吧...我觉得 M-S 模式还有个问题就是较大 TPS,如你所说的 8W,跑稳定性测试的时候,比如跑 2 个小时,会产生巨大无比的 JTL 文件... 这个文件处理和分析都是噩梦... 而我的多 M 模式,则结果数据分散在多个 M 上,目前我是使用自己写的算法将 JTL--->JSON,将 JTL 里每 S 的数据聚合成 JSON 数组的一条,大概的数据结构就是: 2018102601<---> PASS:100,FAILED:10,AVG:10MS,TP99:15 ...,一个数十 G 的 JTL 产生的 JSON 文件一般都不超过 1MB,然后将各个 M 的 JSON 数据合并.
目前我的难点是实时的展示测试数据...
没有呀,我的平台支持不生成 css 结果文件的,然后监控数据可以直接来我的平台截图呀,这样测试报告不会过于单薄,同时还会有监控。
你这个自己的算法还是不错的,但是还会面对一个问题,就是测试报告的整合。
你自己的算法也是改的 Jmeter 源码吗还是插件生成的?还是说处理已有的 JTL 文件?
嗯. 不生成结果这个思路可以的... 有趋势图和统计之后的数据一般都足够了..
但是楼主这个好像没有那种汇总的数据... 就是 对整个测试做一个采样分析的比如 总平均 TPS,TP99,MAX,MIN 之类的...
另外就是一个最大的问题就是,很多公司都有诸如 dubbo、SAF 之类的 SOA 系统,测试这种类型的需求,需要:引入被测的 jar--->调用被测方法--->测试并统计结果...
楼主这种直接 CALL API 的方式,如果有多人同时使用并测试 SOA 的话,怎么搞呢?
唉,也是一种取舍吧。
想要十全十美,肯定是要费一番功夫的。
其实性能测试到底目的是什么,这个要想清楚,后续我合计介绍介绍这个。
有些人都不看测试报告的,或者说报告中有什么根本看不明白,看不出来门道。
我们测试人想的,测试报告,什么趋势图,什么统计数据,其实对某些人来说,有了就是 “哦”,没有了就是 “你这不行呀”。
我们想的周到的,费力实现的,其实除了自己,别人都体会不到。
测试人不能自己把自己玩死,还是要聚焦到能提高自身价值的地方去。
嗯. 内嵌调用 API 的方式 确实在 RPC 测试方面有天然的劣势... 这样会导致多个测试需求共用 JRE
看来你这一下提了不少的需求啊,总体的数据结果分析 + 分布式节点的拆分利用。
简单聊聊吧。
数据结果 table 展示:
当然这个我还没做,因为 Jmeter 提供的测试报告是包含这些的。
你提的应该是抛弃测试报告的时候,这些聚合数据怎么弄?
我可以给折线图增加这些数据的线啊,Jmeter 传统的聚合报告的 table 展示是有弊端的,因为对比它,折线图不仅能展示趋势,还能包含历史数据,是更优的选择。
目前我没做因为我用不到 99%Line 等,还因为没人给我提这种需求。
分布式节点的拆分利用:
这个比较复杂了,其实 Jmeter 自己对这个支持的就不好啊,想一想,如果单独用 Jmeter,怎么利用多个 slave?还不是要多个 master。
我的平台想要展示不同的 slave 集群的结果,还要基于 Jmeter 的 API 之上,其实是有难度的。
这个地方我是有想法的,但是还没验证就不在这里说了。
我的原则是能不改 Jmeter 的源码就不改,因为它发展的很快,改它源码不合适。
是有想法的,嗯嗯,如果真有这方面的需求,是可以实现的。
是吧,平台上传 jar 包这种操作,是测试自己掌握的。
不能说平台的管理还搞一堆其他部门的人来染指,那就说不过去了。
你说的包冲突,频繁上传,都是我们测试来掌握的。
测试的 jar 包要稳定,可以先 Jmeter 工具自身测试验证后,再到平台上来,所以你说的平台频繁启动刷新 JRE,是属于过度使用平台了。
不是的... 使用 jmeter 测试 RPC 需求的时候,需要把测试 jar 和依赖的 jar 放到 JmeterHome\lib\ext 下面,可以预见经历若干个测试需求以后,JmeterHome\lib\ext 下会有大量重复的 jar... 引发 jar 包冲突...
不过如果想使用一套 jmeter 环境的话,可以考虑下面的解决方案;
楼主,经我验证,你的平台目前需要改掉 3 个地方才能进行 RPC 脚本的测试;
StressTestFileServiceImpl.java 中修改三处:
// 1. 加入 loader 声明的全局变量
private static final DynamicClassLoader loader;
// 2. static 代码块的最后 加入
loader = AccessController.doPrivileged(
new java.security.PrivilegedAction() {
@Override
public DynamicClassLoader run() {
return new DynamicClassLoader(jars.toArray(new URL[jars.size()]));
}
}
);
// 3. setJmeterProperties() 方法开始加入
Thread.currentThread().setContextClassLoader(loader);
以上均经过实测.
这几处代码是我当初没有放进去的。主要是因为最后一行:Thread.currentThread().setContextClassLoader(loader); 这会将当前线程的类加载器换成自定义的。
Jmeter 的自己的原有的启动类是需要这个的,为了将 lib 目录下的 jar 包的类加载到内存中,但我们平台是不同的,平台的环境里已经存在了绝大部分的类,没必要把 lib 目录下的所有的 jar 包都在每一个脚本执行的时候再加载一遍(应该还是占用内存的,即使重复也要来一套,没验证)。
如果你非要追求 Jmeter_Home 的那种全量的环境,可以使用脚本模式执行,同时外挂 influxDB+Grafana 监控,这是满足你的需求的。
当前平台还不打算搞的所有的 lib 包还要重复加载一遍。
嗯嗯... 仅仅给是楼主提下建议... 主要是要测试 RPC 的需求的话,必须要将 RPC 接口本身的包引入 JMETER 环境...
其实比如 PTS 也支持了原生 JMeter 的压测了,不用担心并发不够的问题,报表也是现成的。XMeter 不了解。
xmter 核心还是 jmeter 吧,
请教一下,我脚本里使用了 BeanShell,Jmeter 脚本启动启动可以,但是以代码的方式,会报错,是有什么插件没有装吗?
大佬,目前是以 shell 方式生成的测试报告,对 jmeter 不是很熟悉,请问可以 java 代码的形式生成吗?
可以的。
你可以查一下源码中的 org.apache.jmeter.report.dashboard.ReportGenerator 类, 是通过它生成报告的。
调用如下:
ReportGenerator generator = new ReportGenerator(reportFile, null);
generator.generate();
关注中,期待二三,希望不会断掉
这个平台能否部署到 centos 系统呢?
为啥生成的报告是 csv 格式的?
你好,主要是因为我使用 jtl 文件生成测试报告会遇到异常,我看是 Jmeter4.0 里强制写的判断。
同时还有一些附带的原因:
可能我这方面了解的还不多,如果你有好的方式,让 Jmeter4 使用 jtl 来生成测试报告,一定要知道我一下如何做……对平台的结果展示很有用。
//String reportPathDir = csvPath.substring(0, csvPath.lastIndexOf("."));
代码这句有问题,下载报告时报错,不应该只截取到点
我本地执行是正常的。
建议把这种必现问题提到 issue 上吧,然后请详细说明一下报的异常是什么,问题现象是什么,多谢了。
因为我初步判断这里应该不存在兼容性问题。那么我的环境是 OK 的,想不到为什么你那里会失败。
提 issue 吧。
在生成报告的时候,也遇到了 The JMETER_HOME environment variable is not defined correctly
跟楼上那位一样的问题,JMETER_HOME D:\software\apache-jmeter-4.0 没问题
建议直接使用 Jmeter 的脚本命令先试一下生成报告。
生成测试报告是建立在 Jmeter 本身的功能上的。
同时注意运行平台的用户和安装平台的用户权限是否一致。
这个异常信息是 Jmeter 自己打印的,我自己的异常信息都是中文大白话的……。
定时任务那块能讲解下吗?是如何定时执行测试用例吗?
目前的定时压测是使用本身 Jmeter 脚本的自带功能:
其他定时任务是执行平台的方法,需要个人对平台根据需求二次开发,和性能测试关系就不太大了。
还不支持。
不过你这种方式真的是不错的,借助 docker 解决 client 部署的问题,甚至能解决 slave 的重复利用问题(需要测试验证不能贸然使用)。
目前平台还仅仅是支持 slave 的事先部署(也可以用 docker 部署 Jmeter),没有 docker 的这种脚本的自动批量部署和销毁(平台虽然没有但是使用者可以自己实现,然后将数据插入到数据库的 slave 表中即可)。
平台目前的职责非常单一清晰,就是把脚本能页面执行 + 页面监控 + 生成测试报告。脚本的页面执行包含了分布式情况下的执行。分布式环境的其实并不在平台的核心职责之内。
还有一点 就是我看你的 Report 是 Jmeter 自带的实际是性能方向的报告.
能支持接口测试方向的报告么? 比如 ant 那种的 或者 allure 等其他 report 框架那种的.
额,这是一个性能测试平台,不负责接口测试的事情。
接口测试的报告还是接口测试平台来做。
其实平台缺少的是一个调试脚本的手段方式,并且这个需求场景越来越频繁。
依次说一下吧。
ant 主要是卡在脚本执行结果文件格式上了。 ant 需要 jtl,但是测试报告需要 CSV,有冲突。
allure 等的是接口测试平台的职责,作为调试手段不如 ant 了。
MASTER_JMETER_USE_SCRIPT_KEY
TRUE or FALSE
FALSE 时,在服务器进程内启动 JMeter,是什么意思?
调试中遇到个问题,因为在测试计划中有个自用的 JAR 包,只能用本地 JMETER_HOME 这种方式
学习了,感谢楼主分享!!我们公司也准备搭建这样的一个平台~~
说一下我怎么给 Jmeter 改动代码的吧:
你好这是报什么错
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'stressTestController': Unsatisfied dependency expressed through field 'stressTestFileService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'stressTestFileService' defined in file [D:\IdeaProjects\stressTestPlatform\target\classes\io\renren\modules\test\service\impl\StressTestFileServiceImpl.class]: Instantiation of bean failed; nested exception is java.lang.ExceptionInInitializerError
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at io.renren.RenrenApplication.main(RenrenApplication.java:21) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.5.6.RELEASE.jar:1.5.6.RELEASE]
Idea 启动报错,大佬帮忙看下
. ____ _ __ _ _
/\ / ' __ _ ()_ __ __ _ \ \ \ \
( ( )_ | '_ | '| | ' \/ ` | \ \ \ \
\/ _)| |)| | | | | || (| | ) ) ) )
' |__| .|| ||| |_, | / / / /
=========||==============|_/=////
:: Spring Boot :: (v1.5.6.RELEASE)
2020-05-21 09:38:04.816 INFO 56239 --- [ restartedMain] io.renren.RenrenApplication : Starting RenrenApplication on MacBookPro with PID 56239 (/Users/zhangxm/Downloads/Chrome_Download/stressTestPlatform-master/target/classes started by zhangxm in /Users/zhangxm/Downloads/Chrome_Download/stressTestPlatform-master)
2020-05-21 09:38:04.818 INFO 56239 --- [ restartedMain] io.renren.RenrenApplication : No active profile set, falling back to default profiles: default
2020-05-21 09:38:05.626 INFO 56239 --- [ restartedMain] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@359a57ad: startup date [Thu May 21 09:38:05 CST 2020]; root of context hierarchy
2020-05-21 09:38:07.500 WARN 56239 --- [ restartedMain] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [io.renren.RenrenApplication]; nested exception is java.lang.IllegalStateException: Failed to introspect annotated methods on class org.springframework.boot.web.support.SpringBootServletInitializer
2020-05-21 09:38:07.527 ERROR 56239 --- [ restartedMain] o.s.b.f.s.DefaultListableBeanFactory : Destroy method on bean with name 'org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory' threw an exception
java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.context.annotation.AnnotationConfigApplicationContext@359a57ad: startup date [Thu May 21 09:38:05 CST 2020]; root of context hierarchy
at org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:414) [spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.ApplicationListenerDetector.postProcessBeforeDestruction(ApplicationListenerDetector.java:97) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:253) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578) [spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554) [spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:961) [spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523) [spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.destroySingletons(FactoryBeanRegistrySupport.java:230) [spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:968) [spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1030) [spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:556) [spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at io.renren.RenrenApplication.main(RenrenApplication.java:21) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.5.6.RELEASE.jar:1.5.6.RELEASE]
2020-05-21 09:38:07.542 ERROR 56239 --- [ restartedMain] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [io.renren.RenrenApplication]; nested exception is java.lang.IllegalStateException: Failed to introspect annotated methods on class org.springframework.boot.web.support.SpringBootServletInitializer
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:181) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:308) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:228) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:270) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:93) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:687) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:525) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at io.renren.RenrenApplication.main(RenrenApplication.java:21) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.5.6.RELEASE.jar:1.5.6.RELEASE]
Caused by: java.lang.IllegalStateException: Failed to introspect annotated methods on class org.springframework.boot.web.support.SpringBootServletInitializer
at org.springframework.core.type.StandardAnnotationMetadata.getAnnotatedMethods(StandardAnnotationMetadata.java:163) ~[spring-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.retrieveBeanMethodMetadata(ConfigurationClassParser.java:380) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:314) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:198) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:167) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
... 17 common frames omitted
Caused by: java.lang.NoClassDefFoundError: javax/servlet/ServletContext
at java.lang.Class.getDeclaredMethods0(Native Method) ~[na:1.8.0_121]
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) ~[na:1.8.0_121]
at java.lang.Class.getDeclaredMethods(Class.java:1975) ~[na:1.8.0_121]
at org.springframework.core.type.StandardAnnotationMetadata.getAnnotatedMethods(StandardAnnotationMetadata.java:152) ~[spring-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
... 22 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContext
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_121]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_121]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_121]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_121]
... 26 common frames omitted
百度 springboot java.lang.ClassNotFoundException: javax.servlet.ServletContext