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

基于Python編寫一個簡單的服務(wù)注冊發(fā)現(xiàn)服務(wù)器

 更新時間:2023年04月21日 08:24:21   作者:真的不能告訴你我的名字  
我們都知道有很多的非常著名的注冊服務(wù)器,例如:?Consul、ZooKeeper、etcd,甚至借助于redis完成服務(wù)注冊發(fā)現(xiàn)。但是本篇文章我們將使用python?socket寫一個非常簡單的服務(wù)注冊發(fā)現(xiàn)服務(wù)器,感興趣的可以了解一下

我們都知道有很多的非常著名的注冊服務(wù)器,例如: Consul、ZooKeeper、etcd,甚至借助于redis完成服務(wù)注冊發(fā)現(xiàn)。但是本篇文章我們將使用python socket寫一個非常簡單的服務(wù)注冊發(fā)現(xiàn)服務(wù)器。

本篇文章所依賴的環(huán)境為:

案例展示

項目地址:

gitee: gitee.com/pdudo/golearn/blob/master/python/registerCenter/registerSer.py

該服務(wù)注冊服務(wù)器,沒有使用第三方庫,可以復(fù)制到本地,使用python registerSer.py啟動即可,啟動成功后,會輸出“注冊服務(wù)器已經(jīng)啟動...”的信息。

該案例使用的協(xié)議是TCP協(xié)議,為了防止粘包,客戶端在發(fā)送消息的時候,使用CRLF進行區(qū)分,服務(wù)器是按照讀取到CRLF進行分割的,服務(wù)數(shù)據(jù),均采用json格式,共支持注冊服務(wù)、查詢服務(wù)、銷毀服務(wù)。

對應(yīng)的json為:

注冊服務(wù):

{"type":"register","key":"redis","values":"123456@127.0.0.1:6379","timeout":"30"}

注冊和更新服務(wù)都是用的上述報文,其中type 是告訴服務(wù)器需要做什么,register代表注冊服務(wù),keyvalues是注冊服務(wù)的名稱和注冊服務(wù)的值,最后的timeout是存活時間,單位是秒,若超過這個時間沒有更新服務(wù),則自動銷毀該服務(wù)。

如果客戶端發(fā)送的信息沒有攜帶time,則注冊存活時間為30s。

查詢服務(wù):

{"type":"query","key":"redis"}

{"type":"query","key":"all"}

查詢服務(wù)使用的typequery,查詢的key若是all則是查詢?nèi)?,其他則是查詢值為key的服務(wù)信息。

銷毀服務(wù):

{"type":"destruction","key":"redis"}

銷毀服務(wù)的typedestruction,key為需要銷毀服務(wù)的名稱。

目前還暫不支持登錄驗證。

案例測試

由于該注冊服務(wù)報文采用的是使用CRLF進行分割,所以可以直接使用telnet進行模擬注冊,為了方便,我們還是使用python來寫這個測試,代碼如下:

上述代碼,我們需要自己指定\r\n進行分割,我們指定了4個注冊,以及等待5s再進行查詢,最后再銷毀了一個服務(wù)。

運行結(jié)果如下:

可以看到上述結(jié)果,第一個輸出是我們注冊的消息,而后我們等待了5秒,目的是為了等redis服務(wù)因為超時被自動銷毀,而后再進行查詢,就沒有redis2的注冊信息了,接著我們銷毀了mysql1的服務(wù),整個測試完畢。

如何來寫一個注冊發(fā)現(xiàn)服務(wù)器

我們想要寫一個注冊服務(wù)器,我們至少需要知道以下幾個知識點:

  • 服務(wù)注冊發(fā)現(xiàn)核心是啥?
  • 應(yīng)用層數(shù)據(jù)報文應(yīng)該如何定義。
  • 如何從tcp數(shù)據(jù)流中按條獲取記錄。

服務(wù)器發(fā)現(xiàn)核心是啥

python中,我們可以通過定義一個字典,來存儲所有注冊信息,例如:

{
        "redis": {
        "value": "123456@127.0.0.1:6379",
        "timeout":30,
        "lastUpdateTime": time.time()
        },
        "redis1": {....}
}

我們只需要維護好這個字典,就可以做到最基本的服務(wù)注冊和服務(wù)發(fā)現(xiàn)了。

報文如何定義

該服務(wù),我們使用的是json來定義的數(shù)據(jù)報文,按照type區(qū)分,分別為:

  • register: 注冊或更新服務(wù)。
  • query: 查詢服務(wù)。
  • destruction銷毀服務(wù)。

json中,以keyvalue來確定服務(wù)名稱和服務(wù)值,還有一個timeout來定義超時銷毀時間。

例如:

{"type":"register","key":"redis1","values":"123456@127.0.0.1:6379","timeout":"30"}
{"type":"query","key":"all"}
{"type":"destruction","key":"mysql1"}

如何從tcp流中獲取記錄

如何從tcp中讀取需要的記錄呢?

這個點其實核心是如何解決tcp粘包,我們都知道,tcp socket也被稱之為數(shù)據(jù)流,就是因為一旦三次握手之后,數(shù)據(jù)就像水龍頭一樣源源不斷流動,我們不知道哪兒是頭,哪兒是尾巴。

所以需要指定一個結(jié)束符,告知程序,讀到哪兒,一條記錄就讀完了,這里我們每條信息都發(fā)送一個\r\n來作為結(jié)束符。

編寫注冊發(fā)現(xiàn)服務(wù)器

如何從tcp流中讀取數(shù)據(jù)

要解決粘包,有2種方法,第一種是定義特殊字段分隔符,例如: \r\n當讀到\r\n的時候,就判斷一條消息結(jié)束了。

例如,如圖:

我們發(fā)送了一條記錄,hello world如何判斷結(jié)束了呢? 在最后面加一個\r\n,當程序讀到的時候,就判斷這條消息接收完了,就可以了。

還有一種方法是,提前計算發(fā)送的字節(jié)數(shù),然后記錄到行首,每次讀取的時候,先讀取行首的個數(shù),而后更具個數(shù)再讀取數(shù)據(jù),例如:

我們提前計算hello world字符串占用多少個字節(jié),而后再在行首分n個字節(jié)來存儲個數(shù),例如我們使用2個字節(jié)來存儲,存儲數(shù)據(jù)為10。

我們這篇服務(wù)發(fā)現(xiàn)使用的是第一種方法。

那要如何判斷\r\n呢?可以參考如下代碼:

data = b""
while True:
    data += client.recv(1)
    if data.endswith(b"\r\n"):
        break
data = data[:len(data)-2]

上述代碼中,我們先定義了一個空的byte,變量名為data,而后每次讀取1個字節(jié),再判斷是否以\r\n結(jié)尾,如果是以\r\n結(jié)尾的話,就跳出循環(huán),跳出循環(huán)后,我們需要刪除掉\r\n所以會有data = data[:len(data)-2]這個語句,這樣的話,我們就成功拿到了記錄。

數(shù)據(jù)包如何區(qū)分類型

上個段落,我們已經(jīng)拿到了一條數(shù)據(jù)包,那么我們這個服務(wù)有3種操作,分別是 查詢、注冊、銷毀,如何客戶端發(fā)上來的請求呢? 其實如之前所述,我們可以通過type來定義,操作流程為:

  • 解析客戶端發(fā)上來的json信息。
  • 判斷其type類型。

整合為語句的話,可以理解為這樣:

上述代碼,我們先使用json.loads序列化為json格式,而后根據(jù)type信息區(qū)分是注冊服務(wù)、銷毀服務(wù)還是其查詢服務(wù)。這里注意的是,若json字符串都沒有type或者key類型,則證明該數(shù)據(jù)包有問題,直接拒絕掉即可。如果不是上述三種服務(wù)類型的話,那也證明包有問題,直接拒絕即可。

服務(wù)注冊

服務(wù)注冊,需要獲取客戶端傳上來的keyvalues信息,若沒有的話,則證明該包有問題,而后判斷其timeout是否攜帶,若沒有攜帶的話,則定義為默認值30s,而后將該值入早已定義好的字典類型中即可,代碼如下:

這里,需要注意的是,我們再更新服務(wù)信息的時候,會將lastUpdateTime更新到目前的時間戳,方便后續(xù)查詢服務(wù)的時候做惰性刪除。

服務(wù)銷毀

服務(wù)銷毀,核心點是刪除字典中的記錄即可,為了避免拋錯,還是要檢查客戶端傳上來的json字符串是否攜帶key,雖然在前面檢查過,這個再檢查一下,還是有必要的。

銷毀服務(wù),就直接刪除字典的該記錄就可以,如果傳入的值,在該字典中沒有記錄的話,默認為銷毀完畢。

代碼如下:

服務(wù)查詢

服務(wù)查詢,客戶端發(fā)上來的還是以key為主,若key的值為all的話,則查詢所有服務(wù),若不為all的話,則查詢單個服務(wù)注冊的信息,這里在查詢的時候,是將服務(wù)超時銷毀一起做了的,采用的是惰性刪除,當查詢到該值的是,它會比對超時時間,若已經(jīng)超時了,則直接刪除該對象,代碼如下:

上述查詢到key后,會做一次超時檢測,若超時了,則刪除該記錄的值,若沒有超出時間,再返回信息。

總結(jié)

該篇文章,介紹了如何使用python socket寫一個服務(wù)注冊發(fā)現(xiàn),該項目還是有很多不完美的地方,比如: 沒有對字典進行加鎖、內(nèi)存數(shù)據(jù)沒有落地等等。但是可以將它理解為一個初始的demo。

該篇文章由于篇幅和時間關(guān)系,所以寫的更多的是思路,應(yīng)該如何如何才能完成這個項目,而沒有對詳細的語法進行梳理,比如 如何開一個多線程來服務(wù)多個客戶端等,這個后面有時間再詳細介紹。

到此這篇關(guān)于基于Python編寫一個簡單的服務(wù)注冊發(fā)現(xiàn)服務(wù)器的文章就介紹到這了,更多相關(guān)Python服務(wù)注冊發(fā)現(xiàn)服務(wù)器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用matplotlib繪制并排柱狀圖的實戰(zhàn)案例

    使用matplotlib繪制并排柱狀圖的實戰(zhàn)案例

    堆積柱狀圖有堆積柱狀圖的好處,比如說我們可以很方便地看到多分類總和的趨勢,下面這篇文章主要給大家介紹了關(guān)于使用matplotlib繪制并排柱狀圖的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • python重寫方法和重寫特殊構(gòu)造方法

    python重寫方法和重寫特殊構(gòu)造方法

    這篇文章主要介紹了python重寫方法和重寫特殊構(gòu)造方法,對于父類的方法,只要他不符合子類模擬的實物的行為,都可以進行重寫,更多相關(guān)內(nèi)容需要的朋友可以參考一下
    2022-07-07
  • 關(guān)于Python如何安裝requests庫

    關(guān)于Python如何安裝requests庫

    這篇文章主要介紹了關(guān)于Python如何安裝requests庫,requests庫自稱“HTTP for Humans”,直譯過來的意思是專門為人類設(shè)計的HTTP庫,能夠被開發(fā)人員安全地使用,需要的朋友可以參考下
    2023-04-04
  • Python表格數(shù)據(jù)處理庫之tablib庫詳解

    Python表格數(shù)據(jù)處理庫之tablib庫詳解

    這篇文章主要介紹了Python表格數(shù)據(jù)處理庫之tablib庫詳解,Tablib是一個用于處理電子表格數(shù)據(jù)的Python庫,它可以輕松地進行數(shù)據(jù)的導(dǎo)入和導(dǎo)出,以及數(shù)據(jù)格式的轉(zhuǎn)換,需要的朋友可以參考下
    2023-08-08
  • 解決使用PyCharm時無法啟動控制臺的問題

    解決使用PyCharm時無法啟動控制臺的問題

    今天小編就為大家分享一篇解決使用PyCharm時無法啟動控制臺的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • Python獲取當前時間的方法

    Python獲取當前時間的方法

    這篇文章主要介紹了Python獲取當前時間的方法,有需要的朋友可以參考一下
    2014-01-01
  • 淺談Python __init__.py的作用

    淺談Python __init__.py的作用

    這篇文章主要介紹了淺談Python __init__.py的作用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Python中re模塊的常用方法總結(jié)

    Python中re模塊的常用方法總結(jié)

    這篇文章主要給大家介紹了關(guān)于Python中re模塊的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Python設(shè)置在shell腳本中自動補全功能的方法

    Python設(shè)置在shell腳本中自動補全功能的方法

    今天小編就為大家分享一篇Python設(shè)置在shell腳本中自動補全功能的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • 基于Python實現(xiàn)有趣的象棋游戲

    基于Python實現(xiàn)有趣的象棋游戲

    一直以來,中國象棋都是中華民族的一種象征,當然也是人們最為喜感的一種娛樂方式。這篇文章主要介紹了如何基于Python實現(xiàn)有趣的象棋游戲,感興趣的可以了解一下
    2023-03-03

最新評論