地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【Linux】so_reuseportに関して

背景

so_reuseportってなんやねんと思って調べた

OSSでの対応

Nginx

Socket Sharding in NGINX OSS Release 1.9.1

apache

Redis

Node.js

サンプルソース

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <netinet/in.h>

void child(int idx)
{
        int S, C;
        const int on = 1;
        struct addrinfo *res;
        struct addrinfo hints;
        struct sockaddr_in sin4;
        socklen_t slen;

        memset(&hints, sizeof(hints), 0);
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = IPPROTO_TCP;
        hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
        getaddrinfo("127.0.0.1", "10000", &hints, &res);
        S = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
        setsockopt(S, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on));
        bind(S, res->ai_addr, res->ai_addrlen);
        freeaddrinfo(res);
        listen(S, 100);

        slen = sizeof(sin4);
        while ((C = accept(S, (struct sockaddr *)&sin4, &slen)) >= 0) {
                close(C);
                printf("accepted by child #%d\n", idx);
        }
}

int main(void)
{
        int status;
        int i;

        for (i = 0; i < 4; i++) {
                pid_t pid = fork();
                if (pid == 0) {
                        child(i);
                        return 0;
                } else if (pid < 0) {
                        perror("fork");
                        return 1;
                }
        }

        wait(&status);

        return 0;
}