优雅的使用goroutine 开启http.Server

package main

import (
	"context"
	"errors"
	"golang.org/x/sync/errgroup"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"syscall"
)

func main()  {
	g,ctx := errgroup.WithContext(context.Background())
	stop := make(chan struct{})
	g.Go(func() error{
		return serverApp(ctx,stop)
	})
	g.Go(func() error{
		return serverDebug(ctx,stop)
	})
	g.Go(func() error { //监听信号
		sign := make(chan os.Signal,1)
		//监听信号 kill ctrl+c 信号值传递给通道sign
		signal.Notify(sign,syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM,syscall.SIGQUIT)
		select {
		case <-sign:
			//取出信号
			fmt.Println("Notify")
			return errors.New("notify")
		case <-stop:
			fmt.Println("Signal stop bay")
		case <-ctx.Done():
			fmt.Println("ctx err")
			return errors.New("ctx err")
		}
		defer close(sign)
		return nil
	})

	err := g.Wait()
	fmt.Println("emo!!",err)
}
func serverDebug(ctx context.Context,stop chan struct{}) error {
	mux := http.NewServeMux()
	mux.HandleFunc("/hello",hellos)
	mux.HandleFunc("/stop", func(writer http.ResponseWriter, request *http.Request) {
		close(stop)
	})
	return server(":888888888",mux,ctx,stop)
}
func serverApp(ctx context.Context,stop <-chan struct{}) error {
	mux := http.NewServeMux()
	mux.HandleFunc("/hello",hello)
	return server(":7777",mux,ctx,stop)
}
func server(addr string,mux http.Handler,ctx context.Context,stop <-chan struct{}) error { //g errgroup.Group
	ser := http.Server{
		Addr: addr,
		Handler: mux,
	}
	go func() {
		select {
		case <-ctx.Done():
			fmt.Println("退出:",addr)
			ser.Shutdown(context.Background())
		case <-stop:
			fmt.Println("stop退出:",addr)
			ser.Shutdown(context.Background())
		}
	}()
	return ser.ListenAndServe()
}
func hello(w http.ResponseWriter,r *http.Request) {
	fmt.Fprintln(w,"hello7777,GopherCon")
}
func hellos(w http.ResponseWriter,r *http.Request) {
	fmt.Fprintln(w,"hellos8888,GopherCon")
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值