public function testAllInOne() { // ²âÊÔ´òÓ¡µ½ÆÁÄ» BigpipeLog::debug('[%s:%u][%s][debug]', __FILE__, __LINE__, __FUNCTION__); BigpipeLog::trace('[%s:%u][%s][trace]', __FILE__, __LINE__, __FUNCTION__); BigpipeLog::notice('[%s:%u][%s][notice]', __FILE__, __LINE__, __FUNCTION__); BigpipeLog::monitor('[%s:%u][%s][monitor]', __FILE__, __LINE__, __FUNCTION__); BigpipeLog::warning('[%s:%u][%s][warning]', __FILE__, __LINE__, __FUNCTION__); BigpipeLog::fatal('[%s:%u][%s][fatal]', __FILE__, __LINE__, __FUNCTION__); // ²âÊÔ²»Êä³ö´òÓ¡ÐÅÏ¢log configure $conf = new BigpipeLogConf(); $conf->severity = BigpipeLogSeverity::FATAL; $conf->disable_ostream = true; $fatal_log = sprintf('[%s:%u][%s][fatal message]', __FILE__, __LINE__, __FUNCTION__); $warning_Log = sprintf('[%s:%u][%s][warning]', __FILE__, __LINE__, __FUNCTION__); $this->assertTrue(BigpipeLog::init($conf)); BigpipeLog::fatal('%s', $fatal_log); $msg = BigpipeLog::get_last_error_message(); BigpipeLog::warning('%s', $warning_Log); $this->assertEquals($msg, BigpipeLog::get_last_error_message()); $new_fatal_log = sprintf('[%s:%u][%s][fatal new message]', __FILE__, __LINE__, __FUNCTION__); $this->assertTrue($msg == BigpipeLog::get_last_error_message()); // ²âÊÔclose BigpipeLog::close(); }
/** * 删除一个stop状态的queue * @param string $name : name of the queue * @param string $token : token of the queue * @param array $meta_params : meta配置信息 * @return boolean */ public static function delete_queue($name, $token, $meta_params) { // 参数检查 if (false === is_array($meta_params) || true === empty($name) || true === empty($token)) { BigpipeLog::fatal("[%s:%u][%s][invalid params]", __FILE__, __LINE__, __FUNCTION__); return false; } $meta = true === self::$unittest ? self::$stub_meta : self::_init_meta($meta_params); if (false === $meta) { BigpipeLog::fatal("[%s:%u][%s][fail to init meta]", __FILE__, __LINE__, __FUNCTION__); return false; } // 读取queue entry信息 $full_entry = sprintf('queue/%s', $name); $stat = array('version' => 'for test'); //仅在测试时有用 $queue_info = $meta->get_entry($full_entry, $stat); if (false === $queue_info) { BigpipeLog::fatal("[%s:%u][%s][can not access to queue under /%s]", __FILE__, __LINE__, __FUNCTION__, $full_entry); return false; } if ($token != $queue_info['token']) { BigpipeLog::fatal("[%s:%u][%s][wrong token][entry:%s]", __FILE__, __LINE__, __FUNCTION__, $full_entry); return false; } $status = $queue_info['status']; if (BigpipeQueueStatus::STOPPED != $status) { // 只删除stop状态的queue node BigpipeLog::warning("[%s:%u][%s][please stop the queue before delete it][entry:%s][status:%s]", __FILE__, __LINE__, __FUNCTION__, $full_entry, BigpipeQueueStatus::to_string($status)); return false; } $curr_version = $stat['version']; $queue_info['status'] = BigpipeQueueStatus::STOPPED; // change status of a queue $ret = $meta->delete_entry($full_entry); if (false === $ret) { BigpipeLog::fatal("[%s:%u][%s][fail to delete the queue][name:%s][ver:%u]", __FILE__, __LINE__, __FUNCTION__, $name, $curr_version); return false; } BigpipeLog::notice("[%s:%u][%s][queue is deleted][name:%s]", __FILE__, __LINE__, __FUNCTION__, $name); return true; }
/** * 从zk中读取一个node并,反序列化node value数组 * @return mixed value of a node. <p> * return value converted into associative arrays on success. <p> * return false on failure */ public function deserialize($buff) { // unpack head $this->_content = $buff; $head_arr = unpack("C1ver/C1len/S1flags/L1bdlen", $this->_content); $this->_version = $head_arr['ver']; $this->_length = $head_arr['len']; $this->_flags = $head_arr['flags']; $this->_body_len = $head_arr['bdlen']; $obj = json_decode(substr($this->_content, $this->_length), true); if (null === $obj) { BigpipeLog::warning("[%s:%u][%s][fail to decode meta node][ver:%d][flags:%u][len:%u]", __FILE__, __LINE__, __FUNCTION__, $this->_version, $this->_flags, $this->_body_len); $obj = false; } else { BigpipeLog::notice("[%s:%u][%s][meta node header][ver:%d][flags:%u][len:%u]", __FILE__, __LINE__, __FUNCTION__, $this->_version, $this->_flags, $this->_body_len); } return $obj; }
/** * 更新一个meta node的值 * @param string $path : 节点全路径(含root) * @param mixed $value : 需要更新的值 * @param number $version : 原来节点的版本 * @return true on success, or false on failure */ public function update($path, $value, $version) { if (false === $this->_inited) { BigpipeLog::warning("[%s:%u][%s][uninited]", __FILE__, __LINE__, __FUNCTION__); return false; } if ($version < 0) { // zookeeper中version == -1表示强制更新节点 // 这里我们不允许有这种操作 BigpipeLog::warning("[%s:%u][%s][invalid version][ver:%d]", __FILE__, __LINE__, __FUNCTION__, $version); return false; } // set value $ret = null; if (false === $this->exists($path)) { BigpipeLog::notice("[%s:%u][%s][node does not exist][path:%s]", __FILE__, __LINE__, __FUNCTION__, $path); } else { // get version of old node $ret = $this->_zk->set($path, $value, $version); } if (null === $ret) { BigpipeLog::warning("[%s:%u][%s][fail to update node][path:%s][ver:%u]", __FILE__, __LINE__, __FUNCTION__, $path, $version); $ret = false; } return $ret; }
/** * 发布一条消息 * @param BigpipeMessagePackage $msg_pacakge * @return BigpipePubResult on success or false on failure */ public function send($msg_package) { if (!$this->_is_started) { BigpipeLog::warning("[connection is not established][pipelet:%d]", $this->_pipelet_id); return false; } // 发送CONNECT $cmd = new BStompSendFrame(); if (!$msg_package->store($cmd->message_body)) { // 包错误,不用考虑failover了 BigpipeLog::warning("[fail to store message body]"); return false; } if (true === $this->_last_send_ok) { // 当上次发送成功才增加session mesage id // 否则message id不变,防止重复发送 $this->_session_msg_id++; } $cmd->destination = $this->_get_stripe_name(); // echo "[stripe name][$cmd->destination]<br>"; $cmd->no_dedupe = $this->_no_dedupe; $cmd->session_id = $this->_session_id; $cmd->session_message_id = $this->_session_msg_id; $cmd->receipt_id = isset($this->unittest) ? 'fake-receipt-id' : BigpipeUtilities::gen_receipt_id(); if ($this->_enable_checksum) { // 发送message包校验 $cmd->last_checksum = $this->_last_sign; $sign = creat_sign_mds64($cmd->message_body); $cmd->cur_checksum = $sign[2]; // 注意函数返回值 $this->_last_sign = $cmd->cur_checksum; } // 进入发送流程, // 发送失败则进入failover流程,直到failover失败。 $send_result = false; do { if (false === $this->_stomp_adapter->send($cmd)) { BigpipeLog::warning("[send message error][session:%s][session_msg_id:%u]", $cmd->session_id, $cmd->session_message_id); continue; } $send_result = $this->_check_ack($cmd->receipt_id, $send_result); if (false === $send_result) { // ACK失败 // 不用考虑BMQ_E_COMMAND_DUPLICATEMSG, 去重在broker做, // 用户不会收到duplicate返回. BigpipeLog::warning("[send message ack error][session:%s][session_msg_id:%u]", $cmd->session_id, $cmd->session_message_id); continue; } else { BigpipeLog::notice("[send message success][pipelet:%u][session:%s][session_msg_id:%u]", $this->_pipelet_id, $cmd->session_id, $cmd->session_message_id); break; // 发布成功 } } while ($this->_failover()); if (false !== $send_result) { $this->_active(); // 清理failover状态 } else { $this->_last_send_ok = false; } return $send_result; }