`

解析Nutch插件系统

阅读更多

    nutch系统架构的一个亮点就是插件,借鉴这个架构我们可以设计出自己的灵活的系统架构,下面就来解析Nutch
的插件系统是怎么回事。

    关于nutch,在这里了解:http://lucene.apache.org/nutch/,目前最新版本是1.0:

    23 March 2009 - Apache Nutch 1.0 Released

    Nutch is open source web-search software. It builds on Lucene Java, adding web-specifics, such as a
crawler, a link-graph database, parsers for HTML and other document formats, etc.
    For more information about Nutch, please see the Nutch wiki:http://wiki.apache.org/nutch/

一、 在Nutch的插件体系架构下,有些术语需要解释:

   1、扩展点(ExtensionPoint )

      扩展点是系统中可以被再次扩展的类或者接口,通过扩展点的定义,可以使得系统的执行过程变得可插入,可
任意变化。
  
   2、扩展 ( Extension )

      扩展式插件内部的一个属性,一个扩展是针对某个扩展点的一个实现,每个扩展都可以有自己的额外属性,用
于在同一个扩展点实现之间进行区分。扩展必须在插件内部进行定义。

   3、插件 ( Plugin )

      插件实际就是一个虚拟的容器,包含了多个扩展 Extension、依赖插件 RequirePlugins 和自身发布的库Runtime,插件可以被启动或者停止。

    Nutch 为了扩展,预留了很多扩展点 ExtenstionPoint,同时提供了这些扩展点的基本实现 Extension,Plugin
用来组织这些扩展,这些都通过配置文件进行控制,主要的配置文件包括了多个定义扩展点和插件(扩展)的配置文
件,一个控制加载哪些插件的配置文件。体系结构图如下:


 

二、插件的内部结构
,如下图:


 

   1. runtime 属性描述了其需要的 Jar 包,和发布的 Jar 包
   2. requires 属性描述了依赖的插件
   3. extension-point 描述了本插件宣布可扩展的扩展点
   4. extension 属性则描述了扩展点的实现

三、插件定义方法 如下:

<plugin
   id="urlfilter-suffix"  插件ID
   name="Suffix URL Filter" 插件名称
   version="1.0.0" 插件版本
   provider-name="nutch.org"> 插件提供者的ID

   <runtime>
      <library name="urlfilter-suffix.jar"> 依赖的JAR包
         <export name="*"/> 发布的JAR包
      </library>
   </runtime>

   <requires>
      <import plugin="nutch-extensionpoints"/> 依赖的插件
   </requires>

   <extension id="org.apache.nutch.net.urlfilter.suffix" 扩展的插件ID
              name="Nutch Suffix URL Filter" 扩展的插件名
              point="org.apache.nutch.net.URLFilter"> 插件的扩展点ID
      <implementation id="SuffixURLFilter" 插件实现ID
                      class="org.apache.nutch.urlfilter.suffix.SuffixURLFilter"/> 实现类
      <!-- by default, attribute "file" is undefined, to keep classic behavior.
      <implementation id="SuffixURLFilter"
                      class="org.apache.nutch.net.SuffixURLFilter">
        <parameter name="file" value="urlfilter-suffix.txt"/>
      </implementation>
      -->
   </extension>

</plugin>
 


四、插件主要配置,在nutch-default.xml里面有:

<!-- plugin properties -->

// 插件所在的目录,缺省位置在 plugins 目录下。
<property>
  <name>plugin.folders</name>
  <value>plugins</value>
  <description>Directories where nutch plugins are located.  Each
  element may be a relative or absolute path.  If absolute, it is used
  as is.  If relative, it is searched for on the classpath.</description>
</property>

// 当被配置为过滤(即不加载),但是又被其他插件依赖的时候,是否自动启动,缺省为 true。
<property>
  <name>plugin.auto-activation</name>
  <value>true</value>
  <description>Defines if some plugins that are not activated regarding
  the plugin.includes and plugin.excludes properties must be automaticaly
  activated if they are needed by some actived plugins.
  </description>
</property>

// 要包含的插件名称列表,支持正则表达式方式定义。
<property>
  <name>plugin.includes</name>
  <value>protocol-http|urlfilter-regex|parse-(text|html|js)|index-(basic|anchor)|query-

(basic|site|url)|response-(json|xml)|summary-basic|scoring-opic|urlnormalizer-(pass|regex|basic)

</value>
  <description>Regular expression naming plugin directory names to
  include.  Any plugin not matching this expression is excluded.
  In any case you need at least include the nutch-extensionpoints plugin. By
  default Nutch includes crawling just HTML and plain text via HTTP,
  and basic indexing and search plugins. In order to use HTTPS please enable
  protocol-httpclient, but be aware of possible intermittent problems with the
  underlying commons-httpclient library.
  </description>
</property>

// 要排除的插件名称列表,支持正则表达式方式定义。
<property>
  <name>plugin.excludes</name>
  <value></value>
  <description>Regular expression naming plugin directory names to exclude. 
  </description>
</property>
 



五、插件主要类 UML 图


 

类包括:

   1. PluginRepository 是一个通过加载 Iconfiguration 配置信息初始化的插件库,里面维护了系统中所有的扩展

点 ExtensionPoint 和所有的插件 Plugin 实例
   2. ExtensionPoint 是一个扩展点,通过扩展点的定义,插件 Plugin 才能定义实际的扩展 Extension,从而实现

扩展,每个 ExtensionPoint 类实例都维护了宣布实现了此扩展点的扩展 Extension.
   3. Plugin 是一个虚拟的组织,提供了一个启动 start 和一个 shutdown 方法,从而实现了插件的启动和停止,

他还有一个描述对象 PluginDescriptor,负责保存此插件相关的配置信息,另外还有一个 PluginClassLoader 负责

此插件相关类和库的加载。


六、插件加载过程时序图:


 


    通过序列图可以发现,Nutch 加载插件的过程需要 actor 全程直接调用每个关联对象,最终得到的是插件的实现
对象。详细过程如下:

   1. 首先通过 PluginRepository.getConf() 方法加载配置信息,配置的内容包括插件的目录,插件的配置文件信息 plugin.properties 等,此时 pluginrepository 将根据配置信息加载各个插件的 plugin.xml,同时根据 Plugin.xml 加载插件的依赖类。
   2. 当 actor 需要加载某个扩展点的插件的时候,他可以:
         1. 首先根据扩展点的名称,通过 PluginRepository 得到扩展点的实例,即 ExtensionPoint 类的实例;
         2. 然后调用 ExtensionPoint 对象的 getExtensions 方法,返回的是实现此扩展点的实例列表
(Extension[]);
         3. 对每个实现的扩展实例 Extension,调用它的 getExtensionInstance() 方法,以得到实际的实现类实
例,此处为 Object;

        4. 根据实际情况,将 Object 转型为实际的类对象类型,然后调用它们的实现方法,例如 helloworld 方法。

七、插件的典型调用方式

private Extension findExtension(String name) throws PluginRuntimeException {

    Extension[] extensions = this.extensionPoint.getExtensions();

    for (int i = 0; i < extensions.length; i++) {
      Extension extension = extensions[i];

      if (contains(name, extension.getAttribute("protocolName")))
        return extension;
    }
    return null;
  }
 
  boolean contains(String what, String where){
    String parts[]=where.split("[, ]");
    for(int i=0;i<parts.length;i++) {
      if(parts[i].equals(what)) return true;
    }
    return false;
  }

 

八、插件类加载机制

    实际整个系统如果使用了插件架构,则插件类的加载是由 PluginClassLoader 类完成的,每个 Plugin 都有自己的 classLoader,此 classloader 继承自 URLClassLoader,并没有做任何事情:

public class PluginClassLoader extends URLClassLoader {
    /**
    * Construtor
    *
    * @param urls
    *          Array of urls with own libraries and all exported libraries of
    *          plugins that are required to this plugin
    * @param parent
    */
    public PluginClassLoader(URL[] urls, ClassLoader parent) {
        super(urls, parent);
    }
} 
 


这个 classloader 是属于这个插件的,它只负责加载本插件相关的类、本地库和依赖插件的发布 (exported) 库,也

包括一些基本的配置文件例如 .properties 文件。

此类的实例化过程:

/**
   * Returns a cached classloader for a plugin. Until classloader creation all
   * needed libraries are collected. A classloader use as first the plugins own
   * libraries and add then all exported libraries of dependend plugins.
   *
   * @return PluginClassLoader the classloader for the plugin
   */
  public PluginClassLoader getClassLoader() {
    if (fClassLoader != null)
      return fClassLoader;
    ArrayList<URL> arrayList = new ArrayList<URL>();
    arrayList.addAll(fExportedLibs);
    arrayList.addAll(fNotExportedLibs);
    arrayList.addAll(getDependencyLibs());
    File file = new File(getPluginPath());
    try {
      for (File file2 : file.listFiles()) {
        if (file2.getAbsolutePath().endsWith("properties"))
          arrayList.add(file2.getParentFile().toURL());
      }
    } catch (MalformedURLException e) {
      LOG.debug(getPluginId() + " " + e.toString());
    }
    URL[] urls = arrayList.toArray(new URL[arrayList.size()]);
    fClassLoader = new PluginClassLoader(urls, PluginDescriptor.class
        .getClassLoader());
    return fClassLoader;
  }

 

    *  首先判断缓存是否存在
    * 加载需要的 Jar 包、自身需要的 Jar 包,依赖插件发布的 Jar 包
    * 加载本地的 properties 文件
    * 构造此 classloader,父 classloader 为 PluginDescriptor 的加载者,通常是 contextClassLoader


九、总结
    Nutch 是一个非常出色的开源搜索框架,它的插件架构更加是它的一个技术亮点,通过此架构,可以保证 Nutch
方便的被灵活的扩展而不用修改原来的代码,通过配置文件可以简单方便的控制加载或者不加载哪些插件,而且这些
都不需要额外的容器支持。这些都是我们在系统架构设计的时候可以学习和参考的有益经验。

  • 大小: 13.6 KB
  • 大小: 17.3 KB
  • 大小: 9.4 KB
  • 大小: 21.2 KB
1
0
分享到:
评论

相关推荐

    Nutch_插件深入研究

    Nutch插件系统的灵活性和强大功能使得Nutch成为了一个极具吸引力的Web爬虫平台。通过深入了解和掌握Nutch插件开发流程,结合Mysql数据存储方案,开发者可以轻松定制和扩展Nutch的功能,满足各种复杂的需求。无论是...

    Nutch插件机制

    Nutch的插件系统是基于Eclipse 2.x插件架构实现的。插件在Nutch中的作用至关重要,所有的解析、索引和搜索功能都是通过不同的插件来完成的。下面详细介绍一些核心概念: - **插件扩展点**:Nutch预定义了一系列扩展...

    nutch的插件机制

    Nutch插件系统的优点包括: - **可扩展性**:通过简单的接口实现,开发者可以轻松地增加新功能,而无需修改Nutch的核心代码。 - **灵活性**:丰富的插件库使得用户可以根据自身需求选择或开发适合的插件。 - **可...

    基于Nutch 的插件系统的原理分析

    为了更好地理解Nutch插件系统的实际应用,我们可以考虑一个具体的例子——添加一个新的文档解析器。 假设我们需要为Nutch添加一个用于解析PDF文档的插件。首先,我们定义一个扩展点`PdfParser`,然后创建一个实现了...

    Nutch插件开发文档

    #### 一、Nutch插件系统概述 Nutch是一款开源的网络爬虫工具,其强大的灵活性与扩展性得益于其独特的插件系统设计。插件(Plugin)作为Nutch的核心组件之一,为用户提供了一种灵活的方式来定制和扩展Nutch的功能。...

    基于ApacheNutch和Htmlunit的扩展实现AJAX页面爬虫抓取解析插件nutch-htmlunit.zip

    由于Nutch运行是基于Unix/Linux环境的,请自行准备Unix/Linux系统或Cygwin运行环境。 git clone整个工程代码后,进行本地git下载目录: cd nutch-htmlunit/runtime/local bin/crawl urls crawl false 1 ...

    mp3文件信息解析-nutch使用

    MP3文件信息解析是音频处理领域的一个重要环节,...这需要对ID3标准有深入理解,并熟悉Nutch的插件体系和解析机制。通过定制`parse-html`,我们可以实现对MP3文件的智能处理,从而更好地服务于音频内容的检索和管理。

    Nutch入门教程 高清 带书签

    四、Nutch插件系统 Nutch的强大之处在于其插件机制,用户可以根据需求编写自己的插件,如自定义解析器、URL过滤器、索引器等。Nutch的核心组件包括:`fetcher`(负责下载网页)、`parse`(解析HTML)、`index`(创建...

    基于Apache Nutch和Htmlunit的扩展实现AJAX页面爬虫抓取解析插件.zip

    【标题】"基于Apache Nutch和Htmlunit的扩展实现AJAX页面爬虫抓取解析插件.zip" 提供了一个深入的爬虫项目实例,旨在解决AJAX动态网页内容的抓取问题。Apache Nutch是一个开源的网络爬虫框架,而Htmlunit是一个无头...

    Nutch_的配置文件

    同时,对于Nutch插件,开发者也需要编写相应的配置文件来设定插件的行为,如设置URL过滤规则、解析策略等。 总之,理解和熟练掌握Nutch的配置文件及其加载机制是有效利用Nutch的关键步骤,它有助于构建高效、定制化...

    nutch

    通过阅读此教程,你可以了解如何搭建 Nutch 爬虫环境,编写自定义插件,以及进行定制化抓取和索引。 总结来说,Nutch 是一个强大的开源网络爬虫工具,借助 Hadoop 实现了大规模的网页抓取和搜索功能。学习和使用 ...

    nutch1.2 java project

    4. **插件系统**:Nutch 的强大之处在于它的插件机制,允许用户自定义处理流程。常见的插件有解析器(如 HTML 解析)、分割器、索引器等。尽管压缩包中未包含插件,但你可以根据需求从 Nutch 的官方网站或其他开源...

    nutch-1.5.1源码

    6. **配置与插件(Configuration & Plugins)**:Nutch允许开发者通过配置文件定制爬虫的行为,并提供了一套插件系统,方便扩展其功能。例如,你可以编写自定义的URL过滤器、解析器或索引增强插件。 在研究Nutch-...

    nutch1.2 java的project

    7. **插件系统**:Nutch支持插件架构,允许用户自定义爬取策略、解析器、索引器等功能。 8. **配置文件**:Nutch的配置文件(如`conf/nutch-site.xml`)非常重要,它们定义了爬虫的行为,如抓取策略、存储路径等。 ...

    nutch开发资料 搜索引擎

    8. **插件系统**:Nutch具有强大的插件架构,允许开发者轻松添加新的功能,如新的解析器、新的索引器或新的URL过滤规则。插件开发可以极大地扩展Nutch的功能。 9. **索引存储**:Nutch通常使用Apache Lucene作为其...

    eclipse配置nutch,eclipse配置nutch

    然而,Nutch的安装和配置可能对初学者来说有些复杂,尤其是在不同的操作系统和开发环境中。因此,利用Eclipse作为开发工具,可以简化Nutch的配置流程,提供一个友好的图形界面来管理项目和代码,同时利用其强大的...

    nutch09版本亲测好用

    Nutch 的核心设计之一是其插件系统,允许用户通过编写插件来扩展其功能,例如添加新的解析器、链接过滤器或索引策略。 9. **应用范围**: Nutch 0.9 适用于需要大规模网页抓取和数据分析的场景,如市场研究、竞争...

Global site tag (gtag.js) - Google Analytics