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

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

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

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

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

案例展示

項(xiàng)目地址:

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

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

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

對(duì)應(yīng)的json為:

注冊(cè)服務(wù):

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

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

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

查詢服務(wù):

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

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

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

銷毀服務(wù):

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

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

目前還暫不支持登錄驗(yàn)證。

案例測(cè)試

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

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

運(yùn)行結(jié)果如下:

可以看到上述結(jié)果,第一個(gè)輸出是我們注冊(cè)的消息,而后我們等待了5秒,目的是為了等redis服務(wù)因?yàn)槌瑫r(shí)被自動(dòng)銷毀,而后再進(jìn)行查詢,就沒有redis2的注冊(cè)信息了,接著我們銷毀了mysql1的服務(wù),整個(gè)測(cè)試完畢。

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

我們想要寫一個(gè)注冊(cè)服務(wù)器,我們至少需要知道以下幾個(gè)知識(shí)點(diǎn):

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

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

python中,我們可以通過定義一個(gè)字典,來存儲(chǔ)所有注冊(cè)信息,例如:

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

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

報(bào)文如何定義

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

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

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

例如:

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

如何從tcp流中獲取記錄

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

這個(gè)點(diǎn)其實(shí)核心是如何解決tcp粘包,我們都知道,tcp socket也被稱之為數(shù)據(jù)流,就是因?yàn)橐坏┤挝帐种螅瑪?shù)據(jù)就像水龍頭一樣源源不斷流動(dòng),我們不知道哪兒是頭,哪兒是尾巴。

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

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

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

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

例如,如圖:

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

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

我們提前計(jì)算hello world字符串占用多少個(gè)字節(jié),而后再在行首分n個(gè)字節(jié)來存儲(chǔ)個(gè)數(shù),例如我們使用2個(gè)字節(jié)來存儲(chǔ),存儲(chǔ)數(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]

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

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

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

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

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

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

服務(wù)注冊(cè)

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

這里,需要注意的是,我們?cè)俑路?wù)信息的時(shí)候,會(huì)將lastUpdateTime更新到目前的時(shí)間戳,方便后續(xù)查詢服務(wù)的時(shí)候做惰性刪除。

服務(wù)銷毀

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

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

代碼如下:

服務(wù)查詢

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

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

總結(jié)

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

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

    解決使用PyCharm時(shí)無法啟動(dòng)控制臺(tái)的問題

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

    Python獲取當(dāng)前時(shí)間的方法

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

    淺談Python __init__.py的作用

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

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

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

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

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

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

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

最新評(píng)論