当前位置:编程学习 > JAVA >>

当JAVA WEB服务器端有一个执行时间长的方法,应该如何处理?

背景:开发一个web版的爬虫系统,没用heritrix,nutch等开源框架,采用的是jsp+servlet。

目标:根据指定网址和关键词,爬出与关键词相关的链接还有内容,并将与关键词相关的那部分文本和url存到数据库当中(已使用jsoup除去html标记和js,css之类的,只存文本)。
用户jsp页面输入url,keywords提交post请求,服务器端servlet调用爬虫方法crawer()。

想达到的效果:
1.客户端可以实时观察查询结果,并能暂停或停止该任务。
2.客户端建立任务,这些任务可以定时运行或以排队运行。

开发中遇到的问题:
crawer()方法执行时间很长,而且有请求网址的操作。
如果把该方法放在doPost()中,会发生提交后无法进行其他的操作,
如果以线程的方式启动这个方法,又会发生线程不安全的状况,也就是说这期间有人进行
请求执行了crawer()方法,结果会比较混乱,而servlet本身并非线程安全的。

1.的效果很难达到,暂时的解决方案是craw()方法中想办法,限定爬行深度和爬行网页数目,让它爬完整个网站就停止,有这种网络操作的线程也根本无法被中断掉。
  crawer()实际上使用的深度(纵向)爬取
2.排队这个更难理解,因为通常的java web应用都是请求响应式的,发现servlet和常见的ssh根本不适用眼下的情形。

----------------------------------------------------------------------------------

眼只有我一个人弄这个,精力实在有限。一个多线程就反复看了很多遍,越看越迷糊,结果是像这类带网络访问的没法暂停或停止,只能等它执行完后自己停掉。

想达到这样的一个效果,如果使用开源框架heritrix+lucene,就涉及到了radius和负载均衡之类的,如果想实现任务排队的,倒也有个rabbitMQ,技术多到眼花缭乱,也很不容易上手,而我的这个并不需要性能能有多高,这也是我为什么选用jsp+servlet来做的原因,只求能有点项目的模样。

只能寄希望各位开发大牛,只要能提供一点想法就非常感谢了。

如果你们有这样的一个需求,会考虑什么思路来做?
--------------------编程问答-------------------- servlet里启动独立线程来爬取页面,把爬取进度什么的写到公共数据里,比如静态变量、数据库、文件,随便什么,web端定时刷新请求看爬取进度。 --------------------编程问答--------------------
引用 1 楼 ygycomon 的回复:
servlet里启动独立线程来爬取页面,把爬取进度什么的写到公共数据里,比如静态变量、数据库、文件,随便什么,web端定时刷新请求看爬取进度。


servlet是线程不安全的,如果启动独立线程,当用户提交另一个抓取请求,数据一致性会受到影响,craw()就是抓取方法。 --------------------编程问答--------------------
引用 2 楼 qingfoo 的回复:
Quote: 引用 1 楼 ygycomon 的回复:

servlet里启动独立线程来爬取页面,把爬取进度什么的写到公共数据里,比如静态变量、数据库、文件,随便什么,web端定时刷新请求看爬取进度。


servlet是线程不安全的,如果启动独立线程,当用户提交另一个抓取请求,数据一致性会受到影响,craw()就是抓取方法。


servlet是线程不安全的,你不独立线程就不会影响数据一致性了? --------------------编程问答--------------------
引用 3 楼 ygycomon 的回复:
Quote: 引用 2 楼 qingfoo 的回复:


Quote: 引用 1 楼 ygycomon 的回复:

servlet里启动独立线程来爬取页面,把爬取进度什么的写到公共数据里,比如静态变量、数据库、文件,随便什么,web端定时刷新请求看爬取进度。


servlet是线程不安全的,如果启动独立线程,当用户提交另一个抓取请求,数据一致性会受到影响,craw()就是抓取方法。


servlet是线程不安全的,你不独立线程就不会影响数据一致性了?


首先谢谢你的回答,这是另一个问题了,因为感觉普通的java web程序不能完成这类需求,所以想看看有没其他的好的解决办法。毕竟java出来很多年了,这种问题前人应该早遇到才是,不过在网上找不到。 --------------------编程问答--------------------
引用 4 楼 qingfoo 的回复:
Quote: 引用 3 楼 ygycomon 的回复:

Quote: 引用 2 楼 qingfoo 的回复:


Quote: 引用 1 楼 ygycomon 的回复:

servlet里启动独立线程来爬取页面,把爬取进度什么的写到公共数据里,比如静态变量、数据库、文件,随便什么,web端定时刷新请求看爬取进度。


servlet是线程不安全的,如果启动独立线程,当用户提交另一个抓取请求,数据一致性会受到影响,craw()就是抓取方法。


servlet是线程不安全的,你不独立线程就不会影响数据一致性了?


首先谢谢你的回答,这是另一个问题了,因为感觉普通的java web程序不能完成这类需求,所以想看看有没其他的好的解决办法。毕竟java出来很多年了,这种问题前人应该早遇到才是,不过在网上找不到。


你这个问题就启动独立线程就可以完成了,不管前台提交了多少任务,保护数据一致性是你在爬取的工作线程里都可以做到的

这是服务器的标准模型:servlet是前端接收请求的组件,独立线程是工作线程,然后二者通过共享数据来做数据交互,你可以试一下,有问题,可以再问 --------------------编程问答-------------------- 现在就是采用独立线程来完成的,不知道java有没不用框架就可以实现的对任务排队?把抓取方法放在后台运行且不影响前台操作的。 --------------------编程问答--------------------
引用 6 楼 qingfoo 的回复:
现在就是采用独立线程来完成的,不知道java有没不用框架就可以实现的对任务排队?把抓取方法放在后台运行且不影响前台操作的。


google BlockingQueue --------------------编程问答--------------------
引用 7 楼 ygycomon 的回复:
Quote: 引用 6 楼 qingfoo 的回复:

现在就是采用独立线程来完成的,不知道java有没不用框架就可以实现的对任务排队?把抓取方法放在后台运行且不影响前台操作的。


google BlockingQueue


谢谢!和想象中有些区别,但可以一试
补充:Java ,  Java相关
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,