zoukankan      html  css  js  c++  java
  • 解决在OFFICE平台传输数据慢的问题,使用GZIP+JSON替代WEBSERVICE提供数据

    解决思路:

    原使用Xfire进行webservice数据提供,严重怀疑是这个家伙造成速度慢,所以考虑的思路是以action和json的方式替换掉这个webservice.

    在JAVA端要提供的数据以下面的形式提供:

        /// <summary>
        /// 功能:绑定JS树的数据
        /// 作者:黄海
        /// 时间:2007-11-14
        /// </summary>
        @RequestMapping(value="/getactiontreedata",method=RequestMethod.GET)
        public @ResponseBody String getactiontreedata()
        {
            return sysMenuService.getactiontreedata();
        }

    老框架这么写

        /**
         * 把字符串返回到前台页面,用Ajax时使
         */
        private void responseTxt(String str){
            try {
                ServletActionContext.getResponse().setContentType(
                        "text/html;charset=utf-8");
                PrintWriter pw = ServletActionContext.getResponse().getWriter();
                pw.write(str);
                pw.flush();
                pw.close();
            } catch (Exception e) {
                e.printStackTrace();
            }        
        }

    因为使用的是text/html形式返回,所以Tomcat设置了压缩后就启用了这个形式的压缩。

    这个是以Spring mvc为框架搭建的提供原码,如果是Struts2的旧项目,应该也是提供String返回值,但不能使用@ResponseBody,而是使用responseText函数完成这个操作。如果获取的是一个List<Bean>,List<Map>,Bean等,建议使用fastjson转化为json字符串后进行提供数据。

    提供的测试调用如下图:

     考虑到json的原始数据模型,需要进行数据压缩进行传递,性能才会更好,所以参考设置一下Tomcat中的gzip压缩,不在代码层面采用GZIP压缩办法:

    http://blog.csdn.net/hbcui1984/article/details/5666327

    黄海成功按上面的文章配置了Tomcat启用了GZIP压缩后,检查了下我们两种输出方式的文本格式:

    @ResponseBody


    responseTxt

    直接按上面的链接配置TOMCAT的gzip,会造成只启用了一部分,不是全都能解析,所以黄海的配置如下:

        <Connector port="8400" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443"
                   URIEncoding="utf-8" 
                   compression="on" 
                   compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata" 
                   compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,text/json"/>

    也就是添加了text/json格式,说明这样的也需要进行GZIP压缩处理。

    然后黄海测试了在JAVA中使用HttpClient进行访问有无GZIP两种方式情况下的代码异同点:

     @Test
        public void testGZIPHttpClient() throws IOException {
    
            //Tomct服务器端启动压缩设置的Url地址
            URL url = new URL("http://10.10.3.13:8080/digital/officegetResrouceBase.action?xdkmid=D4F913E3-EA88-4B06-B9FD-3F1C6AE9341A&ts=0&currentpage=1&pagerow=5000");
    
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            //如果这里不设置,返回的就不是gzip的数据了,也就不用解压缩了
            conn.setRequestProperty("Accept-Encoding", "gzip,deflate");
            //构建user-agent头
            //conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Alexa Toolbar; Maxthon 2.0)");
    
            conn.connect();
            InputStream in = conn.getInputStream();
    
            /*经实测试,可以压缩的大小由335K压缩到74KB*/
            //持久化这个流,我们测试一下大小
            /*
            String outPath="c:/2.data";
            FileOutputStream out = new FileOutputStream(new File(outPath));
            int chByte = in.read();
            while (chByte != -1)
            {
                out.write(chByte);
                chByte = in.read();
            }
            out.close();
            */
    
            //无压缩设置时启用下面的代码,关闭以    GZIPInputStream读取的代码
           // BufferedReader bin = new BufferedReader(new InputStreamReader(in,"UTF-8"));
    
            //有GZIP压缩设置时启用下面的代码,关闭上面的无压缩设置代码
            GZIPInputStream gzin = new GZIPInputStream(in);
            BufferedReader bin = new BufferedReader(new InputStreamReader(gzin, "UTF-8"));
    
            String s = null;
            while((s=bin.readLine())!=null)
            {
                System.out.println(s);
            }
        }

    至此,JAVA端的提供服务完成,下面将开始C#客户端接收的部分。

    ================================================================================

    ================================================================================

    ================================================================================

    在C#端调用的示例代码如下:

     private void button1_Click(object sender, EventArgs e)
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:8400/base_db/getactiontreedata.action");
                request.Method = "GET";
                request.ContentType = "text/html;charset=UTF-8";
    
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream myResponseStream = response.GetResponseStream();
                StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
                string retString = myStreamReader.ReadToEnd();
                myStreamReader.Close();
                myResponseStream.Close();
    
                MessageBox.Show(retString);
            }

    执行结果:

     c# 接收到json数据后,采用下面的办法转换为可以理解的对象进行处理:

    http://www.cnblogs.com/txw1958/archive/2012/08/01/csharp-json.html

    如果需要进一步优化,那么需要在JAVA端启用了GZIP压缩方式,这样一来,C#需要使用WEBCLIENT进行调用 ,也需要启用GZIP解压功能,参考下面的链接:

    http://www.2cto.com/kf/201109/106076.html

     ======================================================================================

    附上测试结果:

    1、在xfire提供的webservice情况下,使用的代码:

     @Test
        public void testWEBSERVICE() throws Exception
        {
            //在你的方法第一行加上:
            long a=System.currentTimeMillis();
    
            String webservice_url="http://10.10.3.13:8080/digital/services/IResourceBaseService?wsdl";
            JaxWsDynamicClientFactory dcf=null;
            Client client=null;
            Object[] objects=null;
            dcf = JaxWsDynamicClientFactory.newInstance();
            client = dcf.createClient(webservice_url);
            objects = client.invoke("getResrouceBase","D4F913E3-EA88-4B06-B9FD-3F1C6AE9341A","0",1,5000);
    
            //在最好的一行加上:
            System.out.println("\r<br>执行耗时 : "+(System.currentTimeMillis()-a)/1000f+"");
        }

    执行时间:

    2、换成json+gzip的方法测试代码:

    @Test
        public void testGZIPHttpClient() throws IOException {
    
            //在你的方法第一行加上:
            long a=System.currentTimeMillis();
    
            //Tomct服务器端启动压缩设置的Url地址
            URL url = new URL("http://10.10.3.13:8080/digital/officegetResrouceBase.action?xdkmid=D4F913E3-EA88-4B06-B9FD-3F1C6AE9341A&ts=0&currentpage=1&pagerow=5000");
    
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            //如果这里不设置,返回的就不是gzip的数据了,也就不用解压缩了
            conn.setRequestProperty("Accept-Encoding", "gzip,deflate");
            //构建user-agent头
            //conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Alexa Toolbar; Maxthon 2.0)");
    
            conn.connect();
            InputStream in = conn.getInputStream();
    
            /*经实测试,可以压缩的大小由335K压缩到74KB*/
            //持久化这个流,我们测试一下大小
            /*
            String outPath="c:/2.data";
            FileOutputStream out = new FileOutputStream(new File(outPath));
            int chByte = in.read();
            while (chByte != -1)
            {
                out.write(chByte);
                chByte = in.read();
            }
            out.close();
            */
    
            //无压缩设置时启用下面的代码,关闭以    GZIPInputStream读取的代码
           // BufferedReader bin = new BufferedReader(new InputStreamReader(in,"UTF-8"));
    
            //有GZIP压缩设置时启用下面的代码,关闭上面的无压缩设置代码
            GZIPInputStream gzin = new GZIPInputStream(in);
            BufferedReader bin = new BufferedReader(new InputStreamReader(gzin, "UTF-8"));
    
            //在最好的一行加上:
            System.out.println("\r<br>执行耗时 : "+(System.currentTimeMillis()-a)/1000f+"");
    
    //        String s = null;
    //        while((s=bin.readLine())!=null)
    //        {
    //            System.out.println(s);
    //        }
        }

    执行时间:

    3、使用josn+no gzip的情况下:

    @Test
        public void testGZIPHttpClient() throws IOException {
    
            //在你的方法第一行加上:
            long a=System.currentTimeMillis();
    
            //Tomct服务器端启动压缩设置的Url地址
            URL url = new URL("http://10.10.3.13:8080/digital/officegetResrouceBase.action?xdkmid=D4F913E3-EA88-4B06-B9FD-3F1C6AE9341A&ts=0&currentpage=1&pagerow=5000");
    
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            //如果这里不设置,返回的就不是gzip的数据了,也就不用解压缩了
            //conn.setRequestProperty("Accept-Encoding", "gzip,deflate");
            //构建user-agent头
            //conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Alexa Toolbar; Maxthon 2.0)");
    
            conn.connect();
            InputStream in = conn.getInputStream();
    
            /*经实测试,可以压缩的大小由335K压缩到74KB*/
            //持久化这个流,我们测试一下大小
            /*
            String outPath="c:/2.data";
            FileOutputStream out = new FileOutputStream(new File(outPath));
            int chByte = in.read();
            while (chByte != -1)
            {
                out.write(chByte);
                chByte = in.read();
            }
            out.close();
            */
    
            //无压缩设置时启用下面的代码,关闭以    GZIPInputStream读取的代码
            BufferedReader bin = new BufferedReader(new InputStreamReader(in,"UTF-8"));
    
            //有GZIP压缩设置时启用下面的代码,关闭上面的无压缩设置代码
           // GZIPInputStream gzin = new GZIPInputStream(in);
           // BufferedReader bin = new BufferedReader(new InputStreamReader(gzin, "UTF-8"));
    
            //在最好的一行加上:
            System.out.println("\r<br>执行耗时 : "+(System.currentTimeMillis()-a)/1000f+"");
    
    //        String s = null;
    //        while((s=bin.readLine())!=null)
    //        {
    //            System.out.println(s);
    //        }
        }

    执行时间:

    测试结论:

    视程序部署到哪种网络环境下,

    如果是内网,TOMCAT不必启用GZIP压缩,这样速度反而更快。如果启用了GZIP压缩,那么瓶颈在于压缩和解压的时间,反而慢了下来,考虑到每次5000条的容量不算小了,这样应该算是一个结论了。

    如果是互联网,TOMCAT应启用GZIP压缩,这样因为瓶颈在于网络传输。 

    后来黄海修改了数据的量,改用20000条做为阀值,结果如下:

    webservice:

    no gzip:

    gzip:

    发现5000的阀值偏小,20000与5000差距不大,建议采用更大的阀值,比如20000,采用NO GZIP的方式。

     为什么webservice这么慢呢?

    http://www.tuicool.com/articles/quuyMv

  • 相关阅读:
    centos8网络连接(1)虚拟机网卡和网络编辑器设置
    centos7离线安装ruby
    centos7安装ruby-2.6.5,简单快捷的下载与安装方式
    redis 4.0.13 -- 集群模式
    活了
    世界无我
    markdown_test
    关于mimikatz在webshell运行
    可用性自动化V3
    关于sqlmap常用
  • 原文地址:https://www.cnblogs.com/littlehb/p/3079368.html
Copyright © 2011-2022 走看看