试想一下以下经常碰到的业务环境的解决方案,比如未联网的*****系统:
- 数据集中部署在地级市(如宁波,杭州,温州等),各个地级市数据并不联网
业务目标:查询全国内范围的满足查询条件的数据记录
解决方案:利用地级市提供的查询接口(可能是Web Service为主)开始多线程查询,并异步展现查询结果
开发步骤:
- 如果使用异步Web Service,可以利用Axis2,核心代码如下:
QName qname = new QName(namespace, operateName);
RPCServiceClient client = new RPCServiceClient();
Options options = new Options();
options.setTo(new EndpointReference(srvcUrl));
options.setAction("urn:" + operateName);
client.setOptions(options);
client.invokeNonBlocking(qname, param, new AxisCallback() {
public void onMessage(MessageContext mc) {
//回调处理代码
}
public void onFault(MessageContext messageContext) {
}
public void onError(Exception e) {
e.printStackTrace();
}
public void onComplete() {
}
});
- 如何利用线程池管理多线程,核心代码如下:
public List invokeAll(List<TraversalProvince> tasks, long timeout) {
List nodes = new ArrayList(tasks.size());
try {
List<Future<CityResult>> futures = null;
if (timeout < 0) {
futures = executorService.invokeAll(tasks);
} else {
futures = executorService.invokeAll(tasks, timeout, TimeUnit.MILLISECONDS);
}
for (Future future : futures) {
try {
nodes.add(future.get());
} catch (ExecutionException e) {
e.printStackTrace();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return nodes;
}
- 对结果产生的回调处理:
String taskno = StrCharUtil.formatNullStr(request.getParameter("taskno"));
String callback = StrCharUtil.formatNullStr(request.getParameter("callback"));
for(int i=0;i<10;i++){
Thread.sleep(1000);//10秒内未获取到数据表示失败
String res = StrCharUtil.formatNullStr(cacheTask.get(taskno));
if(!res.equals("")){
if(callback.equals("")){
out.println(res);
}else{
out.println(callback+"("+res+")");
}
return;
}
}
out.println("超时(timeout)");
以下是Log4J跟踪的运行效果:
2010 五月 07 14:08:18 INFO cn.aw.task.REHunt - [14:08:18]接收到新请求:reqid=030c95364050453987c6b9a597e80295id=1,type=null,mode=0,prov=zhejiang,city=ningbo,city=hangzhou,city=shaoxing,city=jinhua,city=zhoushan,prov=shanghai,city=putuo 2010 五月 07 14:08:18 INFO cn.aw.task.TraversalProvince - ================================线程: ningbo 开始处理... 2010 五月 07 14:08:18 INFO cn.aw.task.TraversalProvince - ================================线程: hangzhou 开始处理... 2010 五月 07 14:08:18 INFO cn.aw.task.TraversalProvince - ================================线程: shaoxing 开始处理... 2010 五月 07 14:08:18 INFO cn.aw.task.TraversalProvince - ================================线程: jinhua 开始处理... 2010 五月 07 14:08:18 INFO cn.aw.task.TraversalProvince - ================================线程: zhoushan 开始处理... 2010 五月 07 14:08:18 INFO cn.aw.task.TraversalProvince - ================================线程: putuo 开始处理... 2010 五月 07 14:08:18 INFO cn.aw.servlet.AjaxServlet - 任务缓存大小:0 2010 五月 07 14:08:18 INFO cn.aw.task.CityTask - endTask:ningbo 2010 五月 07 14:08:18 INFO cn.aw.task.CityTask - endTask:putuo 2010 五月 07 14:08:19 INFO cn.aw.task.CityTask - endTask:hangzhou 2010 五月 07 14:08:19 INFO cn.aw.task.CityTask - endTask:shaoxing 2010 五月 07 14:08:19 INFO cn.aw.task.CityTask - endTask:jinhua 2010 五月 07 14:08:19 INFO cn.aw.task.CityTask - 无法查询【zhoushan】的【1】信息,出错 2010 五月 07 14:08:19 INFO cn.aw.task.CityTask - endTask:zhoushan 2010 五月 07 14:08:19 INFO cn.aw.task.REHunt - 开始调用返回URL:http://localhost:8080/ws/ajax... 2010 五月 07 14:08:19 INFO cn.aw.servlet.AjaxServlet - 已缓存结果:030c95364050453987c6b9a597e80295
如果你有更好的思路,欢迎探讨,主要解决查询效率问题和并发问题!