简体   繁体   English

PHP套接字服务器问题(mysql连接,最大连接数限制)

[英]PHP socket server issues (mysql connection, max connections limit)

I need to write a socket server that will be handling at least something about 1000 (much more in future) low-traffic permanent connections. 我需要编写一个套接字服务器,它将至少处理大约1000个(将来会有更多)低流量的永久连接。 I have made a draft version on PHP for testing purposes (we are developing a monitoring hardware, so we needed to develop and test a conversation protocol and hardware capabilities), which suited me very well when i had just a couple of clients connected. 我已经出于测试目的在PHP上草拟了一个版本(我们正在开发监视硬件,因此我们需要开发和测试会话协议和硬件功能),当我只有几个客户端连接时,这非常适合我。 But when the amount of connections had grown to ten, some critical issues appeared. 但是,当连接数量增加到十个时,出现了一些关键问题。 Here some info about server architecture: 以下是有关服务器体系结构的一些信息:

I have a master process, which waits for socket connections and on connecting creates a child process (that serves this connection from now on) using pcntl_fork(). 我有一个主进程,它等待套接字连接,并在连接时使用pcntl_fork()创建一个子进程(从现在开始为该连接提供服务)。 Also i am setting up a PDO connection to MySQL in master process. 我也在主进程中建立与MySQL的PDO连接。 All the child processes are sharing the same single PDO object. 所有子进程都共享相同的单个PDO对象。 At first i was afraid of getting some collisions during simultaneous queries, but i haven't encountered them, even through stress-test (10 children were making queries in the loop without stopping). 起初,我担心在同时进行查询时会遇到一些冲突,但是即使通过压力测试,我也没有遇到它们(10个孩子在循环中进行查询而不停止)。 But there is usleep(500000) in each child, so it could be luck, though i had this testing running for a couple of hours. 但是每个孩子都有usleep(500000),所以运气不错,尽管我已经进行了几个小时的测试。 But such load should not be present even at 1k clients connected, due to rare conversations between them and server. 但是,即使在连接的1k客户端上也不会出现这样的负载,这是因为它们与服务器之间的对话很少。

So here is my first question : is it safe to use single PDO object for a big amount of child processes (ideally there would be around 1000)? 所以这是我的第一个问题 :对于大量子进程(理想情况下大约有1000个子进程)使用单个PDO对象是否安全? I can use single connection for each child, but MySQL doesn't support nearly as much connections. 我可以为每个孩子使用单个连接,但是MySQL不支持那么多连接。

The second issue is in getting parasite MySQL connections. 第二个问题是获取寄生MySQL连接。 As i mentioned before, i have only one PDO object. 如前所述,我只有一个PDO对象。 But when i have more than one clients connected, and after they had run some queries, i see in mytop that there is more than one DB connection, and i could not find any correlation between the amount of connections and amount of child processes i have. 但是,当我连接了多个客户端,并且在它们运行了一些查询之后,我在mytop中看到存在多个数据库连接,并且我找不到连接数量和子进程数量之间的任何关联。 。 For example i have 3 childs, and 5 DB connections. 例如,我有3个孩子,和5个DB连接。 I tried to establish persistent connections, and it didn't changed anything. 我试图建立持久的连接,但并没有改变任何东西。

Second question : Is it PDO who makes those additional connecitons to MySQL, or it is the MySQL driver? 第二个问题 :是PDO为MySQL提供了这些额外的连接器,还是MySQL驱动程序? And is there a way to force them to use one connection? 有没有办法强迫他们使用一个连接? I don't think it could be my fault, my code prints an alert to console every time i call method which creates PDO object, and that happens only once, at the script start, before forking. 我不认为这是我的错,每次我调用创建PDO对象的方法时,我的代码都会打印警报以进行控制台,并且在脚本开始之前,在派生之前仅发生一次。 After that i only run querys out of children, using parent's PDO object. 之后,我仅使用父级的PDO对象运行子级查询。 Once again i can not afford to have so many connections due to MySQL limitations. 由于MySQL的限制,我再也负担不起这么多的连接。

Third question : Will be one thousand of socket connections a problem by itself? 第三个问题 :一千个套接字连接本身是否会成为问题? Aside of the CPU and database load, i mean. 除了CPU和数据库负载外,我的意思是。 Or i should do some amount of lesser servers (128 connections for example), that will tell the clients to connect to other one if max number of connects is exceeded? 或者我应该做一些较小的服务器(例如128个连接),如果超过最大连接数,这些服务器将告诉客户端连接到另一台服务器?

Thanks in advance for your time and possible answers. 预先感谢您的时间和可能的答案。

Currently your primary concern should be your socket server architecture. 当前,您最关心的应该是套接字服务器体系结构。 Forking a process for each client is super heavy. 为每个客户分叉一个过程非常繁琐。 AFAIK an average PC can tolerate around 2000 threads and it's not going to work fast. AFAIK,一台普通的PC可以忍受大约2000个线程,并且无法快速运行。 Switching between processes means that CPU should save its state in memory, and if you have enormous amount of processes, CPU will be busy with memory IO and will have little time for actually doing stuff. 在进程之间进行切换意味着CPU应该将其状态保存在内存中,并且如果您有大量的进程,CPU将忙于内存IO,并且几乎没有时间进行实际操作。

You may want to look at Apache for inspiration. 您可能想看看Apache的启发。 In Apache they use a fixed amount of worker processes/threads, each process/thread working with multiple clients via select function and sockets in a non-blocking mode. 在Apache中,它们使用固定数量的工作进程/线程,每个进程/线程通过select函数和套接字在非阻塞模式下与多个客户端一起工作。 This is a far more robust approach. 这是一种更为可靠的方法。

Regarding database IO, I would spawn a process/thread that would be the sole owner of database connections. 关于数据库IO,我将产生一个将成为数据库连接唯一所有者的进程/线程。 Worker processes would communicate with the DB IO process using IPC (in case of processes) or lock-free queues (in case of threads). 辅助进程将使用IPC(对于进程)或无锁队列(对于线程)与DB IO进程进行通信。 This approach makes you independent of PDO implementation details (if it is thread safe or does it spawn connections etc). 这种方法使您独立于PDO实施细节(如果它是线程安全的或生成连接等)。

PS I suspect that you actually spawn new PDO objects with forking (forking merely means making a copy of a process with its memory and everything inside it) and PDO objects create and shut down connections on demand. PS我怀疑您实际上是通过派生产生了新的PDO对象(派生仅意味着使用其内存及其中的所有内容制作一个进程的副本),而PDO对象会根据需要创建和关闭连接。 It may explain why you're not seeing correlation between low traffic clients and DB connections. 它可以解释为什么您看不到低流量客户端和数据库连接之间的关联。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM