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

通過(guò)實(shí)例解析Python RPC實(shí)現(xiàn)原理及方法

 更新時(shí)間:2020年07月07日 10:10:22   作者:cxc1357  
這篇文章主要介紹了通過(guò)實(shí)例解析Python RPC實(shí)現(xiàn)原理及方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

單線程同步

  • 使用socket傳輸數(shù)據(jù)
  • 使用json序列化消息體
  • struct將消息編碼為二進(jìn)制字節(jié)串,進(jìn)行網(wǎng)絡(luò)傳輸

消息協(xié)議

// 輸入
{
  in: "ping",
  params: "ireader 0"
}

// 輸出
{
  out: "pong",
  result: "ireader 0"
}

客戶端 client.py

# coding: utf-8
# client.py

import json
import time
import struct
import socket


def rpc(sock, in_, params):
  response = json.dumps({"in": in_, "params": params}) # 請(qǐng)求消息體
  length_prefix = struct.pack("I", len(response)) # 請(qǐng)求長(zhǎng)度前綴
  sock.sendall(length_prefix)
  sock.sendall(response)
  length_prefix = sock.recv(4) # 響應(yīng)長(zhǎng)度前綴
  length, = struct.unpack("I", length_prefix)
  body = sock.recv(length) # 響應(yīng)消息體
  response = json.loads(body)
  return response["out"], response["result"] # 返回響應(yīng)類型和結(jié)果

if __name__ == '__main__':
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  s.connect(("localhost", 8080))
  for i in range(10): # 連續(xù)發(fā)送10個(gè)rpc請(qǐng)求
    out, result = rpc(s, "ping", "ireader %d" % i)
    print out, result
    time.sleep(1) # 休眠1s,便于觀察
  s.close() # 關(guān)閉連接

服務(wù)端 blocking_single.py

# coding: utf8
# blocking_single.py

import json
import struct
import socket


def handle_conn(conn, addr, handlers):
  print addr, "comes"
  while True: # 循環(huán)讀寫(xiě)
    length_prefix = conn.recv(4) # 請(qǐng)求長(zhǎng)度前綴
    if not length_prefix: # 連接關(guān)閉了
      print addr, "bye"
      conn.close()
      break # 退出循環(huán),處理下一個(gè)連接
    length, = struct.unpack("I", length_prefix)
    body = conn.recv(length) # 請(qǐng)求消息體
    request = json.loads(body)
    in_ = request['in']
    params = request['params']
    print in_, params
    handler = handlers[in_] # 查找請(qǐng)求處理器
    handler(conn, params) # 處理請(qǐng)求


def loop(sock, handlers):
  while True:
    conn, addr = sock.accept() # 接收連接
    handle_conn(conn, addr, handlers) # 處理連接


def ping(conn, params):
  send_result(conn, "pong", params)


def send_result(conn, out, result):
  response = json.dumps({"out": out, "result": result}) # 響應(yīng)消息體
  length_prefix = struct.pack("I", len(response)) # 響應(yīng)長(zhǎng)度前綴
  conn.sendall(length_prefix)
  conn.sendall(response)


if __name__ == '__main__':
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 創(chuàng)建一個(gè)TCP套接字
  sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 打開(kāi)reuse addr選項(xiàng)
  sock.bind(("localhost", 8080)) # 綁定端口
  sock.listen(1) # 監(jiān)聽(tīng)客戶端連接
  handlers = { # 注冊(cè)請(qǐng)求處理器
    "ping": ping
  }
  loop(sock, handlers) # 進(jìn)入服務(wù)循環(huán)

多線程同步

  • 使用線程庫(kù)thread創(chuàng)建原生線程
  • 服務(wù)器可并行處理多個(gè)客戶端

服務(wù)端 multithread.py

多進(jìn)程同步

  • Python的GIL導(dǎo)致單個(gè)進(jìn)程只能占滿一個(gè)CPU核心,多線程無(wú)法利用多核優(yōu)勢(shì)
  • os.fork()會(huì)生成子進(jìn)程
  • 子進(jìn)程退出后,父進(jìn)程需使用waitpid系統(tǒng)調(diào)用收割子進(jìn)程,防止其稱為僵尸資源
  • 在子進(jìn)程中關(guān)閉服務(wù)器套接字后,在父進(jìn)程中也要關(guān)閉服務(wù)器套接字
  • 因?yàn)檫M(jìn)程fork后,父子進(jìn)程都有自己的套接字引用指向內(nèi)核的同一份套接字對(duì)象,套接字引用計(jì)數(shù)為2,對(duì)套接字進(jìn)程close,即將套接字對(duì)象的引用計(jì)數(shù)減1

PreForking同步

  • 進(jìn)程比線程耗費(fèi)資源,通過(guò)PreForking進(jìn)程池模型對(duì)服務(wù)器開(kāi)辟的進(jìn)程數(shù)量進(jìn)行限制,避免服務(wù)器負(fù)載過(guò)重
  • 如果并行的連接數(shù)量超過(guò)了prefork進(jìn)程數(shù)量,后來(lái)的客戶端請(qǐng)求將會(huì)阻塞

單進(jìn)程異步

  • 通過(guò)事件輪詢API,查詢相關(guān)套接字是否有響應(yīng)的讀寫(xiě)事件,有則攜帶事件列表返回,沒(méi)有則阻塞
  • 拿到讀寫(xiě)事件后,可對(duì)事件相關(guān)的套接字進(jìn)行讀寫(xiě)操作
  • 設(shè)置讀寫(xiě)緩沖區(qū)
  • Nginx/Nodejs/Redis都是基于異步模型
  • 異步模型編碼成本高,易出錯(cuò),通常在公司業(yè)務(wù)代碼中采用同步模型,僅在講究高并發(fā)高性能的場(chǎng)合才使用異步模型

PreForking異步

Tornado/Nginx采用了多進(jìn)程PreForking異步模型,具有良好的高并發(fā)處理能力

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 將Python腳本打包成exe文件

    將Python腳本打包成exe文件

    大家好,本篇文章主要講的是將Python腳本打包成exe文件,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-02-02
  • python關(guān)鍵字and和or用法實(shí)例

    python關(guān)鍵字and和or用法實(shí)例

    這篇文章主要介紹了python關(guān)鍵字and和or用法實(shí)例,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2015-05-05
  • 簡(jiǎn)單了解python中對(duì)象的取反運(yùn)算符

    簡(jiǎn)單了解python中對(duì)象的取反運(yùn)算符

    這篇文章主要介紹了簡(jiǎn)單了解python中對(duì)象的取反運(yùn)算符,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • Python按照某列內(nèi)容對(duì)兩個(gè)DataFrame進(jìn)行合并操作方法

    Python按照某列內(nèi)容對(duì)兩個(gè)DataFrame進(jìn)行合并操作方法

    這篇文章主要給大家介紹了關(guān)于Python按照某列內(nèi)容對(duì)兩個(gè)DataFrame進(jìn)行合并操作的相關(guān)資料,文中通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Python具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • Python可視化神器pyecharts之繪制箱形圖

    Python可視化神器pyecharts之繪制箱形圖

    這篇文章主要介紹了Python可視化神器pyecharts之繪制箱形圖,箱形圖(Box-plot)又稱為盒須圖、盒式圖或箱線圖,是一種用作顯示一組數(shù)據(jù)分散情況資料的統(tǒng)計(jì)圖,因形狀如箱子而得名
    2022-07-07
  • Python GUI編程學(xué)習(xí)筆記之tkinter界面布局顯示詳解

    Python GUI編程學(xué)習(xí)筆記之tkinter界面布局顯示詳解

    這篇文章主要介紹了Python GUI編程學(xué)習(xí)筆記之tkinter界面布局顯示,結(jié)合實(shí)例形式分析了Python GUI編程中tkinter界面布局顯示的相關(guān)操作技巧與使用注意事項(xiàng),需要的朋友可以參考下
    2020-03-03
  • Django 限制用戶訪問(wèn)頻率的中間件的實(shí)現(xiàn)

    Django 限制用戶訪問(wèn)頻率的中間件的實(shí)現(xiàn)

    這篇文章主要介紹了Django 限制用戶訪問(wèn)頻率的中間件的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • 使用python對(duì)excel表格處理的一些小功能

    使用python對(duì)excel表格處理的一些小功能

    這篇文章主要介紹了使用python對(duì)excel表格處理的一些小功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • Tensorflow訓(xùn)練MNIST手寫(xiě)數(shù)字識(shí)別模型

    Tensorflow訓(xùn)練MNIST手寫(xiě)數(shù)字識(shí)別模型

    這篇文章主要為大家詳細(xì)介紹了Tensorflow訓(xùn)練MNIST手寫(xiě)數(shù)字識(shí)別模型,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • Python @property裝飾器原理解析

    Python @property裝飾器原理解析

    這篇文章主要介紹了Python @property裝飾器原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01

最新評(píng)論