Fabric底层SDK压测中遇到的问题以及总结

最近在开发一个压测需求,主要就是在并发的环境总测试fabric底层代码tps,在这个过程中遇到的很多问题,主要包括不同线程池并发下不同情况所造成的影响不同,其中Exectors类中四种线程池方法,一开始我使用的newScheduleThreadPool,让线程周期性运行,在线程并发下效率不是很高,然后,我使用了newFixedThreadPool,在这其中声明了count静态变量用于计算并发中 运行的次数,开始我把它放在run方法中由于是在并发的环境,所以使用了 synchronized保证变量的均匀的变化,但是这带来的效果是运行效率相当低,而且在使用execute()来循环执行线程池,发现运行时方法效率超级低,有的时候底层方法直接就调用超时。在这之后,我使用submit()来执行发现可以正常运行,但是效率依旧很低,之后我使用callable接口重写它的call()方法,同时通过call方法将count在main方法中返回来实现运行次数的判断。发现这样也不是很好,后来看到并发工具类中提供了一些类可以实现并发的计数,其中有Sempore主要实现并发中控制允许并发的线程数,countdownlatch主要使用其中的countdown()方法统计并发次数,await()方法实现主线程等待子线程允许完后关闭线程池,之后发现可以直接在主线程中使用count自增来实现运行次数的控制,同时,也将newFixedThreadPool换成了newCacheThreadPool主要是因为在并发情况下第二种线程池运行更快,查阅了资料发现newFixedThreadPool使用了LinkedBlockingQueue而newCacheThreadPool是SynchronousQueues所以运行效率更高,同时使用Semphore来控制并发量.
这就是我最近压测中遇到的一些情况,欢迎大年指点。
import java.io.IOException;
import java.util.concurrent.*;
import org.apache.log4j.Logger;
public class PressureTestInvokeCacheSem implements Runnable {
     private static Logger infolog = Logger.getLogger(PressureTestInvoke3.class);
     @SuppressWarnings("rawtypes")
     private static ParaContent content; // invoke方法参数
     private static int count;// 通过count查询参数
     private static String[] runPara = ReadInvokePara.readFixPara();// 运行状态参数
     private static Semaphore se = new Semaphore(Integer.valueOf(runPara[0]));// 并发量
public ChannelClient buildCommonChannel(String channelName, String chainCode) throws IOException {
FabricConfigFactory fabricConfigFactory = new FabricConfigFactory();
String path = PressureTestInvoke.class.getResource("/resources").getFile();
fabricConfigFactory.setBaseDir(path.substring(5, path.length() - 27) + "fabric");
ChannelClientFactory channelClientFactory = new ChannelClientFactory();
channelClientFactory.setFabricConfig(fabricConfigFactory.buildFabricConfig());
     ChannelClient channelClient= channelClientFactory.buildChannelClient(channelName,chainCode);
     return channelClient;
}
public T preTestAsync(String channelName, String chainCode, String fcn, Class cl, String... args)throws FabricException, IOException {
T t = buildCommonChannel(channelName, chainCode).invokeAsync(fcn, cl, args);
return t;
}
@SuppressWarnings({ "rawtypes" })
public static void main(String[] args) {
int runCount = 0; // 运行总次数
ExecutorService executor = Executors.newCachedThreadPool();
while (runCount <= Integer.valueOf(runPara[1])) {
++runCount;
executor.execute(new PressureTestInvokeCacheSem());
}
executor.shutdown();
infolog.info("压测结束");
}
@SuppressWarnings("unchecked")
@Override
public void run() {
try {
se.acquire(); // 请求
++count;
content = ReadInvokePara.readPara(count);
if (null != content) {
     preTestAsync(content.getChannelName(), content.getChainCode(), content.getFcn(),
     (Class) String.class, content.getArgs());
int invokewait = Integer.valueOf(runPara[4]);
if (0 != invokewait) {
 Thread.sleep(invokewait);
              }
}
} catch (Exception e) {
e.printStackTrace();
}
se.release(); // 释放
}
}

你可能感兴趣的:(Fabric底层SDK压测中遇到的问题以及总结)