由于 SocketTimeoutException,声纳报告上传失败

Upload of Sonar report fails due to SocketTimeoutException

我们遇到的问题与 Sonar analysis fails with SocketTimeoutException and 中已经讨论过的问题类似,但它发生在我们的 5.6.2 版本中。我们有大量的声纳分析,作为一系列从午夜开始到清晨结束的夜间构建。在报告上传期间,只有第一次分析(有时是前几次分析)受到 SocketTimeoutException 的影响:

[exec] 00:15:33.724 DEBUG: Upload report
[exec] 00:16:34.065 INFO: ------------------------------------------------------------------------
[exec] 00:16:34.065 INFO: EXECUTION FAILURE
[exec] 00:16:34.065 INFO: ------------------------------------------------------------------------
[exec] 00:16:34.065 INFO: Total time: 1:28.329s
[exec] 00:16:34.320 ERROR: Error during SonarQube Scanner execution
[exec] java.lang.IllegalStateException: Fail to request http://mysonar:9000/sonar/api/ce/submit?projectKey=myproject&projectName=myproject
[exec]  at org.sonarqube.ws.client.HttpConnector.doCall(HttpConnector.java:212)
[exec]  at org.sonarqube.ws.client.HttpConnector.post(HttpConnector.java:175)
[exec]  at org.sonarqube.ws.client.HttpConnector.call(HttpConnector.java:146)
[exec]  at org.sonar.batch.bootstrap.BatchWsClient.call(BatchWsClient.java:67)
[exec]  at org.sonar.batch.report.ReportPublisher.upload(ReportPublisher.java:172)
[exec]  at org.sonar.batch.report.ReportPublisher.execute(ReportPublisher.java:127)
[exec]  at org.sonar.batch.phases.PublishPhaseExecutor.publishReportJob(PublishPhaseExecutor.java:64)
[exec]  at org.sonar.batch.phases.PublishPhaseExecutor.executeOnRoot(PublishPhaseExecutor.java:51)
[exec]  at org.sonar.batch.phases.AbstractPhaseExecutor.execute(AbstractPhaseExecutor.java:86)
[exec]  at org.sonar.batch.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:192)
[exec]  at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:142)
[exec]  at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:127)
[exec]  at org.sonar.batch.scan.ProjectScanContainer.scan(ProjectScanContainer.java:241)
[exec]  at org.sonar.batch.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:236)
[exec]  at org.sonar.batch.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:226)
[exec]  at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:142)
[exec]  at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:127)
[exec]  at org.sonar.batch.task.ScanTask.execute(ScanTask.java:47)
[exec]  at org.sonar.batch.task.TaskContainer.doAfterStart(TaskContainer.java:86)
[exec]  at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:142)
[exec]  at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:127)
[exec]  at org.sonar.batch.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:106)
[exec]  at org.sonar.batch.bootstrapper.Batch.executeTask(Batch.java:119)
[exec]  at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:62)
[exec]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[exec]  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[exec]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[exec]  at java.lang.reflect.Method.invoke(Method.java:498)
[exec]  at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
[exec]  at com.sun.proxy.$Proxy0.execute(Unknown Source)
[exec]  at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:233)
[exec]  at org.sonarsource.scanner.api.EmbeddedScanner.runAnalysis(EmbeddedScanner.java:151)
[exec]  at org.sonarsource.scanner.cli.Main.runAnalysis(Main.java:110)
[exec]  at org.sonarsource.scanner.cli.Main.execute(Main.java:74)
[exec]  at org.sonarsource.scanner.cli.Main.main(Main.java:61)
[exec] Caused by: java.net.SocketTimeoutException: timeout
[exec]  at okio.Okio.newTimeoutException(Okio.java:207)
[exec]  at okio.AsyncTimeout.exit(AsyncTimeout.java:261)
[exec]  at okio.AsyncTimeout.read(AsyncTimeout.java:215)
[exec]  at okio.RealBufferedSource.indexOf(RealBufferedSource.java:306)
[exec]  at okio.RealBufferedSource.indexOf(RealBufferedSource.java:300)
[exec]  at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196)
[exec]  at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191)
[exec]  at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:79)
[exec]  at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:909)
[exec]  at com.squareup.okhttp.internal.http.HttpEngine.access0(HttpEngine.java:93)
[exec]  at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:894)
[exec]  at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:748)
[exec]  at com.squareup.okhttp.Call.getResponse(Call.java:277)
[exec]  at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:234)
[exec]  at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:196)
[exec]  at com.squareup.okhttp.Call.execute(Call.java:79)
[exec]  at org.sonarqube.ws.client.HttpConnector.doCall(HttpConnector.java:209)
[exec]  ... 34 more
[exec] Caused by: java.net.SocketException: Socket closed
[exec]  at java.net.SocketInputStream.read(SocketInputStream.java:204)
[exec]  at java.net.SocketInputStream.read(SocketInputStream.java:141)
[exec]  at okio.Okio.read(Okio.java:139)
[exec]  at okio.AsyncTimeout.read(AsyncTimeout.java:211)
[exec]  ... 48 more
[exec] 00:16:34.322 ERROR: 
[exec] 00:16:34.322 ERROR: Re-run SonarQube Scanner using the -X switch to enable full debug logging.
[exec] 00:16:34.320 INFO: Final Memory: 59M/426M
[exec] 00:16:34.320 INFO: ------------------------------------------------------------------------
[exec] Result: 1
[echo] Sonar execution failed, please check the log

通常情况下,上传只需要几毫秒(最大的项目大约需要 200 毫秒),而在这种情况下,超时似乎会在 60 秒后发生(上传 00:15:33,00:16:34 失败) .同时,服务器上的 access.log 显示出一个非常奇怪的模式:POST /sonar/api/ce/submit 在 00:21:39 到达服务器,在初始上传请求后六分钟,在客户端后五分钟收到 TimeoutException(客户端和服务器的时钟完全同步)。

10.0.206.160 - - [13/Mar/2017:00:15:09 +0100] "GET /sonar/batch/project.protobuf?key=myprojectkey HTTP/1.1" 200 2556 "-" "SonarQubeRunner/2.7"
10.0.206.160 - - [13/Mar/2017:00:15:09 +0100] "GET /sonar/api/qualityprofiles/search.protobuf?projectKey=myprojectkey HTTP/1.1" 200 909 "-" "SonarQubeRunner/2.7"
10.0.206.160 - - [13/Mar/2017:00:21:39 +0100] "POST /sonar/api/ce/submit?projectKey=myprojectkey&projectName=myproject HTTP/1.1" 200 60 "-" "SonarQubeRunner/2.7"

更奇怪的是,Sonar GUI 实际上会显示所有分析结果以及初始上传时间的时间戳(在客户端,00:15)并且后台任务视图显示以下时间戳:submitted=12: 15:33 AM,开始 = 12:22:03 AM,完成 = 12:22:08 AM。 基本上,从分析的角度来看,一切正常,但由于超时异常,构建仍然失败。

这个问题是我们的设置所特有的。它是由 Sonar 数据库备份 运行 与一些夜间构建同时引起的。在 mysqldump 运行 创建备份的约 20 分钟内,Sonar 服务完全没有响应,并在客户端尝试上传分析报告时导致 SocketTimeoutException。

这种情况下的解决方案:将数据库备份移动到 Sonar 空闲的时间。