Update Jedis 4.x plugin to support Sharding and Cluster models. (#677)
This commit is contained in:
parent
a751e324f6
commit
30d60b9c61
|
|
@ -19,6 +19,7 @@ Release Notes.
|
|||
* Fix a bug in Spring Cloud Gateway if HttpClientFinalizer#send does not invoke, the span created at NettyRoutingFilterInterceptor can not stop.
|
||||
* Fix not tracing in HttpClient v5 when HttpHost(arg[0]) is null but `RoutingSupport#determineHost` works.
|
||||
* Support across thread tracing for SOFA-RPC.
|
||||
* Update Jedis 4.x plugin to support Sharding and Cluster models.
|
||||
|
||||
#### Documentation
|
||||
* Update docs to describe `expired-plugins`.
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
package org.apache.skywalking.apm.plugin.jedis.v4;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.context.tag.StringTag;
|
||||
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
|
||||
|
|
@ -39,6 +40,8 @@ public abstract class AbstractConnectionInterceptor implements InstanceMethodsAr
|
|||
|
||||
private static final String CACHE_TYPE = "Redis";
|
||||
|
||||
private static final StringTag TAG_ARGS = new StringTag("actual_target");
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
|
||||
Iterator<Rawable> iterator = getCommands(allArguments);
|
||||
|
|
@ -49,12 +52,15 @@ public abstract class AbstractConnectionInterceptor implements InstanceMethodsAr
|
|||
// Use lowercase to make config compatible with jedis-2.x-3.x plugin
|
||||
// Refer to `plugin.jedis.operation_mapping_read`, `plugin.jedis.operation_mapping_write` config item in agent.config
|
||||
String cmd = protocolCommand == null ? UNKNOWN : protocolCommand.toLowerCase();
|
||||
String peer = String.valueOf(objInst.getSkyWalkingDynamicField());
|
||||
ConnectionInformation connectionData = (ConnectionInformation) objInst.getSkyWalkingDynamicField();
|
||||
// Use cluster information to adapt Virtual Cache if exists, otherwise use real server host
|
||||
String peer = StringUtil.isBlank(connectionData.getClusterNodes()) ? connectionData.getActualTarget() : connectionData.getClusterNodes();
|
||||
AbstractSpan span = ContextManager.createExitSpan("Jedis/" + cmd, peer);
|
||||
span.setComponent(ComponentsDefine.JEDIS);
|
||||
readKeyIfNecessary(iterator).ifPresent(key -> Tags.CACHE_KEY.set(span, key));
|
||||
Tags.CACHE_CMD.set(span, cmd);
|
||||
Tags.CACHE_TYPE.set(span, CACHE_TYPE);
|
||||
TAG_ARGS.set(span, connectionData.getActualTarget());
|
||||
parseOperation(cmd).ifPresent(op -> Tags.CACHE_OP.set(span, op));
|
||||
SpanLayer.asCache(span);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ public class ConnectionConstructorInterceptor implements InstanceConstructorInte
|
|||
@Override
|
||||
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws Throwable {
|
||||
HostAndPort hostAndPort = ((DefaultJedisSocketFactory) allArguments[0]).getHostAndPort();
|
||||
objInst.setSkyWalkingDynamicField(hostAndPort.getHost() + ":" + hostAndPort.getPort());
|
||||
ConnectionInformation connectionData = new ConnectionInformation();
|
||||
connectionData.setActualTarget(hostAndPort.toString());
|
||||
objInst.setSkyWalkingDynamicField(connectionData);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.jedis.v4;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ConnectionInformation {
|
||||
private String clusterNodes;
|
||||
private String actualTarget;
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.jedis.v4;
|
||||
|
||||
import java.util.Collection;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
|
||||
import org.apache.skywalking.apm.util.StringUtil;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
|
||||
public class ConnectionProviderConstructorInterceptor implements InstanceConstructorInterceptor {
|
||||
@Override
|
||||
public void onConstruct(final EnhancedInstance objInst, final Object[] allArguments) throws Throwable {
|
||||
if (objInst.getSkyWalkingDynamicField() != null) {
|
||||
return;
|
||||
}
|
||||
Object arg = allArguments[0];
|
||||
if (arg instanceof Collection) {
|
||||
Collection<?> collection = (Collection<?>) arg;
|
||||
final String[] array = collection.stream().map(Object::toString).toArray(String[]::new);
|
||||
objInst.setSkyWalkingDynamicField(StringUtil.join(',', array));
|
||||
}
|
||||
if (arg instanceof HostAndPort) {
|
||||
objInst.setSkyWalkingDynamicField(arg.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.jedis.v4;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
|
||||
public class ConnectionProviderGetConnectionInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
@Override
|
||||
public void beforeMethod(final EnhancedInstance objInst,
|
||||
final Method method,
|
||||
final Object[] allArguments,
|
||||
final Class<?>[] argumentsTypes,
|
||||
final MethodInterceptResult result) throws Throwable {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(final EnhancedInstance objInst,
|
||||
final Method method,
|
||||
final Object[] allArguments,
|
||||
final Class<?>[] argumentsTypes,
|
||||
final Object ret) throws Throwable {
|
||||
if (ret instanceof EnhancedInstance) {
|
||||
EnhancedInstance connection = (EnhancedInstance) ret;
|
||||
if (connection.getSkyWalkingDynamicField() != null
|
||||
&& connection.getSkyWalkingDynamicField() instanceof ConnectionInformation) {
|
||||
((ConnectionInformation) connection.getSkyWalkingDynamicField()).setClusterNodes(
|
||||
(String) objInst.getSkyWalkingDynamicField());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(final EnhancedInstance objInst,
|
||||
final Method method,
|
||||
final Object[] allArguments,
|
||||
final Class<?>[] argumentsTypes,
|
||||
final Throwable t) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
package org.apache.skywalking.apm.plugin.jedis.v4;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.context.tag.StringTag;
|
||||
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
|
||||
|
|
@ -27,18 +28,23 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInt
|
|||
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import org.apache.skywalking.apm.util.StringUtil;
|
||||
|
||||
public class JedisMethodInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
private static final StringTag TAG_ARGS = new StringTag("actual_target");
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
MethodInterceptResult result) throws Throwable {
|
||||
String peer = String.valueOf(objInst.getSkyWalkingDynamicField());
|
||||
final ConnectionInformation connectionData = (ConnectionInformation) objInst.getSkyWalkingDynamicField();
|
||||
// Use cluster information to adapt Virtual Cache if exists, otherwise use real server host
|
||||
String peer = StringUtil.isBlank(connectionData.getClusterNodes()) ? connectionData.getActualTarget() : connectionData.getClusterNodes();
|
||||
AbstractSpan span = ContextManager.createExitSpan("Jedis/" + method.getName(), peer);
|
||||
span.setComponent(ComponentsDefine.JEDIS);
|
||||
SpanLayer.asCache(span);
|
||||
Tags.CACHE_TYPE.set(span, "Redis");
|
||||
Tags.CACHE_CMD.set(span, "BATCH_EXECUTE");
|
||||
TAG_ARGS.set(span, connectionData.getActualTarget());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.jedis.v4.define;
|
||||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.HierarchyMatch.byHierarchyMatch;
|
||||
|
||||
public class ConnectionProviderInstrumentation extends AbstractWitnessInstrumentation {
|
||||
|
||||
private static final String ENHANCE_INTERFACE = "redis.clients.jedis.providers.ConnectionProvider";
|
||||
private static final String CONNECTION_PROVIDER_CONSTRUCTION_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jedis.v4.ConnectionProviderConstructorInterceptor";
|
||||
private static final String CONNECTION_PROVIDER_GET_CONNECTION_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jedis.v4.ConnectionProviderGetConnectionInterceptor";
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return byHierarchyMatch(ENHANCE_INTERFACE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[]{
|
||||
new ConstructorInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getConstructorMatcher() {
|
||||
return ElementMatchers.takesArgument(0, named("redis.clients.jedis.HostAndPort"))
|
||||
.or(ElementMatchers.takesArgument(0, hasSuperType(named("java.util.Collection"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConstructorInterceptor() {
|
||||
return CONNECTION_PROVIDER_CONSTRUCTION_INTERCEPT_CLASS;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[] {
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named("getConnection");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return CONNECTION_PROVIDER_GET_CONNECTION_INTERCEPT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -16,4 +16,5 @@
|
|||
|
||||
jedis-4.x=org.apache.skywalking.apm.plugin.jedis.v4.define.ConnectionInstrumentation
|
||||
jedis-4.x=org.apache.skywalking.apm.plugin.jedis.v4.define.PipelineInstrumentation
|
||||
jedis-4.x=org.apache.skywalking.apm.plugin.jedis.v4.define.TransactionConstructorInstrumentation
|
||||
jedis-4.x=org.apache.skywalking.apm.plugin.jedis.v4.define.TransactionConstructorInstrumentation
|
||||
jedis-4.x=org.apache.skywalking.apm.plugin.jedis.v4.define.ConnectionProviderInstrumentation
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ segmentItems:
|
|||
- {key: cache.key, value: a}
|
||||
- {key: cache.cmd, value: set}
|
||||
- {key: cache.type, value: Redis}
|
||||
- {key: actual_target, value: 'redis-server:6379'}
|
||||
- {key: cache.op, value: write}
|
||||
- operationName: Jedis/get
|
||||
operationId: 0
|
||||
|
|
@ -53,6 +54,7 @@ segmentItems:
|
|||
- {key: cache.key, value: a}
|
||||
- {key: cache.cmd, value: get}
|
||||
- {key: cache.type, value: Redis}
|
||||
- {key: actual_target, value: 'redis-server:6379'}
|
||||
- {key: cache.op, value: read}
|
||||
- operationName: Jedis/del
|
||||
operationId: 0
|
||||
|
|
@ -70,6 +72,7 @@ segmentItems:
|
|||
- {key: cache.key, value: a}
|
||||
- {key: cache.cmd, value: del}
|
||||
- {key: cache.type, value: Redis}
|
||||
- {key: actual_target, value: 'redis-server:6379'}
|
||||
- {key: cache.op, value: write}
|
||||
- operationName: Jedis/syncAndReturnAll
|
||||
operationId: 0
|
||||
|
|
@ -86,6 +89,7 @@ segmentItems:
|
|||
tags:
|
||||
- {key: cache.type, value: Redis}
|
||||
- {key: cache.cmd, value: BATCH_EXECUTE}
|
||||
- {key: actual_target, value: 'redis-server:6379'}
|
||||
- operationName: Jedis/exec
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
|
|
@ -101,6 +105,7 @@ segmentItems:
|
|||
tags:
|
||||
- {key: cache.type, value: Redis}
|
||||
- {key: cache.cmd, value: BATCH_EXECUTE}
|
||||
- {key: actual_target, value: 'redis-server:6379'}
|
||||
- operationName: Jedis/discard
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
|
|
@ -116,6 +121,7 @@ segmentItems:
|
|||
tags:
|
||||
- {key: cache.type, value: Redis}
|
||||
- {key: cache.cmd, value: BATCH_EXECUTE}
|
||||
- {key: actual_target, value: 'redis-server:6379'}
|
||||
- operationName: Jedis/xadd
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
|
|
@ -132,6 +138,7 @@ segmentItems:
|
|||
- {key: cache.key, value: abc}
|
||||
- {key: cache.cmd, value: xadd}
|
||||
- {key: cache.type, value: Redis}
|
||||
- {key: actual_target, value: 'redis-server:6379'}
|
||||
- {key: cache.op, value: write}
|
||||
- operationName: Jedis/xread
|
||||
operationId: 0
|
||||
|
|
@ -148,6 +155,7 @@ segmentItems:
|
|||
tags:
|
||||
- {key: cache.cmd, value: xread}
|
||||
- {key: cache.type, value: Redis}
|
||||
- {key: actual_target, value: 'redis-server:6379'}
|
||||
- {key: cache.op, value: read}
|
||||
- operationName: Jedis/xdel
|
||||
operationId: 0
|
||||
|
|
@ -165,6 +173,109 @@ segmentItems:
|
|||
- {key: cache.key, value: abc}
|
||||
- {key: cache.cmd, value: xdel}
|
||||
- {key: cache.type, value: Redis}
|
||||
- {key: actual_target, value: 'redis-server:6379'}
|
||||
- {key: cache.op, value: write}
|
||||
- operationName: Jedis/set
|
||||
parentSpanId: 0
|
||||
spanId: 10
|
||||
spanLayer: Cache
|
||||
startTime: gt 0
|
||||
endTime: gt 0
|
||||
componentId: 30
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: redis-server:6379,redis-server:6379
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: cache.key, value: x}
|
||||
- {key: cache.cmd, value: set}
|
||||
- {key: cache.type, value: Redis}
|
||||
- {key: actual_target, value: 'redis-server:6379'}
|
||||
- {key: cache.op, value: write}
|
||||
- operationName: Jedis/get
|
||||
parentSpanId: 0
|
||||
spanId: 11
|
||||
spanLayer: Cache
|
||||
startTime: gt 0
|
||||
endTime: gt 0
|
||||
componentId: 30
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: redis-server:6379,redis-server:6379
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: cache.key, value: x}
|
||||
- {key: cache.cmd, value: get}
|
||||
- {key: cache.type, value: Redis}
|
||||
- {key: actual_target, value: 'redis-server:6379'}
|
||||
- {key: cache.op, value: read}
|
||||
- operationName: Jedis/del
|
||||
parentSpanId: 0
|
||||
spanId: 12
|
||||
spanLayer: Cache
|
||||
startTime: gt 0
|
||||
endTime: gt 0
|
||||
componentId: 30
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: redis-server:6379,redis-server:6379
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: cache.key, value: x}
|
||||
- {key: cache.cmd, value: del}
|
||||
- {key: cache.type, value: Redis}
|
||||
- {key: actual_target, value: 'redis-server:6379'}
|
||||
- {key: cache.op, value: write}
|
||||
- operationName: Jedis/set
|
||||
parentSpanId: 0
|
||||
spanId: 13
|
||||
spanLayer: Cache
|
||||
startTime: gt 0
|
||||
endTime: gt 0
|
||||
componentId: 30
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: redis-cluster-m3:6379,redis-cluster-m2:6379,redis-cluster-m1:6379
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: cache.key, value: x}
|
||||
- {key: cache.cmd, value: set}
|
||||
- {key: cache.type, value: Redis}
|
||||
- {key: actual_target, value: not blank }
|
||||
- {key: cache.op, value: write}
|
||||
- operationName: Jedis/get
|
||||
parentSpanId: 0
|
||||
spanId: 14
|
||||
spanLayer: Cache
|
||||
startTime: gt 0
|
||||
endTime: gt 0
|
||||
componentId: 30
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: redis-cluster-m3:6379,redis-cluster-m2:6379,redis-cluster-m1:6379
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: cache.key, value: x}
|
||||
- {key: cache.cmd, value: get}
|
||||
- {key: cache.type, value: Redis}
|
||||
- {key: actual_target, value: not blank}
|
||||
- {key: cache.op, value: read}
|
||||
- operationName: Jedis/del
|
||||
parentSpanId: 0
|
||||
spanId: 15
|
||||
spanLayer: Cache
|
||||
startTime: gt 0
|
||||
endTime: gt 0
|
||||
componentId: 30
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: redis-cluster-m3:6379,redis-cluster-m2:6379,redis-cluster-m1:6379
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: cache.key, value: x}
|
||||
- {key: cache.cmd, value: del}
|
||||
- {key: cache.type, value: Redis}
|
||||
- {key: actual_target, value: not blank }
|
||||
- {key: cache.op, value: write}
|
||||
- operationName: GET:/jedis-scenario/case/jedis-scenario
|
||||
operationId: 0
|
||||
|
|
@ -181,4 +292,4 @@ segmentItems:
|
|||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/jedis-scenario/case/jedis-scenario'}
|
||||
- {key: http.method, value: GET}
|
||||
- {key: http.status_code, value: '200'}
|
||||
- {key: http.status_code, value: '200'}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,27 @@ startScript: ./bin/startup.sh
|
|||
environment:
|
||||
- REDIS_HOST=redis-server
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_CLUSTER_M1_HOST=redis-cluster-m1
|
||||
- REDIS_CLUSTER_M1_PORT=6379
|
||||
- REDIS_CLUSTER_M2_HOST=redis-cluster-m2
|
||||
- REDIS_CLUSTER_M2_PORT=6379
|
||||
- REDIS_CLUSTER_M3_HOST=redis-cluster-m3
|
||||
- REDIS_CLUSTER_M3_PORT=6379
|
||||
|
||||
dependencies:
|
||||
redis-server:
|
||||
image: redis:7.0.4
|
||||
hostname: redis-server
|
||||
|
||||
redis-cluster-m1:
|
||||
image: redis:7.2.4
|
||||
hostname: redis-cluster-m1
|
||||
command: sh -c " printf '%s\\n' 'port 6379'>> /etc/redis.conf && printf '%s\\n' 'cluster-enabled yes'>> /etc/redis.conf && printf '%s\\n' 'cluster-config-file nodes.conf'>> /etc/redis.conf && printf '%s\\n' 'nohup redis-server /etc/redis.conf>>/tmp/redis.log &' >> /tmp/start-redis.sh && printf '%s\\n' 'while true; do printf yes | redis-cli --cluster create redis-cluster-m1:6379 redis-cluster-m2:6379 redis-cluster-m3:6379 --cluster-replicas 0 && break; done ' >> /tmp/start-redis.sh && printf '%s\\n' 'tail -f /tmp/redis.log' >> /tmp/start-redis.sh && sh /tmp/start-redis.sh"
|
||||
redis-cluster-m2:
|
||||
image: redis:7.2.4
|
||||
hostname: redis-cluster-m2
|
||||
command: sh -c " printf '%s\\n' 'port 6379'>> /etc/redis.conf && printf '%s\\n' 'cluster-enabled yes'>> /etc/redis.conf && printf '%s\\n' 'cluster-config-file nodes.conf'>> /etc/redis.conf && printf '%s\\n' 'nohup redis-server /etc/redis.conf>>/tmp/redis.log &' >> /tmp/start-redis.sh && printf '%s\\n' 'while true; do printf yes | redis-cli --cluster create redis-cluster-m1:6379 redis-cluster-m2:6379 redis-cluster-m3:6379 --cluster-replicas 0 && break; done ' >> /tmp/start-redis.sh && printf '%s\\n' 'tail -f /tmp/redis.log' >> /tmp/start-redis.sh && sh /tmp/start-redis.sh"
|
||||
redis-cluster-m3:
|
||||
image: redis:7.2.4
|
||||
hostname: redis-cluster-m3
|
||||
command: sh -c " printf '%s\\n' 'port 6379'>> /etc/redis.conf && printf '%s\\n' 'cluster-enabled yes'>> /etc/redis.conf && printf '%s\\n' 'cluster-config-file nodes.conf'>> /etc/redis.conf && printf '%s\\n' 'nohup redis-server /etc/redis.conf>>/tmp/redis.log &' >> /tmp/start-redis.sh && printf '%s\\n' 'while true; do printf yes | redis-cli --cluster create redis-cluster-m1:6379 redis-cluster-m2:6379 redis-cluster-m3:6379 --cluster-replicas 0 && break; done ' >> /tmp/start-redis.sh && printf '%s\\n' 'tail -f /tmp/redis.log' >> /tmp/start-redis.sh && sh /tmp/start-redis.sh"
|
||||
|
|
|
|||
|
|
@ -18,10 +18,13 @@
|
|||
|
||||
package org.apache.skywalking.apm.testcase.jedis.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/case")
|
||||
|
|
@ -35,6 +38,21 @@ public class CaseController {
|
|||
@Value("${redis.port:6379}")
|
||||
private Integer redisPort;
|
||||
|
||||
@Value("${redis.cluster.m1.host:127.0.0.1}")
|
||||
private String redisClusterM1Host;
|
||||
@Value("${redis.cluster.m1.port:6379}")
|
||||
private Integer redisClusterM1Port;
|
||||
|
||||
@Value("${redis.cluster.m2.host:127.0.0.1}")
|
||||
private String redisClusterM2Host;
|
||||
@Value("${redis.cluster.m2.port:6379}")
|
||||
private Integer redisClusterM2Port;
|
||||
|
||||
@Value("${redis.cluster.m3.host:127.0.0.1}")
|
||||
private String redisClusterM3Host;
|
||||
@Value("${redis.cluster.m3.port:6379}")
|
||||
private Integer redisClusterM3Port;
|
||||
|
||||
@RequestMapping("/jedis-scenario")
|
||||
@ResponseBody
|
||||
public String testcase() throws Exception {
|
||||
|
|
@ -43,7 +61,6 @@ public class CaseController {
|
|||
command.get("a");
|
||||
command.del("a");
|
||||
}
|
||||
|
||||
try (RedisPipelineCommandExecutor command = new RedisPipelineCommandExecutor(redisHost, redisPort)) {
|
||||
command.pipelineExecute();
|
||||
}
|
||||
|
|
@ -55,7 +72,18 @@ public class CaseController {
|
|||
try (RedisStreamCommandExecutor executor = new RedisStreamCommandExecutor(redisHost, redisPort)) {
|
||||
executor.exec();
|
||||
}
|
||||
|
||||
try (ShardingExecutor shardingExecutor = new ShardingExecutor(
|
||||
Arrays.asList(new HostAndPort(redisHost, redisPort), new HostAndPort(redisHost, redisPort)))) {
|
||||
shardingExecutor.exec();
|
||||
}
|
||||
try (ClusterExecutor clusterExecutor = new ClusterExecutor(new HashSet<>(
|
||||
Arrays.asList(
|
||||
new HostAndPort(redisClusterM1Host, redisClusterM1Port),
|
||||
new HostAndPort(redisClusterM2Host, redisClusterM2Port),
|
||||
new HostAndPort(redisClusterM3Host, redisClusterM3Port)
|
||||
)))) {
|
||||
clusterExecutor.exec();
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.testcase.jedis.controller;
|
||||
|
||||
import java.util.Set;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.JedisCluster;
|
||||
|
||||
public class ClusterExecutor implements AutoCloseable {
|
||||
|
||||
private final JedisCluster jedisCluster;
|
||||
|
||||
public ClusterExecutor(Set<HostAndPort> jedisClusterNodes) {
|
||||
this.jedisCluster = new JedisCluster(jedisClusterNodes);
|
||||
}
|
||||
|
||||
public void exec() {
|
||||
jedisCluster.set("x", "1");
|
||||
jedisCluster.get("x");
|
||||
jedisCluster.del("x");
|
||||
}
|
||||
|
||||
public void close() {
|
||||
this.jedisCluster.close();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.testcase.jedis.controller;
|
||||
|
||||
import java.util.List;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.JedisSharding;
|
||||
|
||||
public class ShardingExecutor implements AutoCloseable {
|
||||
private JedisSharding jedisSharding;
|
||||
|
||||
public ShardingExecutor(List<HostAndPort> hostAndPorts) {
|
||||
this.jedisSharding = new JedisSharding(hostAndPorts);
|
||||
}
|
||||
|
||||
public void exec() {
|
||||
jedisSharding.set("x", "1");
|
||||
jedisSharding.get("x");
|
||||
jedisSharding.del("x");
|
||||
}
|
||||
|
||||
public void close() {
|
||||
jedisSharding.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -14,6 +14,8 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
4.4.6
|
||||
4.3.2
|
||||
4.2.3
|
||||
4.1.1
|
||||
4.0.1
|
||||
4.0.1
|
||||
|
|
|
|||
Loading…
Reference in New Issue