解决思路:
原使用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
|