今天排查一个问题,走了一些弯路,总结一下,希望可以为后来者提供参考建议。
问题:
XX反馈,使用OSS PostObject的callback没有发生回调。但是通过putobject用同样的callback是有回调发生的。客户怀疑我们的PostObject有问题。
排查:
OSS回调流程为 客户端->OSS->应用服务器->客户端
创建一台ECS用于当测试应用服务器
创建一个asp.net 的ashx,代码自行实现,用于获取OSS callback参数。
写了两个上传demo
- Putobject (SDK上有示例https://help.aliyun.com/document_detail/32013.html)
PutObjectRequest putObjectRequest=new PutObjectRequest(bucketName, key, new ByteArrayInputStream(content.getBytes()), meta);
Callback callback = new Callback();
callback.setCallbackUrl("http://接收端IP/Revice.ashx");
callback.setCallbackBody("{\\\"mimeType\\\":${mimeType},\\\"size\\\":${size}}");
putObjectRequest.setCallback(callback);
ossClient.putObject(putObjectRequest)
- postobject(post demo,参考https://github.com/aliyun/aliyun-oss-java-sdk/blob/master/src/samples/PostObjectSample.java?spm=a2c4g.11186623.2.11.3bMYXb&file=PostObjectSample.java)
关键代码:
File file = new File(localFile);
String filename = file.getName();
String contentType = new MimetypesFileTypeMap().getContentType(file);
if (contentType == null || contentType.equals("")) {
contentType = "application/octet-stream";
}
StringBuffer strBuf = new StringBuffer();
strBuf.append("\r\n").append("--").append(boundary).append("\r\n");
strBuf.append("Content-Disposition: form-data; name=\"file\"; "+ "filename=\"" + filename + "\"\r\n");
strBuf.append("Content-Type: " + contentType + "\r\n\r\n");
out.write(strBuf.toString().getBytes());
//callback部分
StringBuffer strBuf1 = new StringBuffer();
String callback="{\"callbackUrl\":\"http://应用接收端IP/Revice.ashx\",\"callbackBody\":\"{\\\"bucket\\\"=${bucket},\\\"size\\\"=${size}}\"}";
byte[] textByte = callback.getBytes("UTF-8");
strBuf1.append("\r\n").append("--").append(boundary).append("\r\n");
String callbackstr=new String(Base64.encodeBase64(textByte));
strBuf1.append("Content-Disposition: form-data; name=\"callback\"\r\n\r\n" + callbackstr + "\r\n\r\n");
out.write(strBuf1.toString().getBytes());
//callback部分
DataInputStream in = new DataInputStream(new FileInputStream(file));
int bytes = 0;
byte[] bufferOut = new byte[1024];
while ((bytes = in.read(bufferOut)) != -1) {
out.write(bufferOut, 0, bytes);
}
in.close();
byte[] endData = ("\r\n--" + boundary + "--\r\n").getBytes();
out.write(endData);
out.flush();
out.close();
测试:
Put方式,应用服务器上有OSS的回调请求。
Post方式,应用服务器无任何回调请求
按理说,如果json格式有错误或者回调失败,都应该会返回对应的msg,而上传后一切成功但为什么没有发生回调呢,难道是bug?不太可能,如果是线上bug,工单早就爆了。
检查代码和OSS后端同学沟通。检查到在发送请求时callback的参数是在file下面。
这样就会作为file的一部分。调整一下位置
业务服务器上也如愿的抓到了请求
总结一下就是细心,还是细心。不要急躁多调试,最终会得到想得到的。