实战示例
- 添加maven依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
- 添加启动类
@SpringBootApplication
public class RetailApp {
public static void main(String[] args){
SpringApplication.run(RetailApp.class, args);
}
}
- 添加领域实体和服务类
@Data
@Accessors(chain = true)
public class Spu {
private Long id;
private String name;
}
@Service
public class SpuService {
public Spu findSpuById(Long id){
try {
TimeUnit.MILLISECONDS.sleep(50); //模拟耗时任务
} catch (InterruptedException e) {
e.printStackTrace();
}
return new Spu().setId(id).setName("spu"+id);
}
}
- 添加rest api
@RestController
@Slf4j
public class SpuRestApi {
@Autowired
SpuService spuService;
@GetMapping("/v1/spu/detail")
public Mono<Spu> findById(Long id){
StopWatch stopWatch = new StopWatch();
stopWatch.start();
return Mono.just(id)
.flatMap(x-> Mono.fromCallable(()-> spuService.findSpuById(x))
.subscribeOn(Schedulers.elastic())) //关键,netty线程不适合用来处理长时间阻塞的任务
.doOnSuccess(x-> {
stopWatch.stop();
log.info("{}", stopWatch.toString());
});
}
}
压力测试
压测环境:
- macbook pro
- 2.7 GHz Intel Core i7
- 16 GB
从压测结果来看,可以达到惊人的1.5w+以上的QPS,系统表现还相对稳定。
wrk -t10 -c100 -d120s --timeout 2s --latency 'http://localhost:8080/v1/spu/detail?id=1'
Running 2m test @ http://localhost:8080/v1/spu/detail?id=1
10 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 54.09ms 2.71ms 163.71ms 86.00%
Req/Sec 185.59 17.25 203.00 85.88%
Latency Distribution
50% 54.29ms
75% 55.26ms
90% 55.94ms
99% 58.27ms
221895 requests in 2.00m, 22.64MB read
Requests/sec: 1847.68
Transfer/sec: 193.07KB
wrk -t10 -c500 -d120s --timeout 2s --latency 'http://localhost:8080/v1/spu/detail?id=1'
Running 2m test @ http://localhost:8080/v1/spu/detail?id=1
10 threads and 500 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 55.44ms 6.89ms 294.20ms 97.99%
Req/Sec 0.89k 108.62 1.01k 91.97%
Latency Distribution
50% 55.14ms
75% 56.32ms
90% 57.70ms
99% 66.94ms
1067897 requests in 2.00m, 108.97MB read
Socket errors: connect 0, read 464, write 0, timeout 0
Requests/sec: 8894.89
Transfer/sec: 0.91MB
wrk -t10 -c1000 -d120s --timeout 2s --latency 'http://localhost:8080/v1/spu/detail?id=1'
Running 2m test @ http://localhost:8080/v1/spu/detail?id=1
10 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 61.92ms 20.97ms 536.55ms 94.69%
Req/Sec 1.58k 294.84 2.02k 83.12%
Latency Distribution
50% 57.85ms
75% 62.72ms
90% 73.75ms
99% 118.44ms
1875346 requests in 2.00m, 191.37MB read
Socket errors: connect 0, read 1081, write 0, timeout 0
Requests/sec: 15616.09
Transfer/sec: 1.59MB
用VisualVM跟踪如下: