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、站內搜索第二版

我們先來看下百度搜索

用戶保存一篇文章就把文章寫入索引庫

用戶輸入“我喜歡的季節”也可以搜索出含有“喜歡的”和“季節”的,這里用到了分詞。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);
                    }
                }
            }
        }
    }

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM