Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

grpc server接受到ctrc+c发送的信号处理问题 #1179

Open
someview opened this issue Nov 21, 2023 · 10 comments
Open

grpc server接受到ctrc+c发送的信号处理问题 #1179

someview opened this issue Nov 21, 2023 · 10 comments

Comments

@someview
Copy link

grpc server接受到ctrc+c发送的信号时,会强制程序退出,
kitex版本:0.7.3
操作系统: widnows
trans_server.go:82: [Error] KITEX: BootstrapServer accept failed, err=accept tcp [::]:52800: use of closed network connection,
这有些奇怪,看起来就像是trans_server自己注册了监听信号一样. d但是对于应用程序来说,也许退出之前需要进行一些优雅的操作。
我认为这个不应该是trans_server做的事情,而是应用本身决定程序怎么退出.

@someview
Copy link
Author

someview commented Nov 21, 2023

grpc server接受到ctrc+c发送的信号时,会强制程序退出, kitex版本:0.7.3 操作系统: widnows trans_server.go:82: [Error] KITEX: BootstrapServer accept failed, err=accept tcp [::]:52800: use of closed network connection, 这有些奇怪,看起来就像是trans_server自己注册了监听信号一样. d但是对于应用程序来说,也许退出之前需要进行一些优雅的操作。 我认为这个不应该是trans_server做的事情,而是应用本身决定程序怎么退出.

withExitSgnal方法,有些本末倒置了,怎么能把应用程序退出的行为注册到框架里面去呢
我认为应该是应用程序自己监听一个信号,然后调用server.Stop(和其他的stop方法.

@someview
Copy link
Author

someview commented Nov 21, 2023

grpc server接受到ctrc+c发送的信号时,会强制程序退出, kitex版本:0.7.3 操作系统: widnows trans_server.go:82: [Error] KITEX: BootstrapServer accept failed, err=accept tcp [::]:52800: use of closed network connection, 这有些奇怪,看起来就像是trans_server自己注册了监听信号一样. d但是对于应用程序来说,也许退出之前需要进行一些优雅的操作。 我认为这个不应该是trans_server做的事情,而是应用本身决定程序怎么退出.

withExitSgnal方法,有些本末倒置了,怎么能把应用程序退出的行为注册到框架里面去呢 我认为应该是应用程序自己监听一个信号,然后调用server.Stop(和其他的stop方法.

func (ts *transServer) BootstrapServer(ln net.Listener) (err error) {
	if ln == nil {
		return errors.New("listener is nil in gonet transport server")
	}
	ts.ln = ln
	for {
		conn, err := ts.ln.Accept()
		if err != nil {
			klog.Errorf("KITEX: BootstrapServer accept failed, err=%s", err.Error())
			os.Exit(1)
		}
		go func() {
			var (
				ctx = context.Background()
				err error
			)
			defer func() {
				transRecover(ctx, conn, "OnRead")
			}()
			bc := newBufioConn(conn)
			ctx, err = ts.transHdlr.OnActive(ctx, bc)
			if err != nil {
				klog.CtxErrorf(ctx, "KITEX: OnActive error=%s", err)
				return
			}
			for {
				ts.refreshDeadline(rpcinfo.GetRPCInfo(ctx), bc)
				err := ts.transHdlr.OnRead(ctx, bc)
				if err != nil {
					ts.onError(ctx, err, bc)
					_ = bc.Close()
					return
				}
			}
		}()
	}
}

这段代码有些奇怪,为什么要一个连接创建一个协程呢. 采用数个个net.listener + routinePool的形式,效率肯定比这个高
另外, os.Exist(1)这句话应该是错误的,会导致应用程序都退出了

@jayantxie
Copy link
Member

grpc server接受到ctrc+c发送的信号时,会强制程序退出, kitex版本:0.7.3 操作系统: widnows trans_server.go:82: [Error] KITEX: BootstrapServer accept failed, err=accept tcp [::]:52800: use of closed network connection, 这有些奇怪,看起来就像是trans_server自己注册了监听信号一样. d但是对于应用程序来说,也许退出之前需要进行一些优雅的操作。 我认为这个不应该是trans_server做的事情,而是应用本身决定程序怎么退出.

withExitSgnal方法,有些本末倒置了,怎么能把应用程序退出的行为注册到框架里面去呢 我认为应该是应用程序自己监听一个信号,然后调用server.Stop(和其他的stop方法.

之所以默认监听了信号,是为了简化接入成本,如果需要自定义信号处理,可以通过server.WithExitSignal函数,注入一个空的chan,来定制你所需要的退出逻辑。

@jayantxie
Copy link
Member

jayantxie commented Nov 23, 2023

你看的应该是gonet下的用法,gonet在kitex框架是没有深度性能优化的,一般是用于windows环境下的开发。在gonet模式下,一个连接对应一个协程是标准用法。 @someview

@someview
Copy link
Author

你看的应该是gonet下的用法,gonet在kitex框架是没有深度性能优化的,一般是用于windows环境下的开发。在gonet模式下,一个连接对应一个协程是标准用法。 @someview

这个有点奇怪吧,客户端使用grpctransport默认使用gonet包吗?我在服务端看见是调用的这个方法,k8s linux容器内看到的服务端运行的server_handler的日志

@someview
Copy link
Author

grpc server接受到ctrc+c发送的信号时,会强制程序退出, kitex版本:0.7.3 操作系统: widnows trans_server.go:82: [Error] KITEX: BootstrapServer accept failed, err=accept tcp [::]:52800: use of closed network connection, 这有些奇怪,看起来就像是trans_server自己注册了监听信号一样. d但是对于应用程序来说,也许退出之前需要进行一些优雅的操作。 我认为这个不应该是trans_server做的事情,而是应用本身决定程序怎么退出.

withExitSgnal方法,有些本末倒置了,怎么能把应用程序退出的行为注册到框架里面去呢 我认为应该是应用程序自己监听一个信号,然后调用server.Stop(和其他的stop方法.

之所以默认监听了信号,是为了简化接入成本,如果需要自定义信号处理,可以通过server.WithExitSignal函数,注入一个空的chan,来定制你所需要的退出逻辑。

外部操控不了这个逻辑吧,你看我贴出来的代码。一旦调用server.stop(),外部直接os.Exit(1)了,我是觉得这里肯定不对.

@jayantxie
Copy link
Member

jayantxie commented Nov 24, 2023

gonet这个是windows环境才会编译的,https://github.com/cloudwego/kitex/blob/develop/internal/server/remote_option_windows.go ,如果你是默认的用法,在linux下网络库采用的是netpoll,客户端也是一样的

@jayantxie
Copy link
Member

你方便把你的代码发一下吗?应该是哪里配置错了

@someview
Copy link
Author

。。。抱歉,我搞错了,没有在linux下去测试,不过windows下这个应该是个bug,调用server.stop()的时候触发了上面代码里面的os.exit(),导致程序退出了

@jayantxie
Copy link
Member

对,gonet这个退出逻辑确实不太合理

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants