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

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

我记得在园子里有园友提出博客园的搜索功能是采用的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 实现的是定时器任务,可以按照定时规则按照规定的时间执行任务。

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

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

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

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

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

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • CNN卷积神经网络框架_fpga 神经网络

    CNN卷积神经网络框架_fpga 神经网络理论建立与效果展示正在写。。。环境:Vivado2019.2。Part:xcku040-ffva1156-2-i,内嵌DSP个数1920个,BRAM600个也就是21.1Mb。说明:通过识别加高斯白噪声的正弦波、余弦波、三角波较简单的实例来利用FPGA实现一维CNN网络,主要是实现CNN网络的搭建。也就是将下列数据传输至FPGA,识别出下面哪些是正弦波、余弦波、三角波,通过简单实例实践,在融会贯通。实现流程:训练参数:通过pytorch对10000个训练集进行训练获得训练参数,反向计算不

    2022年9月22日
    4
  • Fork/Join框架阅读笔记[通俗易懂]

    Fork/Join框架阅读笔记[通俗易懂]什么是Fork/Join框架Fork/Join框架是Java 7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干 个小任务,最终汇总每个小任务结果后得到大任务结果的框架。 我们再通过Fork和Join这两个单词来理解一下Fork/Join框架。Fork就是把一个大任务切分 为若干子任务并行的执行,Join就是合并这些子任务的执行结果,最后得到这个大任务的结 果。比如计算1+2+…+10000,可以分割成10个子任务,每个子任务分别对1000个数进行求和, 最终汇总这10个子任务的结果。Fork/

    2022年8月9日
    14
  • android华为账号登陆,华为手机怎么找回华为账号密码?华为账号密码两种找回方法…

    android华为账号登陆,华为手机怎么找回华为账号密码?华为账号密码两种找回方法…忘记华为账号密码真的是一件让人头疼的事,账号绑定的游戏进不去、喜欢的主题无法下载,真是让人干着急,别担心,小编这就整理了一些如何找回华为账号密码的方法,一起来了解下吧!方法一通过华为官方链接找回密码您可以通过此华为官方链接:https://cloud.huawei.com/,点击“忘记密码”找回华为账号密码方法二通过手机客户端重置密码未登录华为帐号:进入手机“设置”>“华为帐号”&gt…

    2022年6月24日
    110
  • Spring Boot 日志管理

    Spring Boot 日志管理在代码有问题的时候,很多人应该都是通过debug的方式去排查,往往忽略了日志的重要性。好的日志管理可以快速定位问题出现的位置,也可以提高代码的阅读性。这篇博文主要介绍一下SpringBoot中关于日志方面的知识。一、Logging介绍SpringBoot为JavaUtilLogging,Log4J2和Logback提供了默认配置。每个日志框架,都默认配置了控…

    2022年5月29日
    62
  • Linux下awk命令简介

    Linux下awk命令简介转载自 http www zsythink net archives 1336 初识 awk 我们先来用专业的术语描述一下 awk 是什么 如果你看不懂 没关系 我们会再用 大白话 解释一遍 awk 是一个报告生成器 它拥有强大的文本格式化的能力 这就是专业的说法 你可能不理解所谓的报告生成器中的 报告 是什么 你可以把 报告 理解为 报表 或者 表格 也就是说 我们可以利用 awk 命令

    2026年1月27日
    1
  • 任务管理器进程中多个chrome.exe的问题

    任务管理器进程中多个chrome.exe的问题

    2021年12月8日
    156

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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