原文地址:http://blog.csdn.net/kaluman/article/details/74535495
开头的注意事项:
1、所有的环境变量和代码,都需要使用英文的符号,变量之间都需要英文分号;隔开。
2、配置环境时,最好切换到英文输入法进行,以免由于中文符号出错,不好查找原因。
3、调试时,没有使用命令行工具,一直使用的Xshell。
一、 安装包准备
JDK:jdk1.8.0_91
Ant:apache-ant-1.9.7
Jmeter:apache-jmeter-3.0(还需要下载jmeter的两个插件JMeterPlugins-Extras-1.4.0和JMeterPlugins-Standard-1.4.0)
Jenkins:jenkins-1.651.1
二、 安装JDK
安装时,一直点下一步就可以,也可以选择自己想安装的目录进行安装。
1、配置JAVA_HOME变量:
桌面右键计算机=>属性=>高级系统设置=>环境变量=>系统变量=>新建
变量名为JAVA_HOME 变量值填写jdk安装路径,如果安装多个jdk版本,在此处写哪个路径就可直接变更jdk版本
2、系统变量=>Path,双击打开编辑
在变量值最后输入 %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
注意,所有变量值之间都必须有英文分号;隔开
3、系统变量=>新建CLASSPATH变量,若有则直接编辑
变量值:.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar
注意:最前面有一个英文句号“.”。
4、打开命令行,输入java-version,会打印出当前JDK的版本号
三、 安装Jmeter
1、 直接解压Jmeter压缩包,就算安装成功了
2、Jmeter插件的安装。
解压JMeterPlugins-Extras-1.4.0.zip、JMeterPlugins-Standard-1.4.0.zip,将两个文件夹lib\ext目录下的所有文件拷贝到apache-jmeter-3.0\lib\ext目录下;
3、配置Jmeter环境变量
1)新建系统变量,变量名称:JMETER_HOME,变量值:D:\software\apache-jmeter-3.0(Jmeter本地安装路径)
2)在系统变量CLASSPATH中添加
%JMETER_HOME%\lib\ext\ApacheJMeter_core.jar;%JMETER_HOME%\lib\jorphan.jar;%JMETER_HOME%\lib\logkit-2.0.jar;
3)在系统变量中Path中添加%JMETER_HOME%\bin
4)打开命令行,输入jmeter-v,打印出jmeter版本号表示安装成功(若是命令行不支持,则使用别的工具,如Xshell)
四、 安装Ant
1、直接解压apache-ant-1.9.7-bin.zip到想要的目录,就算安装成功了
2、 配置Ant环境变量
1) 新建系统变量:ANT_HOME,变量值为Ant的本地安装路径,如我的:D:\software\apache-ant-1.9.7
2) 在系统变量Path后添加%ANT_HOME%\bin
3)打开命令行,输入ant-version,打印出ant版本号表示配置成功(若是命令行不支持,则使用别的工具,如Xshell)
3、 本地调试使用ant构建运行Jmeter,并且生成jtl、html格式报告
3.1 jmeter默认保存的是.csv格式文件,因此需要把默认的进行修改,找到bin/jmeter.properties文件,修改jmeter.save.saveservice.output_format=xml,需要把前面的注释符去掉
3.2 将apache-jmeter-3.0\extras\ant-jmeter-1.1.1.jar拷贝到apache-ant-1.9.7\lib目录下
3.3 在Xshell或命令行,先进入\apache-jmeter-2.13\extras目录,运行"ant.bat-file build.xml -Dtest=Test" . 查看\apache-jmeter-2.13\extras目录下是否出现Test.jtl、Test.html文件,若有,则构建成功。
到这里出问题了,一直构建失败,提示jtl文件不存在(***.Jtl does not exist),尝试了很多方法,都不行,最后到网上找了一个范例,把build.xml文件整个给改了,然后终于成功了,步骤如下:
1)在本地创建一个存放report的目录;
2)把build.xml和样式文件jmeter-results-detail-report_21.xsl(这个需要自己上网找正确的,不然样式会错)都放入该目录下;
3)自己本地有专门存放脚本的目录,每次要运行哪个目录的脚本,需要去修改build.xml文件脚本文件目录;
4)修改build.xml,代码如下;
5)命令行或者别的工具,进入自己创建的report目录后,执行ant.bat -file build.xml -Dtest=脚本文件名(不需要后缀),发现就能在这个目录生成jtl和html文件了。
附上我的build.xml代码,注意第一行必须顶格,不然会报错:
<?xml version="1.0" encoding="UTF-8"?> <project name="ant-jmeter-test" default="run" basedir="."> <tstamp> <format property="time" pattern="yyyyMMddHHmm" /> </tstamp> <!-- 本地存放报告的路径--> <property name="basedirectory" value="D:\software\workspace\report" /> <!-- 本地存放脚本的路径--> <property name="scriptdirectory" value="D:\scriptFile\jmeter\yuejuanxing" /> <!-- 需要改成自己本地的 Jmeter 目录--> <property name="jmeter.home" value="D:\software\apache-jmeter-3.0" /> <!-- jmeter生成jtl格式的结果报告的路径--> <property name="jmeter.result.jtl.dir" value="${basedirectory}" /> <!-- jmeter生成html格式的结果报告的路径--> <property name="jmeter.result.html.dir" value="${basedirectory}" /> <!-- Name of test (without .jmx) --> <property name="test" value="Test"/> <!-- 生成的报告的前缀--> <property name="ReportName" value="TestReport" /> <property name="jmeter.result.jtlName" value="${jmeter.result.jtl.dir}/${test}.jtl" /> <property name="jmeter.result.htmlName" value="${jmeter.result.html.dir}/${test}.html" /> <path id="xslt.classpath"> <fileset dir="${jmeter.home}/lib" includes="xalan*.jar"/> <fileset dir="${jmeter.home}/lib" includes="serializer*.jar"/> </path> <target name="run"> <antcall target="test" /> <antcall target="report" /> </target> <target name="test"> <taskdef name="jmeter" classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask" /> <jmeter jmeterhome="${jmeter.home}" resultlog="${jmeter.result.jtlName}"> <!-- 声明要运行的脚本。"*.jmx"指包含此目录下的所有jmeter脚本--> <testplans dir="${scriptdirectory}" includes="${test}.jmx" /> </jmeter> </target> <target name="report"> <tstamp> <format property="report.datestamp" pattern="yyyy/MM/dd HH:mm" /></tstamp> <xslt classpathref="xslt.classpath" force="true" in="${jmeter.result.jtlName}" out="${jmeter.result.htmlName}" style="${basedirectory}/jmeter-results-detail-report_21.xsl"> <param name="dateReport" expression="${report.datestamp}"/> </xslt> <copy todir="${jmeter.result.html.dir}"> <fileset dir="${jmeter.home}/extras"> <include name="collapse.png" /> <include name="expand.png" /> </fileset> </copy> </target> </project>
上面代码中,同一个测试脚本生成的报告名一样,假如想每次报告名都不一样,可以把报告名后缀前加上${time},如下,这样生成的文件就会加上报告时间(精确到分)
<property name="jmeter.result.jtlName" value="${jmeter.result.jtl.dir}/${test}${time}.jtl" />
xml的语法,时间格式yyyyMMddHHmm(H大写,是24小时制),yyyyMMddhhmm(h小写,就变为12小时制了),对语法不熟的人,这是个小坑啦。
中间其实还出了一个问题,运行ant一直没调通,我就把jdk改成1.7版本了,并按照上面的步骤做完,发现能运行了,很开心;但乐极生悲,打开jmeter后,发现不能打开脚本文件了,报Could not initialize class org.apache.jmeter.save.SaveService,后来又把jdk版本还原成1.8,然后所有的都好了(各种报错啊,还看不懂,真心累)
此时生成报告的样式如下:
五、配置测试报告样式
之前配置的样式,报告中只有错误多少,没有错误的详细信息,因此把样式进行优化
1、下载样式文件jmeter.results.shanhe.me.xsl ,并把该文件放入正确目录下,我这里是放到我创建的report目录下
2、修改jmeter.properties文件如下部分,我这里基本上都修改成true,这样执行完脚本后就会保存这些结果到.jtl文件里面
jmeter.save.saveservice.data_type=true jmeter.save.saveservice.label=true jmeter.save.saveservice.response_code=true # response_data is not currently supported for CSV output jmeter.save.saveservice.response_data=true # Save ResponseData for failed samples jmeter.save.saveservice.response_data.on_error=false jmeter.save.saveservice.response_message=true jmeter.save.saveservice.successful=true jmeter.save.saveservice.thread_name=true jmeter.save.saveservice.time=true jmeter.save.saveservice.subresults=true jmeter.save.saveservice.assertions=true jmeter.save.saveservice.latency=true jmeter.save.saveservice.connect_time=true jmeter.save.saveservice.samplerData=true jmeter.save.saveservice.responseHeaders=true jmeter.save.saveservice.requestHeaders=true jmeter.save.saveservice.encoding=false jmeter.save.saveservice.bytes=true jmeter.save.saveservice.url=true jmeter.save.saveservice.filename=true jmeter.save.saveservice.hostname=true jmeter.save.saveservice.thread_counts=true jmeter.save.saveservice.sample_count=true jmeter.save.saveservice.idle_time=true
3、修改build.xml文件,把
style="${basedirectory}/jmeter-results-detail-report_21.xsl">
改为:
style="${basedirectory}/jmeter.results.shanhe.me.xsl">
4、执行脚本,生成报告如下,这个报告展示的内容比之前的报告多了很多,定位问题也比较方便直观
这里还遇到了一个问题,我自己的能运行,但我的小伙伴们配置环境时,就一直报错,后来才发现:若是build.xml里的地址,带有特殊符号(中文、下划线之类的),运行时就会报错,然后把目录都变为纯英文和数字的,就成功了,不报错了。
六、安装Jenkins并配置
1、双击jenkins.msi启动安装,安装完成后启动成功
(1)Jenkins服务默认端口为8080,如与其他服务冲突,可在..\Jenkins\jenkins.xml中修改默认端口,如下方的8080改为未被其他服务占用的端口
<executable>%BASE%\jre\bin\java</executable> <arguments>-Xrs -Xmx256m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=8080 --webroot="%BASE%\war"</arguments>
(2)jenkins服务是自动启动的,如想更改为手动启动,计算机图标上点击右键=>管理,找到服务与应用程序,展开后点击服务,在右侧列表找到jenkins服务,双击打开编辑页面,改为手动即可(改为手动后,每次启动,需要手动进入该目录,找到Jenkins后右键=>启动)
2、打开jenkins,首次进入需要先安装插件,首页点击系统设置,然后在右侧选择管理插件,去选择需要的这几个插件安装就ok了,这里用到的插件有如下几个:
PerformancePlugin(jmeter报告需要)、EmailExtension Plugin(邮件需要)、HTML Publisher plugin(可在jenkins中生成单独的测试报告菜单)
3、设置jenkins,系统管理=>系统设置
在Jenkins首页,点击系统管理,然后右侧选择系统设置,进入系统设置页面,前面的不需要改动,往下滑动到JDK安装处
(1)JDK安装,输入jdk版本和jdk安装的目录路径,如下图
(2)ANT安装,输入ant版本和ant安装的目录路径,如下图
(3)Jenkins邮件配置,找到Jenkins location,其中Jenkins URL有默认值,如下图,但是最好修改,默认地址不安全。系统管理员邮件地址也一定要写,否则所发邮件会变为垃圾邮件。
然后往下滑动到下图位置,继续进行邮件设置,这里按照自己实际使用的邮箱进行配置,需要配置的项如下图中有内容的项;
邮件通知,是jenkins自带的基础邮件功能,可以设置构建异常或不稳定时,邮件通知相关人员。设置时,要点击高级展开,然后输入邮箱和密码,选择编码格式,如下图所示
至此,系统设置就设置完成。
七、使用Jenkins,构建项目
1、新建Item
第一次使用Jenkins,需要新建项目,点击左侧菜单的新建,右侧选择构建一个自由风格的软件项目,并根据实际,输入项目名称(若是后续使用,可以选择复制已有的Item,然后进行一些修改),点击ok,进入项目配置页面
2、配置:所有的配置,都要注意该项下方或右方是否有高级选项,有的话都点开看看是否需要配置
(1)需要勾选“丢弃旧的构建”,不然每次构建数据都保存,浪费储存空间,这里保留的个数和天数的数值,根据需要填写
(2)参数化构建过程:
构建时,可能每次构建使用的脚本都不一样,因此把脚本名称参数化,这样会比较方便,具体步骤为:
(a)点击配置进入配置页面,如图中标1的地方
(b)项目名称下面有一个参数化构建过程,勾选后会增加一个添加参数的按钮,点击该按钮弹出参数列表,这里选择choice,如图中标2的地方
(c)choice的使用:图中3是参数名,4是该参数的值列表,一行一个值,可以多行,构建时选择参数就行;5是对这些参数和值的描述
(d)把下面所有用到这个参数testscript的地方,都用 ${testscript}代替,以后想换脚本,直接在参数值处添加或更换就行,不用动其他地方,参数化后用起来很方便。
(3)高级项目选项,点击右侧高级展开,此处选择使用自定义的工作空间,该路径是build.xml文件的根目录
(4)源码管理,高级下方的源码管理选择none,如用到svn或git需要勾选对应选项
(5)构建触发器,源码管理下方的构建触发器,可根据需求选择,因为要做接口自动化,每天定时跑任务并监控,所以这里选择的是Build periodically(定期构建)。
注意:关于定期构建参数的说明:"* * * * *",总共有5个参数,分别代表分(0~59)、时(0~23)、天(1~31)、月(1~12)、周(0~7,0和7表示星期天);
日程表的填写方法,下图是一个填写样例;
(6)增加构建步骤,Execute Windows batch command
此处需要在命令处,添加删除jtl或html的命令,若是想保留所有的jtl和html,则可以不添加删除命令,若是要添加,命令如下;
此处使用的是bat脚本(也可用别的脚本语言),用于删除指定目录里存在的报告,这里的语法,引用参数格式为:%参数名%;模糊匹配格式:**.html(所有html格式的文件)。
del "D:\software\workspace\report"\%testscript%**.jtl del "D:\software\workspace\report"\%testscript%**.html
(7)增加构建步骤,选择Invoke Ant,然后在ant version处,选择之前安装的ant版本即可;
右侧点击高级,展开的页面,在Properties中填写test=xxxx,xxxx是指脚本文件的名字;由于我参数化了,所以此处直接填写test=$testscript
(8)增加构建后操作步骤,Archive the artifacts
用于存档的文件填写**/**.html,模糊匹配html文件,也可以写上具体的文件名如:**/登录.html,参数化以后写成:**/${testscript}*.html
(9)增加构建后操作步骤,publish html reports,index page(s),可以如下图这样写,也可以写上具体的文件名,但写具体的文件名后期得改,不方便;参数化以后写成:${testscript}*.html
这样在Jenkins的项目中,就会出现一个HTML样式测试报告的菜单,点击可在Jenkins中直接预览测试报告
(8)、(9)设置如下图
(10)增加构建后操作步骤,PublishPerformance test result report,Source data files (autodetects format)指jtl源文件,**/xxx.jtl,这里xxx与jmx文件名一致;参数化后,填写:**/${testscript}**.jtl,(模糊匹配),也可以全匹配:**/${testscript}.jtl;
下方还有一个错误比例,现在设置的是0-100,即不管错多少都发邮件,具体设置如下图:
(11)增加构建后操作步骤,E-mail Notification,当构建不稳定或者失败时会通知收件人
(12)增加构建后操作步骤,Editable Email Notification,这个是要给哪些人发送邮件,可以有多个,收件人的邮箱,用英文分号";"间隔
这里将Content Type改为html格式,我们的邮件正文就能呈html格式显示,邮件标题随意设置,正文内容如下,将其粘default content中即可,也可根据需要自己编写、修改:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>${PROJECT_NAME}-第${BUILD_NUMBER}次构建日志</title> </head> <body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" offset="0"> <table width="95%" cellpadding="0" cellspacing="0" style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif"> <tr> <td>(本邮件是程序自动下发的,请勿回复!)</td> </tr> <tr> <td><h2> <font color="#0000FF">构建结果 - ${BUILD_STATUS}</font> </h2></td> </tr> <tr> <td><br /> <b><font color="#0B610B">构建信息</font></b> <hr size="2" width="100%" align="center" /></td> </tr> <tr> <td> <ul> <li>项目名称 : ${PROJECT_NAME}</li> <li>构建编号 : 第${BUILD_NUMBER}次构建</li> <li>触发原因 : ${CAUSE}</li> <li>构建日志 : <a href="${BUILD_URL}console">${BUILD_URL}console</a></li> <li>工作目录 : <a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li> <li>构建 Url : <a href="${BUILD_URL}">${BUILD_URL}</a></li> <li>项目 Url : <a href="${PROJECT_URL}">${PROJECT_URL}</a></li> </ul> </td> </tr> <tr> <td><b><font color="#0B610B">Changes Since Last Successful Build:</font></b> <hr size="2" width="100%" align="center" /></td> </tr> <tr> <td> <ul> <li>历史变更记录 : <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a></li> </ul> ${CHANGES_SINCE_LAST_SUCCESS,reverse=true, format="Changes for Build #%n:<br />%c<br />",showPaths=true,changesFormat="<pre>[%a]<br />%m</pre>",pathFormat=" %p"} </td> </tr> <tr> <td><b>Test Informations</b> <hr size="2" width="100%" align="center" /></td> </tr> <tr> <td><pre style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">Total:${TEST_COUNTS,var="total"},Pass:${TEST_COUNTS,var="pass"},Failed:${TEST_COUNTS,var="fail"},Skiped:${TEST_COUNTS,var="skip"}</pre> <br /></td> </tr> <tr> <td><b><font color="#0B610B">构建日志 (最后 100行):</font></b> <hr size="2" width="100%" align="center" /></td> </tr> <tr> <td><textarea cols="80" rows="30" readonly="readonly" style="font-family: Courier New">${BUILD_LOG, maxLines=100}</textarea> </td> </tr> </table> </body> </html>
在Attachments中填写需要发送的附件名称,构建文件夹下的文件都能当成邮件附件去发送,这里将测试报告名字填入框中即可,我的是参数化+模糊匹配:${testscript}**.html
点击右侧的AdvanceSettings,找到Trigger,点击Add,增加触发器
目前我们常用的是,每次测试的执行结果发送给自己,接口测试执行异常,结果发送至研发人员和自己,所以可添加Always和Failure-Any两种触发器
点击高级,展开的菜单下,填写邮件的各项内容即可(两种触发器都要填,分别填需要发送人员的邮箱,邮件发给多个人时,在Recipient List栏添加多个邮箱,每个邮箱之间以英文逗号“,”隔开);如图
都配置好以后,点击保存或应用,就配置好了一个项目
3、构建项目
项目配置好以后,就可以构建了
(1)没有参数化,构建时,点击左侧的立即构建按钮,就开始构建了;
(2)参数化了,立即构建按钮就变为下图build with parameters参数构建了,点击参数构建,右方会出来参数列表,选择需要构建的参数值,就能选中脚本直接构建了
构建时,有可能会报错,然后返回检查一下系统设置和项目构建,是否有没保存成功的项,有的话再保存一遍,应该就没问题了。我当时遇到的问题,就是邮箱开始配置好了,但是后来没收到邮件,再次去检查,发现系统设置和项目构建里,之前配置的邮箱数据都丢失了,为什么丢了不知道,不过我又配置了一遍,然后发邮件带上附件,就都没问题了
遇到的问题及解决方案
1、在Jenkins上直接预览测试报告时,发现报告的明细无法查看,可参考https://wiki.jenkins.io/display/JENKINS/Configuring+Content+Security+Policy
(1)暂时解决方案,也是最简单的解决方案,就是在Jenkins的系统管理-脚本命令行,输入下面的命令,在构建就成功了
System.setProperty("hudson.model.DirectoryBrowserSupport.CSP","")
(2)永久解决方案,网上找到的方法,Windows的方法是,修改jenkins.xml,把端口这一行代表替换为下方的代码,然后就ok啦
<arguments>-Xrs -Xmx256m -Dhudson.model.DirectoryBrowserSupport.CSP= -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=8080 --webroot="%BASE%\war"</arguments>
Linux的方法有两种
第一种:Jenkins会有一些默认的安全规则集,会影响一些插件的功能,去掉就可以了。启动Jenkins的时候添加参数即可。
- 默认的是:
java -jar /usr/local/Cellar/jenkins-lts/1.651.2/libexec/jenkins.war
- 修改为:
java -Dhudson.model.DirectoryBrowserSupport.CSP= -jar/usr/local/Cellar/jenkins-lts/1.651.2/libexec/jenkins.war
第二种:参考链接 http://blog.csdn.net/hifour/article/details/54947841
步骤1:通过systemctl status jenkins 查看jenkins的启动脚本文件位置
[[email protected] ~]# systemctl status jenkins
● jenkins.service - LSB: Jenkins Continuous Integration Server
Loaded: loaded (/etc/rc.d/init.d/jenkins; bad; vendor preset: disabled)
Active: active (running) since Tue 2017-02-07 15:25:23 CST; 1h 4min ago
Docs: man:systemd-sysv-generator(8)
Process: 936 ExecStart=/etc/rc.d/init.d/jenkins start (code=exited, status=0/SUCCESS)
CGroup: /system.slice/jenkins.service
└─1616 /etc/alternatives/java -Dcom.sun.akuma.Daemon=daemonized -Djava.awt.headless=true -DJENKINS_HOME=/var/lib/jenkins -Dhudson.model.Direc...
步骤2:进入后查看jenkins的启动文件,可以查到jenkins配置文件所在位置。
vim /etc/rc.d/init.d/jenkins
/JENKINS_CONFIG
步骤3:进入配置文件所在位置
vim /etc/sysconfig/jenkins
进入后增加环境变量
HUDSON_OPTIONS="-Dhudson.model.DirectoryBrowserSupport.CSP=\"sandbox; default-src ‘unsafe-inline‘;\""
步骤4:再次进入jenkins启动文件,修改代码,增加HUDSON_OPTIONS变量
vim /etc/rc.d/init.d/jenkins
JAVA_CMD="$JENKINS_JAVA_CMD $JENKINS_JAVA_OPTIONS -DJENKINS_HOME=$JENKINS_HOME$HUDSON_OPTIONS -jar $JENKINS_WAR"
PARAMS="--logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --daemon"
步骤5:重启Jenkins服务,使配置生效。
systemctl restart jenkins
步骤6:查看jenkins服启动参数,配置已生效
/etc/alternatives/java -Dcom.sun.akuma.Daemon=daemonized -Djava.awt.headless=true -DJENKINS_HOME=/var/lib/jenkins-Dhudson.model.DirectoryBrowserSupport.CSP="script-src ‘unsafe-inline‘" -jar /usr/lib/jenkins/jenkins.war --logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --daemon --httpPort=8080 --debug=5 --handlerCountMax=100 --handlerCountMaxIdle=20
步骤7:进入到jenkins的系统管理->脚本命令行,输入命令查看系统属性
System.getProperty("hudson.model.DirectoryBrowserSupport.CSP")
步骤8:可看到配置已修改成功。
2、Jenkins构建后,发现最后一次构建结果把所有的html文件都显示出来了
(1)Archive the artifacts 这个地方,用于存档的文件一开始填写成了**/**.html,模糊匹配html文件,就把所有的html文件都显示出来了,后来改为这个,每次就只显示本次构建的这个脚本的html文件了:**/${testscript}*.html
3、参数化以后,选择非第一个参数构建job时,发现好几个地方以及发送的邮件附件的html格式的报告,都不是最后构建的这份报告,而是最后以第一个参数值构建的报告
在项目的配置里,把参数化的地方,都由$testscript变为${testscript},然后就好了
4、构建job后,发现Performance Trend不显示
5、
原文地址:https://www.cnblogs.com/yrxns/p/8274901.html