Nutch 1.3 学习笔记 10-1 - Ntuch 插件机制简单介绍

来源:互联网 发布:井下电钳网络考试平台 编辑:程序博客网 时间:2024/06/03 11:16

分类: Nutch 590人阅读 评论(0) 收藏 举报
Nutch 1.3 学习笔记 10 -1 - Ntuch 插件机制简单介绍
----------------------------------------
  在Nutch中,大量的可扩展的部分都使用了插件来做,如网页下载时所用的协议选择,解析不同类型的网页,url的过滤和规范化都使用了Nutch的插件机制。
  Nutch中插件的主要目标是:
  1.   可扩展性:用户可以通过实现相应的接口来生成自己的扩展插件
  2.   灵活性:任务人都可以参与插件的编写。
  3.   可维护性:插件的开发者只要实现相应的扩展接口,而不需要关注插件的内部原理。
  下面对其原理和代码做一个简单的分析。

1. 一些概念

1.1 插件仓库(PluginRepository)

插件仓库是一个所有插件的注册器,在系统启动时,这个仓库是通过分析插件目录中所有插件的mainfest文件来生成。对于每一个插件都会生成一个插件描述实例,它包含了每一个插件的元数据,所以插件的真正的实例会在用的时候再来创建,也就是所谓的延迟插件载入机制(lazy plugin loading)。


1.2 插件(Plugin)

Nutch中的插件实际上是一系列自定义逻辑的容器,而这些自定义逻辑为Nutch的核心功能提供扩展和为其它插件提供扩展API。一个插件要提供一个或者一组扩展。而对于扩展点来说(ExtensionPoints)来说,这些扩展都可以被看做是一组可以被动态加载的监听器。每一个具体的插件都扩展自基类Plugin,而这些实例又被用于去管理相关功能的生命周期。插件打开与关闭都由Nutch的插件管理系统来操作。

1.3 扩展(Extension)

扩展相当于一种被安装在具体的扩展点(ExtensionPoint)上的监听描述符,这里的扩展点扮演了一个发布者的角色。


1.4 扩展点(ExtensionPoint)

扩展点提供了一类具体功能扩展的元信息,它包含了具体的扩展。

1.5 插件描述符(PluginDescriptor)

插件描述符提供了一种对于Nutch所插件元数据的一种描述,它包含了国际化资源和插件本自的classloader。而这些元数据包含了插件(Plugin)、插件扩展点(ExtensionPoint)和扩展(Extension).而这里为了能够通过插件描述符来管理元数据,提供了一种延迟加载机制。



2. 使用bin/nutch运行插件

   本机运行出现的帮助
   
[html] view plaincopy
  1. lemo@debian:~/Workspace/java/Apache/Nutch/nutch-1.3$ bin/nutch plugin   
  2.     Usage: PluginRepository pluginId className [arg1 arg2 ...]  

   这里主要有三个参数:
  •    pluginId:这个是插件的id号,它是每一个插件目录中的plugin.xml文件里里面plugin标签中的id属性
  •    className:这是扩展插件的类全
  •    args:这是插件main函数的参数


一个简单的调用protocoal的Http协议的命令:

[html] view plaincopy
  1. bin/nutch plugin protocol-http org.apache.nutch.protocol.http.Http -verbose -timeout 10 http://www.baidu.com      

  •         pluginId: protocol-http
  • className: org.apache.nutch.protocol.http.Http
  • args: -verbos -timeout 10 http://www.baidu.com

这里的输出就是baidu的网页源代码。
下面简单分析一下其调用的源代码。


3. 源代码分析


这是PluginRepository.java中的main函数,上面的bin/nutch plugin命令就是调用这个函数的

[html] view plaincopy
  1. public static void main(String[] args) throws Exception {  
  2.    if (args.length < 2) {  
  3.      System.err  
  4.          .println("Usage: PluginRepository pluginId className [arg1 arg2 ...]");  
  5.      return;  
  6.    }  
  7. // 生成Nutch的配置  
  8. // 这里主要使用的参数是plugin的目录名,还有plugin.includes包含哪些要读取的plugin  
  9.    Configuration conf = NutchConfiguration.create();  
  10. // 根据配置生成一个插件仓库,并且对其进行初始化  
  11.    PluginRepository repo = new PluginRepository(conf);  
  12.    // args[0] - plugin ID  
  13. // 根据插件ID得到特定的插件描述符  
  14.    PluginDescriptor d = repo.getPluginDescriptor(args[0]);  
  15.    if (d == null) {  
  16.      System.err.println("Plugin '" + args[0] + "' not present or inactive.");  
  17.      return;  
  18.    }  
  19. // 从插件描述符对象中得到类加载器  
  20.    ClassLoader cl = d.getClassLoader();  
  21.    // args[1] - class name  
  22.    Class clazz = null;  
  23.    try {  
  24.     // 加载对应的类  
  25.      clazz = Class.forName(args[1], true, cl);  
  26.    } catch (Exception e) {  
  27.      System.err.println("Could not load the class '" + args[1] + ": "  
  28.          + e.getMessage());  
  29.      return;  
  30.    }  
  31.    Method m = null;  
  32.    try {  
  33.     // 得到特定的main方法  
  34.      m = clazz.getMethod("main", new Class[] { args.getClass() });  
  35.    } catch (Exception e) {  
  36.      System.err.println("Could not find the 'main(String[])' method in class "  
  37.          + args[1] + ": " + e.getMessage());  
  38.      return;  
  39.    }  
  40.    String[] subargs = new String[args.length - 2];  
  41.    System.arraycopy(args, 2, subargs, 0, subargs.length);  
  42. // 这里是运行插件的main方法  
  43.    m.invoke(null, new Object[] { subargs });  
  44.  }  




4. 总结

   这里只是对Nutch的插件做一个简单的介绍,下面我们会来自己动手写一个相应的插件,最后我们会看一下其插件的实现原理。

5. 参考

http://wiki.apache.org/nutch/PluginCentral?highlight=%28%28WhichTechnicalConceptsAreBehindTheNutchPluginSystem%29%29
http://www.mikkoo.info/?p=101
http://hi.baidu.com/bupo_jung/blog/item/0603dcd871af2e2033fa1cd5.html
原创粉丝点击