解決思路:
原使用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¤tpage=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¤tpage=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¤tpage=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