php / pecl-networking-gearman

PHP wrapper to libgearman
https://pecl.php.net/package/gearman
Other
33 stars 25 forks source link

Adding Gearman server with host and port #31

Closed tree28 closed 3 months ago

tree28 commented 3 months ago

Hello,

Background: I am using Gearman with PHP and am having difficulty successfully adding Gearman clients with ports other than default. Documentation [ here ] suggests the following: ie. `<?php

// Create our client object. $gmclient= new GearmanClient();

// Add two job servers, the first on the default 4730 port $gmclient->addServer("10.0.0.1"); $gmclient->addServer("10.0.0.2", 7003);

?>`

Observation: I am using two AWS instances as a testing environment. I have confirmed with AWS that the instances are connecting. I can successfully add a server in the default configuration or by specifying the localhost ip. ie. `<?php

// Create our client object. $gmclient= new GearmanClient();

// Add two job servers, the first on the default 4730 port $gmclient->addServer("127.0.0.1"); $gmclient->addServer("127.0.0.1", 4730); // note port update

?>`

However I cannot successfully add a server when departing from the the default host value. ie. `<?php

// Create our client object. $gmclient= new GearmanClient();

// Add two job servers, the first on the default 4730 port $gmclient->addServer("10.0.3.1"); $gmclient->addServer("10.0.3.1", 4730); // note port update

?>`

Php error: Fatal error: Uncaught GearmanException: Failed to set exception option in /var/www/html/gearman_test.php:7 Stack trace: #0 /var/www/html/gearman_test.php.php(7): GearmanClient->addServer() #1 {main} thrown in /var/www/html/gearman_test.php.php on line 7

Machine Observations: 2x Fresh AWS Ubuntu 24 instances running PHP 8.3 and Apache. No VPC security group rules are blocking communications. No firewalls are enabled. No iptables are enabled. And the following listener is enabled on each machine: ie. sudo netstat -tulpn | grep LISTEN tcp 0 0 127.0.0.1:4730 0.0.0.0:* LISTEN 775/gearmand

Question: At this point I am unsure if the underlying problem is a bug, a Gearman configuration issue, or a documentation issue. I am a new Gearman user. I think Gearman is the solution I am looking for however I do need help resolving this issue because my application really must leverage Gearman servers beyond localhost.

Please assist and many sincere thanks in advance.

tree28 commented 3 months ago

Followup:

The fatal error generated by PHP will stop by using the following boolean parameter to addServer: ie. $gmclient= new GearmanClient(); $gmclient->addServer("10.0.3.1", 4730, false);

Remaining Issue: While I still do not understand how the false option works (cannot find clear documentation) I am now receiving a new connection error. The add server problem remains. I cannot find a way to use PHP to add Gearman servers that are not the default value.

Here is the connection error: Warning: GearmanClient::doNormal(): flush(GEARMAN_COULD_NOT_CONNECT) Connection to 10.0.3.1:4730 failed -> libgearman/connection.cc:724: pid(43588)

If anyone could point me in the right direction I'd be seriously grateful.

Here is the complete code:

Client (Instance A - ip: 10.0.4.1):

$client = new GearmanClient(); $client->addServer('10.0.3.1','4730',false); $result = $client->doNormal("reverse", "Hello World!"); if ($result) { echo "Success: $result\n"; }

Worker (Instance B - ip: 10.0.3.1):

$worker = new GearmanWorker(); $worker->addServer('127.0.0.1','4730'); $worker->addFunction('reverse','reverse_fn'); function reverse_fn(GearmanJob $job) { $workload = $job->workload(); echo "Received job: " . $job->handle() . "\n"; echo "Workload: $workload\n"; $result = strrev($workload); echo "Result: $result\n"; return $result; } while ($worker->work());

ngmlabs commented 3 months ago

Hello,

gearmand seems to listen only on loopback interface (127.0.0.1:4730 in your netstat output), so you will not be able to connect via any other IP on that node (or from any other node).

You will need to remove the -L / --listen argument when running gearmand, so it will bind to all interfaces (be careful on your security groups, so that the instances will not be opened to the Internet).

tree28 commented 3 months ago

@ngmlabs – thanks for the reply.

How does one bind new addresses with Gearman or gearmand?

If you could point me toward the right documentation or offer a suggestion for how to correctly do this I'd be sincerely appreciative. I'd like to use the private ip addresses in my network.

Sincerely. (Sorry to ask such a basic question – I'm clearly very new at this)

ngmlabs commented 3 months ago
$ gearmand --help
...
  -L [ --listen ] arg                   Address the server should listen on.
                                        Default is INADDR_ANY.

I suppose you are using -L 127.0.0.1 or --listen 127.0.0.1.

If you want gearmand to listen to all interfaces, you cand remove the -L / --listen argument or you may specify the IP that the service should listen on (like --listen 10.0.3.1).

tree28 commented 3 months ago

@ngmlabs – thanks once again.

I understand and have executed the change but have encountered some new problems / or have new questions.

  1. It seems that the change needs to be run as sudo otherwise the following is returned: gearmand: Could not open log file "/var/log/gearmand.log", from "/home/ubuntu", switching to stderr. (Permission denied) (sharing an observation with you).

  2. When running sudo gearmand -L 10.0.3.1 the machine hangs and the only way I can return control is to ^C

Do you have any thoughts? Have you encountered this before?

ngmlabs commented 3 months ago

If you're using Ubuntu, I suppose you installed the gearman package and you're running the service via systemd. If my assumption is correct, you would need to replace --listen=localhost with --listen 10.0.3.1 in /etc/default/gearman-job-server and restart the service with sudo systemctl restart gearman-job-server.

tree28 commented 3 months ago

@ngmlabs – thanks for your help (and patience). Things are working and are stable. Your help has been instrumental and sincerely appreciated.

I do have one last question. I'm slightly reluctant asking here because this is actually a documentation question and I can move this question or request to another forum if wished, but I will ask it here because it's directly related to the thread. I also am reluctant to ask because it's a very basic question – but here goes.

When building a distributed gearman system that consists of at least one worker and several clients, for example: Instance A (worker) 10.0.3.1, Instance B (client) 10.0.4.1, Instance C (client) 10.0.5.1. What ip addresses should be used as parameters when adding clients and workers in php.

For example – first we to configure the client in php: Instance B (client) 10.0.4.1 $client = new GearmanClient(); $client->addServer('xx.xx.xx.xx','4730',false); // if wanting to point to Instance A (worker) is the correct ip that of instance A (ie. 10.0.3.1)?

For example – second we configure the worker in php: Instance C (worker) 10.0.3.1 $worker = new GearmanWorker(); $worker->addServer('10.0.3.1','4730'); // if this machine is the worker the ip address should belong to the given machine (ie. 10.0.3.1) correct? also note that parameters vary from clients to workers, there is no 3rd parameter.

It would be nice to have a clear example of this for example to complement and extend the simple reverse example.

ngmlabs commented 3 months ago

Besides workers and clients, you also have (at least) one server (a node that runs the gearmand service). You should add the IP of that node when calling addServer() on both workers and clients.

You can refer to the schematic below that's on the homepage of the project:

image

You can also find a clear example in the Getting Started section of the documentation.

tree28 commented 3 months ago

@ngmlabs – many sincere thanks for pointing me in the right direction. The example is clear and noted however it would be nice to see the ip addresses be explicitly included, certainly it would complement the schematic well.

Will close this ticket now, once again a sincere thanks.