In a previous post I introduced the serverAddToCluster Web API action which allows us to initiate clusters and join existing ones with Zend Server. That post showed some code and discussed how the clustering process is started; now I will talk about how we should track the progress of our cluster and deal with ongoing issues. In this article, I aim to take what was discussed in my overview of Zend Server Asynchronous Actions and combine it with what we know about joining a cluster, to create a complete process.
Connecting to a cluster: Recap
Having called serverAddToCluster, we now have a server which is in transition from being a standalone, sqlite based Zend Server to a MySQL connected Zend Server cluster. It’s important to stress that this transformation is a subtle one as far as Zend Server is concerned – we merely switch the data source for management and handling of directives, extensions and applications. The rest is just setting the configuration to match the baseline so that the new member is identical to the other cluster members.
The serverAddToCluster response should look something like this:
<serverInfo> <id>5</id> .... </serverInfo>
<newCredentials> <new>Yes</new> </newCredentials>
<clusterAdminKey> <id>2</id> <username>admin</username> <name><![CDATA[admin]]></name> <hash><![CDATA[...]]></hash> <creationTime>2010-12-15T17:59:12+02:00</creationTime> </clusterAdminKey>
I’ve left in the important bits: A new database user/password pair was created, the current cluster admin Web API key is displayed.
[box type=”info”]First thing first: copy over the <hash> element and replace the current key you’re using, this will be the Web API key to sign signatures with from now on on this server.[/box]
Polling after serverAddToCluster
serverAddToCluster is unusual in that it goes through three phases once it has begun its processing. We’ve seen the first phase in the previous post. This initial phase is concluded when we finally have some information about the new cluster member in the cluster database.
Next, Zend Server continues the connection process on the cluster’s database, updating the Server record with its progress. During this stage, the cluster’s configuration is applied to the new member. Changes are made to the existing members to accomodate the new IP address and those configuration directives that reflect the cluster’s structure.
Once this step is complete, the server is effectively connected and the Join task is deleted. Polling the tasksComplete action from this point on will indicate that the cluster has no ongoing tasks. While this indicates that the cluster joining has been completed, there is still work being done: in the 3rd phase the newly joined server now goes through the process of deploying all existing applications, vhosts and libraries.
During this time you can poll the clusterGetServerStatus Web API action to retrieve the current server’s status. Once this status shows the server is at a final state (i.e, not in-progress) the entire process is finally complete.
Lets see some code
First, we will poll on the tasksComplete action:
$client = new \Zend\Http\Client(); $client->setUri('http://localhost:10081/ZendServer/Api/ tasksComplete') ->setMethod('POST') ->setHeaders(array( ... )); $response = $client->send(); echo $response->getBody();
Which should return something like this:
tasksComplete may be false for a few iterations but eventually it will become true, signaling the 2nd phase is complete. Now begins the last part of the connection process.
Next, we can retrieve server status information to see how our server is doing in the 3rd phase:
$client = new \Zend\Http\Client(); $client->setUri('http://localhost:10081/ZendServer/Api/ clusterGetServerStatus') ->setMethod('GET') ->setHeaders(array( ... ))->getRequest()->getQuery()->fromArray(array('servers' => array(5)));
$response = $client->send(); echo $response->getBody();
[box type=”info”]The “5” identifier for the server comes from the serverInfo element in the response we got earlier for serverAddToCluster[/box]
Which should respond with:
<serverInfo> <id>25</id> <name>Server unique name</name> <address>10.0.0.10</address> <status>restarting</status> <messageList /> <debugModeEnabled>false</debugModeEnabled> </serverInfo>
Continuously polling the clusterGetServerStatus should eventually land the server in some final state – error, warning or otherwise an “OK” state. At this point, you can rest assured that your server is connected and operating within your cluster. Should there be any errors, you will also get a message detailing the issues encountered.
Having completed the above process, you should now have a new cluster with a cluster member connected and ready to add new members. As we’ve seen, this process is slightly more complicated than just firing off a request, and involves polling on two sources and analyzing responses. The reward, however, is the ability to automatically grow your cluster to meet rising needs. This elasticity is used by our clients daily adapt large production systems to user spikes and prepare for known load peaks.
Next time, we will see how an established cluster can be used to add new members much more easily than the first one, with a blast from the past.