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

[question] help for multiple port or multiple instance for http services #346

Closed
tsingson opened this issue Jun 22, 2015 · 11 comments · Fixed by #1119
Closed

[question] help for multiple port or multiple instance for http services #346

tsingson opened this issue Jun 22, 2015 · 11 comments · Fixed by #1119
Labels

Comments

@tsingson
Copy link

hi,

func main() {
    router := gin.Default()
    router.GET("/", func(c *gin.Context) {
       ....
    })
    router.Run(":8080") // data services 

    routerAdmin := gin.Default()
    routerAdmin.GET("/", func(c *gin.Context) {
        .....
    })
    routerAdmin.Run(":8090") // admin and monitor services 
}

but , only one port ( 8080 port ) working

yet, i know there some others solution to split different URL rout for two propose.
i just want to know single program can service tow port or not.

some one help for this??
thanks a lot.

@JimmyPettersson85
Copy link

gin.Run() is blocking so you have to call them in separate goroutines if you want to accomplish that.

@manucorporat
Copy link
Contributor

@tsingson @Slimmy is right.

func main() {
    router := gin.Default()
    router.GET("/", func(c *gin.Context) {
       ....
    })
    go router.Run(":8080") // data services 

    routerAdmin := gin.Default()
    routerAdmin.GET("/", func(c *gin.Context) {
        .....
    })
    routerAdmin.Run(":8090") // admin and monitor services 
}

@tsingson
Copy link
Author

tsingson commented Jul 5, 2015

@Slimmy @manucorporat thanks a lot!!

@shen-xianpeng
Copy link

you can do it like this:
go func() { router1.Run("127.0.0.1:9000") }()
router2.Run("127.0.0.1:8000")

@eubyte
Copy link

eubyte commented Dec 16, 2016

Is there support for multiple sites/vhosts?

@appleboy
Copy link
Member

See the PR #1119 and the following example:

package main

import (
	"log"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"golang.org/x/sync/errgroup"
)

var (
	g errgroup.Group
)

func router01() http.Handler {
	e := gin.New()
	e.Use(gin.Recovery())
	e.GET("/", func(c *gin.Context) {
		c.JSON(
			http.StatusOK,
			gin.H{
				"code":  http.StatusOK,
				"error": "Welcome server 01",
			},
		)
	})

	return e
}

func router02() http.Handler {
	e := gin.New()
	e.Use(gin.Recovery())
	e.GET("/", func(c *gin.Context) {
		c.JSON(
			http.StatusOK,
			gin.H{
				"code":  http.StatusOK,
				"error": "Welcome server 02",
			},
		)
	})

	return e
}

func main() {
	server01 := &http.Server{
		Addr:         ":8080",
		Handler:      router01(),
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
	}

	server02 := &http.Server{
		Addr:         ":8081",
		Handler:      router02(),
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
	}

	g.Go(func() error {
		return server01.ListenAndServe()
	})

	g.Go(func() error {
		return server02.ListenAndServe()
	})

	if err := g.Wait(); err != nil {
		log.Fatal(err)
	}
}

@feiyuchuixue
Copy link

Hi, Run multiple service using Gin can use https ? I want create a http and https multiple service

@kai-zer-ru
Copy link

Hi! How to use graceful shutdown with multiple servers?

@cdyue
Copy link

cdyue commented Feb 19, 2021

Hi! How to use graceful shutdown with multiple servers?

any update?

@appleboy
Copy link
Member

What is the scenario on graceful shutdown with multiple servers?

@KnBrBz
Copy link

KnBrBz commented Aug 6, 2021

Can this considered graceful? Not full code, but main idea is shown

type CSrv struct {
	done    chan struct{}
	sig     chan struct{}	
	running bool
	mux     sync.RWMutex
}

func New() *CSrv {
	return &C{
		done: make(chan struct{}),
		sig:  make(chan struct{}),
	}
}

func (c *CSrv ) Run() (err error) {
	router := gin.New()
	//router.Use(middleware.CORS())
	router.Use(gin.Logger())
	router.Use(gin.Recovery())
	router.GET("someRoute", routeHandler)

	srv := &http.Server{
		Addr:    "localhost:1111",
		Handler: router,
	}
	go c.waitForStop(srv)
	return srv.ListenAndServe()
}

func (c *C) waitForStop(srv *http.Server) {
	c.setRunning(true)
	defer close(c.sig)
	<-c.done	
	log.Println("Shutdown")
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := srv.Shutdown(ctx); err != nil {
		log.Fatal(err)
	}
	log.Println("Shutdown chart")	
}

func (c *CSrv) Stop() {
	if c.isRunning() {
		c.setRunning(false)
		close(c.done)
		<-c.sig
	}
}

func (c *CSrv) isRunning() bool {
	c.mux.RLock()
	defer c.mux.RUnlock()
	return c.running
}

func (c *CSrv) setRunning(val bool) {
	c.mux.Lock()
	defer c.mux.Unlock()
	c.running = val
}

func TestRun(t *testing.T) {
	csrv := New()
	var errG errgroup.Group

	errG.Go(func() error {
		return srv.Run()
	})
	// making some requests, check some stuff...
	....
	chrt.Stop()
	if err = errG.Wait(); err != nil {
		if !strings.HasSuffix(err.Error(), "Server closed") {
			t.Fatal(err)
		}		
	}
}

For now using this only in tests.

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

Successfully merging a pull request may close this issue.

10 participants