1.修复API和Server代码中,MachineUtil的gethost/getip,在没有配置静态IP的时候,性能极慢的问题。

2.API增加底层拦截器,FirstInvokeInterceptor。用于首次拦截方法调用,避免方法内部的方法调用被多次拦截。
3.提供Jedis插件实现。并提交性能测试。
#38
This commit is contained in:
wusheng 2016-03-18 16:34:19 +08:00
parent c02c3f3ed1
commit 6efa8e1db8
9 changed files with 194 additions and 22 deletions

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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");
}
}

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -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(){}
}

View File

@ -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);
}
}

View File

@ -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;
}