基于开源搜索引擎的架构设计和J2EE实现(一)

开发 后端
本文介绍了基于开源搜索引擎的架构设计和J2EE实现。搜索引擎技术伴随着WWW的发展是引人注目的。本文主要介绍了搜索引擎的背景与结构,以及网络机器人的概念。

第一章 引言

面对浩瀚的网络资源,搜索引擎为所有网上冲浪的用户提供了一个入口,毫不夸张的说,所有的用户都可以从搜索出发到达自己想去的网上任何一个地方。因此它也成为除了电子邮件以外最多人使用的网上服务。

搜索引擎技术伴随着WWW的发展是引人注目的。搜索引擎大约经历了三代的更新发展:

第一代搜索引擎出现于1994年。这类搜索引擎一般都索引少于1,000,000个网页,极少重新搜集网页并去刷新索引。而且其检索速度非常慢,一般都要等待10秒甚至更长的时间。在实现技术上也基本沿用较为成熟的IR(Information Retrieval)、网络、数据库等技术,相当于利用一些已有技术实现的一个WWW上的应用。在1994年3月到4月,网络爬虫World Web Worm (WWWW)平均每天承受大约1500次查询。

大约在1996年出现的第二代搜索引擎系统大多采用分布式方案(多个微型计算机协同工作)来提高数据规模、响应速度和用户数量,它们一般都保持一个大约50,000,000网页的索引数据库,每天能够响应10,000,000次用户检索请求。1997年11月,当时最先进的几个搜索引擎号称能建立从2,000,000到100,000,000的网页索引。Altavista搜索引擎声称他们每天大概要承受20,000,000次查询。

2000年搜索引擎2000年大会上,按照Google公司总裁Larry Page的演讲,Google正在用3,000台运行Linux系统的个人电脑在搜集Web上的网页,而且以每天30台的速度向这个微机集群里添加电脑,以保持与网络的发展相同步。每台微机运行多个爬虫程序搜集网页的峰值速度是每秒100个网页,平均速度是每秒48.5个网页,一天可以搜集超过4,000,000网页

搜索引擎一词在国内外因特网领域被广泛使用,然而他的含义却不尽相同。在美国搜索引擎通常指的是基于因特网的搜索引擎,他们通过网络机器人程序收集上千万到几亿个网页,并且每一个词都被搜索引擎索引,也就是我们说的全文检索。著名的因特网搜索引擎包括First Search、Google、HotBot等。在中国,搜索引擎通常指基于网站目录的搜索服务或是特定网站的搜索服务,本人这里研究的是基于因特网的搜索技术。

第二章 搜索引擎的结构

2.1系统概述

搜索引擎是根据用户的查询请求,按照一定算法从索引数据中查找信息返回给用户。为了保证用户查找信息的精度和新鲜度,搜索引擎需要建立并维护一个庞大的索引数据库。一般的搜索引擎由网络机器人程序、索引与搜索程序、索引数据库等部分组成。

2.2搜索引擎的构成

2.2.1网络机器人

网络机器人也称为“网络蜘蛛”(Spider),是一个功能很强的WEB扫描程序。它可以在扫描WEB页面的同时检索其内的超链接并加入扫描队列等待以后扫描。因为WEB中广泛使用超链接,所以一个Spider程序理论上可以访问整个WEB页面。

为了保证网络机器人遍历信息的广度和深度需要设定一些重要的链接并制定相关的扫描策略。

2.2.2索引与搜索

网络机器人将遍历得到的页面存放在临时数据库中,如果通过SQL直接查询信息速度将会难以忍受。为了提高检索效率,需要建立索引,按照倒排文件的格式存放。如果索引不及时跟新的话,用户用搜索引擎也不能检索到。

用户输入搜索条件后搜索程序将通过索引数据库进行检索然后把符合查询要求的数据库按照一定的策略进行分级排列并且返回给用户。

2.2.3 Web服务器

客户一般通过浏览器进行查询,这就需要系统提供Web服务器并且与索引数据库进行连接。客户在浏览器中输入查询条件,Web服务器接收到客户的查询条件后在索引数据库中进行查询、排列然后返回给客户端。

2.3搜索引擎的主要指标及分析

搜索引擎的主要指标有响应时间、召回率、准确率、相关度等。这些指标决定了搜索引擎的技术指标。搜索引擎的技术指标决定了搜索引擎的评价指标。好的搜索引擎应该是具有较快的反应速度和高召回率、准确率的,当然这些都需要搜索引擎技术指标来保障。

召回率:一次搜索结果中符合用户要求的数目与用户查询相关信息的总数之比

准确率:一次搜索结果中符合用户要求的数目与该次搜索结果总数之比

相关度:用户查询与搜索结果之间相似度的一种度量

精确度:对搜索结果的排序分级能力和对垃圾网页的抗干扰能力

2.4小节

以上对基于因特网的搜索引擎结构和性能指标进行了分析,本人在这些研究的基础上利用JavaTM技术和一些Open Source工具实现了一个简单的搜索引擎——新闻搜索引擎。在接下来的几章里将会就本人的设计进行详细的分析。

第三章 网络机器人

3.1什么是网络机器人

网络机器人又称为Spider程序,是一种专业的Bot程序。用于查找大量的Web页面。它从一个简单的Web页面上开始执行,然后通过其超链接在访问其他页面,如此反复理论上可以扫描互联网上的所有页面。

基于因特网的搜索引擎是Spider的最早应用。例如搜索巨头Google公司,就利用网络机器人程序来遍历Web站点,以创建并维护这些大型数据库。

网络机器人还可以通过扫描Web站点的主页来得到这个站点的文件清单和层次机构。还可以扫描出中断的超链接和拼写错误等。

3.2网络机器人的结构分析

Internet是建立在很多相关协议基础上的,而更复杂的协议又建立在系统层协议之上。Web就是建立在HTTP ( Hypertext Transfer Protocol ) 协议基础上,而HTTP又是建立在TCP/IP ( Transmission Control Protocol / Internet Protocol ) 协议之上,它同时也是一种Socket协议。所以网络机器人本质上是一种基于Socket的网络程序。

3.2.1如何解析HTML

因为Web中的信息都是建立在HTML协议之上的,所以网络机器人在检索网页时的第一个问题就是如何解析HTML。在解决如何解析之前,先来介绍下HTML中的几种数据。

文本:除了脚本和标签之外的所有数据

注释:程序员留下的说明文字,对用户是不可见的

简单标签:由单个表示的HTML标签

开始标签和结束标签:用来控制所包含的HTML代码

我们在进行解析的时候不用关心所有的标签,只需要对其中几种重要的进行解析即可。

超连接标签

超连接定义了WWW通过Internet链接文档的功能。他们的主要目的是使用户能够任意迁移到新的页面,这正是网络机器人最关心的标签。

图像映射标签

图像映射是另一种非常重要的标签。它可以让用户通过点击图片来迁移到新的页面中。

表单标签

表单是Web页面中可以输入数据的单元。许多站点让用户填写数据然后通过点击按钮来提交内容,这就是表单的典型应用。

表格标签

表格是HTML的构成部分,通常用来格式化存放、显示数据。

我们在具体解析这些HTMl标签有两种方法:通过JavaTM中的Swing类来解析或者通过Bot包中的HTMLPage类来解析,本人在实际编程中采用后者。

Bot包中的HTMLPage类用来从指定URL中读取数据并检索出有用的信息。下面给出该类几种重要的方法。

HTMLPage构造函数 构造对象并指定用于通讯的HTTP对象

Public HTMLPage(HTTP http)

GetForms方法 获取最后一次调用Open方法检索到的表单清单

Public Vector getForms()

GetHTTP方法 获取发送给构造函数的HTTP对象

Public HTTP getHTTP()

GetImage方法 获取指定页面的图片清单

Public Vector getImage()

GetLinks方法 获取指定页面的连接清单

Public Vector getLinks()

Open方法 打开一个页面并读入该页面,若指定了回调对象则给出所有该对象数据

Public void open(String url,HTMLEditorKit.ParserCallback a)

3.2.2 Spider程序结构

网络机器人必须从一个网页迁移到另一个网页,所以必须找到该页面上的超连接。程序首先解析网页的HTML代码,查找该页面内的超连接然后通过递归和非递归两种结构来实现Spider程序。

递归结构

递归是在一个方法中调用自己本身的程序设计技术。虽然比较容易实现但耗费内存且不能使用多线程技术,故不适合大型项目。

非递归结构

这种方法使用队列的数据结构,当Spider程序发现超连接后并不调用自己本身而是把超连接加入到等待队列中。当Spider程序扫描完当前页面后会根据制定的策略访问队列中的下一个超连接地址。

虽然这里只描述了一个队列,但在实际编程中用到了四个队列,他们每个队列都保存着同一处理状态的URL。

等待队列 在这个队列中,URL等待被Spider程序处理。新发现的URL也被加入到这个队列中

处理队列 当Spider程序开始处理时,他们被送到这个队列中

错误队列 如果在解析网页时出错,URL将被送到这里。该队列中的URL不能被移入其他队列中

完成队列 如果解析网页没有出错,URL将被送到这里。该队列中的URL不能被移入其它队列中

在同一时间URL只能在一个队列中,我们把它称为URL的状态。

以上的图表示了队列的变化过程,在这个过程中,当一个URL被加入到等待队列中时Spider程序就会开始运行。只要等待队列中有一个网页或Spider程序正在处理一个网页,程序就会继续他的工作。当等待队列为空并且当前没有任何网页时,Spider程序就会停止它的工作。

3.2.3如何构造Spider程序

在构造Spider程序之前我们先了解下程序的各个部分是如何共同工作的。以及如何对这个程序进行扩展。

流程图如下所示:

IspiderReportable接口

这是一个必须实现的接口,可以通过回调函数接受Spider所遇到的页面。接口定义了Spider向他的控制者发送的几个事件。通过提供对每个事件的处理程序,可以创建各种Spider程序。下面是他的接口声明:

  1. public interface IspiderReportable{   
  2. public boolean foundInternalLink(String url);   
  3. public boolean foundExternalLink(String url);   
  4. public boolean foundOtherLink(String url);   
  5. public void processPage(HTTP page);   
  6. public void completePage(HTTP page,boolean error);   
  7. public boolean getRemoveQuery();   
  8. public void SpiderComplete();   
  9. }  

3.2.4如何提高程序性能

Internet中拥有海量的Web页面,如果开发出高效的Spider程序是非常重要的。下面就来介绍下几种提高性能的技术:

Java的多线程技术

线程是通过程序的一条执行路线。多线程是一个程序同时运行多个任务的能力。它是在一个程序的内部进行分工合作。

优化程序的通常方法是确定瓶颈并改进他。瓶颈是一个程序中最慢的部分,他限制了其他任务的运行。据个例子说明:一个Spider程序需要下载十个页面,要完成这一任务,程序必须向服务器发出请求然后接受这些网页。当程序等待响应的时候其他任务不能执行,这就影响了程序的效率。如果用多线程技术可以让这些网页的等待时间合在一起,不用互相影响,这就可以极大的改进程序性能。

数据库技术

当Spider程序访问一个大型Web站点时,必须使用一种有效的方法来存储站点队列。这些队列管理Spider程序必须维护大型网页的列表。如果把他们放在内存中将会是性能下降,所以我们可以把他们放在数据库中减少系统资源的消耗。

3.2.5网络机器人的代码分析

程序代码实现如下:

  1. package news;   
  2. /**   
  3. * 新闻搜索引擎   
  4. * 计算机99630 沈晨   
  5. * 版本 1.0   
  6. */   
  7. import com.heaton.bot.HTTP;   
  8. import com.heaton.bot.HTTPSocket;   
  9. import com.heaton.bot.ISpiderReportable;   
  10. import com.heaton.bot.IWorkloadStorable;   
  11. import com.heaton.bot.Spider;   
  12. import com.heaton.bot.SpiderInternalWorkload;   
  13. /**   
  14. * 构造一个Bot程序   
  15. */   
  16. public class Searcher   
  17. implements ISpiderReportable {   
  18. public static void main(String[] args) throws Exception {   
  19. IWorkloadStorable wl = new SpiderInternalWorkload();   
  20. Searcher _searcher = new Searcher();   
  21. Spider _spider   
  22. new Spider(_searcher, "http://127.0.0.1/news.htm",   
  23. new HTTPSocket(), 100, wl);   
  24. _spider.setMaxBody(100);   
  25. _spider.start();   
  26. }   
  27. // 发现内部连接时调用,url表示程序发现的URL,若返回true则加入作业中,否则不加入。   
  28. public boolean foundInternalLink(String url) {   
  29. return false;   
  30. }   
  31. // 发现外部连接时调用,url表示程序所发现的URL,若返回true则把加入作业中,否则不加入。   
  32. public boolean foundExternalLink(String url) {   
  33. return false;   
  34. }   
  35. // 当发现其他连接时调用这个方法。其他连接指的是非HTML网页,可能是E-mail或者FTP   
  36. public boolean foundOtherLink(String url) {   
  37. return false;   
  38. }   
  39. // 用于处理网页,这是Spider程序要完成的实际工作。   
  40. public void processPage(HTTP http) {   
  41. System.out.println("扫描网页:" + http.getURL());   
  42. new HTMLParse(http).start();   
  43. }   
  44. // 用来请求一个被处理的网页。   
  45. public void completePage(HTTP http, boolean error) {   
  46. }   
  47. // 由Spider程序调用以确定查询字符串是否应删除。如果队列中的字符串应当删除,方法返回真。   
  48. public boolean getRemoveQuery() {   
  49. return true;   
  50. }   
  51. // 当Spider程序没有剩余的工作时调用这个方法。   
  52. public void spiderComplete() {   
  53. }   
  54. }  

3.3小节

在本章中,首先介绍了网络机器人的基本概念,然后具体分析了Spider程序的结构和功能。在最后还结合具体代码进行了详细说明。

本人在编程中运用了Java技术,主要涉及到了net和io两个包。此外还用了第三方开发包Bot(由Jeff Heaton提供的开发包)。

【编辑推荐】

  1. 学习J2EE必须掌握的36个Package
  2. solaris上开发J2EE应用中文问题的解决
  3. J2EE框架的种类一览
  4. J2EE架构和过程
  5. J2EE架构的6个最佳实践

责任编辑:book05 来源: 百度博客
相关推荐

2009-06-23 08:05:02

搜索引擎

2009-06-23 08:06:46

J2EE体系架构J2EE模型J2EE设计模式

2009-06-22 17:34:40

J2EE架构

2009-06-11 17:11:07

J2EE设计模式工厂模式

2009-06-10 16:25:43

J2EE架构架构

2009-06-23 08:08:45

J2EE体系架构会话面数据访问对象

2009-06-10 14:10:23

J2EE学习J2EE是什么

2009-06-10 13:37:06

J2EE可伸缩性J2EE灵活性J2EE维护

2009-06-11 17:19:47

J2EE设计模式Template

2009-02-23 11:18:06

J2EE架构师Java

2011-06-20 18:23:06

SEO

2009-02-05 10:54:47

登录方式J2EEWeb

2009-06-23 16:48:26

J2EE常见问题J2EE平台

2009-06-19 17:03:44

J2EE学习

2011-04-07 13:05:23

DBSight搜索关系型数据库

2009-06-11 17:06:11

J2EE历史Java EE概述

2009-06-11 17:23:09

J2EE设计模式State模式

2009-06-23 08:03:02

2009-06-10 16:35:26

2009-06-08 21:34:09

J2EEJ2SEJ2ME
点赞
收藏

51CTO技术栈公众号