纵有疾风起
人生不言弃

Lucene.net站内搜索—4、搜索引擎第一版技术储备(简单介绍Log4Net、生产者消费者模式)

目录

Lucene.net站内搜索—1、SEO优化
Lucene.net站内搜索—2、Lucene.Net简介和分词
Lucene.net站内搜索—3、最简单搜索引擎代码
Lucene.net站内搜索—4、搜索引擎第一版技术储备(简单介绍Log4Net、生产者消费者模式)
Lucene.net站内搜索—5、搜索引擎第一版实现
Lucene.net站内搜索—6、站内搜索第二版

我们先来看下百度搜索

Lucene.net站内搜索—4、搜索引擎第一版技术储备(简单介绍Log4Net、生产者消费者模式)插图

用户保存一篇文章就把文章写入索引库

用户输入“我喜欢的季节”也可以搜索出含有“喜欢的”和“季节”的,这里用到了分词。query.Add(new Term(“body’,str))

搜索结果页面显示标题和帖子的一部分(帖子的前100个字)。点击标题可以进入帖子页面。我这里结果页面暂时不用分页。

英文搜索时要转换为小写的,因为盘古分词会默认把英文转化为小写保存。

面试可能会问的问题:Lucene.Net的原理:分词、B+树、索引。

如果搜索结果为空,看看是不是创建索引download下来的是乱码,因为如果download的是乱码,当然搜索不到

显示用Repeater,将搜索结果放到

 public class SearchResultInfo    {        public string URL{get;set;}        public String Title { get; set; }        public String Summary { get; set; }    }List< SearchResultInfo> list = new List< SearchResultInfo>();repeater.DataSource=list;

把list绑定到Repeater,不考虑分页,设置一下Repeater的ItemTempelete

 <asp:Repeater ID=”Repeater1″ runat=”server”>

        <ItemTemplate><a href=”Eval(‘URL’)” /></ItemTemplate>

    </asp:Repeater>

对象中,然后绑定到ListView中,其实用Repeater也可以

 <asp:ListView ID="listResult" runat="server">        <ItemTemplate>            <p>                <a href="<%#Eval("URL") %>"><%#Eval("Title") %></a></p>            <p>                <%#Eval("Summary")%></p>        </ItemTemplate>        <LayoutTemplate>            <asp:PlaceHolder ID="itemPlaceholder" runat="server" />        </LayoutTemplate>        <EmptyDataTemplate>            <p>                No Result</p>        </EmptyDataTemplate>    </asp:ListView>

Log4Net

这里我简单介绍下Log4Net,因为后面用得到。

    Log4Net是用来记录日志的,可以将程序运行过程中的信息输出到一些地方(文件、数据库、EventLog等),日志就是程序的黑匣子,可以通过日志查看系统的运行过程,从而发现系统的问题。日志的作用:将运行过程的步骤、成功失败记录下来,将关键性的数据记录下来分析系统问题所在。Log4J

    对于网站来讲,不能把异常信息显示给用户,异常信息只能记录到日志,出了问题把日志文件发给开发人员,就能知道问题所在。

Log4net的安装:

用户可以从http://logging.apache.org/log4net/下载log4net的源代码。解压软件包后,在解压的src目录下将log4net.sln载入Visual Studio .NET,编译后可以得到log4net.dll。用户要在自己的程序里加入日志功能,只需将log4net.dll引入工程即可。

配置Log4Net环境

  • 新建一个WebApplication
  • 添加对log4net.dll的引用(bin\net\2.0\release)
  • 在Web.Config (或App.Config)添加配置,见备注
  • 初始化:在程序最开始加入log4net.Config.XmlConfigurator.Configure();不要加到页面的Load
  • 在要打印日志的地方LogManager.GetLogger(typeof(Program)).Debug(“信息”); 。通过LogManager.GetLogger传递要记录的日志类类名获得这个类的ILog(这样在日志文件中就能看到这条日志是哪个类输出的了),然后调用Debug方法输出消息。因为一个类内部不止一个地方要打印日志,所以一般把ILog声明为一个static字段。
  • 输出错误信息用ILog.Error方法,第二个参数可以传递Exception对象。log.Error(“***错误”+ex),log.Error(“***错误”,ex)
  • 测试代码:见下面。
    log("准备执行数据库清理"+DateTime.Now);try{clear();log("清理成功"+DateTime.Now);}catch(Excepion ex){log("清理失败"+DateTime.Now+ex);}

    在VS2010中的控制台项目引用Log4Net的时候要将项目的“目标框架”改为非“Client Profile”

    备注:

    1、Log4Net配置

    <configuration>  <configSections>    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>  </configSections>  <log4net>    <!-- Define some output appenders -->    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">      <file value="test.txt"/>      <appendToFile value="true"/>      <maxSizeRollBackups value="10"/>      <maximumFileSize value="1024KB"/>      <rollingStyle value="Size"/>      <staticLogFileName value="true"/>      <layout type="log4net.Layout.PatternLayout">        <conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>      </layout>    </appender>    <root>      <level value="DEBUG"/>      <appender-ref ref="RollingLogFileAppender"/>    </root>  </log4net></configuration>

    2、完整示例

     class Program    {        private static ILog log = LogManager.GetLogger(typeof(Program));        static void Main(string[] args)        {            log4net.Config.XmlConfigurator.Configure();            log.Debug("开始运行");            string s = Console.ReadLine();            log.Debug("用户输入:"+s);            try            {                int i = Convert.ToInt32(s);            }            catch (Exception ex)            {                log.Error("用户输入的数据错误:" + s, ex);            }            Console.ReadKey();            log.Debug("程序退出");        }

    生产者消费者模式

  • 生产者、消费者模式:生产者、消费者不用互相等待,用仓库做缓冲。简单原理性代码见备注

  • 举例:多线程操作同一个文件时会出现并发问题。解决的一个办法就是给文件加锁(lock),但是这样的话,一个线程操作文件时,其它的都得等待,这样的话性能非常差。另外一个解决方案,就是先将数据放在队列中,然后开启一个线程,负责从队列中取出数据,再写到文件中。
  • 因为同时只能有一个线程对索引库进行写操作,所以以一种策略(联想火车中等厕所可用,红灯/绿灯就是标志是否有人在用)是一直检测是否厕所可用,带来的问题就是效率低;另外一种策略就是委托给乘务员排队处理,这样就可以去干别的。

  • 队列(先入先出):Queue、ConcurrentQueue(*线程安全,多线程中用这个)。栈(*):Stack:先进后出。

  • 发邮件、发短信偶尔会遇到半个小时才收到的情况就是在排队处理。

    Demo:

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;namespace 生产者消费者模式{    class Program    {        //仓库        static List<int> list = new List<int>();        static void Main(string[] args)        {            //while (true)            //{            //    Console.WriteLine("请输入一个数字");            //    int i = Convert.ToInt32(Console.ReadLine());            //    耗时操作.Process(i);            //}            //消费线程            Thread thread = new Thread(ThreadRun);            thread.Start();            //生产线程            while (true)            {                Console.WriteLine("请输入一个数字");                int i = Convert.ToInt32(Console.ReadLine());                list.Add(i);//把任务放入仓库            }        }        static void ThreadRun()        {            while (true)            {                //如果仓库中有产品,就消费                if (list.Count > 0)                {                    int i = list[0];//有线程安全问题                    list.RemoveAt(0);//消费完毕后从仓库移除                    Thread.Sleep(5000);//模拟耗时操作.Process(i);                }            }        }    }}

     

文章转载于:https://www.cnblogs.com/jiekzou/p/4372399.html

原著是一个有趣的人,若有侵权,请通知删除

未经允许不得转载:起风网 » Lucene.net站内搜索—4、搜索引擎第一版技术储备(简单介绍Log4Net、生产者消费者模式)
分享到: 生成海报

评论 抢沙发

评论前必须登录!

立即登录