How to understand the seata-golang Communication Model of distributed transaction Framework based on getty
This article introduces the knowledge of "how to understand the seata-golang communication model of getty-based distributed transaction framework". Many people will encounter this dilemma in the operation of actual cases, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
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.
When I practiced microservices in the company for 18 years, the biggest problem I encountered at that time was distributed transactions. In the same year, Ali opened up their distributed transaction solution in the community, and I quickly followed the project, which was originally called fescar and later renamed seata. Because I was very interested in open source technology, I added a lot of community groups, and I was very concerned about the dubbo-go project at that time, diving silently in it. With the understanding of seata, the idea of making a go version of the distributed transaction framework gradually came into being.
To make a golang version of the distributed transaction framework, the first problem is how to implement RPC communication. Dubbo-go is a good example, so we began to study the underlying getty of dubbo-go.
2. How to realize RPC communication based on getty
The overall model of the getty framework is as follows:
Cdn.nlark.com/yuque/0/2020/png/990845/1607269570148-17ad7ccb-6c38-489a-af28-a799ff007172.png ">
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))