java |
您所在的位置:网站首页 › 打印失败如果重复出现错误怎么解决呢 › java |
场景:
实际项目中,程序操作出了问题,后续要怎么处理是个很重要的问题,如果这个问题是同步操作引起的解决起来比较简单,比如用户注册,如果系统注册失败,后台可以马上返回错误信息,用户也可以马上看到错误点是什么。但是如果是异步操作,比如用户注册成功后,系统异步发送短信给用户,发短信的操作出问题了没有发出去,而且这个操作也不是用户主动操作了,所以可能会出现用户不知道你有这个操作,系统也没办法知道自己操作出了问题,或者说知道了操作出问题后,要考虑怎么处理。 解决方式:可以用消息队列去处理异步请求,但是如果是一些比较小的项目,请求量不大,用消息队列就有点大材小用了,单独用数据库保存也可以,但是也是有点浪费资源了,所以可以用文件来保存这些错误请求信息,采用定时或者说每次执行异步操作时先进行判断,看之前是否有错误请求消息,有的话和当前请求一起重新发起请求。 大致流程图: 我的代码的情况是,异步上传文件到阿里云OSS服务器,通过文件URL(真实有效的,输入到网页上可以看到对应资源的URL)找到文件,然后把文件上传到OSS服务器,如果上传失败,把文件URL信息保存到txt文件中,同时修改静态变量 isHaveDefailUpLoadFile(表示是否有文件上传失败,false为没有,true为有)为true,这样下次有请求进来时,就会根据这个静态变量了解到之前有上传失败的文件,于是会读取文件的信息,重新发起请求(通过静态变量来标识,可以防止每次请求都去读取文件看是否有错误信息,减少资源浪费)。 步骤: 1:配置文件信息 system.properties system.emedical.oosurl=https://diaoguihua.oss-cn-shenzhen.aliyuncs.com/ system.emedical.taskdir=H:/Tomcat/task/配置文件工具类 SysConfig.java:可参考我另一篇博客 https://blog.csdn.net/DGH2430284817/article/details/86521151 2:I/O流工具类 FileUtil.java import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.util.HashSet; import java.util.Set; public class FileUtil { /** * 创建目录 * @param path * @throws Exception */ public static void CreatFileDir(String path) throws Exception { try { File file = new File(path); if(file.getParentFile().isDirectory()){//判断上级目录是否是目录 if(!file.exists()){ //如果文件目录不存在 file.mkdirs(); //创建文件目录 } }else{ throw new Exception("传入目录非标准目录名"); } } catch (Exception e) { throw new Exception("创建目录失败:" + e.getMessage()); } } /** * 创建文件 * @param path * @throws Exception */ public static void CreatFile(String path) throws Exception { try { File file = new File(path); if(file.getParentFile().isDirectory()){//判断上级目录是否是目录 if(!file.exists()){ //如果文件不存在 file.createNewFile(); //创建文件 } }else{ throw new Exception("传入目录非标准文件名"); } } catch (Exception e) { throw new Exception("创建文件失败:" + e.getMessage()); } } /**读文件 * @param path * @return * @throws Exception */ public static Set readFile(String path) throws Exception { FileInputStream fis = null; try { Set list = new HashSet(); File file = new File(path); fis = new FileInputStream(file); InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); BufferedReader br = new BufferedReader(isr); String line = ""; while ((line = br.readLine()) != null) { list.add(line); } br.close(); isr.close(); fis.close(); return list; } catch (Exception e) { throw new Exception("读取文件失败:" + e.getMessage()); }finally { fis.close(); } } /**清空文件 * @param path * @return * @throws Exception */ public static void cleanFile(String path) throws Exception { OutputStream fos = null; try { File file = new File(path); CreatFile(path); fos = new FileOutputStream(file, false); fos.write("".getBytes("UTF-8")); } catch (Exception e) { throw new Exception("保存Oss失败信息失败:" + e.getMessage()); }finally { fos.close(); } } /**写文件 (一行) * @param path * @return * @throws Exception */ public static void writeFileOneLine(String path , String Msg) throws Exception { OutputStream fos = null; try { File file = new File(path); CreatFile(path); fos = new FileOutputStream(file, true); fos.write((Msg + "\r\n").getBytes("UTF-8")); } catch (Exception e) { throw new Exception("写文件 (一行)失败:" + e.getMessage()); }finally { fos.close(); } } }
3:上传文件工具类 OOSUtil.java import java.io.File; import java.io.InputStream; import java.net.URL; import java.net.URLEncoder; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.aliyun.oss.OSSClient; import com.ft.emedical.config.SysConfig; public class OOSUtil extends Thread{ private static Log log = LogFactory.getLog(OOSUtil.class); private static boolean isHaveDefailUpLoadFile = false;//是否之前有上传OSS失败的文件 private String UrlMsg; private OOSUtil() { } /** * @param UrlMsg 文件url */ public OOSUtil(String UrlMsg) { this.UrlMsg = UrlMsg; } @Override public void run() { if(isHaveDefailUpLoadFile){//判断之前有没有上传失败的文件 UpLoadDefailFile();//先把以前的失败文件重新上传 } OSSupLoadFileByUrl(this.UrlMsg);//上传文件到OSS服务器 } private static void OSSupLoadFileByUrl(String UrlMsg) { log.info("上传OSS文件:" + UrlMsg); // Endpoint以杭州为例,其它Region请按实际情况填写。 String endpoint = "https://oss-cn-shenzhen.aliyuncs.com"; // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建。 String accessKeyId = "your-accessKeyId"; String accessKeySecret = "your-accessKeySecret"; // 创建OSSClient实例。 OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret); try { String source = UrlMsg.substring(0,UrlMsg.indexOf("upload/")+16) + URLEncoder.encode(UrlMsg.substring(UrlMsg.indexOf("upload/")+16), "utf-8"); URL url = new URL(source); InputStream inputStream = url.openStream(); ossClient.putObject("xylcdn", UrlMsg.substring(UrlMsg.indexOf("upload/")), inputStream); } catch (Exception e) {//保存失败的上传OSS文件信息 log.error("上传Oss失败:" + e.getMessage()); isHaveDefailUpLoadFile = true; File newfile = new File(SysConfig.TASKDIR + "NotUpLoadFile.txt" ); try { FileUtil.CreatFileDir(SysConfig.TASKDIR); FileUtil.writeFileOneLine(SysConfig.TASKDIR+"NotUpLoadFile.txt" , UrlMsg ); } catch (Exception e1) { log.error("保存Oss失败信息失败:" + e1.getMessage()); } } finally { // 关闭OSSClient。 ossClient.shutdown(); } } /**重新上传以前上传OSS失败的文件 * */ private void UpLoadDefailFile() { Set aa; try { //读取OSS上传失败文件信息 aa = FileUtil.readFile(SysConfig.TASKDIR + "NotUpLoadFile.txt"); //清空上传失败信息文件 FileUtil.cleanFile(SysConfig.TASKDIR + "NotUpLoadFile.txt"); for(String value : aa){ log.info("重新上传OSS文件:" + value); OSSupLoadFileByUrl(value); } } catch (Exception e) { log.error("重新上传失败OSS文件失败:" + e.getMessage()); } } }
5:测试方法 public static void main(String[] args) throws Exception { //执行上传OSS文件 new OOSUtil("http://127.0.0.1:8080/medical-web-boss/upload/20190628/1561653493197555.jpg").start(); new OOSUtil("http://127.0.0.1:8080/medical-web-boss/upload/20190628/1561653919242555.jpg").start(); }
6:测试结果(看阿里云是否已经上传文件) 文件已经上传,并且本地保存错误信息文件 NotUpLoadFile.txt 为空:
我们也可以重新测试,把其中一个URL改成不存在的文件地址,模拟上传文件失败 public static void main(String[] args) throws Exception { //执行上传OSS文件 new OOSUtil("http://127.0.0.1:8080/medical-web-boss/upload/20190628/666.jpg").start(); }执行完后就会上传失败,保存到文件中 日志: [Thread-0] INFO com.ft.emedical.util.OOSUtil - 上传OSS文件:http://127.0.0.1:8080/medical-web-boss/upload/20190628/666.jpg [Thread-0] ERROR com.ft.emedical.util.OOSUtil - 上传Oss失败:Connection refused: connect文件NotUpLoadFile.txt: |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |