Search in sources :

Example 6 with ClusterStats

use of io.grpc.xds.Stats.ClusterStats in project grpc-java by grpc.

the class ClusterImplLoadBalancerTest method subtest_maxConcurrentRequests_appliedWithDefaultValue.

private void subtest_maxConcurrentRequests_appliedWithDefaultValue(boolean enableCircuitBreaking) {
    LoadBalancerProvider weightedTargetProvider = new WeightedTargetLoadBalancerProvider();
    WeightedTargetConfig weightedTargetConfig = buildWeightedTargetConfig(ImmutableMap.of(locality, 10));
    ClusterImplConfig config = new ClusterImplConfig(CLUSTER, EDS_SERVICE_NAME, LRS_SERVER_INFO, null, Collections.<DropOverload>emptyList(), new PolicySelection(weightedTargetProvider, weightedTargetConfig), null);
    EquivalentAddressGroup endpoint = makeAddress("endpoint-addr", locality);
    deliverAddressesAndConfig(Collections.singletonList(endpoint), config);
    // one leaf balancer
    assertThat(downstreamBalancers).hasSize(1);
    FakeLoadBalancer leafBalancer = Iterables.getOnlyElement(downstreamBalancers);
    assertThat(leafBalancer.name).isEqualTo("round_robin");
    assertThat(Iterables.getOnlyElement(leafBalancer.addresses).getAddresses()).isEqualTo(endpoint.getAddresses());
    Subchannel subchannel = leafBalancer.helper.createSubchannel(CreateSubchannelArgs.newBuilder().setAddresses(leafBalancer.addresses).build());
    leafBalancer.deliverSubchannelState(subchannel, ConnectivityState.READY);
    assertThat(currentState).isEqualTo(ConnectivityState.READY);
    for (int i = 0; i < ClusterImplLoadBalancer.DEFAULT_PER_CLUSTER_MAX_CONCURRENT_REQUESTS; i++) {
        PickResult result = currentPicker.pickSubchannel(mock(PickSubchannelArgs.class));
        assertThat(result.getStatus().isOk()).isTrue();
        ClientStreamTracer.Factory streamTracerFactory = result.getStreamTracerFactory();
        streamTracerFactory.newClientStreamTracer(ClientStreamTracer.StreamInfo.newBuilder().build(), new Metadata());
    }
    ClusterStats clusterStats = Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER));
    assertThat(clusterStats.clusterServiceName()).isEqualTo(EDS_SERVICE_NAME);
    assertThat(clusterStats.totalDroppedRequests()).isEqualTo(0L);
    PickResult result = currentPicker.pickSubchannel(mock(PickSubchannelArgs.class));
    clusterStats = Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER));
    assertThat(clusterStats.clusterServiceName()).isEqualTo(EDS_SERVICE_NAME);
    if (enableCircuitBreaking) {
        assertThat(result.getStatus().isOk()).isFalse();
        assertThat(result.getStatus().getCode()).isEqualTo(Code.UNAVAILABLE);
        assertThat(result.getStatus().getDescription()).isEqualTo("Cluster max concurrent requests limit exceeded");
        assertThat(clusterStats.totalDroppedRequests()).isEqualTo(1L);
    } else {
        assertThat(result.getStatus().isOk()).isTrue();
        assertThat(clusterStats.totalDroppedRequests()).isEqualTo(0L);
    }
}
Also used : ClientStreamTracer(io.grpc.ClientStreamTracer) Metadata(io.grpc.Metadata) WeightedTargetConfig(io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedTargetConfig) WeightedPolicySelection(io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedPolicySelection) PolicySelection(io.grpc.internal.ServiceConfigUtil.PolicySelection) ClusterImplConfig(io.grpc.xds.ClusterImplLoadBalancerProvider.ClusterImplConfig) ClusterStats(io.grpc.xds.Stats.ClusterStats) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) LoadBalancerProvider(io.grpc.LoadBalancerProvider) PickResult(io.grpc.LoadBalancer.PickResult) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs)

Example 7 with ClusterStats

use of io.grpc.xds.Stats.ClusterStats in project grpc-java by grpc.

the class ClusterImplLoadBalancerTest method recordLoadStats.

@Test
public void recordLoadStats() {
    LoadBalancerProvider weightedTargetProvider = new WeightedTargetLoadBalancerProvider();
    WeightedTargetConfig weightedTargetConfig = buildWeightedTargetConfig(ImmutableMap.of(locality, 10));
    ClusterImplConfig config = new ClusterImplConfig(CLUSTER, EDS_SERVICE_NAME, LRS_SERVER_INFO, null, Collections.<DropOverload>emptyList(), new PolicySelection(weightedTargetProvider, weightedTargetConfig), null);
    EquivalentAddressGroup endpoint = makeAddress("endpoint-addr", locality);
    deliverAddressesAndConfig(Collections.singletonList(endpoint), config);
    FakeLoadBalancer leafBalancer = Iterables.getOnlyElement(downstreamBalancers);
    Subchannel subchannel = leafBalancer.helper.createSubchannel(CreateSubchannelArgs.newBuilder().setAddresses(leafBalancer.addresses).build());
    leafBalancer.deliverSubchannelState(subchannel, ConnectivityState.READY);
    assertThat(currentState).isEqualTo(ConnectivityState.READY);
    PickResult result = currentPicker.pickSubchannel(mock(PickSubchannelArgs.class));
    assertThat(result.getStatus().isOk()).isTrue();
    ClientStreamTracer streamTracer1 = result.getStreamTracerFactory().newClientStreamTracer(ClientStreamTracer.StreamInfo.newBuilder().build(), // first RPC call
    new Metadata());
    ClientStreamTracer streamTracer2 = result.getStreamTracerFactory().newClientStreamTracer(ClientStreamTracer.StreamInfo.newBuilder().build(), // second RPC call
    new Metadata());
    ClientStreamTracer streamTracer3 = result.getStreamTracerFactory().newClientStreamTracer(ClientStreamTracer.StreamInfo.newBuilder().build(), // third RPC call
    new Metadata());
    streamTracer1.streamClosed(Status.OK);
    streamTracer2.streamClosed(Status.UNAVAILABLE);
    ClusterStats clusterStats = Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER));
    UpstreamLocalityStats localityStats = Iterables.getOnlyElement(clusterStats.upstreamLocalityStatsList());
    assertThat(localityStats.locality()).isEqualTo(locality);
    assertThat(localityStats.totalIssuedRequests()).isEqualTo(3L);
    assertThat(localityStats.totalSuccessfulRequests()).isEqualTo(1L);
    assertThat(localityStats.totalErrorRequests()).isEqualTo(1L);
    assertThat(localityStats.totalRequestsInProgress()).isEqualTo(1L);
    streamTracer3.streamClosed(Status.OK);
    // stats recorder released
    subchannel.shutdown();
    clusterStats = Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER));
    // Locality load is reported for one last time in case of loads occurred since the previous
    // load report.
    localityStats = Iterables.getOnlyElement(clusterStats.upstreamLocalityStatsList());
    assertThat(localityStats.locality()).isEqualTo(locality);
    assertThat(localityStats.totalIssuedRequests()).isEqualTo(0L);
    assertThat(localityStats.totalSuccessfulRequests()).isEqualTo(1L);
    assertThat(localityStats.totalErrorRequests()).isEqualTo(0L);
    assertThat(localityStats.totalRequestsInProgress()).isEqualTo(0L);
    clusterStats = Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER));
    // no longer reported
    assertThat(clusterStats.upstreamLocalityStatsList()).isEmpty();
}
Also used : UpstreamLocalityStats(io.grpc.xds.Stats.UpstreamLocalityStats) ClientStreamTracer(io.grpc.ClientStreamTracer) Metadata(io.grpc.Metadata) WeightedTargetConfig(io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedTargetConfig) WeightedPolicySelection(io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedPolicySelection) PolicySelection(io.grpc.internal.ServiceConfigUtil.PolicySelection) ClusterImplConfig(io.grpc.xds.ClusterImplLoadBalancerProvider.ClusterImplConfig) ClusterStats(io.grpc.xds.Stats.ClusterStats) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) LoadBalancerProvider(io.grpc.LoadBalancerProvider) PickResult(io.grpc.LoadBalancer.PickResult) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) Test(org.junit.Test)

Example 8 with ClusterStats

use of io.grpc.xds.Stats.ClusterStats in project grpc-java by grpc.

the class ClusterImplLoadBalancerTest method dropRpcsWithRespectToLbConfigDropCategories.

@Test
public void dropRpcsWithRespectToLbConfigDropCategories() {
    LoadBalancerProvider weightedTargetProvider = new WeightedTargetLoadBalancerProvider();
    WeightedTargetConfig weightedTargetConfig = buildWeightedTargetConfig(ImmutableMap.of(locality, 10));
    ClusterImplConfig config = new ClusterImplConfig(CLUSTER, EDS_SERVICE_NAME, LRS_SERVER_INFO, null, Collections.singletonList(DropOverload.create("throttle", 500_000)), new PolicySelection(weightedTargetProvider, weightedTargetConfig), null);
    EquivalentAddressGroup endpoint = makeAddress("endpoint-addr", locality);
    deliverAddressesAndConfig(Collections.singletonList(endpoint), config);
    when(mockRandom.nextInt(anyInt())).thenReturn(499_999, 999_999, 1_000_000);
    // one leaf balancer
    assertThat(downstreamBalancers).hasSize(1);
    FakeLoadBalancer leafBalancer = Iterables.getOnlyElement(downstreamBalancers);
    assertThat(leafBalancer.name).isEqualTo("round_robin");
    assertThat(Iterables.getOnlyElement(leafBalancer.addresses).getAddresses()).isEqualTo(endpoint.getAddresses());
    Subchannel subchannel = leafBalancer.helper.createSubchannel(CreateSubchannelArgs.newBuilder().setAddresses(leafBalancer.addresses).build());
    leafBalancer.deliverSubchannelState(subchannel, ConnectivityState.READY);
    assertThat(currentState).isEqualTo(ConnectivityState.READY);
    PickResult result = currentPicker.pickSubchannel(mock(PickSubchannelArgs.class));
    assertThat(result.getStatus().isOk()).isFalse();
    assertThat(result.getStatus().getCode()).isEqualTo(Code.UNAVAILABLE);
    assertThat(result.getStatus().getDescription()).isEqualTo("Dropped: throttle");
    ClusterStats clusterStats = Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER));
    assertThat(clusterStats.clusterServiceName()).isEqualTo(EDS_SERVICE_NAME);
    assertThat(Iterables.getOnlyElement(clusterStats.droppedRequestsList()).category()).isEqualTo("throttle");
    assertThat(Iterables.getOnlyElement(clusterStats.droppedRequestsList()).droppedCount()).isEqualTo(1L);
    assertThat(clusterStats.totalDroppedRequests()).isEqualTo(1L);
    // Config update updates drop policies.
    config = new ClusterImplConfig(CLUSTER, EDS_SERVICE_NAME, LRS_SERVER_INFO, null, Collections.singletonList(DropOverload.create("lb", 1_000_000)), new PolicySelection(weightedTargetProvider, weightedTargetConfig), null);
    loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(Collections.singletonList(endpoint)).setAttributes(Attributes.newBuilder().set(InternalXdsAttributes.XDS_CLIENT_POOL, xdsClientPool).build()).setLoadBalancingPolicyConfig(config).build());
    result = currentPicker.pickSubchannel(mock(PickSubchannelArgs.class));
    assertThat(result.getStatus().isOk()).isFalse();
    assertThat(result.getStatus().getCode()).isEqualTo(Code.UNAVAILABLE);
    assertThat(result.getStatus().getDescription()).isEqualTo("Dropped: lb");
    clusterStats = Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER));
    assertThat(clusterStats.clusterServiceName()).isEqualTo(EDS_SERVICE_NAME);
    assertThat(Iterables.getOnlyElement(clusterStats.droppedRequestsList()).category()).isEqualTo("lb");
    assertThat(Iterables.getOnlyElement(clusterStats.droppedRequestsList()).droppedCount()).isEqualTo(1L);
    assertThat(clusterStats.totalDroppedRequests()).isEqualTo(1L);
    result = currentPicker.pickSubchannel(mock(PickSubchannelArgs.class));
    assertThat(result.getStatus().isOk()).isTrue();
}
Also used : ClusterStats(io.grpc.xds.Stats.ClusterStats) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) LoadBalancerProvider(io.grpc.LoadBalancerProvider) PickResult(io.grpc.LoadBalancer.PickResult) WeightedTargetConfig(io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedTargetConfig) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) WeightedPolicySelection(io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedPolicySelection) PolicySelection(io.grpc.internal.ServiceConfigUtil.PolicySelection) ClusterImplConfig(io.grpc.xds.ClusterImplLoadBalancerProvider.ClusterImplConfig) Test(org.junit.Test)

Example 9 with ClusterStats

use of io.grpc.xds.Stats.ClusterStats in project grpc-java by grpc.

the class LoadStatsManager2Test method sharedDropCounterStatsAggregation.

@Test
public void sharedDropCounterStatsAggregation() {
    ClusterDropStats ref1 = loadStatsManager.getClusterDropStats(CLUSTER_NAME1, EDS_SERVICE_NAME1);
    ClusterDropStats ref2 = loadStatsManager.getClusterDropStats(CLUSTER_NAME1, EDS_SERVICE_NAME1);
    ref1.recordDroppedRequest("lb");
    ref2.recordDroppedRequest("throttle");
    ref1.recordDroppedRequest();
    ref2.recordDroppedRequest();
    ClusterStats stats = Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER_NAME1));
    assertThat(stats.droppedRequestsList()).hasSize(2);
    assertThat(findDroppedRequestCount(stats.droppedRequestsList(), "lb")).isEqualTo(1L);
    assertThat(findDroppedRequestCount(stats.droppedRequestsList(), "throttle")).isEqualTo(1L);
    // 2 cagetorized + 2 uncategoized
    assertThat(stats.totalDroppedRequests()).isEqualTo(4L);
}
Also used : ClusterStats(io.grpc.xds.Stats.ClusterStats) ClusterDropStats(io.grpc.xds.LoadStatsManager2.ClusterDropStats) Test(org.junit.Test)

Example 10 with ClusterStats

use of io.grpc.xds.Stats.ClusterStats in project grpc-java by grpc.

the class LoadStatsManager2 method getClusterStatsReports.

/**
 * Gets the traffic stats (drops and loads) as a list of {@link ClusterStats} recorded for the
 * specified cluster since the previous call of this method or {@link
 * #getAllClusterStatsReports}. A {@link ClusterStats} includes stats for a specific cluster with
 * edsServiceName.
 */
synchronized List<ClusterStats> getClusterStatsReports(String cluster) {
    if (!allDropStats.containsKey(cluster) && !allLoadStats.containsKey(cluster)) {
        return Collections.emptyList();
    }
    Map<String, ReferenceCounted<ClusterDropStats>> clusterDropStats = allDropStats.get(cluster);
    Map<String, Map<Locality, ReferenceCounted<ClusterLocalityStats>>> clusterLoadStats = allLoadStats.get(cluster);
    Map<String, ClusterStats.Builder> statsReportBuilders = new HashMap<>();
    // Populate drop stats.
    if (clusterDropStats != null) {
        Set<String> toDiscard = new HashSet<>();
        for (String edsServiceName : clusterDropStats.keySet()) {
            ClusterStats.Builder builder = ClusterStats.newBuilder().clusterName(cluster);
            if (edsServiceName != null) {
                builder.clusterServiceName(edsServiceName);
            }
            ReferenceCounted<ClusterDropStats> ref = clusterDropStats.get(edsServiceName);
            if (ref.getReferenceCount() == 0) {
                // stats object no longer needed after snapshot
                toDiscard.add(edsServiceName);
            }
            ClusterDropStatsSnapshot dropStatsSnapshot = ref.get().snapshot();
            long totalCategorizedDrops = 0L;
            for (Map.Entry<String, Long> entry : dropStatsSnapshot.categorizedDrops.entrySet()) {
                builder.addDroppedRequests(DroppedRequests.create(entry.getKey(), entry.getValue()));
                totalCategorizedDrops += entry.getValue();
            }
            builder.totalDroppedRequests(totalCategorizedDrops + dropStatsSnapshot.uncategorizedDrops);
            builder.loadReportIntervalNano(dropStatsSnapshot.durationNano);
            statsReportBuilders.put(edsServiceName, builder);
        }
        clusterDropStats.keySet().removeAll(toDiscard);
    }
    // Populate load stats for all localities in the cluster.
    if (clusterLoadStats != null) {
        Set<String> toDiscard = new HashSet<>();
        for (String edsServiceName : clusterLoadStats.keySet()) {
            ClusterStats.Builder builder = statsReportBuilders.get(edsServiceName);
            if (builder == null) {
                builder = ClusterStats.newBuilder().clusterName(cluster);
                if (edsServiceName != null) {
                    builder.clusterServiceName(edsServiceName);
                }
                statsReportBuilders.put(edsServiceName, builder);
            }
            Map<Locality, ReferenceCounted<ClusterLocalityStats>> localityStats = clusterLoadStats.get(edsServiceName);
            Set<Locality> localitiesToDiscard = new HashSet<>();
            for (Locality locality : localityStats.keySet()) {
                ReferenceCounted<ClusterLocalityStats> ref = localityStats.get(locality);
                ClusterLocalityStatsSnapshot snapshot = ref.get().snapshot();
                // Only discard stats object after all in-flight calls under recording had finished.
                if (ref.getReferenceCount() == 0 && snapshot.callsInProgress == 0) {
                    localitiesToDiscard.add(locality);
                }
                UpstreamLocalityStats upstreamLocalityStats = UpstreamLocalityStats.create(locality, snapshot.callsIssued, snapshot.callsSucceeded, snapshot.callsFailed, snapshot.callsInProgress);
                builder.addUpstreamLocalityStats(upstreamLocalityStats);
                // Use the max (drops/loads) recording interval as the overall interval for the
                // cluster's stats. In general, they should be mostly identical.
                builder.loadReportIntervalNano(Math.max(builder.loadReportIntervalNano(), snapshot.durationNano));
            }
            localityStats.keySet().removeAll(localitiesToDiscard);
            if (localityStats.isEmpty()) {
                toDiscard.add(edsServiceName);
            }
        }
        clusterLoadStats.keySet().removeAll(toDiscard);
    }
    List<ClusterStats> res = new ArrayList<>();
    for (ClusterStats.Builder builder : statsReportBuilders.values()) {
        res.add(builder.build());
    }
    return Collections.unmodifiableList(res);
}
Also used : UpstreamLocalityStats(io.grpc.xds.Stats.UpstreamLocalityStats) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ClusterStats(io.grpc.xds.Stats.ClusterStats) HashSet(java.util.HashSet) AtomicLong(java.util.concurrent.atomic.AtomicLong) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map)

Aggregations

ClusterStats (io.grpc.xds.Stats.ClusterStats)10 Test (org.junit.Test)7 UpstreamLocalityStats (io.grpc.xds.Stats.UpstreamLocalityStats)5 EquivalentAddressGroup (io.grpc.EquivalentAddressGroup)4 PickResult (io.grpc.LoadBalancer.PickResult)4 PickSubchannelArgs (io.grpc.LoadBalancer.PickSubchannelArgs)4 Subchannel (io.grpc.LoadBalancer.Subchannel)4 LoadBalancerProvider (io.grpc.LoadBalancerProvider)4 PolicySelection (io.grpc.internal.ServiceConfigUtil.PolicySelection)4 ClusterImplConfig (io.grpc.xds.ClusterImplLoadBalancerProvider.ClusterImplConfig)4 WeightedPolicySelection (io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedPolicySelection)4 WeightedTargetConfig (io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedTargetConfig)4 ClientStreamTracer (io.grpc.ClientStreamTracer)3 Metadata (io.grpc.Metadata)3 ClusterDropStats (io.grpc.xds.LoadStatsManager2.ClusterDropStats)3 ClusterLocalityStats (io.grpc.xds.LoadStatsManager2.ClusterLocalityStats)3 DropOverload (io.grpc.xds.Endpoints.DropOverload)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1