私は、ログ メッセージ要求を Service Bus のキューにプッシュし、後でそれらをテーブル ストアに挿入するワーカー ロールによって選択される、ある種のトレース ロガーに取り組んでいます。私のマシンで実行している間、これは問題なく動作しますが (これを使用しているのは私だけなので)、サーバーに置いてテストすると、次のエラーが発生しました。
HTTP_Request2_MessageException: Malformed response: in D:\home\site\wwwroot\vendor\pear-pear.php.net\HTTP_Request2\HTTP\Request2\Adapter\Socket.php on line 1013
0 HTTP_Request2_Response->__construct('', true, Object(Net_URL2)) D:\home\site\wwwroot\vendor\pear-pear.php.net\HTTP_Request2\HTTP\Request2\Adapter\Socket.php:1013
1 HTTP_Request2_Adapter_Socket->readResponse() D:\home\site\wwwroot\vendor\pear-pear.php.net\HTTP_Request2\HTTP\Request2\Adapter\Socket.php:139
2 HTTP_Request2_Adapter_Socket->sendRequest(Object(HTTP_Request2)) D:\home\site\wwwroot\vendor\pear-pear.php.net\HTTP_Request2\HTTP\Request2.php:939
3 HTTP_Request2->send() D:\home\site\wwwroot\vendor\microsoft\windowsazure\WindowsAzure\Common\Internal\Http\HttpClient.php:262
4 WindowsAzure\Common\Internal\Http\HttpClient->send(Array, Object(WindowsAzure\Common\Internal\Http\Url)) D:\home\site\wwwroot\vendor\microsoft\windowsazure\WindowsAzure\Common\Internal\RestProxy.php:141
5 WindowsAzure\Common\Internal\RestProxy->sendContext(Object(WindowsAzure\Common\Internal\Http\HttpCallContext)) D:\home\site\wwwroot\vendor\microsoft\windowsazure\WindowsAzure\Common\Internal\ServiceRestProxy.php:86
6 WindowsAzure\Common\Internal\ServiceRestProxy->sendContext(Object(WindowsAzure\Common\Internal\Http\HttpCallContext)) D:\home\site\wwwroot\vendor\microsoft\windowsazure\WindowsAzure\ServiceBus\ServiceBusRestProxy.php:139
7 WindowsAzure\ServiceBus\ServiceBusRestProxy->sendMessage('<queuename>/mes…', Object(WindowsAzure\ServiceBus\Models\BrokeredMessage)) D:\home\site\wwwroot\vendor\microsoft\windowsazure\WindowsAzure\ServiceBus\ServiceBusRestProxy.php:155
⋮
同様の問題を説明する以前の投稿を見たことがあります。すなわち:
これは、許可される HTTPS 接続の量が制限されている PHP Azure ストレージ ライブラリに関する既知の問題であることを意味します。要件が変更される前に、私はテーブル ストアに直接アクセスしていましたが、この同じ問題に遭遇し、最初のリンクで説明されている方法で修正しました。
問題は、Table Store (など) の接続文字列エンドポイントとは異なり、接続文字列の Service Bus エンドポイントが「HTTPS」でなければならないことです。「HTTP」で使用しようとすると、400 - Bad Request エラーが返されます。
誰かが潜在的な回避策についてアイデアを持っているかどうか疑問に思っていました. アドバイスをいただければ幸いです。
ありがとう!
編集(ゲイリー・リューのコメントの後):
アイテムをキューに追加するために使用するコードは次のとおりです。
private function logToAzureSB($source, $msg, $severity, $machine)
{
// Gather all relevant information
$msgInfo = array(
"Severity" => $severity,
"Message" => $msg,
"Machine" => $machine,
"Source" => $source
);
// Encode it to a JSON string, and add it to a Brokered message.
$encoded = json_encode($msgInfo);
$message = new BrokeredMessage($encoded);
$message->setContentType("application/json");
// Attempt to push the message onto the Queue
try
{
$this->sbRestProxy->sendQueueMessage($this->azureQueueName, $message);
}
catch(ServiceException $e)
{
throw new \DatabaseException($e->getMessage, $e->getCode, $e->getPrevious);
}
}
$this->sbRestProxy
これは Service Bus REST Proxy で、ロギング クラスの初期化時に設定されます。
物事の受信側では、これの Worker ロール側のコードは次のとおりです。
public override void Run()
{
// Initiates the message pump and callback is invoked for each message that is received, calling close on the client will stop the pump.
Client.OnMessage((receivedMessage) =>
{
try
{
// Pull the Message from the recieved object.
Stream stream = receivedMessage.GetBody<Stream>();
StreamReader reader = new StreamReader(stream);
string message = reader.ReadToEnd();
LoggingMessage mMsg = JsonConvert.DeserializeObject<LoggingMessage>(message);
// Create an entry with the information given.
LogEntry entry = new LogEntry(mMsg);
// Set the Logger to the appropriate table store, and insert the entry into the table.
Logger.InsertIntoLog(entry, mMsg.Service);
}
catch
{
// Handle any message processing specific exceptions here
}
});
CompletedEvent.WaitOne();
}
ここで、Logging Message は基本的に PHP でログに記録されたメッセージ (JSON デシリアライゼーションに使用) と同じフィールドを含む単純なオブジェクトであり、LogEntry はこれらのフィールドも含む TableEntity であり、Logger はテーブル ストア ロガーのインスタンスであり、セットアップされます。 worker ロールの OnStart メソッド中。