代码之家  ›  专栏  ›  技术社区  ›  Sixthpoint

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

  •  0
  • Sixthpoint  · 技术社区  · 6 年前

    我正在为仪表板创建报表API终结点。报告最初调用24个线程(layer1),然后每个线程调用另外4个线程(layer2)。然后layer2service调用存储库来获取数据。从结果中我看到的是layer2服务在每个线程中都开始减速。看起来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;
       }
    }
    

    第2层与存储库交互,这是减速开始发生的地方。有24*4=96个线程或对数据库的调用几乎同时发生。

    @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 回复  |  直到 6 年前