Socket Sharding

· 227 words · 2 minute read

Is it possible for us to listen on the same port within the same machine and application? The answer is yes—it is possible.

The OS kernel provides an option called SO_REUSEPORT, which allows multiple sockets to bind to the same port for the same application and user.

For example, we can run TCP server A on 0.0.0.0:8080 and, at the same time, run TCP server B on 0.0.0.0:8080 using SO_REUSEPORT.

However, if TCP server A and TCP server B are run by different users, the OS will throw an error.

Typically, SO_REUSEPORT is used to distribute traffic between applications more efficiently. This option is supported on Linux and FreeBSD for traffic distribution, with FreeBSD also providing the SO_REUSEPORT_LB option specifically for load balancing. On macOS, SO_REUSEPORT is available, but it does not support traffic distribution.

Implementation in Go.

package main

import (
	"context"
	"fmt"
	"golang.org/x/sys/unix"
	"net"
	"net/http"
	"os"
	"syscall"
)

func main() {
	config := net.ListenConfig{
		Control: func(network, address string, c syscall.RawConn) error {
			var opErr error
			if err := c.Control(func(fd uintptr) {
				opErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1)
			}); err != nil {
				return err
			}
			return opErr
		},
	}
	pid := os.Getpid()
	l, _ := config.Listen(context.Background(), "tcp", "127.0.0.1:8080")
	server := &http.Server{}
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Response from PID %d \n", pid)
	})
	fmt.Printf("Server with PID: %d is running \n", pid)
	panic(server.Serve(l))
}