embed/etcd.go
func (e *Etcd) servePeers() (err error) {
	ph := etcdhttp.NewPeerHandler(e.GetLogger(), e.Server)
	var peerTLScfg *tls.Config
	if !e.cfg.PeerTLSInfo.Empty() {
		if peerTLScfg, err = e.cfg.PeerTLSInfo.ServerConfig(); err != nil {
			return err
		}
	}

	for _, p := range e.Peers {
		u := p.Listener.Addr().String()
		gs := v3rpc.Server(e.Server, peerTLScfg)
		m := cmux.New(p.Listener)
		go gs.Serve(m.Match(cmux.HTTP2()))
		srv := &http.Server{
			Handler:     grpcHandlerFunc(gs, ph),
			ReadTimeout: 5 * time.Minute,
			ErrorLog:    defaultLog.New(ioutil.Discard, "", 0), // do not log user error
		}
		go srv.Serve(m.Match(cmux.Any()))
		p.serve = func() error { return m.Serve() }
		p.close = func(ctx context.Context) error {
			// gracefully shutdown http.Server
			// close open listeners, idle connections
			// until context cancel or time-out
			if e.cfg.logger != nil {
				e.cfg.logger.Info(
					"stopping serving peer traffic",
					zap.String("address", u),
				)
			}
			stopServers(ctx, &servers{secure: peerTLScfg != nil, grpc: gs, http: srv})
			if e.cfg.logger != nil {
				e.cfg.logger.Info(
					"stopped serving peer traffic",
					zap.String("address", u),
				)
			}
			return nil
		}
	}

	// start peer servers in a goroutine
	for _, pl := range e.Peers {
		go func(l *peerListener) {
			u := l.Addr().String()
			if e.cfg.logger != nil {
				e.cfg.logger.Info(
					"serving peer traffic",
					zap.String("address", u),
				)
			} else {
				plog.Info("listening for peers on ", u)
			}
			e.errHandler(l.serve())
		}(pl)
	}
	return nil
}
func (e *Etcd) servePeers() (err error) {
	ph := etcdhttp.NewPeerHandler(e.GetLogger(), e.Server)
	var peerTLScfg *tls.Config
	if !e.cfg.PeerTLSInfo.Empty() {
		if peerTLScfg, err = e.cfg.PeerTLSInfo.ServerConfig(); err != nil {
			return err
		}
	}

	for _, p := range e.Peers {
		u := p.Listener.Addr().String()
		gs := v3rpc.Server(e.Server, peerTLScfg)
		m := cmux.New(p.Listener)
		go gs.Serve(m.Match(cmux.HTTP2()))
		srv := &http.Server{
			Handler:     grpcHandlerFunc(gs, ph),
			ReadTimeout: 5 * time.Minute,
			ErrorLog:    defaultLog.New(ioutil.Discard, "", 0), // do not log user error
		}
		go srv.Serve(m.Match(cmux.Any()))
		p.serve = func() error { return m.Serve() }
		p.close = func(ctx context.Context) error {
			// gracefully shutdown http.Server
			// close open listeners, idle connections
			// until context cancel or time-out
			if e.cfg.logger != nil {
				e.cfg.logger.Info(
					"stopping serving peer traffic",
					zap.String("address", u),
				)
			}
			stopServers(ctx, &servers{secure: peerTLScfg != nil, grpc: gs, http: srv})
			if e.cfg.logger != nil {
				e.cfg.logger.Info(
					"stopped serving peer traffic",
					zap.String("address", u),
				)
			}
			return nil
		}
	}

	// start peer servers in a goroutine
	for _, pl := range e.Peers {
		go func(l *peerListener) {
			u := l.Addr().String()
			if e.cfg.logger != nil {
				e.cfg.logger.Info(
					"serving peer traffic",
					zap.String("address", u),
				)
			} else {
				plog.Info("listening for peers on ", u)
			}
			e.errHandler(l.serve())
		}(pl)
	}
	return nil
}
func ( e * Etcd ) servePeers ( ) ( err error ) { ph := etcdhttp . NewPeerHandler ( e . GetLogger ( ) , e . Server ) var peerTLScfg * tls . Config if ! e . cfg . PeerTLSInfo . Empty ( ) { if peerTLScfg , err = e . cfg . PeerTLSInfo . ServerConfig ( ) ; err != nil { return err } } for _ , p := range e . Peers { u := p . Listener . Addr ( ) . String ( ) gs := v3rpc . Server ( e . Server , peerTLScfg ) m := cmux . New ( p . Listener ) go gs . Serve ( m . Match ( cmux . HTTP2 ( ) ) ) srv := & http . Server { Handler : grpcHandlerFunc ( gs , ph ) , ReadTimeout : 5 * time . Minute , ErrorLog : defaultLog . New ( ioutil . Discard , " " , 0 ) , // do not log user error } go srv . Serve ( m . Match ( cmux . Any ( ) ) ) p . serve = func ( ) error { return m . Serve ( ) } p . close = func ( ctx context . Context ) error { // gracefully shutdown http.Server // close open listeners, idle connections // until context cancel or time-out if e . cfg . logger != nil { e . cfg . logger . Info ( " " , zap . String ( " " , u ) , ) } stopServers ( ctx , & servers { secure : peerTLScfg != nil , grpc : gs , http : srv } ) if e . cfg . logger != nil { e . cfg . logger . Info ( " " , zap . String ( " " , u ) , ) } return nil } } // start peer servers in a goroutine for _ , pl := range e . Peers { go func ( l * peerListener ) { u := l . Addr ( ) . String ( ) if e . cfg . logger != nil { e . cfg . logger . Info ( " " , zap . String ( " " , u ) , ) } else { plog . Info ( " " , u ) } e . errHandler ( l . serve ( ) ) } ( pl ) } return nil }
// configure peer handlers after rafthttp.Transport started
configure peer handlers after rafthttp . Transport started