walkor / GatewayWorker

Distributed realtime messaging framework based on workerman.
MIT License
1.01k stars 294 forks source link

Use of Multiple Business Worker in distributed system #83

Open abhinavgmfs opened 2 years ago

abhinavgmfs commented 2 years ago

Hi Walkor,

Currently we are using workerman in our current project and now we want to scale our socket server using GatewayWorker. We are thinking to use multiple gateway and business worker but we are storing clients array and lots of dynamic array on worker start. So my question is if we run multiple business worker then both business worker can share the same arrays or both business workers has their own?

We are populating dynamic array on workerstart from database and it's taking atleast 5min to populate.

Thanks

walkor commented 2 years ago

So my question is if we run multiple business worker then both business worker can share the same arrays or both business workers has their own.

Business workers has their own arrays which not be shared each other.

abhinavgmfs commented 2 years ago

Hi Walkor,

We want to avoid single point of failure so need to understand:

  1. If we are using multiple gateway workers and business worker in the different servers then how the connection is distributed. What is the concept behind this? Is there any load balancer behind this?

  2. If all the business worker are running in the different servers then all the business workers are actively working? Or one BW is active and the others are idle?

  3. What will happen if one Business worker crashes? How are Gateway workers forwarded to another Business worker?

  4. Suppose if the Registers goes down then what will happen to the existing connection and new connection? Also if we restart the Register then all the previous connections will be lost?

  5. We want to use multiple gateway and business workers so how can they share the same dynamic array that we are storing for each connection.

Please help me the above queries.

Thanks Abhinav

@walkor

walkor commented 2 years ago
  1. After the client establishes a connection with the gateway, the gateway will randomly select a worker to bind the connection with this worker. All requests for this connection will be processed by this worker. Macroscopically, different connection requests are processed by different workers. You can modify that by https://www.workerman.net/doc/gateway-worker/router.html .
  2. All the business workers are actively working.
  3. Gateway will forwarded requests to other Business workers when Business worker crashes.
  4. The register process is mainly used when the gateway and business worker are started to coordinate the establishment of connections between the gateways and business workers. After the gateways establishes connections with the business workers, the register has no effect. Therefore, register goes down will not affect the business in most cases, unless the gateway or business worker crashes and restarts then they needs register to coordinate to re-establish the connections.
  5. It is difficult to share connections directly between processes or servers in PHP. The connections are stored in the gateway process. Each connection has a unique client_id, through this client_id we can control any connection by API in business worker, such as sending data Gateway:: sendToClient ($client_id, $data). So we can control connections by API without storing connections in business.

GatewayWorker also support Gateway::bindUid($client_id, $uid) Gateway::sendToUid($client_id, $uid) Gateway:joinGroup($client_id, $group_id) Gateway:sendToGroup($group_id, $data) etc which can bind the client to the uid or join group to facilitate data distribution according to the user ID or group ID.

abhinavgmfs commented 2 years ago

Hi walkor,

If we are using multiple gateway in different servers then how the connection from client will be distributed to all the gateways. All gateway will have different lanIP and SocketIp.

$gateway = new Gateway("Websocket://192.168.43.109:7272");
$gateway->name = 'Gateway-1';
$gateway->count = 4;
$gateway->lanIp = "192.168.43.109";

$gateway = new Gateway("Websocket://192.168.43.110:7272");
$gateway->name = 'Gateway-2';
$gateway->count = 4;
$gateway->lanIp = "192.168.43.110";

$gateway = new Gateway("Websocket://192.168.43.111:7272");
$gateway->name = 'Gateway-3';
$gateway->count = 4;
$gateway->lanIp = "192.168.43.111";

Thank you

walkor commented 2 years ago

If there are multiple gateway servers, you need to add a load balancer before the gateway. There are many load balancing schemes. For example, DNS load balancing (adding multiple A records), LVS, nginx reverse proxy, haproxy, etc

abhinavgmfs commented 2 years ago

Ok thank you for the prompt reply.

According to our implementation we can only run one business worker in one server so if it goes down then how we can initiate it again from the same server or how to initiate another business worker from another server when first BW server goes down.

Thank you

walkor commented 2 years ago

When one business worker goes down the master process will immediately recreates a new available business worker.

how to initiate another business worker from another server when first BW server goes down.

GatewayWorker does not have this feature.

abhinavgmfs commented 2 years ago

When one business worker goes down the master process will immediately recreates a new available business worker.

But we are only running one business worker with single process so how it will recreates a new available business worker can you please explain?

walkor commented 2 years ago

After the workerman starts, it will create two kind of processes: the master process and the child process. The child process is used to process business, and the master process is used to monitor the child process. If a child process goes down and exits, the master process will immediately recreate a new child process. Therefore, if a business worker process goes down and exits, a new business worker process will be generated immediately

abhinavgmfs commented 2 years ago

Hi Walkor,

Can you please let me know how can I test this functionality to make the child process down and see if master is creating a new BW or not.

I have tried by killing the BW but it's not initiating a new BW.

Thank you

walkor commented 2 years ago

Are you using windows? This feature is available on Linux systems.

abhinavgmfs commented 2 years ago

I tried in both but no luck. Can you please let me know the steps to check how it generate the BW again?

walkor commented 2 years ago

image image

abhinavgmfs commented 2 years ago

Yes, it worked but what if the master business worker goes down. Is there any possibility?

walkor commented 2 years ago

Master process does not run business code, it is stable enough. Don't worry about it.

abhinavgmfs commented 2 years ago

Hi Walkor,

We are using multiple gateway in different server and if we kill one gateway from one server the connections are not transferring to server 1 gateway. We are using Mod Proxy Load balancer in Apache. Can you please help me on this?

Thank you

walkor commented 2 years ago

I'm not familiar with Mod Proxy Load balancer in Apache. Load balancer needs to have the function of detecting and kicking out failed nodes. I don't know if Apache has that.

abhinavgmfs commented 2 years ago

Ok lets keep it simple we have started a gateway 1 process and it creates master and child process. So when we kill the child process it recreates the child process again but we lost all the connected clients. How can we keep or transfer the connected clients in another gateway running.

walkor commented 2 years ago

The killing of the business process does not affect the client connection, and all clients still maintain this connection with the gateway process. If the gateway process is killed, all connections will be disconnected and cannot be transferred to other processes.

abhinavgmfs commented 2 years ago

HI Walkor,

We were running workerman previously and it has some arrays in the ws class but now we are using business worker with 4 instance but all of them have different arrays. We want to keep the arrays same in all the 4 running instances. Can you please help me on that?

$worker = new BusinessWorker();
// worker名称
$worker->name = 'MrsBusinessWorker-1';
// bussinessWorker进程数量
$worker->count = 4;
// 服务注册地址
$worker->registerAddress = '192.168.43.109:1236';

// 如果不是在根目录启动,则运行runAll方法
if(!defined('GLOBAL_START'))
{
    Worker::runAll();
}

Thanks

walkor commented 2 years ago

PHP cannot share variables directly between processes. You can store arrays in redis so that other processes can read them

abhinavgmfs commented 2 years ago

Can I use channel server to update the variables in other instance?

https://www.workerman.net/doc/workerman/components/channel-client-on.html

walkor commented 2 years ago

Yes, you can.

abhinavgmfs commented 2 years ago

Can you send me an example how we can update the variables of another instance?

abhinavgmfs commented 2 years ago

Hi Walkor,

Please send me the example as soon as possible. We have to use multiple instance of business worker one instance is not enough.

Thank you