vitess中rpc兼容http请求的技巧

简介: vitess是google的一个mysql项目,用go和python实现。https://code.google.com/p/vitess/vitess中用rpc方式来中转mysql的请求,其中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\n\n' % parts.path)
    while True:
      data = self.conn.recv(1024)
      if not data:
        raise GoRpcError('Unexpected EOF in handshake')
      if '\n\n' 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\n\n")

        // 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}
}



相关文章
|
1月前
|
JSON 监控 API
掌握使用 requests 库发送各种 HTTP 请求和处理 API 响应
本课程全面讲解了使用 Python 的 requests 库进行 API 请求与响应处理,内容涵盖环境搭建、GET 与 POST 请求、参数传递、错误处理、请求头设置及实战项目开发。通过实例教学,学员可掌握基础到高级技巧,并完成天气查询应用等实际项目,适合初学者快速上手网络编程与 API 调用。
361 130
|
2月前
|
XML JSON API
识别这些API接口定义(http,https,api,RPC,webservice,Restful api ,OpenAPI)
本内容介绍了API相关的术语分类,包括传输协议(HTTP/HTTPS)、接口风格(RESTful、WebService、RPC)及开放程度(API、OpenAPI),帮助理解各类API的特点与应用场景。
|
2月前
HTTP协议中请求方式GET 与 POST 什么区别 ?
GET和POST的主要区别在于参数传递方式、安全性和应用场景。GET通过URL传递参数,长度受限且安全性较低,适合获取数据;而POST通过请求体传递参数,安全性更高,适合提交数据。
442 2
|
4月前
|
JavaScript 前端开发 API
Node.js中发起HTTP请求的五种方式
以上五种方式,尽管只是冰山一角,但已经足以让编写Node.js HTTP请求的你,在连接世界的舞台上演奏出华丽的乐章。从原生的 `http`到现代的 `fetch`,每种方式都有独特的风格和表现力,让你的代码随着项目的节奏自由地舞动。
498 65
|
3月前
|
Go 定位技术
Golang中设置HTTP请求代理的策略
在实际应用中,可能还需要处理代理服务器的连接稳定性、响应时间、以及错误处理等。因此,建议在使用代理时增加适当的错误重试机制,以确保网络请求的健壮性。此外,由于网络编程涉及的细节较多,彻底测试以确认代理配置符合预期的行为也是十分重要的。
182 8
|
3月前
|
缓存
|
2月前
|
JSON JavaScript API
Python模拟HTTP请求实现APP自动签到
Python模拟HTTP请求实现APP自动签到
|
2月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
3月前
|
缓存 JavaScript 前端开发
Vue 3 HTTP请求封装导致响应结果无法在浏览器中获取,尽管实际请求已成功。
通过逐项检查和调试,最终可以定位问题所在,修复后便能正常在浏览器中获取响应结果。
197 0
|
3月前
|
Go
如何在Go语言的HTTP请求中设置使用代理服务器
当使用特定的代理时,在某些情况下可能需要认证信息,认证信息可以在代理URL中提供,格式通常是:
319 0