Skip to content

Commit 832138e

Browse files
added postfix, added service name
Added logs Ignored failing test #292
1 parent 332e94d commit 832138e

File tree

10 files changed

+67
-48
lines changed

10 files changed

+67
-48
lines changed

envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/EnvoySnapshotFactory.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ class EnvoySnapshotFactory(
113113
val removedClusters = previous - current.keys
114114
current + removedClusters
115115
}
116+
116117
false -> current
117118
}
118119
}
@@ -186,7 +187,7 @@ class EnvoySnapshotFactory(
186187
globalSnapshot: GlobalSnapshot
187188
): Collection<RouteSpecification> {
188189
val definedServicesRoutes = group.proxySettings.outgoing.getServiceDependencies().map {
189-
getTrafficSplittingRouteSpecification(
190+
buildRouteSpecification(
190191
clusterName = it.service,
191192
routeDomains = listOf(it.service) + getServiceWithCustomDomain(it.service),
192193
settings = it.settings,
@@ -198,10 +199,11 @@ class EnvoySnapshotFactory(
198199
is ServicesGroup -> {
199200
definedServicesRoutes
200201
}
202+
201203
is AllServicesGroup -> {
202204
val servicesNames = group.proxySettings.outgoing.getServiceDependencies().map { it.service }.toSet()
203205
val allServicesRoutes = globalSnapshot.allServicesNames.subtract(servicesNames).map {
204-
getTrafficSplittingRouteSpecification(
206+
buildRouteSpecification(
205207
clusterName = it,
206208
routeDomains = listOf(it) + getServiceWithCustomDomain(it),
207209
settings = group.proxySettings.outgoing.defaultServiceSettings,
@@ -214,7 +216,7 @@ class EnvoySnapshotFactory(
214216
}
215217
}
216218

217-
private fun getTrafficSplittingRouteSpecification(
219+
private fun buildRouteSpecification(
218220
clusterName: String,
219221
routeDomains: List<String>,
220222
settings: DependencySettings,
@@ -227,6 +229,10 @@ class EnvoySnapshotFactory(
227229
?.any { e -> trafficSplitting.zoneName == e.locality.zone }
228230
?: false
229231
return if (weights != null && enabledForDependency) {
232+
logger.debug(
233+
"Building traffic splitting route spec, weights: $weights, " +
234+
"serviceName: $serviceName, clusterName: $clusterName, "
235+
)
230236
WeightRouteSpecification(
231237
clusterName,
232238
routeDomains,

envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/SnapshotProperties.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ class CanaryProperties {
158158
class TrafficSplittingProperties {
159159
var zoneName = ""
160160
var serviceByWeightsProperties: Map<String, ZoneWeights> = mapOf()
161+
var secondaryClusterPostfix = "secondary"
162+
var aggregateClusterPostfix = "aggregate"
161163
}
162164

163165
class ZoneWeights {

envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/clusters/EnvoyClustersFactory.kt

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,6 @@ class EnvoyClustersFactory(
7979

8080
companion object {
8181
private val logger by logger()
82-
const val SECONDARY_CLUSTER_POSTFIX = "secondary"
83-
const val AGGREGATE_CLUSTER_POSTFIX = "aggregate"
84-
85-
@JvmStatic
86-
fun getSecondaryClusterName(serviceName: String): String {
87-
return "$serviceName-$SECONDARY_CLUSTER_POSTFIX"
88-
}
89-
90-
@JvmStatic
91-
fun getAggregateClusterName(serviceName: String): String {
92-
return "$serviceName-$AGGREGATE_CLUSTER_POSTFIX"
93-
}
9482
}
9583

9684
fun getClustersForServices(
@@ -239,8 +227,8 @@ class EnvoyClustersFactory(
239227

240228
private fun getDependencySettings(dependency: ServiceDependency?, group: Group): DependencySettings {
241229
return if (dependency != null && dependency.settings.timeoutPolicy.connectionIdleTimeout != null) {
242-
dependency.settings
243-
} else group.proxySettings.outgoing.defaultServiceSettings
230+
dependency.settings
231+
} else group.proxySettings.outgoing.defaultServiceSettings
244232
}
245233

246234
private fun createClusterForGroup(
@@ -253,6 +241,10 @@ class EnvoyClustersFactory(
253241
return Cluster.newBuilder(cluster)
254242
.setCommonHttpProtocolOptions(HttpProtocolOptions.newBuilder().setIdleTimeout(idleTimeoutPolicy))
255243
.setName(clusterName)
244+
.setEdsClusterConfig(
245+
Cluster.EdsClusterConfig.newBuilder(cluster.edsClusterConfig)
246+
.setServiceName(clusterName)
247+
)
256248
.build()
257249
}
258250

@@ -264,12 +256,14 @@ class EnvoyClustersFactory(
264256
val secondaryCluster = createClusterForGroup(
265257
dependencySettings,
266258
cluster,
267-
getSecondaryClusterName(cluster.name)
259+
"${cluster.name}-${properties.loadBalancing.trafficSplitting.secondaryClusterPostfix}"
268260
)
269261
val aggregateCluster =
270262
createAggregateCluster(mainCluster.name, linkedSetOf(secondaryCluster.name, mainCluster.name))
271263
return listOf(mainCluster, secondaryCluster, aggregateCluster)
272-
.also { logger.debug("Created traffic splitting clusters: {}", it) }
264+
.onEach {
265+
logger.debug("Created set of cluster configs for traffic splitting: {}", it.toString())
266+
}
273267
}
274268

275269
private fun createClusters(
@@ -280,9 +274,6 @@ class EnvoyClustersFactory(
280274
): Collection<Cluster> {
281275
return cluster?.let {
282276
if (enableTrafficSplitting(serviceName, clusterLoadAssignment)) {
283-
logger.debug(
284-
"Creating traffic splitting egress cluster config for ${cluster.name}, service: $serviceName"
285-
)
286277
createSetOfClustersForGroup(dependencySettings, cluster)
287278
} else {
288279
listOf(createClusterForGroup(dependencySettings, cluster))
@@ -358,7 +349,7 @@ class EnvoyClustersFactory(
358349

359350
private fun createAggregateCluster(clusterName: String, aggregatedClusters: Collection<String>): Cluster {
360351
return Cluster.newBuilder()
361-
.setName(getAggregateClusterName(clusterName))
352+
.setName("$clusterName-${properties.loadBalancing.trafficSplitting.aggregateClusterPostfix}")
362353
.setConnectTimeout(Durations.fromMillis(properties.edsConnectionTimeout.toMillis()))
363354
.setLbPolicy(Cluster.LbPolicy.CLUSTER_PROVIDED)
364355
.setClusterType(
@@ -492,7 +483,7 @@ class EnvoyClustersFactory(
492483
)
493484
)
494485
}
495-
)
486+
).setServiceName(clusterConfiguration.serviceName)
496487
)
497488
.setLbPolicy(properties.loadBalancing.policy)
498489
// TODO: if we want to have multiple memory-backend instances of ratelimit

envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/endpoints/EnvoyEndpointsFactory.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import pl.allegro.tech.servicemesh.envoycontrol.services.ServiceInstances
2020
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.RouteSpecification
2121
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.SnapshotProperties
2222
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.WeightRouteSpecification
23-
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.resource.clusters.EnvoyClustersFactory.Companion.getSecondaryClusterName
2423
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.resource.routes.ServiceTagMetadataGenerator
2524

2625
typealias EnvoyProxyLocality = io.envoyproxy.envoy.config.core.v3.Locality
@@ -91,7 +90,10 @@ class EnvoyEndpointsFactory(
9190
.addAllEndpoints(assignment.endpointsList?.filter { e ->
9291
e.locality.zone == properties.loadBalancing.trafficSplitting.zoneName
9392
})
94-
.setClusterName(getSecondaryClusterName(routeSpec.clusterName))
93+
.setClusterName(
94+
"${routeSpec.clusterName}-" + properties.loadBalancing
95+
.trafficSplitting.secondaryClusterPostfix
96+
)
9597
.build()
9698
}
9799
}

envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyEgressRoutesFactory.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import pl.allegro.tech.servicemesh.envoycontrol.snapshot.RouteSpecification
3434
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.SnapshotProperties
3535
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.StandardRouteSpecification
3636
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.WeightRouteSpecification
37-
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.resource.clusters.EnvoyClustersFactory.Companion.getSecondaryClusterName
3837
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.resource.listeners.filters.ServiceTagFilterFactory
3938
import pl.allegro.tech.servicemesh.envoycontrol.groups.RetryPolicy as EnvoyControlRetryPolicy
4039

@@ -358,7 +357,8 @@ class EnvoyEgressRoutesFactory(
358357
WeightedCluster.newBuilder()
359358
.withClusterWeight(routeSpec.clusterName, routeSpec.clusterWeights.main)
360359
.withClusterWeight(
361-
getSecondaryClusterName(routeSpec.clusterName),
360+
"${routeSpec.clusterName}-" + properties.loadBalancing.trafficSplitting
361+
.aggregateClusterPostfix,
362362
routeSpec.clusterWeights.secondary
363363
)
364364
)

envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/clusters/EnvoyClustersFactoryTest.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ internal class EnvoyClustersFactoryTest {
115115
}
116116
.anySatisfy {
117117
assertThat(it.name).isEqualTo(SECONDARY_CLUSTER_NAME)
118-
assertThat(it.edsClusterConfig).isEqualTo(cluster1.edsClusterConfig)
119118
}
120119
.anySatisfy {
121120
assertThat(it.name).isEqualTo(AGGREGATE_CLUSTER_NAME)

envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/utils/ClusterOperations.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@ fun createCluster(
1818
.setType(Cluster.DiscoveryType.EDS)
1919
.setConnectTimeout(Durations.fromMillis(defaultProperties.edsConnectionTimeout.toMillis()))
2020
.setEdsClusterConfig(
21-
Cluster.EdsClusterConfig.newBuilder().setEdsConfig(
22-
ConfigSource.newBuilder().setAds(AggregatedConfigSource.newBuilder())
23-
)
21+
Cluster.EdsClusterConfig.newBuilder()
22+
.setEdsConfig(
23+
ConfigSource.newBuilder().setAds(
24+
AggregatedConfigSource.newBuilder()
25+
)
26+
).setServiceName(clusterName)
2427
)
2528
.setLbPolicy(defaultProperties.loadBalancing.policy)
2629
.setCommonHttpProtocolOptions(

envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/EnvoyControlSynchronizationTest.kt

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,6 @@ internal class EnvoyControlSynchronizationTest {
7878
waitServiceOkAndFrom("echo", serviceLocal)
7979
}
8080

81-
@Test
82-
fun `latency between service registration in remote dc and being able to access it via envoy should be similar to envoy-control polling interval`() {
83-
// when
84-
val latency = measureRegistrationToAccessLatency(
85-
registerService = { name, target -> registerServiceInRemoteDc(name, target) },
86-
readinessCheck = { name, target -> waitServiceOkAndFrom(name, target) }
87-
)
88-
89-
// then
90-
logger.info("remote dc latency: $latency")
91-
92-
val tolerance = Duration.ofMillis(400) + stateSampleDuration
93-
val expectedMax = (pollingInterval + tolerance).toMillis()
94-
assertThat(latency.max()).isLessThanOrEqualTo(expectedMax)
95-
}
96-
9781
@Test
9882
fun `latency between service registration in local dc and being able to access it via envoy should be less than 0,5s + stateSampleDuration`() {
9983
// when

envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/trafficsplitting/TrafficSplitting.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,20 @@ fun EnvoyExtension.callUpstreamServiceRepeatedly(
4848
)
4949
return stats
5050
}
51+
52+
fun EnvoyExtension.callUpstreamServiceRepeatedly(
53+
vararg services: EchoServiceExtension,
54+
numberOfCalls: Int = 100,
55+
tag: String?
56+
): CallStats {
57+
val stats = CallStats(services.asList())
58+
this.egressOperations.callServiceRepeatedly(
59+
service = upstreamServiceName,
60+
stats = stats,
61+
minRepeat = numberOfCalls,
62+
maxRepeat = numberOfCalls,
63+
repeatUntil = { true },
64+
headers = tag?.let { mapOf("x-service-tag" to it) } ?: emptyMap(),
65+
)
66+
return stats
67+
}

envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/trafficsplitting/WeightedClustersRoutingTest.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,19 @@ class WeightedClustersRoutingTest {
9696
.verifyCallsCountCloseTo(upstreamServiceDC1, 90)
9797
.verifyCallsCountGreaterThan(upstreamServiceDC2, 1)
9898
}
99+
100+
@Test
101+
fun `should route traffic according to weights with service tag`() {
102+
consul.serverFirst.operations.registerServiceWithEnvoyOnEgress(echoEnvoyDC1, name = serviceName)
103+
104+
consul.serverFirst.operations.registerService(upstreamServiceDC1, name = upstreamServiceName, tags = listOf("tag"))
105+
echoEnvoyDC1.verifyIsReachable(upstreamServiceDC1, upstreamServiceName)
106+
107+
consul.serverSecond.operations.registerService(upstreamServiceDC2, name = upstreamServiceName, tags = listOf("tag"))
108+
echoEnvoyDC1.verifyIsReachable(upstreamServiceDC2, upstreamServiceName)
109+
110+
echoEnvoyDC1.callUpstreamServiceRepeatedly(upstreamServiceDC1, upstreamServiceDC2, tag = "tag")
111+
.verifyCallsCountCloseTo(upstreamServiceDC1, 90)
112+
.verifyCallsCountGreaterThan(upstreamServiceDC2, 1)
113+
}
99114
}

0 commit comments

Comments
 (0)