/// <summary> /// 向服务端ACK /// </summary> /// <param name="server"></param> /// <param name="timeout"></param> /// <param name="chunk"></param> /// <returns></returns> public ChunkAck Ack(PhysicalServer server, int timeout, ConsumerAckChunk chunk) { Guard.ArgumentNotNull(server, "server"); Guard.ArgumentNotNull(chunk, "chunk"); Guard.ArgumentNotNullOrEmpty(server.ServerDomainName, "server.ServerDomainName"); Guard.ArgumentNotNullOrEmpty(server.ServerName, "server.ServerName"); MetricUtil.Set(new AckRequestCountMetric { ServerHostName = server.ServerName }); foreach (var ack in chunk.ConsumerAcks) { MetricUtil.Set(new AckMessageCountMetric { Consumer = ack.Uri }); } ChunkAck chunkAck=null; var watch = new Stopwatch(); DispatcherServiceWrapper.Client client=null; try { client = Client.CreateDispatcherServiceClient(server.ServerDomainName, timeout); watch.Start(); chunkAck = client.Ack(chunk); return chunkAck; } catch { if (client != null) client.Dispose(); throw; } finally { watch.Stop(); var milliseconds = watch.ElapsedMilliseconds; MetricUtil.Set(new AckResponseCountMetric { ServerHostName = server.ServerName, Latency = milliseconds, StatusCode = chunkAck == null ? "0" : chunkAck.StatusCode.ToString() }); MetricUtil.Set(new AckResponseLatencyMetric { ServerHostName = server.ServerName }, milliseconds); } }
public AckingEventArgs(string uri, ConsumerAckChunk chunk) { Uri = uri; AckChunk = chunk; }
/// <summary> /// Task ACK处理 /// </summary> private void RunTaskAck(object obj) { var server = obj as PhysicalServer; if (server == null) return; ConcurrentQueue<CBox<Tuple<string, ConsumerAck>>> queue; if (!Output.TryGetValue(server.ServerDomainName, out queue)) return; var consumerAcks = new List<ConsumerAck>(queue.Count); var list = new List<Tuple<string, ConsumerAck>>(queue.Count); int size = 0; while (size < Consts.Consumer_DefaultAckQueueBoundary) { size++; CBox<Tuple<string, ConsumerAck>> cbox; if (!queue.TryDequeue(out cbox)) break; var consumerAck = cbox.Value; consumerAcks.Add(consumerAck.Item2); list.Add(consumerAck); cbox.Value = null; } if (consumerAcks.Count < 1) return; //if (queue.Count > 0) //{ // System.Threading.ThreadPool.QueueUserWorkItem(RunTaskAck, server); //} for (int i = 0; i < 3; i++) { try { var chunk = new ConsumerAckChunk { ChunkID = Guid.NewGuid().ToString(), ConsumerAcks = consumerAcks, Timestamp = Time.ToTimestamp(), ClientIP = Local.IPV4 }; var ack = _server.Ack(server, 0, chunk); if (ack != null && (ack.StatusCode == StatusCode.OK || ack.StatusCode == StatusCode.Accepted)) { #if DEBUG foreach (var item in consumerAcks) { debugLog.Write(string.Format("ack->{0},server:{1}",item.MessageID,server.ServerName),item.Uri); } #endif return; } } catch (Exception ex) { MetricUtil.Set(new ExceptionCountMetric { HappenedWhere = ExceptionType.OnAck.ToString() }); Logg.Write(ex, LogLevel.Error, Consts.Consumer_Title_AckFail, new[] { new KeyValue{Key = "ServerDomainName",Value = server.ServerDomainName}, new KeyValue{Key = "ServerName",Value = server.ServerName}, new KeyValue{Key = "ServerIP",Value = server.ServerIP} }); } System.Threading.Thread.Sleep(Consts.Consumer_AckRetryIntervalTime); } }