PHP 套接字。多个端口是否更好?

PHP 套接字。多个端口是否更好?

过去 6 年来,我的服务器一直在运行,没有任何问题,但最近遇到了一些麻烦。我收到了很多 SYN_RECV 连接,这使得连接设备的积压工作推后了很多,而且没有任何东西像应该的那样更新。现在我的服务器是 Intel(R) Xeon(R) CPU E31230 @ 3.20GHz,7 核,32GB 内存,运行 CentOS 6.7 Red Hat。我在这台机器上运行了大约 +- 800 个活动连接。我有 12 个端口在运行,所有 +-800 个设备分布在这 12 个端口上,每个端口最多 100 个设备。我通过 PHP 创建/运行套接字。我将不胜感激任何建议。

-将所有东西都放在 1 个端口上有帮助吗? -将它们扩展到更多端口有帮助吗(每个端口最多 50 个设备) -调整 Linux 设置有帮助吗(会是哪些设置) -用另一种语言编写有帮助吗(如果有的话最好) -还有什么可能导致这个问题?

我启用了 SYN Cookies 来帮助应对 SYN 攻击:

sysctl -n net.ipv4.tcp_syncookies

这是我的 sysctl.conf:

/# Red Hat Linux 的内核 sysctl 配置文件 /# /# 对于二进制值,0 表示禁用,1 表示启用。有关更多详细信息,请参阅 sysctl(8) 和 /# sysctl.conf(5)。

/# 控制 IP 数据包转发 net.ipv4.ip_forward = 0

/# 控制源路由验证 net.ipv4.conf.default.rp_filter = 1

/# 不接受源路由 net.ipv4.conf.default.accept_source_route = 0

/# 控制内核的系统请求调试功能 kernel.sysrq = 0

/# 控制核心转储是否将 PID 附加到核心文件名。 /# 适用于调试多线程应用程序。 kernel.core_uses_pid = 1

/# 控制 TCP syncookies 的使用 net.ipv4.tcp_syncookies = 1

/# 在网桥上禁用 netfilter。net.bridge.bridge-nf-call-ip6tables = 0 net.bridge.bridge-nf-call-iptables = 0 net.bridge.bridge-nf-call-arptables = 0

/# 控制消息队列的默认最大大小 kernel.msgmnb = 65536

/# 控制消息的最大大小,以字节为单位 kernel.msgmax = 65536

/# 控制最大共享段大小,以字节为单位 kernel.shmmax = 68719476736

/# 控制共享内存段的最大数量,以页为单位 kernel.shmall = 4294967296

/# 重试 SYN/ACK 仅三次,而不是五次 net.ipv4.tcp_synack_retries = 5

/# 尝试关闭两次 net.ipv4.tcp_orphan_retries = 5

/# FIN-WAIT-2 仅持续 5 秒 net.ipv4.tcp_fin_timeout = 30

/# 增加 syn 套接字队列大小 (默认值:512) net.ipv4.tcp_max_syn_backlog = 1024 net.core.netdev_max_backlog = 1000

/# 使用较少探测次数进行一小时保持活动 (默认值:7200 & 9) net.ipv4.tcp_keepalive_time = 7200 net.ipv4.tcp_keepalive_probes = 5

/# 输入可以排队的最大数据包 net.core.netdev_max_backlog = 65536

/# 保留片段 15 秒(默认值:30)net.ipv4.ipfrag_time = 30

/# 使用 H-TCP 拥塞控制 net.ipv4.tcp_congestion_control = htcp

net.core.rmem_default = 256960 net.core.rmem_max = 256960 net.core.wmem_default = 256960 net.core.wmem_max = 256960

net.ipv4.tcp_sack = 1 net.ipv4.tcp_window_scaling = 1 net.ipv4.tcp_timestamps = 0 net.ipv4.ip_local_port_range = 15000 61000 net.core.somaxconn = 1024

减去“#”前的“/”

以下是运行端口的 PHP 代码:

#!/usr/bin/php -q
<?php
    error_reporting(0);
    set_time_limit(0);
    ob_implicit_flush();
    $address = '123.123.123.123';
    $port = 8000;

    //Check for the connections
    if (($master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) 
    { 
        logs("socket_create() failed, reason: " . socket_strerror($master) . "\n", $enable_logging); 
    }

    socket_set_option($master, SOL_SOCKET,SO_REUSEADDR, 1); 

    if (($ret = socket_bind($master, $address, $port)) < 0) 
    { 
        logs("socket_bind() failed, reason: " . socket_strerror($ret) . "\n", $enable_logging); 
    }

    if (($ret = socket_listen($master, SOMAXCONN)) < 0) 
    { 
        logs("socket_listen() failed, reason: " . socket_strerror($ret) . "\n", $enable_logging); 
    } 

    $read_sockets = array($master);

    //Read all data from buffer
    while (true) 
    { 
        $changed_sockets = $read_sockets; 
        $num_changed_sockets = socket_select($changed_sockets, $write = NULL, $except = NULL, NULL); 
        foreach($changed_sockets as $socket) 
        { 

            if ($socket == $master) 
            { 
                if (($client = socket_accept($master)) < 0) 
                { 
                    logs("socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n", $enable_logging); 
                    continue; 
                }
                else
                { 
                    array_push($read_sockets, $client);
                    logs("[".date('Y-m-d H:i:s')."] ".$client." CONNECTED "."(".count($read_sockets)."/".SOMAXCONN.")\r\n", $enable_logging);
                } 
            }
            else
            { 
                $buffer = socket_read($socket, 8192);
                if ($buffer === "") 
                { 
                    $index = array_search($socket, $read_sockets); 
                    unset($read_sockets[$index]); 
                    socket_close($socket); 
                }
                else
                {
                    //Do DB connections etc here
                }
            }
        }
    }
?>

我使用 bash 脚本打开和关闭端口。

任何帮助,我都愿意接受。

答案1

我设法解决了我的服务器和跟踪单元一直遇到的问题。发生了什么事,我们正在使用来自本地服务提供商的自定义 APN 网络,并且我们遇到了他们那边的问题。连接会丢失,当与我的服务器建立连接时,APN 会断开连接。这就是为什么我收到很多 SYN_RECV 连接,这些连接只有在超时后才会退出。

相关内容