仿照博客园搜索功能 找找看的实现 发现问题 杂谈

仿照博客园搜索功能 找找看的实现 发现问题 杂谈

我记得在园子里有园友提出博客园的搜索功能是采用的Lucene.net,具体是不是我也不确定,但是宁可信其是,所以我在仿照博客园 搜索功能的时候采用的也是Lucene.net,有园友给我提意见,就是我以前的博客中提到的那些框架,例如log4net,Quartz.net等都是片面的讲解一个框架结构,只能作为练习用,而不能真正的在项目中使用,具体原因就是在实战中会遇到各种问题,没对应的策略,所以今天我就来把我这个仿照系统的搜索功能的实现简单的描述一下,重点说明的是在项目中使用这些框架应该注意的地方,这样才会更贴切实战,也更有用一些。

利用Lucene.net 进行搜索,应该分为三步走战略

  1. 利用IndexWriter进行创建索引
  2. 利用Analyzer对索引进行分词
  3. 利用IndexReader对索引进行提取

总的来说就是这三步,下面我们来具体分析一下这三步在实战中都应该采用什么策略。

首先,创建索引,因为博客会不断的被添加,所以我们在创建索引的时候要指定索引为增量添加(在IndexWriter实例化的时候有一个属性设置为false就可以)

1  Lucene.Net.Store.Directory dir = FSDirectory.Open("d:/index"); 2  IndexWriter writer = new IndexWriter(dir, new PanGuAnalyzer(), false, IndexWriter.MaxFieldLength.LIMITED);

 

设置了创建索引为增量索引以后,我们还需要指定其中的某些参数,让lucene.net在特定的计算机上工作最大化。

现在有一个问题出现了,我们不可能手动的去创建索引,所以我们要使用定时器去自动的创建索引,这就用到了Quartz.net定时器,

还有一个问题就是我们创建索引因为是自动创建,所以不需要界面显示,并且需要在后台运行,所以我们创建索引最好是采用Windows 服务形式来承载。

当然了,在程序运行过程中会遇到各种问题,需要我们记录成粗错误发生的位置以及时间,这就会用到log4net 日志管理框架。

 

问题一个一个的出现了,现在我们就要把这些问题逐个的解决,首先就是创建Windows 服务,这个在Vs中很容易的就可以实现。现在我把仿照博客园实现搜索的Windows服务的部分代码贴出来分析一下,

 1  public partial class Service1 : ServiceBase  2  {  3         private readonly ILog logger = LogManager.GetLogger(typeof(Service1));  4         
 5 
 6         public Service1()  7  {  8  log4net.Config.XmlConfigurator.Configure();  9  InitializeComponent(); 10  SchedulerManager.GetSchedulerFactory().GetScheduler().ListenerManager.AddJobListener(SchedulerManager.GetJobListener()); 11  } 12 
13         protected override void OnStart(string[] args) 14  { 15             try
16  { 17                 JobKey jobKey = new JobKey("CreateIndex", "CreateIndexGroup"); 18 
19                 IJobDetail jobDetail = JobBuilder.Create().WithIdentity(jobKey).OfType(typeof(Jobs.QuzrtaNet)).Build(); 20 
21                 ITrigger trigger = TriggerBuilder.Create().WithCronSchedule("0 0/59 * * * ?").StartNow().Build(); 22  SchedulerManager.GetScheduler().ScheduleJob(jobDetail, trigger); 23                 logger.Info("任务 " + jobDetail.Key.Group + "已经调度陈功"); 24                 if (SchedulerManager.GetScheduler().IsStarted == false) 25  { 26  SchedulerManager.GetScheduler().Start(); 27                     logger.Info("服务已经成功启动"); 28  } 29  } 30             catch (Exception ex) 31  { 32                 logger.Error("服务启动失败", ex); 33                 if (this.CanStop == true) 34  { 35                     this.Stop(); 36  } 37  } 38  } 39 
40         protected override void OnStop() 41  { 42             try
43  { 44                 if (SchedulerManager.GetScheduler().IsShutdown == false) 45  { 46  SchedulerManager.GetScheduler().Shutdown(); 47                     logger.Info("Quartz服务成功终止"); 48  } 49  } 50             catch (Exception ex) 51  { 52                 logger.Error("服务停止失败",ex); 53  } 54 
55  } 56         protected override void OnPause() 57  { 58             
59  } 60 
61         protected override void OnContinue() 62  { 63             
64  } 65     }

 

 

在上面额代码中,有几点我要说明一下。

  1. 对于log4net 需要在程序启动的时候进行配置log4net.Config.XmlConfigurator.Configure();这句代码一定不能少,否则log4net就不会根据配置文件进行更改其特性
  2. 对于Quartz.net的操作,我们利用单例模式来获取对象的实例,因为在Quartz.net 3.0中的很多接口方法都已经改变,所以如果你采用的是最新版的版

    本,那么你可能要进行一些修改,你可以看到我现在的写法和园子里其他园友的写法有所不同,这都不是什么问题,因为接口方法更改了。

    在quartz.net 中通过继承IJOb接口来实现一个任务,我们在Windows 服务启动的时候可以定时执行多个任务。这就会遇到一个问题,例如,你规定了

    一个trigger的周期为1分钟,那么触发器没隔一分钟就胡执行一次这个任务,但是你的这个任务的执行需要一个小时的时间?这时你看会出现什么问题?

    触发器没一分钟触发一次,但是任务会执行一个小时。这个问题我曾经想过,但是也没找到很完美的解决方案,最好的办法可能就是把触发器的触发周期

    调长,比如调成每天执行一次,这样就可以避免多次触发的问题。

  3. 我们再来注意一下log4net,这个框架会根据配置文件来动态的输出日志到不同的介质,但是在我们配置log4net的时候,一定要注意精确,因为一点的拼

    写错误都会导致log4net 不能正常工作。

     1  <configSections>
     2     <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
     3   </configSections>
     4   <log4net debug="false">
     5     <appender name="LogFileAppender" type="log4net.Appender.FileAppender">
     6       <param name="File" value="c:\Log\DBLog.txt"/>
     7       <param name="AppendToFile" value="true"/>
     8       <layout type="log4net.Layout.PatternLayout">
     9         <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n"/>
    10       </layout>
    11     </appender>
    12 
    13     <appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
    14       <bufferSize value="10"/>
    15       <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
    16       <connectionString value="server=.\sqlexpress;database=DbLog;user id=sa;password=yuanjinzhou"/>
    17       <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)"/>
    18       <parameter>
    19         <parameterName value="@log_date"/>
    20         <dbType value="DateTime"/>
    21         <layout type="log4net.Layout.RawTimeStampLayout"/>
    22       </parameter>
    23       <parameter>
    24         <parameterName value="@thread"/>
    25         <dbType value="String"/>
    26         <size value="255"/>
    27         <layout type="log4net.Layout.PatternLayout">
    28           <conversionPattern value="%thread"/>
    29         </layout>
    30       </parameter>
    31       <parameter>
    32         <parameterName value="@log_level"/>
    33         <dbType value="String"/>
    34         <size value="50"/>
    35         <layout type="log4net.Layout.PatternLayout">
    36           <conversionPattern value="%level"/>
    37         </layout>
    38       </parameter>
    39       <parameter>
    40         <parameterName value="@logger"/>
    41         <dbType value="String"/>
    42         <size value="255"/>
    43         <layout type="log4net.Layout.PatternLayout">
    44           <conversionPattern value="%logger"/>
    45         </layout>
    46       </parameter>
    47       <parameter>
    48         <parameterName value="@message"/>
    49         <dbType value="String"/>
    50         <size value="4000"/>
    51         <layout type="log4net.Layout.PatternLayout">
    52           <conversionPattern value="%message"/>
    53         </layout>
    54       </parameter>
    55       <parameter>
    56         <parameterName value="@exception"/>
    57         <dbType value="String"/>
    58         <size value="2000"/>
    59         <layout type="log4net.Layout.ExceptionLayout"/>
    60       </parameter>
    61     </appender>
    62     <root>
    63       <level value="DEBUG"/>
    64       <appender-ref ref="ADONetAppender"/>
    65       <appender-ref ref="LogFileAppender"/>
    66     </root>
    67   </log4net>

    log4net的输出介质园子里有很多介绍,我这里贴出来配置文件,就是不想有太多人因为拼写错误而导致log4net不能正常工作。其中我要特别强调一下的

    就是log4net输出日志到数据库中,这里面有很多配置参数,其中 

    <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

    connectionType结点中的System.Data后面的Version以后的内容我们一定要添加上,我在多次试验中发现如果后面的版本号不加上的话,log4net不

    会正确的把日志插入到数据库中,而加上版本号就可以,所以当你不能把日志插入到数据库中时,检查一下版本号是否写上。

  4. 另外有一点我想再说一下,就是我们在服务启动的时候为Scheduler添加任务以及触发器,其中任务和触发器是分开的,我们不要在继承自IJOb的任务类

    中添加任何的触发器,因为我发现园子里有园友这样用过,所以我提醒一下各位,触发器和任务是分开的。

  5. 对于Lucene.net如何创建索引以及查询,以及分词,我这里使用的分词插件是盘古分词,这些内容在前面的博客中我有说明过,不再赘述。

总结一下,log4net日志管理框架,可以输出日志到任何的介质,对log4net的配置文件的配置是重点。

Lucene.net可以用来实现创建索引,通过索引进行查询,实现全文检索的功能。

Quartz.net 实现的是定时器任务,可以按照定时规则按照规定的时间执行任务。

根据我在仿照博客园搜索功能中遇到的问题,其实任何一个框架的单纯使用都很简单,但是在实战中如何更加合理的使用这些框架,更加高效的让这些框架协同工

作使我们做项目的时候需要思考的重点,有时候思考 分析一下,甚至总结一下会对自己的能力提升有很大的好处。虽然我在这篇博客中总结的问题不多,但是这

都是我在做项目的时候遇到的问题,困扰了我好几天的时间才发现的原因。

有总结才会有提高,有总结才会有进步,我不敢说通过完善这个仿照博客园的系统我有学习到很多东西,但是我发现了我自己的很多不足,这是很珍贵的,只有发
现不足才可以弥补。

我经常看见有些园友看了一下某个框架的配置文件,在试验的时候能够让框架运行输出自己想要的结果,然后就说掌握了这个框架,这个框架有多么的简单,等等,我都会笑一笑,继续其他的事情。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/110242.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • idea20212.13激活_最新在线免费激活「建议收藏」

    (idea20212.13激活)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.html0BXA05X8YC-eyJsaWN…

  • 刀塔2显示连接服务器调解中,大师调解正在连接至dota2网络 【操作方案】 的具体步骤_…

    刀塔2显示连接服务器调解中,大师调解正在连接至dota2网络 【操作方案】 的具体步骤_…近日有小伙伴发现电脑出现问题了,在突然遇到正在连接至dota2网络时不知所措了,对于正在连接至dota2网络带来的问题,其实很好解决正在连接至dota2网络带来的问题,下面小编跟大家介绍正在连接至dota2网络解决方法:一直卡在正在连接至dota2网络什么情况答:您好,若您运行DOTA2时遇到无法连接到DOTA2网络或一直显示正在连接到DOTA2网络,请您完全关闭DOTA2国服客户端,再重新启…

  • android计算器开发实例_安卓开发计算器代码

    android计算器开发实例_安卓开发计算器代码实习第四天了,第一天熟悉了一下java,这三天学习了解了一下安卓开发的一些基础知识。做了一个小程序—计算器,以此帖来记录一下。也许也有人可以参考一下)功能真的只有最基本哈哈,最最新手的人可以参考hh首先是activity_main.xml的布局代码<GridLayoutxmlns:android=”http://schemas.android.com/apk/res/android”xmlns:tools=”http://schemas.android.com/tools”a

  • objective c源码_以下C代码有哪些错误

    objective c源码_以下C代码有哪些错误我是前言看开源代码时,总会看到一些大神级别的代码,给人眼前一亮的感觉,多数都是被淡忘的C语言语法,总结下objc写码中遇到的各类非主流代码技巧和一些妙用:[娱乐向]objc最短的方法声明[C]结构体的初始化[C]三元条件表达式的两元使用[C]数组的下标初始化[objc]可变参数类型的block[objc]readonly属性支持扩展的写法[C]小括号内联复合表达式[娱乐向]奇葩的C

    2022年10月18日
  • Android——NDK基础概念——ndk-build介绍

    Android——NDK基础概念——ndk-build介绍

  • DotNet开发的微商分销系统源码,微信三级分销系统源码

    DotNet开发的微商分销系统源码,微信三级分销系统源码DotNet开发的微商分销系统源码,微信三级分销系统源码开发环境:vs2017+sqlserver2012部署环境:iis7,.netframework4.0,应用程序池为4.0经典模式。安装请注意:1、将安装目录:UI.Web拷贝到服务器上,搭建站点;1、打开网站xxx.com域名/Installer/Default.aspx,按照安装提示一步一步走(傻瓜式的安装)2、安装完毕后,请打开web.config文件,找到节点:CurDomainUrl,设置vlaue的值…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号