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] Server Multi Threading #5664

Closed
smathersPersonal opened this issue Jan 19, 2025 · 7 comments
Closed

[Question] Server Multi Threading #5664

smathersPersonal opened this issue Jan 19, 2025 · 7 comments

Comments

@smathersPersonal
Copy link

Hi, Thank you for the v6 release, I've started testing it. One thing I'm unclear on is how Multi Threading works with Server implementations. I've tried it with my existing implementation (But changed to use SWOOLE_BASE). I guess I'm unclear if its working, in the process list i still see a bunch of processes. With a server config like below, is it using threads in the workers automatically? if so how many threads? Or maybe i mis understood and threads are only present if created manually using, Thread::exec(string $script_file, array ...$argv); . Another thing i tested is 'single_thread' => false and SWOOLE_PROCESS, which the documentation says NOT to do and no errors occurred.

use Swoole\WebSocket\Server;
use Swoole\Http\Request;
use Swoole\HTTP\Response;
use Swoole\WebSocket\Frame;

$server = new Server('[::]', 9000, SWOOLE_BASE);
$cpus = swoole_cpu_num();
$server->set([
  'log_level' => 5,
  'enable_coroutine' => true,
  'reactor_num' => $cpus * 2,
  'worker_num' => $cpus * 4,
  'hook_flags' => SWOOLE_HOOK_TCP | SWOOLE_HOOK_NATIVE_CURL | SWOOLE_HOOK_SLEEP | SWOOLE_HOOK_BLOCKING_FUNCTION,
  'single_thread' => false,
  'dispatch_func' => function ($server, $fd, $type) use ($sTables) {
    return ProcessHelper::dispatchFunction($sTables, $fd, $type);
  },
]);

...

PHP Version:

PHP 8.4.3 (cli) (built: Jan 18 2025 03:30:45) (ZTS)
Copyright (c) The PHP Group
Zend Engine v4.4.3, Copyright (c) Zend Technologies

Swoole Info:

swoole

Swoole => enabled
Author => Swoole Team <[email protected]>
Version => 6.0.0
Built => Jan 18 2025 04:35:13
coroutine => enabled with boost asm context
epoll => enabled
eventfd => enabled
thread => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
sockets => enabled
openssl => OpenSSL 3.0.2 15 Mar 2022
dtls => enabled
http2 => enabled
json => enabled
curl-native => enabled
pcre => enabled
zlib => 1.2.11
brotli => E16777225/D16777225
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled

Directive => Local Value => Master Value
swoole.enable_library => On => On
swoole.enable_fiber_mock => Off => Off
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => On => On
swoole.unixsock_buffer_size => 8388608 => 8388608

Thanks!

@NathanFreeman
Copy link
Member

NathanFreeman commented Jan 19, 2025

Swoole was not compiled with the --enable-swoole-thread option, so it is currently in multi-process mode.

@NathanFreeman
Copy link
Member

Due to the inability of ZendVM to support a multi-threaded environment, even if multiple Reactor threads are set in SWOOLE_PROCESS mode, only one dispatch_func can be executed at a time. Therefore, the underlying execution of this PHP function will involve locking operations, which may lead to lock contention issues

@NathanFreeman
Copy link
Member

In Swoole 6.0, when you set the dispatch_func, single_thread is automatically set to true.

@smathersPersonal
Copy link
Author

Hey, so this is how i compiled it:

phpize
./configure --enable-swoole-thread --with-php-config=/usr/bin/php-config --enable-openssl --enable-sockets --enable-swoole-curl --with-openssl-dir=/usr
make && make install

I removed the dispatch_func:

use Swoole\WebSocket\Server;
use Swoole\Http\Request;
use Swoole\HTTP\Response;
use Swoole\WebSocket\Frame;
$server = new Server('[::]', 9000, SWOOLE_BASE);
$cpus = swoole_cpu_num();
$server->set([
  'log_level' => 5,
  'enable_coroutine' => true,
  'reactor_num' => $cpus * 2,
  'worker_num' => $cpus * 4,
  'hook_flags' => SWOOLE_HOOK_TCP | SWOOLE_HOOK_NATIVE_CURL | SWOOLE_HOOK_SLEEP | SWOOLE_HOOK_BLOCKING_FUNCTION,
]);
...

Restarted service (this is a 2 cpu machine):

root     1987461       1  0 06:02 ?        00:00:00 /usr/bin/php /opt/??????/src/websocket/ws.php
root     1987462 1987461  0 06:02 ?        00:00:00 php ws_server
root     1987463 1987461  0 06:02 ?        00:00:00 php ws_server
root     1987464 1987461  0 06:02 ?        00:00:00 php ws_server
root     1987465 1987461  0 06:02 ?        00:00:00 php ws_server
root     1987466 1987461  0 06:02 ?        00:00:00 php ws_server
root     1987467 1987461  0 06:02 ?        00:00:00 php ws_server
root     1987468 1987461  0 06:02 ?        00:00:00 php ws_server
root     1987469 1987461  0 06:02 ?        00:00:00 php ws_server

Thanks!

@NathanFreeman
Copy link
Member

NathanFreeman commented Jan 19, 2025

change SWOOLE_BASE to SWOOLE_THREAD,

@smathersPersonal
Copy link
Author

Thanks for reply, unfortunately its not working very well. I tired 3 server implementation, all didn't seem to run properly, although they did only spawn 1 php process. It's just that the implementations would not process any api requests, TCP packets, or Websocket messages.

  1. Websocket
$server = new Swoole\WebSocket\Server('[::]', 9000, SWOOLE_THREAD);
$cpus = swoole_cpu_num();
$server->set([
  'log_level' => 5,
  'enable_coroutine' => true,
  'reactor_num' => $cpus * 2,
  'worker_num' => $cpus * 4,
  'hook_flags' => SWOOLE_HOOK_TCP | SWOOLE_HOOK_NATIVE_CURL | SWOOLE_HOOK_SLEEP | SWOOLE_HOOK_BLOCKING_FUNCTION,
]);
...
  1. TCP
$server = new Swoole\Server('[::]', 9090, SWOOLE_THREAD);
$cpus = swoole_cpu_num();
$server->set([
  'log_level' => 4,
  'enable_coroutine' => true,
  'reactor_num' => $cpus * 2,
  'worker_num' => $cpus * 6,
  'hook_flags' => SWOOLE_HOOK_TCP | SWOOLE_HOOK_NATIVE_CURL | SWOOLE_HOOK_SLEEP | SWOOLE_HOOK_BLOCKING_FUNCTION,
]);
...
  1. Http (My website started throwing 504 api errors after this change)
$server = new Swoole\HTTP\Server('[::]', 9009, SWOOLE_THREAD);
$cpus = swoole_cpu_num();
$server->set([
  'log_level' => 4,
  'reactor_num' => $cpus * 2,
  'worker_num' => $cpus * 6,
  'enable_coroutine' => true,
  'hook_flags' => SWOOLE_HOOK_TCP | SWOOLE_HOOK_NATIVE_CURL | SWOOLE_HOOK_SLEEP | SWOOLE_HOOK_BLOCKING_FUNCTION,
  'package_max_length' => 50 * 1024 * 1024 // 50MB
]);
...

In addition to that during restarts of the processes i saw several errors:

php: PHP Deprecated:  Swoole\Event::rshutdown(): Event::wait() in shutdown function is deprecated in Unknown on line 0 [Repeated 12 times]
php[113630]: zend_mm_heap corrupted

Perhaps later tonight Ill convert my other process that is using: $pm = new Swoole\Process\Manager();
To threads and see how it works.

Thanks!

@smathersPersonal
Copy link
Author

Just to update, I've given up on this, i will still update to use v6
But gonna focus on transitioning SWOOLE_PROCESS to SWOOLE_BASE
multiprocess only

Thanks anyways!

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

No branches or pull requests

2 participants