How to understand the seata-golang Communication Model of distributed transaction Framework
This article will explain in detail how to understand the seata-golang communication model of the distributed transaction framework. The content of the article is of high quality, so the editor shares it for you as a reference. I hope you will have some understanding of the relevant knowledge after reading this article.
I. brief introduction
In the world of Java, netty, a high-performance network communication framework, is widely used. Many RPC frameworks are based on netty. In the golang world, getty is also a high-performance network communication library similar to netty. Getty was originally developed by Yu Yu, the head of the dubbogo project, and is used in dubbo-go as an underlying communication library. With the donation of dubbo-go to the apache Foundation and the joint efforts of small community partners, getty finally joined the apache family and changed its name to dubbo-getty.
2. How to realize RPC communication based on getty
The overall model of the getty framework is as follows:
The RPC communication process of seata-golang is described in detail in combination with the relevant code.
1. Establish a connection
To achieve RPC communication, we must first establish a network connection. Let's start with client.go.
Func (c * client) connect () {var (err error ss Session) for {/ / establish a session connection ss = c.dial () if ss = = nil {/ / client has been closed break } err = c.newSession (ss) if err = = nil {/ / send and receive messages ss. (* session) .run () / omit part of the code break} here / / don't distinguish between tcp connection and websocket connection. Because / / gorilla/websocket/conn.go: (Conn) Close also invoke net.Conn.Close () ss.Conn () .Close ()
The connect () method gets a session connection through the dial () method and enters the dial () method:
Func (c * client) dial () Session {switch c.endPointType {case TCP_CLIENT: return c.dialTCP () case UDP_CLIENT: return c.dialUDP () case WS_CLIENT: return c.dialWS () case WSS_CLIENT: return c.dialWSS ()} return nil}
We are focused on the TCP connection, so move on to the c.dialTCP () method:
Func (c * client) dialTCP () Session {var (err error conn net.Conn) for {if c.IsClosed () {return nil} if c.sslEnabled {if sslConfig, err: = c.tlsConfigBuilder.BuildTlsConfig () Err = = nil & & sslConfig! = nil {d: = & net.Dialer {Timeout: connectTimeout} / / establish an encrypted connection conn, err = tls.DialWithDialer (d, "tcp", c.addr) SslConfig)} else {/ / establish tcp connection conn, err = net.DialTimeout ("tcp", c.addr, connectTimeout)} if err = = nil & & gxnet.IsSameAddr (conn.RemoteAddr () Conn.LocalAddr () {conn.Close () err = errSelfConnect} if err = = nil {/ / returns a TCPSession return newTCPSession (conn, c)} log.Infof ("net.DialTimeout (addr:%s)" Timeout:%v) = error:%+v ", c.addr, connectTimeout, perrors.WithStack (err))