我正在为仪表板创建报告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"
]
}
]
}
如何使这项服务更高效?