多线程创建缓慢的存储库调用

时间:2018-12-12 22:46:08

标签: spring multithreading spring-boot

我正在为仪表板创建报告api端点。该报告最初调用24个线程(第1层),然后每个线程又调用另外4个线程(第2层)。然后,Layer2Service调用存储库以获取数据。从结果中看到的是,我的Layer2Service在每个线程期间开始变慢。看来Spring可能正在合并这些存储库调用。为什么我的线程速度变慢?

@Service
public class BaseService {

   @Autowired
   private Layer1Service layer1Service;

   public BaseLayer baseLayer() throws ExecutionException, InterruptedException {

       Stopwatch stopWatch = Stopwatch.createStarted();
       List<CompletableFuture<Layer1Service.Layer1>> threadQueue = new ArrayList<>();

       int maxThreads = 24;
       int threadCount = 0;
       while(threadCount < maxThreads) {
           CompletableFuture<Layer1Service.Layer1> threadAsync = layer1Service.layer1();
           threadQueue.add(threadAsync);
           threadCount++;
       }

       CompletableFuture<Void> allDoneFutures =
            CompletableFuture.allOf(threadQueue.toArray(new CompletableFuture[threadQueue.size()]));
       CompletableFuture<List<Layer1Service.Layer1>> allCompletableFuture = allDoneFutures.thenApply(future -> {
           List<Layer1Service.Layer1> list = new ArrayList<>();
           for (CompletableFuture<Layer1Service.Layer1> completableFuture : threadQueue) {
               Layer1Service.Layer1 join = completableFuture.join();
               list.add(join);
           }
           return list;
       });


       List<Layer1Service.Layer1> results = allCompletableFuture.get();

       stopWatch.stop();

       BaseLayer baseLayer = new BaseLayer();
       baseLayer.setThreadResults(results);

       String result = "Base layer: " + Thread.currentThread().getId() + " Completion time: " + stopWatch.elapsed(TimeUnit.MILLISECONDS);
       baseLayer.setTimingResult(result);

       return baseLayer;
   }

   @Data
   public class BaseLayer {

       public String timingResult;
       public List<Layer1Service.Layer1> threadResults;
   }
}

Layer1Services从Layer2Service再创建4个线程。

@Service
public class Layer1Service {

   @Autowired
   private Layer2Service layer2Service;

   @Async("dashboard")
   public CompletableFuture<Layer1> layer1() throws InterruptedException, ExecutionException {

       Stopwatch stopWatch = Stopwatch.createStarted();
       List<CompletableFuture<String>> threadQueue = new ArrayList<>();

       int maxThreads = 4;
       int threadCount = 0;
       while(threadCount < maxThreads) {
           CompletableFuture<String> threadAsync = layer2Service.layer2(Thread.currentThread().getId());
           threadQueue.add(threadAsync);
           threadCount++;
       }

       CompletableFuture<Void> allDoneFutures =
            CompletableFuture.allOf(threadQueue.toArray(new CompletableFuture[threadQueue.size()]));
       CompletableFuture<List<String>> allCompletableFuture = allDoneFutures.thenApply(future -> {
           List<String> list = new ArrayList<>();
           for (CompletableFuture<String> completableFuture : threadQueue) {
               String join = completableFuture.join();
               list.add(join);
           }
           return list;
       });

       List<String> results = allCompletableFuture.get();

       stopWatch.stop();

       Layer1 layer1 = new Layer1();
       layer1.setThreadResults(results);

       String result = "Layer 1: " + Thread.currentThread().getId() + " Completion time: " + stopWatch.elapsed(TimeUnit.MILLISECONDS);
       layer1.setTimingResult(result);

       return CompletableFuture.completedFuture(layer1);
   }

   @Data
   public class Layer1 {

       public String timingResult;
       public List<String> threadResults;
   }
}

Layer2与存储库进行交互,这是开始减速的地方。几乎同时发生了24 * 4 = 96个线程或对db的调用。

@Service
public class Layer2Service {

   @Autowired
   private LanguageRepository languageRepository;

   @Async("dashboard")
   public CompletableFuture<String> layer2(long threadId) {
       Stopwatch stopWatch = Stopwatch.createStarted();
       final Optional<Language> firstById = languageRepository.findById(Long.valueOf(1));
       stopWatch.stop();
       String result = "Layer1: " + threadId + " Layer2: " + Thread.currentThread().getId() + " Runtime: " + stopWatch.elapsed(TimeUnit.MILLISECONDS);
       return CompletableFuture.completedFuture(result);
   }

要管理池的大小,我创建了一个自定义执行程序:

@Bean(name = "dashboard")
public Executor asyncDashboard() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(150);
    executor.setMaxPoolSize(225);
    executor.setQueueCapacity(300);
    executor.setThreadNamePrefix("Dashboard-");
    executor.initialize();
    return executor;
}

结果:

{
  "timingResult": "Base layer: 65 Completion time: 5295",
  "threadResults": [
    {
      "timingResult": "Layer 1: 93 Completion time: 2439",
      "threadResults": [
        "Layer1: 93 Layer2: 117 Runtime: 2346",
        "Layer1: 93 Layer2: 145 Runtime: 2346",
        "Layer1: 93 Layer2: 146 Runtime: 2347",
        "Layer1: 93 Layer2: 147 Runtime: 2416"
      ]
    },
    {
      "timingResult": "Layer 1: 94 Completion time: 2901",
      "threadResults": [
        "Layer1: 94 Layer2: 116 Runtime: 2417",
        "Layer1: 94 Layer2: 148 Runtime: 2416",
        "Layer1: 94 Layer2: 150 Runtime: 2803",
        "Layer1: 94 Layer2: 156 Runtime: 2876"
      ]
    },
    {
      "timingResult": "Layer 1: 95 Completion time: 3372",
      "threadResults": [
        "Layer1: 95 Layer2: 115 Runtime: 2419",
        "Layer1: 95 Layer2: 149 Runtime: 2796",
        "Layer1: 95 Layer2: 157 Runtime: 3343",
        "Layer1: 95 Layer2: 163 Runtime: 3342"
      ]
    },
    {
      "timingResult": "Layer 1: 96 Completion time: 2913",
      "threadResults": [
        "Layer1: 96 Layer2: 114 Runtime: 1463",
        "Layer1: 96 Layer2: 118 Runtime: 2346",
        "Layer1: 96 Layer2: 144 Runtime: 2416",
        "Layer1: 96 Layer2: 151 Runtime: 2887"
      ]
    },
    {
      "timingResult": "Layer 1: 97 Completion time: 1479",
      "threadResults": [
        "Layer1: 97 Layer2: 112 Runtime: 1474",
        "Layer1: 97 Layer2: 119 Runtime: 999",
        "Layer1: 97 Layer2: 121 Runtime: 1001",
        "Layer1: 97 Layer2: 122 Runtime: 1448"
      ]
    },
    {
      "timingResult": "Layer 1: 98 Completion time: 1480",
      "threadResults": [
        "Layer1: 98 Layer2: 113 Runtime: 1001",
        "Layer1: 98 Layer2: 123 Runtime: 999",
        "Layer1: 98 Layer2: 124 Runtime: 1475",
        "Layer1: 98 Layer2: 125 Runtime: 985"
      ]
    },
    {
      "timingResult": "Layer 1: 99 Completion time: 1950",
      "threadResults": [
        "Layer1: 99 Layer2: 111 Runtime: 1475",
        "Layer1: 99 Layer2: 126 Runtime: 1466",
        "Layer1: 99 Layer2: 139 Runtime: 1893",
        "Layer1: 99 Layer2: 140 Runtime: 1934"
      ]
    },
    {
      "timingResult": "Layer 1: 100 Completion time: 3243",
      "threadResults": [
        "Layer1: 100 Layer2: 110 Runtime: 1475",
        "Layer1: 100 Layer2: 127 Runtime: 1915",
        "Layer1: 100 Layer2: 135 Runtime: 3080",
        "Layer1: 100 Layer2: 153 Runtime: 3216"
      ]
    },
    {
      "timingResult": "Layer 1: 101 Completion time: 2650",
      "threadResults": [
        "Layer1: 101 Layer2: 109 Runtime: 2645",
        "Layer1: 101 Layer2: 129 Runtime: 1902",
        "Layer1: 101 Layer2: 134 Runtime: 1002",
        "Layer1: 101 Layer2: 136 Runtime: 1902"
      ]
    },
    {
      "timingResult": "Layer 1: 102 Completion time: 2914",
      "threadResults": [
        "Layer1: 102 Layer2: 106 Runtime: 1944",
        "Layer1: 102 Layer2: 131 Runtime: 2883",
        "Layer1: 102 Layer2: 154 Runtime: 2887",
        "Layer1: 102 Layer2: 158 Runtime: 2887"
      ]
    },
    {
      "timingResult": "Layer 1: 103 Completion time: 5219",
      "threadResults": [
        "Layer1: 103 Layer2: 107 Runtime: 1946",
        "Layer1: 103 Layer2: 128 Runtime: 981",
        "Layer1: 103 Layer2: 137 Runtime: 5207",
        "Layer1: 103 Layer2: 138 Runtime: 1938"
      ]
    },
    {
      "timingResult": "Layer 1: 104 Completion time: 1468",
      "threadResults": [
        "Layer1: 104 Layer2: 108 Runtime: 998",
        "Layer1: 104 Layer2: 130 Runtime: 997",
        "Layer1: 104 Layer2: 132 Runtime: 1446",
        "Layer1: 104 Layer2: 133 Runtime: 1461"
      ]
    },
    {
      "timingResult": "Layer 1: 105 Completion time: 2822",
      "threadResults": [
        "Layer1: 105 Layer2: 120 Runtime: 1930",
        "Layer1: 105 Layer2: 142 Runtime: 2145",
        "Layer1: 105 Layer2: 143 Runtime: 2800",
        "Layer1: 105 Layer2: 152 Runtime: 2798"
      ]
    },
    {
      "timingResult": "Layer 1: 155 Completion time: 3347",
      "threadResults": [
        "Layer1: 155 Layer2: 159 Runtime: 3216",
        "Layer1: 155 Layer2: 160 Runtime: 3215",
        "Layer1: 155 Layer2: 161 Runtime: 3272",
        "Layer1: 155 Layer2: 162 Runtime: 3346"
      ]
    },
    {
      "timingResult": "Layer 1: 164 Completion time: 3805",
      "threadResults": [
        "Layer1: 164 Layer2: 166 Runtime: 3342",
        "Layer1: 164 Layer2: 168 Runtime: 3547",
        "Layer1: 164 Layer2: 170 Runtime: 3666",
        "Layer1: 164 Layer2: 172 Runtime: 3803"
      ]
    },
    {
      "timingResult": "Layer 1: 165 Completion time: 3744",
      "threadResults": [
        "Layer1: 165 Layer2: 167 Runtime: 3347",
        "Layer1: 165 Layer2: 169 Runtime: 3667",
        "Layer1: 165 Layer2: 171 Runtime: 3667",
        "Layer1: 165 Layer2: 173 Runtime: 3742"
      ]
    },
    {
      "timingResult": "Layer 1: 174 Completion time: 4019",
      "threadResults": [
        "Layer1: 174 Layer2: 176 Runtime: 3802",
        "Layer1: 174 Layer2: 177 Runtime: 3802",
        "Layer1: 174 Layer2: 179 Runtime: 3802",
        "Layer1: 174 Layer2: 181 Runtime: 4018"
      ]
    },
    {
      "timingResult": "Layer 1: 175 Completion time: 4152",
      "threadResults": [
        "Layer1: 175 Layer2: 178 Runtime: 3802",
        "Layer1: 175 Layer2: 180 Runtime: 4118",
        "Layer1: 175 Layer2: 182 Runtime: 4118",
        "Layer1: 175 Layer2: 183 Runtime: 4151"
      ]
    },
    {
      "timingResult": "Layer 1: 184 Completion time: 4274",
      "threadResults": [
        "Layer1: 184 Layer2: 185 Runtime: 4207",
        "Layer1: 184 Layer2: 187 Runtime: 4263",
        "Layer1: 184 Layer2: 188 Runtime: 4263",
        "Layer1: 184 Layer2: 190 Runtime: 4273"
      ]
    },
    {
      "timingResult": "Layer 1: 186 Completion time: 5249",
      "threadResults": [
        "Layer1: 186 Layer2: 189 Runtime: 4250",
        "Layer1: 186 Layer2: 191 Runtime: 4516",
        "Layer1: 186 Layer2: 192 Runtime: 4575",
        "Layer1: 186 Layer2: 193 Runtime: 4646"
      ]
    },
    {
      "timingResult": "Layer 1: 194 Completion time: 4418",
      "threadResults": [
        "Layer1: 194 Layer2: 202 Runtime: 4264",
        "Layer1: 194 Layer2: 209 Runtime: 4264",
        "Layer1: 194 Layer2: 211 Runtime: 4101",
        "Layer1: 194 Layer2: 213 Runtime: 4035"
      ]
    },
    {
      "timingResult": "Layer 1: 195 Completion time: 4800",
      "threadResults": [
        "Layer1: 195 Layer2: 200 Runtime: 4643",
        "Layer1: 195 Layer2: 205 Runtime: 4328",
        "Layer1: 195 Layer2: 207 Runtime: 4274",
        "Layer1: 195 Layer2: 208 Runtime: 4166"
      ]
    },
    {
      "timingResult": "Layer 1: 196 Completion time: 4676",
      "threadResults": [
        "Layer1: 196 Layer2: 199 Runtime: 4520",
        "Layer1: 196 Layer2: 206 Runtime: 4100",
        "Layer1: 196 Layer2: 210 Runtime: 3829",
        "Layer1: 196 Layer2: 212 Runtime: 4101"
      ]
    },
    {
      "timingResult": "Layer 1: 197 Completion time: 4881",
      "threadResults": [
        "Layer1: 197 Layer2: 198 Runtime: 4595",
        "Layer1: 197 Layer2: 201 Runtime: 4707",
        "Layer1: 197 Layer2: 203 Runtime: 4514",
        "Layer1: 197 Layer2: 204 Runtime: 4328"
      ]
    }
  ]
}

如何使这项服务更高效?

0 个答案:

没有答案