欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

用Go語言編寫一個簡單的分布式系統(tǒng)

 更新時間:2023年08月01日 11:41:15   作者:uccs  
這篇文章主要介紹了用Go語言編寫一個簡單的分布式系統(tǒng),文中的代碼示例講解的非常詳細,對我們的學習或工作有一定的幫助,感興趣的小伙伴跟著小編一起來看看吧

分布式

  • 注冊服務:RegistryService
  • 日志服務:LogService
  • 其他服務:GradingServiceportal

RegistryService

RegistryService 提供的服務:

  • 提供 /services 接口,用于其他服務在啟動或者停止時告知
    • POST:告訴 RegistryService,我啟動了一個服務,調用 add 方法
    • DELETE:告訴 RegistryService,我停止了一個服務,調用 remove 方法
  • 通過 add 函數將服務添加到 registrations 列表中
    • r.registrations = append(r.registrations, reg)
  • 通過 remove 函數將服務從 registrations 列表中移除
    • r.registrations = append(r.registrations[:i], r.registrations[i+1:]...)
  • 這里需要注意的是:要保證線程安全,也就是在 append 時,需要使用到鎖
mutex.Lock()
append(xxx, xxx)
mutex.UnLock()
  • 服務發(fā)現(xiàn):

    比如說 GradingService 依賴 LogService,那么 GradingService 就需要知道 LogService 的地址

    這個時候 RegistryService 就可以通過 registrations 列表來通知 GradingServiceLogService 的地址

    RegistryService 是通過 ServiceUpdateURL 來通知的,GradingServiceLogService 的地址

  • 服務發(fā)現(xiàn)需要分兩步進行

    如果 GradingService 啟動時,如果 LogService 已經啟動了,那么 RegistryService 就可以直接通知 GradingService,LogService 的地址(r.sendRequiredServices(reg) 方法)

    如果 GradingService 啟動時,如果 LogService 還沒有啟動,那么 RegistryService 就不會通知 GradingService,LogService 的地址,等到 LogService 啟動后,RegistryService 才會通知 GradingService,LogService 的地址(notify 方法)

RegistryService 對外只需要提供 RegisterService 方法,其他服務調用這個函數,就能夠獲取 RegistryService 提供的服務

  • 調用 RegisterService 提供的接口 /services,將服務注冊到 RegistryService
  • 為注冊的服務添加路由:ServiceUpdateURL
  • 為注冊的服務添加 ServeHTTP 方法,用于處理 ServiceUpdateURL 的請求,這個請求在方法 sendRequiredServices 調用時相應,更新 providers 中的 service
  • 為每個注冊的服務提供健康檢查

最后在提供一個 ShutdownService 用于像 /services 接口發(fā)送 delete 請求,告知 RegistryService,我停止了一個服務

LogService

LogService 服務是對日志進行管理,將其他服務的日志進行收集、存儲,提供 /log 接口,用于其他服務將日志發(fā)送給 LogService

GradingService 和 Portal

這兩個是業(yè)務服務

  • 在啟動服務時調用方法 RegistryService,將自己注冊到 RegistryService
  • 在停止服務時調用方法 ShutdownService,將自己從 RegistryService 中移除

api

os.OpenFile

用于指定模式打開文件,并返回文件的指針

func OpenFile(name string, flag int, perm FileMode) (*File, error)

flag 參數:

  • os.O_RDONLY:只讀模式打開文件
  • os.O_WRONLY:只寫模式打開文件
  • os.O_RDWR:讀寫模式打開文件
  • os.O_APPEND:追加模式,寫入內容時將數據附加到文件尾部
  • os.O_CREATE:如果文件不存在,則創(chuàng)建一個新文件

perm 參數:

- 0:無權限
- 1:執(zhí)行權限
- 2:寫權限
- 3:寫和執(zhí)行權限
- 4:讀權限
- 5:讀和執(zhí)行權限
- 6:讀和寫權限
- 7:讀、寫和執(zhí)行權限

  • 0644:表示文件的所有者可以讀取和寫入文件,文件所屬組和其他用戶只能讀取文件。這是比較常見的設置
  • 0600:表示文件的所有者可以讀取和寫入文件,但是文件所屬組和其他用戶不能訪問該文件。這種權限安全性較高

ioutil.ReadAll

可以將整個文件內容讀取到內存中,可以將請求體的內容讀取到內存中

ps:將整個文件的內容或者請求體一次性讀取到內存中,對于非常大的文件或者請求體,內存占用過高

fmt.Scanln

會阻塞程序的執(zhí)行,直到用戶在終端輸入一行內容并按下回車鍵,然后它會將用戶輸入的值存儲到傳入的參數中

它主要用于讀取并解析簡單的基本類型數據

func main(){
  var name string
	var age int
	fmt.Print("Enter your name: ")
	fmt.Scanln(&name)
	fmt.Print("Enter your age: ")
	fmt.Scanln(&age)
	fmt.Printf("Hello, %s! You are %d years old.\n", name, age)
}

http

http.Server

  • ListenAndServe:啟動服務,并監(jiān)聽指定的地址和端口,會阻塞
  • Shutdown:優(yōu)雅地關閉服務,可以保證正在處理的服務不會被中斷
var srv htto.Server
go func(){
  srv.ListenAndServe()
}()
go func(){
  srv.Shutdown()
}()

ServeHTTP

當一個結構體實現(xiàn)了 ServeHTTP 方法后,那么這個結構體就實現(xiàn)了 http.Handler 接口

實現(xiàn)了 http.Handler 接口的結構體,就可以作為 http.Handle 方法的第二個參數

然后調用 http.ListenAndServe 方法就可以啟動一個服務,會自動調用 ServeHTTP 方法來處理請求

func main() {
	http.Handle("/ping", &MyHandler{})
	http.ListenAndServe(":8080", nil)
}
type MyHandler struct{}
func (mh MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case http.MethodGet:
		w.WriteHeader(http.StatusOK)
		w.Write([]byte("pong"))
	default:
		w.WriteHeader(http.StatusMethodNotAllowed)
	}
}

將結構體序列化

  • buf := new(bytes.Buffer) 創(chuàng)建了一個新的 bytes.Buffer 對象,用于存儲編碼后的 JSON 數據
  • enc := json.NewEncoder(buf) 創(chuàng)建了一個新的 JSON 編碼器 enc,并將其關聯(lián)到 buf 對象。這意味著編碼后的 JSON 數據將被寫入到 buf
  • err := enc.Encode(r) 使用 JSON 編碼器 enc 將結構體 r 編碼為 JSON 數據,并將結果寫入到 buf 中。Encode 方法返回一個可能的錯誤 err
type Registration struct {
	ServiceName string
	ServiceURL  string
}
r := Registration{
  ServiceName: "LogService",
  ServiceURL:  "http://localhost:3000/services",
}
buf := new(bytes.Buffer)
enc := json.NewEncoder(buf)
err := enc.Encode(r)
res, err := http.Post(ServicesURL, "application/json", buf)

使用 http 默認請求

  • http.DefaultClient 是標準庫中提供的默認 HTTP 請求。它已經預先配置好了一些默認的設置,例如超時時間、重試機制等
  • Do(req)http.Client 類型的方法,用于執(zhí)行一個 HTTP 請求并返回響應
    • 它接受一個 http.Request 對象作為參數,表示要發(fā)送的請求
req, _ := http.NewRequest(http.MethodDelete, "http://localhost:3000/services", bytes.NewBuffer([]byte("http://localhost:4000/log")))
req.Header.Add("Content-Type", "text/plain")
res, err := http.DefaultClient.Do(req)

log

log.New

log.New 用于創(chuàng)建一個新的日志記錄器實例,用于將日志消息寫入指定的輸出地,并可選擇性地添加前綴字符串

  • 以文件的形式記錄日志,用 log.New 創(chuàng)建一個新的 log 實例,然后調用 log.Printf 方法將日志寫入文件

它接收 io.Writer 類型的參數,os.OpenFile 返回的文件指針類型 *os.File 實現(xiàn)了 io.Writer 接口,所以可以將文件指針傳入 log.New 方法中

代碼參考如下:

import (
	"fmt"
	stlog "log"
	"os"
)
func main() {
	file, err := os.OpenFile("./logs", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
	if err != nil {
		fmt.Println(err)
	}
	defer file.Close()
	log := stlog.New(file, "[go] -  ", stlog.LstdFlags)
	log.Println("hello world")
}
  • 重寫 log 的 Write 方法,也能實現(xiàn)將日志寫入文件

在重寫 Write 方法時,需要定義一個類型別名,然后在類型別名上實現(xiàn) Write 方法,那么這個類型別名就能夠傳入 log.New 方法中

代碼參考如下:

import (
	stlog "log"
	"os"
)
type filelog string
func (fl filelog) Write(data []byte) (int, error) {
	file, err := os.OpenFile(string(fl), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
	if err != nil {
		return 0, err
	}
	defer file.Close()
	file.Write(data)
	return len(data), nil
}
func main() {
	log := stlog.New(filelog("./logs"), "[go] -  ", stlog.LstdFlags)
	log.Println("hello world")
}

以上就是用Go語言編寫一個簡單的分布式系統(tǒng)的詳細內容,更多關于Go語言分布式系統(tǒng)的資料請關注腳本之家其它相關文章!

相關文章

  • Go每日一庫之dateparse處理時間

    Go每日一庫之dateparse處理時間

    不管什么時候,處理時間總是讓人頭疼的一件事情。今天要介紹的dateparse實現(xiàn)解析日期時間格式的字符串。具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • golang中實現(xiàn)graphql請求的方法

    golang中實現(xiàn)graphql請求的方法

    這篇文章主要介紹了如何在golang中實現(xiàn)graphql請求,在本文中,我們介紹了如何使用gqlgen來構建GraphQL服務,需要的朋友可以參考下
    2023-04-04
  • Golang中map數據類型的使用方法

    Golang中map數據類型的使用方法

    這篇文章主要介紹了Golang中map數據類型的使用方法,文章圍繞主題展開詳細的內容戒殺,具有一定的參考價值,需要的朋友可以參考一下
    2022-09-09
  • Golang 字符串轉time類型實現(xiàn)

    Golang 字符串轉time類型實現(xiàn)

    本文主要介紹了Golang 字符串轉time類型實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • Go實現(xiàn)文件上傳和下載

    Go實現(xiàn)文件上傳和下載

    這篇文章主要為大家詳細介紹了Go實現(xiàn)文件上傳和下載,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • 詳解如何在Golang中實現(xiàn)CORS(跨域)

    詳解如何在Golang中實現(xiàn)CORS(跨域)

    很多時候,需要允許Web應用程序在不同域之間(跨域)實現(xiàn)共享資源,本文將簡介跨域、CORS的概念,以及如何在Golang中如何實現(xiàn)CORS,文中有詳細的示例代碼,需要的朋友可以參考下
    2023-10-10
  • 關于go-zero服務自動收集問題分析

    關于go-zero服務自動收集問題分析

    這篇文章主要介紹了關于go-zero服務自動收集問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-12-12
  • 詳解go中的引用類型

    詳解go中的引用類型

    這篇文章主要介紹了go中的引用類型,文中給大家提到了值類型和引用類型的區(qū)別,通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • Golang 實現(xiàn)簡單隨機負載均衡

    Golang 實現(xiàn)簡單隨機負載均衡

    均衡算法又分為 隨機,輪詢,加權輪詢,哈希,而隨機負載均衡算法就是本文的重點,需要的朋友們下面隨著小編來一起學習學習吧
    2021-06-06
  • go語言make初始化的實現(xiàn)

    go語言make初始化的實現(xiàn)

    Go語言中的make函數用于初始化切片、映射和通道,本文就來介紹一下go語言make初始化的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2024-12-12

最新評論