首頁 >後端開發 >Golang >使用go-zero實現分散式搜尋引擎

使用go-zero實現分散式搜尋引擎

WBOY
WBOY原創
2023-06-22 17:59:181442瀏覽

隨著網路時代的來臨,搜尋引擎的角色越來越重要。作為網友最常用的工具之一,搜尋引擎不僅為我們提供了便捷的檢索方式,也為網路資訊的篩選和分類提供了支援。但對於大規模的資料量和使用者存取量的處理,傳統的搜尋引擎架構已經無法滿足需求。

分散式搜尋引擎架構能夠有效解決傳統架構中的瓶頸問題,透過將不同的任務分配到不同的節點上執行,充分利用叢集的運算資源,提高系統的回應速度和穩定性。在目前分散式架構技術中,go-zero框架是一個非常優秀的選擇。

go-zero是一個基於Golang開發的輕量級開源微服務框架。它提供了一整套工具鏈,包括程式碼產生、參數校驗、路由、日誌、錯誤處理、快取、限流等功能,大大簡化了微服務的開發和維護工作。在分散式搜尋引擎建置中,go-zero框架可以幫助我們快速實現高效能、高可用的系統。

下面,我們將結合實例來介紹如何使用go-zero建立分散式搜尋引擎。

第一步:建立環境

首先,我們需要安裝Golang和go-zero框架。安裝完畢後,使用go-zero提供的工具命令列產生一個專案範本。在命令列中輸入:

goctl api new search

即可產生一個新專案。在此基礎上,我們可以開始進行開發。

第二步:設定配置

在開發分散式搜尋引擎時,最重要的一步是定義系統的分散式配置。我們需要在專案根目錄下建立一個名為search-api.yaml的設定文件,並在其中定義以下設定資訊:

Name: search # 服务名
Description: "搜索服务" # 服务描述
Version: 1.0.0 # 服务版本

Host: 127.0.0.1 # 服务绑定IP地址
Port: 8888 # 服务绑定端口号

Redis:
  Host: 127.0.0.1 # Redis服务地址
  Port: 6379 # Redis服务端口号
  Password: "" # Redis密码

Etcd:
  Hosts:
    - 127.0.0.1:2379 # Etcd集群地址

在設定檔中,我們定義了服務名稱、描述、版本、服務綁定位址和連接埠號,也包括了Redis和Etcd的設定資訊。其中,Redis用於快取搜尋結果,Etcd用於實現服務註冊和發現。

第三步:定義API介面

接下來,我們需要定義搜尋引擎的API介面。在search/api/search.api中,定義以下內容:

syntax = "proto3";

package search.api;

option go_package = "search/api/search";

message Request {
    string keyword = 1;
    int32 page = 2;
    int32 size = 3;
}

message Response {
    repeated Result result = 1;
}

message Result {
    string title = 1;
    string url = 2;
    string abstract = 3;
}

service Search {
    rpc Query(Request) returns (Response);
}

在搜尋API中,我們定義了Request請求和Response回應參數,以及Result搜尋結果結構體。搜尋API包含一個Query接口,接受使用者搜尋關鍵字、分頁資訊等參數,傳回搜尋結果。

第四步:實作業務邏輯

有了API介面定義之後,我們可以開始寫業務邏輯程式碼。在search/internal/search/search.go中,實作搜尋請求的處理和搜尋結果的快取功能。具體程式碼實作詳見註解:

package search

import (
    "context"
    "encoding/json"

    "github.com/Yesterday17/go-search-engine/global"
    "github.com/Yesterday17/go-search-engine/internal/search/model"
    "github.com/Yesterday17/go-search-engine/internal/search/service"
    "github.com/Yesterday17/go-zero/core/stores/redis"
    "github.com/Yesterday17/go-zero/rest/httpx"
)

type Search struct {
    redis      *redis.Redis
    searchFunc func(string, int32, int32) ([]model.Result, error)
}

func NewSearch(redis *redis.Redis) *Search {
    return &Search{
        redis: redis,
        searchFunc: service.Search.implement,
    }
}

func (s *Search) Query(ctx context.Context, req *model.Request) (*model.Response, error) {
    resp := &model.Response{}
    key := generateKey(req.Keyword, req.Page, req.Size)

    // 搜索结果缓存
    result, err := s.redis.Get(key).Result()
    if err == nil {
        if err := json.Unmarshal([]byte(result), resp); err != nil {
            return nil, err
        }
        return resp, nil
    }

    result, err = s.searchFunc(req.Keyword, req.Page, req.Size)
    if err != nil {
        return nil, err
    }

    // 将搜索结果序列化为json,存储至redis
    data, err := json.Marshal(result)
    if err != nil {
        return nil, err
    }

    if err := s.redis.Set(key, string(data), global.SearchResultExpire).Err(); err != nil {
        return nil, err
    }

    resp.Result = result
    return resp, nil
}

func generateKey(keyword string, page, size int32) string {
    return "search_" + keyword + "_" + httpx.ConvertIntToString(int(page)) + "_" +
        httpx.ConvertIntToString(int(size))
}

在程式碼中,我們實作了Query方法,接收使用者請求,從Redis中檢索搜尋結果。如果Redis中存在該搜尋結果,則直接傳回快取結果;如果不存在,則呼叫service.Search.implement方法執行搜索,同時將搜尋結果序列化為json並快取至Redis。

第五步:啟動服務

最後一步是將搜尋服務啟動。我們在search目錄中,在命令列執行以下命令:

go run search.go -f api/search.api -s svc.yaml -c search-api.yaml

在服務成功啟動後,我們可以透過存取localhost:8888/search/query介面測試搜尋功能的實作。

總結

本文介紹如何使用go-zero框架快速建立分散式搜尋引擎。在分散式系統開發中,go-zero框架的靈活性和高效性得到了廣泛認可,並在微服務、高並發業務場景中得到了廣泛的應用。希望本文對想要掌握分散式系統開發技術的讀者有幫助。

以上是使用go-zero實現分散式搜尋引擎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn