vitess中rpc相容http請求的技巧
vitess是google的一個mysql專案,用go和python實現。https://code.google.com/p/vitess/
vitess中用rpc方式來中轉mysql的請求,其中rpc的實現很有意思,相容了http請求。
相容http請求有明顯的好處:
1.可以用現成的監控工具來監控服務是否正常,不用另外寫外掛
2.可以方便地實現查詢資訊功能,不用另外再開發工具或者介面
3.可以方便地用現成的工具測試
在vitess中很簡單地實現了這個功能。client在建立連線後,第一個包是http頭,而server端也會有一個200的回應。
詳細見程式碼:
https://code.google.com/p/vitess/source/browse/py/net/gorpc.py#87
https://code.google.com/p/vitess/source/browse/go/rpcwrap/rpcwrap.go
python client:
class _GoRpcConn(object):
def __init__(self, timeout):
self.conn = None
self.timeout = timeout
self.start_time = None
def dial(self, uri):
parts = urlparse.urlparse(uri)
netloc = parts.netloc.split(`:`)
# NOTE(msolomon) since the deadlines are approximate in the code, set
# timeout to oversample to minimize waiting in the extreme failure mode.
socket_timeout = self.timeout / 10.0
self.conn = socket.create_connection((netloc[0], int(netloc[1])),
socket_timeout)
self.conn.sendall(`CONNECT %s HTTP/1.0
` % parts.path)
while True:
data = self.conn.recv(1024)
if not data:
raise GoRpcError(`Unexpected EOF in handshake`)
if `
` in data:
return
go server:
const ( connected = "200 Connected to Go RPC" ) type ClientCodecFactory func(conn io.ReadWriteCloser) rpc.ClientCodec type BufferedConnection struct { *bufio.Reader io.WriteCloser } func NewBufferedConnection(conn io.ReadWriteCloser) *BufferedConnection { return &BufferedConnection{bufio.NewReader(conn), conn} } // DialHTTP connects to a go HTTP RPC server using the specified codec. func DialHTTP(network, address, codecName string, cFactory ClientCodecFactory) (*rpc.Client, error) { var err error conn, err := net.Dial(network, address) if err != nil { return nil, err } io.WriteString(conn, "CONNECT "+GetRpcPath(codecName)+" HTTP/1.0 ") // Require successful HTTP response // before switching to RPC protocol. buffered := NewBufferedConnection(conn) resp, err := http.ReadResponse(buffered.Reader, &http.Request{Method: "CONNECT"}) if err == nil && resp.Status == connected { return rpc.NewClientWithCodec(cFactory(buffered)), nil } if err == nil { err = errors.New("unexpected HTTP response: " + resp.Status) } conn.Close() return nil, &net.OpError{"dial-http", network + " " + address, nil, err} }
相關文章
- React技巧之發出http請求ReactHTTP
- 【HTTP】HTTP請求體中的四種格式HTTP
- 淺嘗flutter中的http請求FlutterHTTP
- http請求HTTP
- HTTP 請求HTTP
- HTTP請求頭中的refer欄位HTTP
- HTTP 請求頭中的 X-Forwarded-ForHTTPForward
- HTTP請求中的referrer和Referrer-PolicyHTTP
- Http 請求頭中的 Proxy-ConnectionHTTP
- HTTP協議---HTTP請求中的常用請求欄位和HTTP的響應狀態碼及響應頭HTTP協議
- http請求概述HTTP
- HTTP請求方法HTTP
- http請求頭HTTP
- go http請求GoHTTP
- HTTP的請求過程HTTP
- golang 的 http 請求池GolangHTTP
- 我知道的HTTP請求HTTP
- JavaScript中發出HTTP請求最常用的方法JavaScriptHTTP
- http請求中get和post方法的區別HTTP
- HTTP協議中請求方法的Get和PostHTTP協議
- 合併HTTP請求vs並行HTTP請求,到底誰更快?HTTP並行
- 合併HTTP請求 vs 並行HTTP請求,到底誰更快?HTTP並行
- Cookie 與 HTTP請求CookieHTTP
- Jsoup http請求JSHTTP
- Android Http請求AndroidHTTP
- HTTP請求報文HTTP
- Python中get、post請求詳解(HTTP請求頭、狀態碼)PythonHTTP
- HTTP的請求與響應HTTP
- golang常用的http請求操作GolangHTTP
- AngularJS中的$http快取以及處理多個$http請求AngularJSHTTP快取
- Flutter中http請求抓包解決方案FlutterHTTP
- Python中http請求方法庫彙總PythonHTTP
- HTTP中的重定向和請求轉發的區別HTTP
- 【轉】怎麼用PHP傳送HTTP請求(POST請求、GET請求)?PHPHTTP
- python做http請求PythonHTTP
- Http請求資料格式HTTP
- HTTP GET請求傳bodyHTTP
- HTTP 請求與響應HTTP