func (app *Ratel) Serve(s ...server.Server) error {
	app.smu.Lock()
	defer app.smu.Unlock()
	app.servers = append(app.servers, s...)
	return nil
}
Serve start server
package ratel
import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"runtime/debug"
	"sync"
	"syscall"
	"time"
	"github.com/abulo/ratel/v2/cycle"
	"github.com/abulo/ratel/v2/goroutine"
	"github.com/abulo/ratel/v2/logger"
	"github.com/abulo/ratel/v2/registry"
	"github.com/abulo/ratel/v2/server"
	"github.com/abulo/ratel/v2/stack"
	"github.com/abulo/ratel/v2/trace"
	"github.com/abulo/ratel/v2/worker"
	"golang.org/x/sync/errgroup"
)
const (
	StageAfterStop uint32 = iota + 1
	StageBeforeStop
)
type Ratel struct {
	cycle       *cycle.Cycle
	smu         *sync.RWMutex
	initOnce    sync.Once
	startupOnce sync.Once
	stopOnce    sync.Once
	servers     []server.Server
	workers     []worker.Worker
	registerer  registry.Registry
	hooks       map[uint32]*stack.DeferStack
	stopped     chan struct{}
	sig         chan os.Signal
}
var App *Ratel
func New(fns ...func() error) (*Ratel, error) {
	App = &Ratel{}
	if err := App.Startup(fns...); err != nil {
		return nil, err
	}
	return App, nil
}
func (app *Ratel) Startup(fns ...func() error) error {
	app.initialize()
	if err := app.startup(); err != nil {
		return err
	}
	return goroutine.SerialUntilError(fns...)()
}
func (app *Ratel) initialize() {
	app.initOnce.Do(func() {
		app.cycle = cycle.NewCycle()
		app.smu = &sync.RWMutex{}
		app.servers = make([]server.Server, 0)
		app.workers = make([]worker.Worker, 0)
		app.stopped = make(chan struct{})
		app.initHooks(StageBeforeStop, StageAfterStop)
		app.Registry(registry.Nop{})
	})
}
func (app *Ratel) initHooks(hookKeys ...uint32) {
	app.hooks = make(map[uint32]*stack.DeferStack, len(hookKeys))
	for _, k := range hookKeys {
		app.hooks[k] = stack.NewStack()
	}
}
func (app *Ratel) runHooks(k uint32) {
	hooks, ok := app.hooks[k]
	if ok {
		hooks.Clean()
	}
}
func (app *Ratel) RegisterHooks(k uint32, fns ...func() error) error {
	hooks, ok := app.hooks[k]
	if ok {
		hooks.Push(fns...)
		return nil
	}
	return fmt.Errorf("hook stage not found")
}
func (app *Ratel) startup() (err error) {
	app.startupOnce.Do(func() {
		err = goroutine.SerialUntilError()()
	})
	return
}