一次http请求优化

  1. 今天发现一个http请求特别慢,需要耗时7s中才返回数据,于是就想把它优化一下
  2. 第一步,打开浏览器开发者模式,切换到netword下,在地址栏访问接口地址,查看返回数据和耗时,返现返回数据大概2000k左右,耗时7000ms左右
  3. 第二步,怀疑时返回数据太大导致http传输演示,在服务器单把返回的数据改为一个32位的加密字符串,发现时间减少了300ms,看来还有其他原因
  4. 继续排查,查看服务器输出日志sql语句,发现有许多查询数据库操作,查看代码,是for循环遍历查询一个数据表,这个表数据每循环一次,都去根据userid和forderid去查,获得返回数据,很明显数据库操作非常耗时,
  5. 找到问题,然后在代码中执行sql前后添加获取执行代码耗时输出,发现果然是这一出有问题,于是修改代码,先查出表中所有的符合条件userid的数据,然后在需要获取文件夹id处,遍历for循环,获取文件夹,
  6. 修改后,速度由7000ms降为800ms,至于为什么不添加缓存,是因为这个数据表经常变动,再加上还需要调用其他服务接口,加入缓存时导致数据不能及时更新,所以暂时未考虑,
  /**
     * 获取用户自定义模型库json
     * ++
     * 文件组织形式 改成有二级目录的形式
     * 为了兼容现在的目录结构
     * 将现在的目录定义为一级目录
     * 在此基础上 添加二级目录表结构
     * 原文件 定义为 文件结构目录
     * 一级目录可以包含 二级和文件
     * 二级只能包含文件 扩展 二级需要能够兼容无限级目录结构 所以需要有一个父id在其上
     * <p>
     * getMylibJSON3 减少查询数据库,走内存, 处理后耗时由7000ms-->300ms,后续待添加缓存,注意缓存及时更新问题
     */
    public void getMylibJSON3() {
        long t1 = System.currentTimeMillis();

        String floderName = "Floder";
        String userid = this.getPara(0);

        Map ret = new HashMap(); //返回前端数据
        List<Map> diymodelFolder = new ArrayList<>();//自定义模型库
        List industry = new ArrayList();  //工业库

        if (StringUtils.isNotEmpty(userid)) {
            User user = User.dao.getById(userid);
            if (user != null) {

                //预先读取数据库
                List<DIYModel> allDiyModels = DIYModel.dao.getAllModels(userid);
                List<DIYFolder> allDiyFolders = DIYFolder.dao.getAllFolders(userid);

//                =================================所有一级文件夹==========================================================
//                List<DIYFolder> folders = DIYFolder.dao.getDIYFolderByUserId(userid);
                List<DIYFolder> folders = getFolderBypid(userid, allDiyFolders, true); //从内存加载
                // 添加系统文件夹
                DIYFolder buyFolder = new DIYFolder();
                buyFolder.set("id", 0).set("name", "已购买的模型").set("userid", userid);
                folders.add(0, buyFolder);
                DIYFolder uploadFolder = new DIYFolder();
                uploadFolder.set("id", -1).set("name", "已上传的模型").set("userid", userid);
                folders.add(1, uploadFolder);
                DIYFolder copyFolder = new DIYFolder();
                copyFolder.set("id", -2).set("name", "已复制的模型").set("userid", userid);
                folders.add(2, copyFolder);
                DIYFolder photoFolder = new DIYFolder();
                photoFolder.set("id", -3).set("name", "照片建模的模型").set("userid", userid);
                folders.add(3, photoFolder);
                DIYFolder quanjingFolder = new DIYFolder();
                quanjingFolder.set("id", -4).set("name", "已上传的全景球").set("userid", userid);
                folders.add(4, quanjingFolder);

//                ===========================================================================================

                Map folder = null;


                for (DIYFolder f : folders) {
                    // 如果是已上传的模型 由于没有存在数据库 需要通过接口获取
                    folder = new HashMap();
                    folder.put("title", f.get("name"));
                    folder.put("id", f.get("id"));
                    folder.put("type", floderName);

                    if (f.getInt("id").equals(-1)) { // 已上传的模型  耗时120ms左右

                        Pager<Model> sss = ModelSdkKit.findPageByUserId(1, 999, null, userid);
                        List<Map> diymodels = new ArrayList<>();
                        if (sss != null) {
                            Map model;
                            for (Model m : sss.getList()) {
                                model = new HashMap();

                                String modelName = m.getId();
                                try {
                                    if ("max".equals(m.getSource())) {
                                        modelName = m.getInfo().get("max").get("name").toString();
                                    } else if ("umodel".equals(m.getSource())) {
                                        modelName = m.getInfo().get("umodel").get("firm").toString();
                                    } else if ("background".equals(m.getSource())) {
                                        modelName = m.getInfo().get("background").get("name").toString();
                                    } else if ("page".equals(m.getSource())) {
                                        modelName = m.getInfo().get("page").get("name").toString();
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }


                                String chang = m.getChang();
                                chang = (chang == null || chang.equals("")) ? "0" : chang;
                                String kuan = m.getKuan();
                                kuan = (kuan == null || kuan.equals("")) ? "0" : kuan;
                                String gao = m.getGao();
                                gao = (gao == null || gao.equals("")) ? "0" : gao;

                                String size = "[0.1,0.1,0.1]";
                                try {
                                    if (Double.valueOf(kuan) > 1000 || Double.valueOf(gao) > 1000 || Double.valueOf(chang) > 1000) {
                                        size = String.format("[%s,%s,%s]", Double.valueOf(kuan) / 1000, Double.valueOf(gao) / 1000, Double.valueOf(chang) / 1000);
                                    } else {
                                        size = String.format("[%s,%s,%s]", Double.valueOf(kuan), Double.valueOf(gao), Double.valueOf(chang));
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }

                                model.put("id", m.getId());
                                // model.put("_id", m.getId());
                                model.put("title", modelName);
                                model.put("type", "Placement");
                                model.put("dirRules", "");
                                model.put("pay", false);
                                model.put("version", String.valueOf(m.getNewVerNum()));
                                model.put("size", JSONArray.parse(size));
                                diymodels.add(model);
                            }
                        }
                        folder.put("children", diymodels);
                        diymodelFolder.add(folder);

                    } else {
                        // 当前目录的 模型信息
//                        List<DIYModel> sss = DIYModel.dao.getModelsByForlderid(f.get("userid").toString(), f.get("id").toString());
                        List<DIYModel> sss = getModelsByForlderid((f.get("id").toString()), allDiyModels);
                        // 当前目录的 二级文件夹信息
                        String temp_userid = f.get("userid").toString();
                        String temp_pid = f.get("id").toString();
                        List<Map> diymodels = new ArrayList<Map>();
//                        List<DIYFolder> floder2 = DIYFolder.dao.getByFatherFolderId(temp_userid, temp_pid);//从数据库加载
                        List<DIYFolder> floder2 = getFolderBypid(temp_pid, allDiyFolders, false); //从内存加载

                        if (floder2 != null) {
                            Map fo2;
                            for (DIYFolder f2 : floder2) {
                                fo2 = new HashMap();
                                fo2.put("title", f2.get("name"));
                                fo2.put("id", f2.get("id"));
                                fo2.put("type", floderName);
                                // 获取二级目录 模型内容
//                                List<DIYModel> floder2models = DIYModel.dao.getModelsByForlderid(f.get("userid").toString(), f2.get("id").toString());
                                List<DIYModel> floder2models = getModelsByForlderid((f2.get("id").toString()), allDiyModels);

                                List<Map> folder2diymodels = new ArrayList<Map>();
                                if (floder2models != null) {
                                    Map model;
                                    for (DIYModel m : floder2models) {
                                        model = new HashMap();
                                        model.put("id", m.get("mid"));
                                        model.put("_id", m.get("id"));
                                        model.put("title", m.get("name"));
                                        model.put("type", m.get("type"));
                                        model.put("dirRules", m.get("group"));
                                        model.put("pay", m.getInt("pay") == 1);
                                        if (m.getStr("type").equals("Texture")) {
                                            String ext = Files.getFileExtension(m.getStr("mid"));
                                            model.put("id", m.get("mid").toString().replace("." + ext, ""));
                                            model.put("ext", ext);
                                        }
                                        model.put("version", m.getInt("version").intValue() + "");
//                    model.put("size", JsonKit.parse(m.getStr("size"), List.class));
                                        String sizeJson = m.getStr("size");
                                        if (sizeJson != null && sizeJson.startsWith("\"")) {
                                            sizeJson = sizeJson.substring(1, sizeJson.length() - 1);
                                        }
                                        model.put("size", JSONArray.parse(sizeJson));
                                        folder2diymodels.add(model);
                                    }
                                }
                                fo2.put("children", folder2diymodels);
                                diymodels.add(fo2);
                            }
                        }
                        if (sss != null) {
                            long t5 = System.currentTimeMillis();
                            Map model;
                            for (DIYModel m : sss) {
                                model = new HashMap();
                                model.put("id", m.get("mid"));
                                model.put("_id", m.get("id"));
                                model.put("title", m.get("name"));
                                model.put("type", m.get("type"));
                                model.put("dirRules", m.get("group"));
                                model.put("pay", m.getInt("pay") == 1);
                                if (m.getStr("type").equals("Texture")) {
                                    String ext = Files.getFileExtension(m.getStr("mid"));
                                    model.put("id", String.valueOf(m.get("mid").toString()).replace("." + ext, ""));
                                    model.put("ext", ext);
                                }
                                model.put("version", m.getInt("version").intValue() + "");

                                String sizeJson = m.getStr("size");
                                if (sizeJson != null && sizeJson.startsWith("\"")) {
                                    sizeJson = sizeJson.substring(1, sizeJson.length() - 1);
                                }
                                model.put("size", JSONArray.parse(sizeJson));
                                diymodels.add(model);
                            }
                        }

                        folder.put("children", diymodels);//添加一级文件夹下孩纸
                        diymodelFolder.add(folder);//for循环,添加object转map结构文件夹和模型
                    }
                }//for循环结束

                industry = user.getLibs();//存在用户
            }
        }

        ret.put("industry", industry);
        ret.put("custom", diymodelFolder);

        long t2 = System.currentTimeMillis();
        System.out.println(t2 - t1);
        String s1 = DigestUtils.md5Hex(JsonUtils.toJson(ret));
        long t3 = System.currentTimeMillis();

        System.out.println(t3 - t2);

        this.renderJson(s1);
//        this.renderJson(ret);

    }

    /**
     * 通过folderid获取模型,减轻查询数据库压力
     *
     * @param folderid
     * @param allModelByUserId
     * @return
     */
    private List<DIYModel> getModelsByForlderid(String folderid, List<DIYModel> allModelByUserId) {
        List list = new ArrayList();
        for (DIYModel diyModel : allModelByUserId) {
            if (folderid.equals(diyModel.get("folderid").toString())) {
                list.add(diyModel);
            }
        }
        return list;
    }


    /**
     * 通过pid获取子文件夹,减轻查询数据库压力
     *
     * @param pid
     * @param allDiyFolders
     * @return
     */
    private List<DIYFolder> getFolderBypid(String pid, List<DIYFolder> allDiyFolders, boolean isNull) {
        List list = new ArrayList();
        for (DIYFolder diyFolder : allDiyFolders) {
            if (isNull) {//一级文件夹,pid==null
                if (null == diyFolder.get("pid")) {
                    list.add(diyFolder);
                }

            } else {//二级文件夹,pid!=null
                if (null == diyFolder.get("pid")) {
                    continue;
                }
                if (pid.equals(diyFolder.get("pid").toString())) {
                    list.add(diyFolder);
                }

            }
        }
        return list;
    }

猜你喜欢

转载自blog.csdn.net/qq_25385555/article/details/81779764