grace

package
v0.0.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 7, 2023 License: MIT Imports: 25 Imported by: 0

README

Grace

服务/进程的优雅重启/热加载

原理

  1. 主进程打开资源句柄(如监听 TCP 端口)
  2. 主进程 fork 出子进程,并将打开的资源句柄传给子进程
  3. 子进程获取资源句柄,处理资源(如处理 HTTP 请求)
  4. 主进程监听信号量 SIGQUIT、SIGUSR2
    1. 收到 SIGUSR2,则
      1. fork 新子进程,处理资源
      2. 老的子进程关闭 ( Graceful )
    2. 收到 SIGQUIT,则
      1. 老的子进程关闭 ( Graceful )
      2. 主进程退出( Start 方法返回)

子进程关闭:

  1. 发送 SIGQUIT 给子进程
  2. 处理逻辑 Graceful Stop
  3. 进程退出

Example

examples/http_server/main.go

1.启动:

./http_server

注意:保持这个进程不要退出。

2.reload:

./http_server reload

或者:

kill -USR2 40332

40332 是主进程pid。

  1. restart:
./http_server reload
./http_server

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsSubProcess

func IsSubProcess() bool

IsSubProcess 判断当前进程是否是由 master 进程派生的子进程

func RegisterResourceDriver

func RegisterResourceDriver(scheme string, fn ResourceDriverFunc)

RegisterResourceDriver 注册新的资源解析协议

func TrySetListener added in v0.0.5

func TrySetListener(res Resource, l net.Listener) error

TrySetListener 给 Resource 重新设置新的 Listener

Types

type Config

type Config struct {
	// Workers 可选,工作进程配置
	Workers map[string]*WorkerConfig `validate:"required,min=1"`

	// StatusDir 必填,状态数据文件目录,如 主进程的 pid 文件都存放在这里
	StatusDir string `validate:"required"`

	// LogDir 必填,日志文件目录
	// 每个子进程一个子目录
	LogDir string `validate:"required"`

	// StopTimeout 可选,优雅关闭的最长时间,若不填写使用默认值 "10s"
	StopTimeout string

	// CheckInterval 可选,检查版本的间隔时间,默认为 "5s"
	CheckInterval string

	// StartWait 可选,启动新进程后,老进程退出前的等待时间,默认为 "5s"
	StartWait string

	// Keep 可选,是否保持子进程一直存在
	Keep bool
}

Config 配置文件的结构体

func LoadConfig

func LoadConfig(name string) (*Config, error)

LoadConfig 加载主程序的配置文件

func NewSimpleConfig added in v0.0.5

func NewSimpleConfig() *Config

NewSimpleConfig 使用默认配置创建 Config

Example
package main

import (
	"context"
	"log"
	"path/filepath"

	"github.com/fsgo/fsgo/grace"
)

func main() {
	do := func() {
		cfg := grace.NewSimpleConfig()
		g := cfg.NewGrace()

		workerCfg := &grace.WorkerConfig{
			LogDir:  filepath.Join(cfg.LogDir, "echo"),
			Cmd:     "echo",
			CmdArgs: []string{"hello"},
		}
		worker := grace.NewWorker(workerCfg)
		g.MustRegister("echo", worker)
		err := g.Start(context.Background())
		log.Println("grace server exit:", err)
	}
	_ = do
}
Output:

func (*Config) AutoCheck added in v0.0.5

func (c *Config) AutoCheck() error

AutoCheck 解析配置

func (*Config) GetCheckInterval added in v0.0.5

func (c *Config) GetCheckInterval() time.Duration

GetCheckInterval 获取检查的间隔时间

func (*Config) GetStartWait added in v0.0.5

func (c *Config) GetStartWait() time.Duration

GetStartWait 获取启动等待间隔

func (*Config) GetStopTimeout

func (c *Config) GetStopTimeout() time.Duration

GetStopTimeout 获取配置的停止服务的超时时间

func (*Config) MustNewWorker added in v0.0.5

func (c *Config) MustNewWorker(name string) *Worker

MustNewWorker 加载配置中指定 name 的 worker

func (*Config) NewGrace added in v0.0.5

func (c *Config) NewGrace() *Grace

NewGrace 通过配置生成 grace server

func (*Config) ToOption

func (c *Config) ToOption() *Option

ToOption 转换格式

type Consumer

type Consumer interface {
	// Start 开始运行 同步、阻塞
	Start(ctx context.Context) error

	// Stop 关闭
	Stop(ctx context.Context) error

	// String 资源的描述
	String() string
}

Consumer 资源消费者

func NewServerConsumer

func NewServerConsumer(ser Server, dsn Resource) Consumer

NewServerConsumer 创建一个新的消费者

type Grace

type Grace struct {
	Option *Option

	// Logger logger,若为空,
	// 将使用默认的使用标准库的log.Writer作为输出
	Logger *log.Logger
	// contains filtered or unexported fields
}

Grace 安全的 stop、reload

func (*Grace) MustRegister added in v0.0.5

func (g *Grace) MustRegister(name string, gg *Worker)

MustRegister 注册,若失败会 panic

func (*Grace) Register

func (g *Grace) Register(name string, gg *Worker) error

Register 注册一个新的 worker

func (*Grace) Start

func (g *Grace) Start(ctx context.Context) (err error)

Start 开始服务,阻塞、同步的

type Option

type Option struct {
	StatusDir string

	LogDir string

	// StopTimeout 子进程优雅退出的超时时间
	StopTimeout time.Duration

	// 检查版本的间隔时间,默认为 5 秒
	CheckInterval time.Duration

	// StartWait 可选,启动新进程后,老进程退出前的等待时间,默认为 3 秒
	StartWait time.Duration

	// Keep 是否保持子进程存活
	// 若为 true,当子进程不存在时,将自动拉起
	Keep bool
}

Option grace 的配置选项

func (*Option) GetCheckInterval

func (c *Option) GetCheckInterval() time.Duration

GetCheckInterval 获取检查的时间间隔

func (*Option) GetMainPIDPath

func (c *Option) GetMainPIDPath() string

GetMainPIDPath 获取主程序的 PID 文件路径

func (*Option) GetStartWait added in v0.0.5

func (c *Option) GetStartWait() time.Duration

func (*Option) GetStopTimeout

func (c *Option) GetStopTimeout() time.Duration

GetStopTimeout 获取停止超时时间

func (*Option) Parser

func (c *Option) Parser() error

Parser 参数解析、检查

type Resource

type Resource interface {
	// Open 打开文件,执行后立即返回
	Open(ctx context.Context) error

	// File 资源的文件,父进程使用,以将file传递给子进程
	File(ctx context.Context) (*os.File, error)

	// Listener 获取 Listener
	Listener(ctx context.Context) (net.Listener, error)

	// String 资源的描述
	String() string
}

Resource 支持 grace 的资源

由于在 unix 上所有资源都可以用文件来表示 所以这里就使用最底层的文件类型 当 我们需要 net.Listen 的时候,也可以将文件转换为 net.Listen 也就是下面的 ListenerResource

func NextResource added in v0.0.5

func NextResource(listen string) Resource

NextResource 获取下一个资源

func ParserListenDSN added in v0.0.5

func ParserListenDSN(index int, dsn string) (Resource, error)

ParserListenDSN 通过 DSN 获取一个 Resource

type ResourceDriverFunc

type ResourceDriverFunc func(index int, dsn string) (Resource, error)

ResourceDriverFunc 解析 DSN 配置 dsn like "tcp@127.0.0.1:8080"

type Server

type Server interface {
	Serve(l net.Listener) error
	Shutdown(ctx context.Context) error
}

Server server 类型

type Worker

type Worker struct {
	// contains filtered or unexported fields
}

Worker 工作进程的逻辑

func NewWorker

func NewWorker(cfg *WorkerConfig) *Worker

NewWorker 创建一个新的 worker

func (*Worker) MustRegister added in v0.0.5

func (w *Worker) MustRegister(c Consumer, res Resource)

MustRegister 注册,若失败会 panic

func (*Worker) MustRegisterServer added in v0.0.5

func (w *Worker) MustRegisterServer(ser Server, res Resource)

MustRegisterServer 注册一个 server,若失败会 panic

func (*Worker) NextResource added in v0.0.5

func (w *Worker) NextResource() Resource

NextResource 自动解析配置的 Listen 的下一个元素为 Resource

若解析失败,panic

func (*Worker) Register

func (w *Worker) Register(c Consumer, res Resource) error

Register 注册新的消费者

func (*Worker) RegisterServer

func (w *Worker) RegisterServer(ser Server, res Resource) error

RegisterServer 注册/绑定一个 server

func (*Worker) Resource added in v0.0.5

func (w *Worker) Resource(index int) Resource

Resource 将配置的 Listen 的第 index 个 元素解析为可传递使用的 Resource

如 配置的 "tcp@127.0.0.1:8080" 会解析为 listenDSN
若解析失败,panic

type WorkerConfig

type WorkerConfig struct {
	// EnvFile 可选,提前配置 Cmd 的环境变量的文件
	// 在执行 Cmd 前,通过此文件获取env 信息
	// 1.先直接解析该文件,获取 kv,正确的格式为:
	// key1=1
	// key2=2
	// 若文件不是这个格式,则解析失败
	// 2.尝试执行当前文件,若文件输出的  kv 对,则解析成功,否则为失败
	// 若文件行以 # 开头,会当做注释
	// 允许有 0 个 kv 对
	EnvFile string

	// HomeDir 可选,执行应用程序的根目录
	// Cmd、Watches 对应的文件路径都是相对于此目录的
	HomeDir string

	// LogDir 必填,当前子进程的日志目录
	LogDir string `validate:"required"`

	// Cmd 必填,工作进程的 cmd
	Cmd string `validate:"required"`

	// StopTimeout  优雅关闭的最长时间,若不填写,则使用全局 Config 的
	StopTimeout string

	// StartWait 可选,启动新进程后,老进程退出前的等待时间,若不填写,则使用全局 Config 的
	StartWait string

	// Listen 可选,监听的资源,如 "tcp@127.0.0.1:8909",
	Listen []string

	// CmdArgs 可选,工作进程 cmd 的其他参数
	CmdArgs []string

	// Watches 可选,用于监听版本变化情况的文件列表
	Watches []string
}

WorkerConfig worker 的配置

func (*WorkerConfig) Parser

func (c *WorkerConfig) Parser() error

Parser 解析当前配置

func (*WorkerConfig) String

func (c *WorkerConfig) String() string

String 格式化输出,打印输出时时候

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL