/// <summary> /// Called to start communication with the service. /// </summary> /// <param name="cancellationToken">CancellationToken instance.</param> /// <returns>String containing the URI the service will be listening on.</returns> public Task <string> OpenAsync(CancellationToken cancellationToken) { // Set the maximum number of concurrent connections. // Recommendation is from http://support.microsoft.com/kb/821268. System.Net.ServicePointManager.DefaultConnectionLimit = 12 * Environment.ProcessorCount; EndpointResourceDescription serviceEndpoint = _context.CodePackageActivationContext.GetEndpoint("OwinServiceEndpoint"); int port = serviceEndpoint.Port; string protocol = Enum.GetName(typeof(EndpointProtocol), serviceEndpoint.Protocol).ToLowerInvariant(); if (_context is StatefulServiceContext) { StatefulServiceContext ssc = (StatefulServiceContext)_context; _listeningAddress = String.Format( CultureInfo.InvariantCulture, "{0}://+:{1}/{2}/{3}/{4}/{5}", protocol, port, _appRoot, ssc.PartitionId, ssc.ReplicaId, Guid.NewGuid()); } else if (_context is StatelessServiceContext) { _listeningAddress = String.Format(CultureInfo.InvariantCulture, "{0}://+:{1}/{2}", protocol, port, _appRoot); } else { _eventSource.ServiceRequestFailed(_context.ServiceTypeName, _context.PartitionId, _context.ReplicaOrInstanceId, nameof(OpenAsync), $"Unknown ServiceContext type '{_context.GetType().FullName}' in service type '{_context.ServiceTypeName}'."); throw new InvalidOperationException(); } _publishAddress = this._listeningAddress.Replace("+", FabricRuntime.GetNodeContext().IPAddressOrFQDN); try { _eventSource.CreateCommunicationListener(_context.ServiceTypeName, _context.PartitionId, _context.ReplicaOrInstanceId, _listeningAddress); _serverHandle = WebApp.Start(_listeningAddress, StartupConfiguration); return(Task.FromResult(_publishAddress)); } catch (Exception ex) { _eventSource.ServiceRequestFailed(_context.ServiceTypeName, _context.PartitionId, _context.ReplicaOrInstanceId, nameof(OpenAsync), ex.ToString()); this.StopWebServer(); throw; } }
/// <summary> /// Reports the health of a node. /// </summary> /// <param name="ttl"></param> public async Task ReportNodeHealthAndLoadAsync(TimeSpan ttl) { const int MB = 1048576; HealthInformation hi = null; NodeHealthReport nhr = null; try { // Get the global memory load and report as a node health parameter. NativeMethods.MEMORYSTATUSEX msex = new NativeMethods.MEMORYSTATUSEX(); if (NativeMethods.GlobalMemoryStatus(ref msex)) { HealthState hs = (msex.dwMemoryLoad > 80) ? HealthState.Warning : (msex.dwMemoryLoad > 95) ? HealthState.Error : HealthState.Ok; // Save the current memory load. MemoryLoad = msex.dwMemoryLoad; // Create the health information to report to Service Fabric. hi = new HealthInformation("NodeHealth", "MemoryLoad", hs); hi.TimeToLive = (0.0 <= ttl.TotalMilliseconds) ? TimeSpan.FromSeconds(30) : ttl; hi.Description = $"Percent of memory in used on this node: {msex.dwMemoryLoad}"; hi.RemoveWhenExpired = true; hi.SequenceNumber = HealthInformation.AutoSequenceNumber; // Create a replica health report. nhr = new NodeHealthReport(Context.NodeContext.NodeName, hi); ServiceFabricClient.HealthManager.ReportHealth(nhr); } // Create the health information and send report to Service Fabric. hi = new HealthInformation("NodeHealth", "CPU", HealthState.Ok); hi.TimeToLive = (0.0 <= ttl.TotalMilliseconds) ? TimeSpan.FromSeconds(30) : ttl; hi.Description = $"Total CPU usage on this node: {_cpuCounter.NextValue()}"; hi.RemoveWhenExpired = true; hi.SequenceNumber = HealthInformation.AutoSequenceNumber; nhr = new NodeHealthReport(Context.NodeContext.NodeName, hi); ServiceFabricClient.HealthManager.ReportHealth(nhr); // Get the number of deployed replicas on this node for this service. int serviceReplicaCount = 0; var replicaList = await ServiceFabricClient.QueryManager.GetDeployedReplicaListAsync(Context.NodeContext.NodeName, Application); for (int i = 0; i < replicaList.Count; i++) { if (Context.ServiceName == replicaList[i].ServiceName) { serviceReplicaCount++; } } DateTimeOffset oldSampleTime = _timeOfCpuSample; TimeSpan oldCpuSample = _cpuProcessTime; _cpuProcessTime = Process.GetCurrentProcess().TotalProcessorTime; _timeOfCpuSample = DateTimeOffset.UtcNow; long processTicks = (_cpuProcessTime - oldCpuSample).Ticks; long periodTicks = (_timeOfCpuSample - oldSampleTime).Ticks; long cpuTicks = (processTicks / periodTicks); long cpuPercent = (cpuTicks / serviceReplicaCount) * 100; long partitionWorkingSet = ((Process.GetCurrentProcess().WorkingSet64 / MB) / serviceReplicaCount); // Report the partition load metrics. LoadMetric[] metrics = new LoadMetric[] { new LoadMetric("PartitionCPU", (int)cpuPercent), new LoadMetric("WorkingSetMB", Convert.ToInt32(partitionWorkingSet)) }; ReportLoad(metrics); } catch (Exception ex) { _eventSource.ServiceRequestFailed(Context.ServiceTypeName, Context.PartitionId, Context.ReplicaId, "ReportNodeHealthAndLoadAsync", ex.Message); } }