1.修复API和Server代码中,MachineUtil的gethost/getip,在没有配置静态IP的时候,性能极慢的问题。
2.API增加底层拦截器,FirstInvokeInterceptor。用于首次拦截方法调用,避免方法内部的方法调用被多次拦截。 3.提供Jedis插件实现。并提交性能测试。 #38
This commit is contained in:
parent
c02c3f3ed1
commit
6efa8e1db8
|
|
@ -0,0 +1,13 @@
|
|||
package com.ai.cloud.skywalking.plugin.interceptor;
|
||||
|
||||
public class InterceptorException extends RuntimeException {
|
||||
private static final long serialVersionUID = 7846035239994885019L;
|
||||
|
||||
public InterceptorException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public InterceptorException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.ai.cloud.skywalking.plugin.interceptor.assist;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.EnhancedClassInstanceContext;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.IAroundInterceptor;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.InterceptorException;
|
||||
|
||||
/**
|
||||
* 用于首次拦截方法调用,避免方法内部的方法调用被多次拦截。
|
||||
*
|
||||
* @author wusheng
|
||||
*
|
||||
*/
|
||||
public abstract class FirstInvokeInterceptor implements IAroundInterceptor {
|
||||
protected String invokeCounterKey = "__$invokeCounterKey";
|
||||
|
||||
protected Object invokeCounterInstLock = new Object();
|
||||
|
||||
public boolean isFirstBeforeMethod(EnhancedClassInstanceContext context) {
|
||||
if (!context.isContain(invokeCounterKey)) {
|
||||
synchronized (invokeCounterInstLock) {
|
||||
if (!context.isContain(invokeCounterKey)) {
|
||||
context.set(invokeCounterKey, new AtomicInteger(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
AtomicInteger counter = context.get(invokeCounterKey,
|
||||
AtomicInteger.class);
|
||||
return counter.incrementAndGet() == 1;
|
||||
}
|
||||
|
||||
public boolean isLastAfterMethod(EnhancedClassInstanceContext context) {
|
||||
if (!context.isContain(invokeCounterKey)) {
|
||||
throw new InterceptorException(
|
||||
"key=invokeCounterKey not found is context. unexpected failue.");
|
||||
}
|
||||
AtomicInteger counter = context.get(invokeCounterKey,
|
||||
AtomicInteger.class);
|
||||
return counter.decrementAndGet() == 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -35,9 +35,10 @@ public final class BuriedPointMachineUtil {
|
|||
if (StringUtil.isEmpty(IP)) {
|
||||
InetAddress netAddress = getInetAddress();
|
||||
if (null == netAddress) {
|
||||
return null;
|
||||
IP = "N/A";
|
||||
}else{
|
||||
IP = netAddress.getHostAddress(); //get the ip address
|
||||
}
|
||||
IP = netAddress.getHostAddress(); //get the ip address
|
||||
}
|
||||
return IP;
|
||||
}
|
||||
|
|
@ -46,9 +47,10 @@ public final class BuriedPointMachineUtil {
|
|||
if (StringUtil.isEmpty(hostName)) {
|
||||
InetAddress netAddress = getInetAddress();
|
||||
if (null == netAddress) {
|
||||
return null;
|
||||
hostName = "N/A";
|
||||
}else{
|
||||
hostName = netAddress.getHostName(); //get the host address
|
||||
}
|
||||
hostName = netAddress.getHostName(); //get the host address
|
||||
}
|
||||
return hostName;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
package test.ai.cloud.api;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ai.cloud.skywalking.buriedpoint.RPCBuriedPointSender;
|
||||
import com.ai.cloud.skywalking.model.Identification;
|
||||
import com.ai.cloud.skywalking.model.Identification.IdentificationBuilder;
|
||||
|
||||
public class TimeTest {
|
||||
@Test
|
||||
public void test(){
|
||||
RPCBuriedPointSender sender = new RPCBuriedPointSender();
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
IdentificationBuilder builder = Identification
|
||||
.newBuilder()
|
||||
.viewPoint("1111");
|
||||
sender.beforeSend(builder.build());
|
||||
sender.afterSend();
|
||||
}
|
||||
long end = System.currentTimeMillis();
|
||||
System.out.println(end - start + "ms");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,12 +2,9 @@ package test.ai.cloud.plugin;
|
|||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ai.cloud.skywalking.plugin.TracingBootstrap;
|
||||
|
||||
public class PluginMainTest {
|
||||
@Test
|
||||
public void testMain() throws IllegalAccessException,
|
||||
IllegalArgumentException, InvocationTargetException,
|
||||
NoSuchMethodException, SecurityException, ClassNotFoundException {
|
||||
|
|
|
|||
|
|
@ -1,27 +1,74 @@
|
|||
package org.skywalking.jedis.v2.plugin;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import redis.clients.jedis.JedisShardInfo;
|
||||
|
||||
import com.ai.cloud.skywalking.buriedpoint.RPCBuriedPointSender;
|
||||
import com.ai.cloud.skywalking.model.Identification;
|
||||
import com.ai.cloud.skywalking.model.Identification.IdentificationBuilder;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.ConstructorInvokeContext;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.EnhancedClassInstanceContext;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.IAroundInterceptor;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.MethodInvokeContext;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.assist.FirstInvokeInterceptor;
|
||||
|
||||
public class JedisInterceptor implements IAroundInterceptor{
|
||||
public class JedisInterceptor extends FirstInvokeInterceptor {
|
||||
private static final String REDIS_CONN_INFO_KEY = "redisConnInfo";
|
||||
|
||||
private static RPCBuriedPointSender sender = new RPCBuriedPointSender();
|
||||
|
||||
@Override
|
||||
public void onConstruct(EnhancedClassInstanceContext context,
|
||||
ConstructorInvokeContext interceptorContext) {
|
||||
|
||||
String redisConnInfo = "";
|
||||
if (interceptorContext.allArguments().length > 0) {
|
||||
if (interceptorContext.allArguments()[0] instanceof String) {
|
||||
redisConnInfo = (String) interceptorContext.allArguments()[0];
|
||||
if (interceptorContext.allArguments().length > 1) {
|
||||
redisConnInfo += ":"
|
||||
+ (Integer) interceptorContext.allArguments()[1];
|
||||
}
|
||||
} else if (interceptorContext.allArguments()[0] instanceof JedisShardInfo) {
|
||||
JedisShardInfo shardInfo = (JedisShardInfo) interceptorContext
|
||||
.allArguments()[0];
|
||||
redisConnInfo = shardInfo.getHost() + ":" + shardInfo.getPort();
|
||||
} else if (interceptorContext.allArguments()[0] instanceof URI) {
|
||||
URI uri = (URI) interceptorContext.allArguments()[0];
|
||||
redisConnInfo = uri.getHost() + ":" + uri.getPort();
|
||||
}
|
||||
}
|
||||
context.set(REDIS_CONN_INFO_KEY, redisConnInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedClassInstanceContext context,
|
||||
MethodInvokeContext interceptorContext) {
|
||||
|
||||
if (this.isFirstBeforeMethod(context)) {
|
||||
/**
|
||||
* redis server wouldn't process rpc context. ignore the
|
||||
* return(ContextData) of sender's beforeSend
|
||||
*/
|
||||
IdentificationBuilder builder = Identification
|
||||
.newBuilder()
|
||||
.viewPoint(
|
||||
context.get(REDIS_CONN_INFO_KEY, String.class)
|
||||
+ " " + interceptorContext.methodName())
|
||||
.spanType(RedisBuriedPointType.instance());
|
||||
if (interceptorContext.allArguments().length > 0
|
||||
&& interceptorContext.allArguments()[0] instanceof String) {
|
||||
builder.businessKey("key="
|
||||
+ interceptorContext.allArguments()[0]);
|
||||
}
|
||||
sender.beforeSend(builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedClassInstanceContext context,
|
||||
MethodInvokeContext interceptorContext, Object ret) {
|
||||
if (this.isLastAfterMethod(context)) {
|
||||
sender.afterSend();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -29,7 +76,7 @@ public class JedisInterceptor implements IAroundInterceptor{
|
|||
public void handleMethodException(Throwable t,
|
||||
EnhancedClassInstanceContext context,
|
||||
MethodInvokeContext interceptorContext, Object ret) {
|
||||
|
||||
sender.handleException(t);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
package org.skywalking.jedis.v2.plugin;
|
||||
|
||||
import com.ai.cloud.skywalking.api.IBuriedPointType;
|
||||
import com.ai.cloud.skywalking.protocol.CallType;
|
||||
|
||||
public class RedisBuriedPointType implements IBuriedPointType {
|
||||
private static RedisBuriedPointType redisBuriedPointType;
|
||||
|
||||
public static IBuriedPointType instance() {
|
||||
if (redisBuriedPointType == null) {
|
||||
redisBuriedPointType = new RedisBuriedPointType();
|
||||
}
|
||||
|
||||
return redisBuriedPointType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return "Redis";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallType getCallType() {
|
||||
return CallType.SYNC;
|
||||
}
|
||||
|
||||
private RedisBuriedPointType(){}
|
||||
}
|
||||
|
|
@ -5,19 +5,34 @@ import java.sql.SQLException;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
import com.ai.cloud.skywalking.plugin.TracingBootstrap;
|
||||
|
||||
public class JedisTest {
|
||||
|
||||
@Test
|
||||
public void test() throws IllegalAccessException,
|
||||
IllegalArgumentException, InvocationTargetException,
|
||||
NoSuchMethodException, SecurityException, ClassNotFoundException {
|
||||
public void test() throws IllegalAccessException, IllegalArgumentException,
|
||||
InvocationTargetException, NoSuchMethodException,
|
||||
SecurityException, ClassNotFoundException {
|
||||
TracingBootstrap
|
||||
.main(new String[] { "org.skywalking.jedis.v2.plugin.JedisTest" });
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws ClassNotFoundException,
|
||||
SQLException, InterruptedException {}
|
||||
|
||||
SQLException, InterruptedException {
|
||||
try(Jedis jedis = new Jedis("10.1.241.18", 16379)){
|
||||
long start = System.currentTimeMillis();
|
||||
jedis.set("11111", "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
|
||||
for (int i = 0; i < 1; i++) {
|
||||
jedis.get("11111");
|
||||
}
|
||||
long end = System.currentTimeMillis();
|
||||
System.out.println(end - start + "ms");
|
||||
jedis.del("11111");
|
||||
}
|
||||
}
|
||||
|
||||
public void testNormal() throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException, InterruptedException{
|
||||
JedisTest.main(null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,9 +35,10 @@ public class MachineUtil {
|
|||
if (StringUtil.isEmpty(IP)) {
|
||||
InetAddress netAddress = getInetAddress();
|
||||
if (null == netAddress) {
|
||||
return null;
|
||||
IP = "N/A";
|
||||
}else{
|
||||
IP = netAddress.getHostAddress(); //get the ip address
|
||||
}
|
||||
IP = netAddress.getHostAddress(); //get the ip address
|
||||
}
|
||||
return IP;
|
||||
}
|
||||
|
|
@ -46,9 +47,10 @@ public class MachineUtil {
|
|||
if (StringUtil.isEmpty(hostName)) {
|
||||
InetAddress netAddress = getInetAddress();
|
||||
if (null == netAddress) {
|
||||
return null;
|
||||
hostName = "N/A";
|
||||
}else{
|
||||
hostName = netAddress.getHostName(); //get the host address
|
||||
}
|
||||
hostName = netAddress.getHostName(); //get the host address
|
||||
}
|
||||
return hostName;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue