Re: Ratchet for 1000+ concurrent connections ?

5,920 views
Skip to first unread message

cboden

unread,
Apr 14, 2013, 4:11:06 PM4/14/13
to ratch...@googlegroups.com, rahe...@gmail.com
Is this exchange through web browsers?  If not you should take a look at React instead; Ratchet is for WebSockets for real time communication with web browsers. 

Threads would not help you achieve this; any language, including PHP, would do this in a single threaded event loop.

React and Ratchet can both handle 1000 connections, but I've never tried to send 1GB through them.  I'd love to see a report of your results. 

On Sunday, 14 April 2013 06:12:18 UTC-4, rahe...@gmail.com wrote:
Hi,

I have this project where I need to write a server software to accept connections from multiple clients and implement a PROTOCOL which will be used to store or retrieve data.
Its possible that there could be upto 1000 connections at the same time.
Can rachet handle that ? Also I will be writing a small protocol of my own to exchange data.
This protocol will be in PHP.
Its going to be a two way communication and there can be a data exchange of 100 MB / connection.

Is Rachet capable to handle that ? Also as far as I know PHP is not a multithreading server. So does Rachet contain the necessary extension to handle concurrent connections which can last upto 10-15 minutes each ?

Romain Neutron

unread,
Apr 15, 2013, 7:55:05 AM4/15/13
to ratch...@googlegroups.com, rahe...@gmail.com, cboden
Hello,

this is the expected behavior.

The web server you wrote is an asynchronous webserver. This mean that every call you will write should not non-blocking.
The sleep method is blocking, that's why it blocks the whole process.

It's a bit disturbing when you start with it, you will have to rethink the way you program PHP to use non-blocking features.

If you need to use blocking function, dispatch these on workers with react/zmq or react/stomp

Hope it will help you

--
Romain


On Monday 15 April 2013 at 07:35, rahe...@gmail.com wrote:

> Hi,
>
> I tested react and though its good as a webserver it still doesnt have the concurrency required.
> Here is the code I tested with :
> <?php
>
> require 'vendor/autoload.php';
>
> $app = function ($request, $response) {
> $response->writeHead(200, array('Content-Type' => 'text/plain'));
> //print_r($request->getQuery());
> $get = $request->getQuery();
>
> // If "e" is there in the query string make this sleep for a 100 seconds
> if(!empty($get['e'])){
> echo sleep(100);
> }
>
> $response->end("Hello World\n");
> };
>
> $loop = React\EventLoop\Factory::create();
> $socket = new React\Socket\Server($loop);
> $http = new React\Http\Server($socket, $loop);
>
> $http->on('request', $app);
> echo "Server running at http://127.0.0.1:1337\n";
>
> $socket->listen(1337);
> $loop->run();
>
> ?>
> You can access http://127.0.0.1:1337/ to see the hello world.
> Then access http://127.0.0.1:1337/?e=1
> That particular request will sleep for 100 seconds.
> Then I access http://127.0.0.1:1337/ again to see if it can serve the file.
> But its not serving anything as its waiting for the first request to complete. So I guess react doesnt have concurrency ?
> Please let me know if I am doing something wrong ?
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "Ratchet" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to ratchet-php...@googlegroups.com (mailto:ratchet-php...@googlegroups.com).
> For more options, visit https://groups.google.com/groups/opt_out.
>
>



Igor Wiedler

unread,
Apr 15, 2013, 7:58:23 AM4/15/13
to ratch...@googlegroups.com
Hi,

You're doing it wrong. :) In a non-blocking environment you _must never block_. Never. This includes: never call any existing PHP function that is blocking.

Examples of blocking functions in PHP core:

* Filesystem: mkdir, touch, file_get_contents, file_put_contents
* Database: PDO, mysql_*, mysqli_*, MongoDB, etc.
* sleep

There's probably quite a few more that I'm forgetting. If you want to do any I/O at all, you need to have an asynchronous driver for it.

Look at the list of projects on reactphp.org, there's non-blocking drivers for redis, dnode, zmq and stomp there. You can use those to move blocking tasks to other processes.

React can do concurrent I/O, but only if all of the calls are non-blocking. React *cannot* do parallel execution, because PHP is single-threaded.

I hope that helps.

Regards,

Igor
> To unsubscribe from this group and stop receiving emails from it, send an email to ratchet-php...@googlegroups.com.

Raheel Gupta

unread,
Apr 15, 2013, 8:07:14 AM4/15/13
to Romain Neutron, ratch...@googlegroups.com, cboden
Hi,


>> It's a bit disturbing when you start with it, you will have to rethink the way you program PHP to use non-blocking features.

I am sorry but I am new to this sir.


>> If you need to use blocking function, dispatch these on workers with react/zmq or react/stomp

How should I make it possible to do concurrent connections even if one connection becomes blocking ? Or is there a non blocking sleep ?

Also is  $response->write or  $response->end blocking or non-blocking ?
What is react/zmq or stomp ?

Raheel Gupta

unread,
Apr 16, 2013, 1:13:13 AM4/16/13
to Romain Neutron, ratch...@googlegroups.com, cboden
I also noticed that neither react or zeroMQ or ratchet doesnt support SSL.
How to implement SSL with either of the 3 ?

Igor Wiedler

unread,
Apr 16, 2013, 9:21:39 AM4/16/13
to ratch...@googlegroups.com
Hi,

For SSL, take a look at stunnel: https://www.stunnel.org/

Regards,

Igor
> To unsubscribe from this group and stop receiving emails from it, send an email to ratchet-php...@googlegroups.com.

cboden

unread,
Apr 16, 2013, 9:22:47 AM4/16/13
to ratch...@googlegroups.com, Romain Neutron, cboden, rahe...@gmail.com
React and Ratchet, if communicating with external resources that require SSL, should be put behind a reverse proxy such as Nginx that will handle SSL. 
> To unsubscribe from this group and stop receiving emails from it, send an email to ratchet-php...@googlegroups.com (mailto:ratchet-php+unsub...@googlegroups.com).

Raheel Gupta

unread,
Apr 16, 2013, 1:38:08 PM4/16/13
to cboden, ratch...@googlegroups.com, Romain Neutron

React and Ratchet, if communicating with external resources that require SSL, should be put behind a reverse proxy such as Nginx that will handle SSL. 

But I wanted to run react and ratchet independent of the web server for a better server health and performance. Otherwise it would be that there would be 2 servers running while actually its just one server required to do the main job. Any possibility of a future inclusion for SSL in Ratchet and react ?

cboden

unread,
Apr 16, 2013, 2:01:40 PM4/16/13
to ratch...@googlegroups.com, cboden, Romain Neutron, rahe...@gmail.com
Using PHP to handle SSL at a server level would be slow at a high concurrency rate; it would hurt performance, not help it.  The unix philosophy is have many small processes each do one thing and work with each other. 

I started a branch that has a working proof of concept to incorporate SSL into React.  I'm working on other features at this time, feel free to contribute to it to get SSL into the master branch. 

Cheers.

Raheel Gupta

unread,
Apr 16, 2013, 2:12:17 PM4/16/13
to cboden, ratch...@googlegroups.com, Romain Neutron
I have been playing with Golang and it takes care of SSL pretty well. Why would PHP not be able to handle SSL any better than any webserver.


>> I'm working on other features at this time, feel free to contribute to it to get SSL into the master branch.

I am no expert on SSL and will try to learn it to cotribute to this. I feel this can be a huge thing.

Igor Wiedler

unread,
Apr 16, 2013, 2:15:36 PM4/16/13
to ratch...@googlegroups.com
One big difference that comes to mind is that golang does actual concurrency, as in, multicore. PHP does not.
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "Ratchet" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to ratchet-php...@googlegroups.com.

cboden

unread,
Apr 16, 2013, 2:20:31 PM4/16/13
to ratch...@googlegroups.com, cboden, Romain Neutron, rahe...@gmail.com
Most languages, PHP included, can do SSL just fine.  In any server environment it's typically better to separate certain jobs out between different services.  Think of it like building a car; 10 people on an assembly line build 10 cars faster than 10 people trying to make 10 cars all by themselves.  

Recently at my office, our Java server (very fast, JIT, and what not) was becoming a bottleneck.  We stopped doing SSL in the application, offloaded that to an Nginx server and performance increased. 

All that being said, I wouldn't mind having SSL in React.  It would help for testing, small scale, and client connections.  

Cheers.

Jordan B

unread,
Apr 23, 2013, 3:01:49 PM4/23/13
to ratch...@googlegroups.com, rahe...@gmail.com
Hiya,
         I am using Ratchet in a production environment with thousands of users (thanks!).
         I am using supervisord to keep ratchet running. However sometimes Supervisor & PHP take up 80% CPU, and we are getting "could not open socket: too many open files" errors in the logs, meaning too many people are connecting. So far supervisor has respawned ratchet successfully. The server load is still ok, is there a way to increase this open file limit?
         Thanks again,
         Jordan

cboden

unread,
Apr 23, 2013, 3:21:51 PM4/23/13
to ratch...@googlegroups.com, rahe...@gmail.com
Hi Jordan,

Fantastic news! I'd love to hear more, including how many concurrent users you peak at.

To fix the error you're having, under the "command" argument in your Supervisor config file, instead of directly launching your Ratchet script call it like this:

bash -c "ulimit -n 10000 && php /path/to/app.php"
The error you're receiving is an OS level error.  Using `ulimit -n` will let you set the number of open file descriptors per running application, for that particular session.

Cheers.

Jordan B

unread,
Apr 23, 2013, 7:01:32 PM4/23/13
to ratch...@googlegroups.com, rahe...@gmail.com
Hi Chris,
          Thank you! That's right, I saw you've mentioned that before. I tried it but the user I'm running ratchet as (apache) doesn't have ulimit permissions. I'd prefer not to run it as root. I have simply run ulimit -n 10000 as root, that should work, right? Did you put it in the supervisor.conf so that ulimit -n will run again on reboot, or does it need to run at the same time it spawns ratchet?
          I'm not actually keeping track of how many simultaneous users we have. o.O I can tell you however that we've had 8000 new users so far to the site today. It's probably not appropriate to link to production in a tech support group, but I just followed you on twitter and can message you there.
          Thanks again, Ratchet is great!

Jordan B

unread,
Apr 24, 2013, 1:04:36 PM4/24/13
to ratch...@googlegroups.com, rahe...@gmail.com
So we were able to fix this issue by editing our limits.conf file:
root            hard    nofile          10000 
root            soft    nofile          10000 
apache          hard    nofile          10000 
apache          soft    nofile          10000 
               It looks like Ratchet is running like a champ now. We had a couple spikes of over 2000 active users yesterday and that's why we were hitting the 1024 limit and crashing. 
               Thanks for your help!

cboden

unread,
Apr 24, 2013, 7:59:06 PM4/24/13
to ratch...@googlegroups.com, rahe...@gmail.com
Good find on the solution!  I hand't known there was a limits.conf file.  I'll update the website documentation with this info, thanks!

Great to hear your service is running great and it's handling > 2k concurrent!

Jordan B

unread,
Apr 26, 2013, 8:45:38 PM4/26/13
to ratch...@googlegroups.com, rahe...@gmail.com
Hi,
           Darn, we had another too-many-files-open chat server crash today, and I'm sure we didn't have 10,000 simultaneous users, so I must not be closing the connection properly. In my chat server, I decided to use an array for my connection storage because it was easier for me to modify. Here is my connection and disconnection code:
public function __construct() {
                 $this->clients = Array();
}
 public function onOpen(ConnectionInterface $conn) {
        $this->clients[$conn->resourceId] = $conn;
    }

public function onClose(ConnectionInterface $conn) {
        unset($this->clients[$conn->resourceId]);
    }
          Does $this->clients->detach($conn) do something that my unset($this->clients[$conn->resourceId]) doesn't do?
          I'm also seeing if I can grep for the error in supervisor to restart it or write a monitoring script or something.
          Thanks,
          Jordan

cboden

unread,
Apr 26, 2013, 9:19:44 PM4/26/13
to ratch...@googlegroups.com, rahe...@gmail.com
I think using an array and calling unset should work just fine. 

Even though your user can't set a ulimit, it should be able to check it.  In your script throw in a `echo exec('ulimit -n');` to verify it's set to your expected value. 

What operating system are you running on?
What version of PHP are you running on?
Which React EventLoop are you using?

Cheers.

Jordan B

unread,
May 1, 2013, 11:38:23 PM5/1/13
to ratch...@googlegroups.com, rahe...@gmail.com
Nm it seems like we had a revert on our server that reset the server. Seems to be running strong again.
Thanks for all your help! Do you have a donate button anywhere? Can't find one on your site!

cboden

unread,
May 5, 2013, 10:33:41 PM5/5/13
to ratch...@googlegroups.com, rahe...@gmail.com
Glad to hear that.  I happened to run into the same problem at work this week, but with a different language, and ended up having to do a bit more work with pam.d.

I don't have any donation stuff set up.  Thank you very much for the offer though, it is greatly appreciated!

Cheers.
Reply all
Reply to author
Forward
Message has been deleted
0 new messages