在我的ExecutorService中,只要任务(包含要传输的数据)可用,执行程序就会激活一个线程以向Google Bigquery发送流请求。我发现一段时间后,它抛出异常:
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1371)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1355)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1281)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1256)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:77)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:964)
at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:283)
at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:307)
at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:269)
at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489)
at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:217)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:858)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
at com.geotab.bigdata.bqstream.util.BigqueryHelper.submitStreamRequest(BigqueryHelper.java:79)
at com.geotab.bigdata.bqstream.pipeline.RequestSendTask.run(RequestSendTask.java:47)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
at sun.security.ssl.InputRecord.read(InputRecord.java:505)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:954)
... 26 more
我认为这是因为我没有刷新我的凭据。所以我更新了我的代码如下。但它没有帮助解决问题。我查看了谷歌API文档(https://developers.google.com/drive/web/credentials)。但它只为Web应用程序帐户提供了方法。但我使用的是Java应用程序的服务帐户。
或者我的问题根本不是由于凭证?我该如何解决?
public class BigqueryHelper {
private String mProjectId;
private String mDataset;
private static Bigquery sBIGQUERY = null;
static{
getBigQuery();
}
public BigqueryHelper(String projectId, String dataSet) {
this.mProjectId = projectId;
this.mDataset = dataSet;
getBigQuery();
}
/**
* Insert a list of Rows into BigQuery
*
* @param bigquery
* The Bigquery client
* @param tableId
* The Bigquery tableId
* @param rowList
* The row list to be streamed onto Bigquery
* @throws IOException
* @throws InterruptedException
*/
public void submitStreamRequest(int taskid,String tableId, List<Rows> rowList)
throws IOException {
if (rowList != null && rowList.size() > 0) {
//System.out.println(taskid+"@@"+tableId+","+rowList.size()+"\n"+rowList.get(0).getJson().toString());
try {
TableDataInsertAllRequest request = new TableDataInsertAllRequest()
.setRows(rowList);
TableDataInsertAllResponse response = sBIGQUERY
.tabledata()
.insertAll(mProjectId, mDataset,
tableId, request).execute();
List<TableDataInsertAllResponse.InsertErrors> insertErrors = response
.getInsertErrors();
if (insertErrors != null && insertErrors.size() > 0) {
System.out.println("Failed to insert "
+ insertErrors.size() + " rows. First error: "
+ insertErrors.get(0).toString());
return;
}
}catch (IOException e) {
e.printStackTrace();
if(e instanceof javax.net.ssl.SSLHandshakeException){
synchronized(sBIGQUERY){
refreshBigQuery();
}
}
throw new IOException();
}
}
}
private static void getBigQuery() {
if (sBIGQUERY == null) {
HttpTransport transport = new NetHttpTransport();
List<String> lScope = new ArrayList<String>();
lScope.add(ConfigConstants.SCOPE);
GoogleCredential credential;
try {
credential = new GoogleCredential.Builder()
.setTransport(transport)
.setJsonFactory(ConfigConstants.JSON_FACTORY)
.setServiceAccountId(ConfigConstants.SERVICE_CLIENT_ID)
.setServiceAccountScopes(lScope)
.setServiceAccountPrivateKeyFromP12File(
new File(ConfigConstants.KEY_FILE)).build();
sBIGQUERY = new Bigquery.Builder(transport,
ConfigConstants.JSON_FACTORY, credential)
.setApplicationName("BigQuery-Service-Accounts/0.1")
.setHttpRequestInitializer(credential).build();
} catch (GeneralSecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void refreshBigQuery() {
sBIGQUERY = null;
getBigQuery();
}
}