You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

rpc_client.go 4.4 kB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. package rpc11
  2. import (
  3. "fmt"
  4. "net"
  5. "sync"
  6. "sync/atomic"
  7. )
  8. import (
  9. getty "github.com/apache/dubbo-getty"
  10. gxsync "github.com/dubbogo/gost/sync"
  11. )
  12. import (
  13. "github.com/seata/seata-go/pkg/config"
  14. log "github.com/seata/seata-go/pkg/util/log"
  15. )
  16. var (
  17. rpcClient *RpcClient
  18. MAX_CHECK_ALIVE_RETRY = 600
  19. CHECK_ALIVE_INTERNAL = 100
  20. )
  21. func init() {
  22. rpcClient = newRpcClient()
  23. }
  24. type RpcClient struct {
  25. lock sync.RWMutex
  26. conf *config.ClientConfig
  27. gettyClients []getty.Client
  28. listener getty.EventListener
  29. // serverAddress -> rpc_client.Session -> bool
  30. serverSessionsMap sync.Map
  31. sessionSize int32
  32. }
  33. func newRpcClient() *RpcClient {
  34. rpcClient := &RpcClient{
  35. conf: config.GetClientConfig(),
  36. gettyClients: make([]getty.Client, 0),
  37. listener: NewClientEventHandler(),
  38. }
  39. rpcClient.init()
  40. return rpcClient
  41. }
  42. func (r *RpcClient) init() {
  43. //todo 暂时写死地址,待改为配置
  44. //addressList := []string{"127.0.0.1:8091"}
  45. addressList := []string{"127.0.0.1:8090"}
  46. if len(addressList) == 0 {
  47. log.Warn("no have valid seata server list")
  48. }
  49. for _, address := range addressList {
  50. gettyClient := getty.NewTCPClient(
  51. getty.WithServerAddress(address),
  52. getty.WithConnectionNumber((int)(r.conf.GettyConfig.ConnectionNum)),
  53. getty.WithReconnectInterval(r.conf.GettyConfig.ReconnectInterval),
  54. getty.WithClientTaskPool(gxsync.NewTaskPoolSimple(2)),
  55. )
  56. gettyClient.RunEventLoop(r.newSession)
  57. r.gettyClients = append(r.gettyClients, gettyClient)
  58. }
  59. }
  60. func (r *RpcClient) newSession(session getty.Session) error {
  61. var (
  62. ok bool
  63. tcpConn *net.TCPConn
  64. )
  65. if r.conf.GettyConfig.GettySessionParam.CompressEncoding {
  66. session.SetCompressType(getty.CompressZip)
  67. }
  68. if tcpConn, ok = session.Conn().(*net.TCPConn); !ok {
  69. panic(fmt.Sprintf("%s, session.conn{%#v} is not tcp connection\n", session.Stat(), session.Conn()))
  70. }
  71. tcpConn.SetNoDelay(r.conf.GettyConfig.GettySessionParam.TCPNoDelay)
  72. tcpConn.SetKeepAlive(r.conf.GettyConfig.GettySessionParam.TCPKeepAlive)
  73. if r.conf.GettyConfig.GettySessionParam.TCPKeepAlive {
  74. tcpConn.SetKeepAlivePeriod(r.conf.GettyConfig.GettySessionParam.KeepAlivePeriod)
  75. }
  76. tcpConn.SetReadBuffer(r.conf.GettyConfig.GettySessionParam.TCPRBufSize)
  77. tcpConn.SetWriteBuffer(r.conf.GettyConfig.GettySessionParam.TCPWBufSize)
  78. session.SetName(r.conf.GettyConfig.GettySessionParam.SessionName)
  79. session.SetMaxMsgLen(r.conf.GettyConfig.GettySessionParam.MaxMsgLen)
  80. session.SetPkgHandler(rpcPkgHandler)
  81. session.SetEventListener(r.listener)
  82. session.SetReadTimeout(r.conf.GettyConfig.GettySessionParam.TCPReadTimeout)
  83. session.SetWriteTimeout(r.conf.GettyConfig.GettySessionParam.TCPWriteTimeout)
  84. session.SetCronPeriod((int)(r.conf.GettyConfig.HeartbeatPeriod.Nanoseconds() / 1e6))
  85. session.SetWaitTime(r.conf.GettyConfig.GettySessionParam.WaitTimeout)
  86. log.Debugf("rpc_client new session:%s", session.Stat())
  87. return nil
  88. }
  89. func (r *RpcClient) AcquireGettySession() getty.Session {
  90. // map 遍历是随机的
  91. var session getty.Session
  92. r.serverSessionsMap.Range(func(key, value interface{}) bool {
  93. session = key.(getty.Session)
  94. if session.IsClosed() {
  95. r.ReleaseGettySession(session)
  96. } else {
  97. return false
  98. }
  99. return true
  100. })
  101. if session != nil {
  102. return session
  103. }
  104. //if sessionSize == 0 {
  105. // ticker := time.NewTicker(time.Duration(CHECK_ALIVE_INTERNAL) * time.Millisecond)
  106. // defer ticker.Stop()
  107. // for i := 0; i < MAX_CHECK_ALIVE_RETRY; i++ {
  108. // <-ticker.C
  109. // allSessions.Range(func(key, value interface{}) bool {
  110. // session = key.(getty.Session)
  111. // if session.IsClosed() {
  112. // sessionManager.ReleaseGettySession(session)
  113. // } else {
  114. // return false
  115. // }
  116. // return true
  117. // })
  118. // if session != nil {
  119. // return session
  120. // }
  121. // }
  122. //}
  123. return nil
  124. }
  125. func (r *RpcClient) RegisterGettySession(session getty.Session) {
  126. //r.serverSessionsMap.Store(session, true)
  127. m, _ := r.serverSessionsMap.LoadOrStore(session.RemoteAddr(), &sync.Map{})
  128. sMap := m.(*sync.Map)
  129. sMap.Store(session, true)
  130. atomic.AddInt32(&r.sessionSize, 1)
  131. }
  132. func (r *RpcClient) ReleaseGettySession(session getty.Session) {
  133. r.serverSessionsMap.Delete(session)
  134. if !session.IsClosed() {
  135. m, _ := r.serverSessionsMap.LoadOrStore(session.RemoteAddr(), &sync.Map{})
  136. sMap := m.(*sync.Map)
  137. sMap.Delete(session)
  138. session.Close()
  139. }
  140. atomic.AddInt32(&r.sessionSize, -1)
  141. }

Go Implementation For Seata