dubbo.apache.org/dubbo-go/v3@v3.1.1/remoting/getty/getty_server.go (about)

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one or more
     3   * contributor license agreements.  See the NOTICE file distributed with
     4   * this work for additional information regarding copyright ownership.
     5   * The ASF licenses this file to You under the Apache License, Version 2.0
     6   * (the "License"); you may not use this file except in compliance with
     7   * the License.  You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  
    18  package getty
    19  
    20  import (
    21  	"crypto/tls"
    22  	"fmt"
    23  	"net"
    24  )
    25  
    26  import (
    27  	getty "github.com/apache/dubbo-getty"
    28  
    29  	"github.com/dubbogo/gost/log/logger"
    30  	gxsync "github.com/dubbogo/gost/sync"
    31  
    32  	perrors "github.com/pkg/errors"
    33  
    34  	"gopkg.in/yaml.v2"
    35  )
    36  
    37  import (
    38  	"dubbo.apache.org/dubbo-go/v3/common"
    39  	"dubbo.apache.org/dubbo-go/v3/config"
    40  	"dubbo.apache.org/dubbo-go/v3/protocol"
    41  	"dubbo.apache.org/dubbo-go/v3/protocol/invocation"
    42  	"dubbo.apache.org/dubbo-go/v3/remoting"
    43  )
    44  
    45  var (
    46  	srvConf *ServerConfig
    47  )
    48  
    49  func initServer(protocol string) {
    50  	srvConf = GetDefaultServerConfig()
    51  	if protocol == "" {
    52  		return
    53  	}
    54  
    55  	// load server config from rootConfig.Protocols
    56  	// default use dubbo
    57  	if config.GetApplicationConfig() == nil {
    58  		return
    59  	}
    60  	if config.GetRootConfig().Protocols == nil {
    61  		return
    62  	}
    63  
    64  	protocolConf := config.GetRootConfig().Protocols[protocol]
    65  	if protocolConf == nil {
    66  		logger.Debug("use default getty server config")
    67  		return
    68  	} else {
    69  		//server tls config
    70  		tlsConfig := config.GetRootConfig().TLSConfig
    71  		if tlsConfig != nil {
    72  			srvConf.SSLEnabled = true
    73  			srvConf.TLSBuilder = &getty.ServerTlsConfigBuilder{
    74  				ServerKeyCertChainPath:        tlsConfig.TLSCertFile,
    75  				ServerPrivateKeyPath:          tlsConfig.TLSKeyFile,
    76  				ServerTrustCertCollectionPath: tlsConfig.CACertFile,
    77  			}
    78  			logger.Infof("Getty Server initialized the TLSConfig configuration")
    79  		}
    80  		//getty params
    81  		gettyServerConfig := protocolConf.Params
    82  		if gettyServerConfig == nil {
    83  			logger.Debug("gettyServerConfig is nil")
    84  			return
    85  		}
    86  
    87  		gettyServerConfigBytes, err := yaml.Marshal(gettyServerConfig)
    88  		if err != nil {
    89  			panic(err)
    90  		}
    91  		err = yaml.Unmarshal(gettyServerConfigBytes, srvConf)
    92  		if err != nil {
    93  			panic(err)
    94  		}
    95  	}
    96  
    97  	if err := srvConf.CheckValidity(); err != nil {
    98  		panic(err)
    99  	}
   100  }
   101  
   102  // SetServerConfig set dubbo server config.
   103  func SetServerConfig(s ServerConfig) {
   104  	srvConf = &s
   105  	err := srvConf.CheckValidity()
   106  	if err != nil {
   107  		logger.Warnf("[ServerConfig CheckValidity] error: %v", err)
   108  		return
   109  	}
   110  }
   111  
   112  // GetServerConfig get getty server config.
   113  func GetServerConfig() ServerConfig {
   114  	return *srvConf
   115  }
   116  
   117  // Server define getty server
   118  type Server struct {
   119  	conf           ServerConfig
   120  	addr           string
   121  	codec          remoting.Codec
   122  	tcpServer      getty.Server
   123  	rpcHandler     *RpcServerHandler
   124  	requestHandler func(*invocation.RPCInvocation) protocol.RPCResult
   125  }
   126  
   127  // NewServer create a new Server
   128  func NewServer(url *common.URL, handlers func(*invocation.RPCInvocation) protocol.RPCResult) *Server {
   129  	// init
   130  	initServer(url.Protocol)
   131  	s := &Server{
   132  		conf:           *srvConf,
   133  		addr:           url.Location,
   134  		codec:          remoting.GetCodec(url.Protocol),
   135  		requestHandler: handlers,
   136  	}
   137  
   138  	s.rpcHandler = NewRpcServerHandler(s.conf.SessionNumber, s.conf.sessionTimeout, s)
   139  
   140  	return s
   141  }
   142  
   143  func (s *Server) newSession(session getty.Session) error {
   144  	var (
   145  		ok      bool
   146  		tcpConn *net.TCPConn
   147  		err     error
   148  	)
   149  	conf := s.conf
   150  
   151  	if conf.GettySessionParam.CompressEncoding {
   152  		session.SetCompressType(getty.CompressZip)
   153  	}
   154  	if _, ok = session.Conn().(*tls.Conn); ok {
   155  		session.SetName(conf.GettySessionParam.SessionName)
   156  		session.SetMaxMsgLen(conf.GettySessionParam.MaxMsgLen)
   157  		session.SetPkgHandler(NewRpcServerPackageHandler(s))
   158  		session.SetEventListener(s.rpcHandler)
   159  		session.SetReadTimeout(conf.GettySessionParam.tcpReadTimeout)
   160  		session.SetWriteTimeout(conf.GettySessionParam.tcpWriteTimeout)
   161  		session.SetCronPeriod((int)(conf.heartbeatPeriod.Nanoseconds() / 1e6))
   162  		session.SetWaitTime(conf.GettySessionParam.waitTimeout)
   163  		logger.Debugf("server accepts new session:%s\n", session.Stat())
   164  		return nil
   165  	}
   166  	if _, ok = session.Conn().(*net.TCPConn); !ok {
   167  		panic(fmt.Sprintf("%s, session.conn{%#v} is not tcp connection\n", session.Stat(), session.Conn()))
   168  	}
   169  
   170  	if _, ok = session.Conn().(*tls.Conn); !ok {
   171  		if tcpConn, ok = session.Conn().(*net.TCPConn); !ok {
   172  			return perrors.New(fmt.Sprintf("%s, session.conn{%#v} is not tcp connection", session.Stat(), session.Conn()))
   173  		}
   174  
   175  		if err = tcpConn.SetNoDelay(conf.GettySessionParam.TcpNoDelay); err != nil {
   176  			return err
   177  		}
   178  		if err = tcpConn.SetKeepAlive(conf.GettySessionParam.TcpKeepAlive); err != nil {
   179  			return err
   180  		}
   181  		if conf.GettySessionParam.TcpKeepAlive {
   182  			if err = tcpConn.SetKeepAlivePeriod(conf.GettySessionParam.keepAlivePeriod); err != nil {
   183  				return err
   184  			}
   185  		}
   186  		if err = tcpConn.SetReadBuffer(conf.GettySessionParam.TcpRBufSize); err != nil {
   187  			return err
   188  		}
   189  		if err = tcpConn.SetWriteBuffer(conf.GettySessionParam.TcpWBufSize); err != nil {
   190  			return err
   191  		}
   192  	}
   193  
   194  	session.SetName(conf.GettySessionParam.SessionName)
   195  	session.SetMaxMsgLen(conf.GettySessionParam.MaxMsgLen)
   196  	session.SetPkgHandler(NewRpcServerPackageHandler(s))
   197  	session.SetEventListener(s.rpcHandler)
   198  	session.SetReadTimeout(conf.GettySessionParam.tcpReadTimeout)
   199  	session.SetWriteTimeout(conf.GettySessionParam.tcpWriteTimeout)
   200  	session.SetCronPeriod((int)(conf.heartbeatPeriod.Nanoseconds() / 1e6))
   201  	session.SetWaitTime(conf.GettySessionParam.waitTimeout)
   202  	logger.Debugf("server accepts new session: %s", session.Stat())
   203  	return nil
   204  }
   205  
   206  // Start dubbo server.
   207  func (s *Server) Start() {
   208  	var (
   209  		addr      string
   210  		tcpServer getty.Server
   211  	)
   212  
   213  	addr = s.addr
   214  	serverOpts := []getty.ServerOption{getty.WithLocalAddress(addr)}
   215  	if s.conf.SSLEnabled {
   216  		serverOpts = append(serverOpts, getty.WithServerSslEnabled(s.conf.SSLEnabled),
   217  			getty.WithServerTlsConfigBuilder(srvConf.TLSBuilder))
   218  		logger.Infof("Getty Server initialized the TLSConfig configuration")
   219  	}
   220  
   221  	serverOpts = append(serverOpts, getty.WithServerTaskPool(gxsync.NewTaskPoolSimple(s.conf.GrPoolSize)))
   222  
   223  	tcpServer = getty.NewTCPServer(serverOpts...)
   224  	tcpServer.RunEventLoop(s.newSession)
   225  	logger.Debugf("s bind addr{%s} ok!", s.addr)
   226  	s.tcpServer = tcpServer
   227  }
   228  
   229  // Stop dubbo server
   230  func (s *Server) Stop() {
   231  	s.tcpServer.Close()
   232  }