“This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!”
How well does Quarkus perform when connecting to a database based on Insert performance?
Server Configuration
CentOS Linux release 7.6.1810 (Core)
Intel(R) Xeon(R) Gold 6278C CPU @ 2.60GHz
4C8G
Copy the code
The performance test
The database is PG, if you like Mysql, same thing.
The test sample
The data model
CREATE TABLE "public"."dynamic_info" (
"id" int8 NOT NULL,
"dynamic_type" int2,
"dynamic_desc" varchar,
"creator" varchar,
"created_time" timestamp.PRIMARY KEY ("id")
);
Copy the code
Map the entity DynamicInfo
package org.mxx.pg.domain;
import com.google.common.collect.Lists;
import io.vertx.mutiny.sqlclient.Row;
import io.vertx.mutiny.sqlclient.RowSet;
import java.time.LocalDateTime;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Id;
<br> * <p>Created Time: 2021/7/8 PM 2:20 </p> **@author<a href="mail to: [email protected]" rel="nofollow"> </a> */
@Entity(name = "dynamic_info")
public class DynamicInfo {
@Id
private Long id;
private Integer dynamicType;
private String dynamicDesc;
private String creator;
private LocalDateTime createdTime;
public static DynamicInfo from(Row row) {
return new DynamicInfo(
row.getLong("id"),
row.getInteger("dynamic_type"),
row.getString("dynamic_desc"),
row.getString("creator"),
row.getLocalDateTime("created_time")); }public static List<DynamicInfo> froms(RowSet<Row> rows) {
List<DynamicInfo> result = Lists.newArrayList();
rows.forEach(row -> {
result.add(from(row));
});
return result;
}
public DynamicInfo(a) {}public DynamicInfo(Long id, Integer dynamicType, String dynamicDesc, String creator, LocalDateTime createdTime) {
this.id = id;
this.dynamicType = dynamicType;
this.dynamicDesc = dynamicDesc;
this.creator = creator;
this.createdTime = createdTime;
}
public Long getId(a) {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getDynamicType(a) {
return dynamicType;
}
public void setDynamicType(Integer dynamicType) {
this.dynamicType = dynamicType;
}
public String getDynamicDesc(a) {
return dynamicDesc;
}
public void setDynamicDesc(String dynamicDesc) {
this.dynamicDesc = dynamicDesc;
}
public String getCreator(a) {
return creator;
}
public void setCreator(String creator) {
this.creator = creator;
}
public LocalDateTime getCreatedTime(a) {
return createdTime;
}
public void setCreatedTime(LocalDateTime createdTime) {
this.createdTime = createdTime; }}Copy the code
Create BaseRepository
package org.mxx.config.base;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import io.quarkus.reactive.datasource.ReactiveDataSource;
import io.vertx.mutiny.pgclient.PgPool;
import javax.inject.Inject;
/**
* Description: Pg .<br>
* <p>Created Time: 2021/6/8 δΈε4:40 </p>
*
* @author<a href="mail to: [email protected]" rel="nofollow"> </a> */
public class BasePgRepository {
@Inject
@ReactiveDataSource("pg")
protected PgPool pgPool;
protected Snowflake snowflake = IdUtil.getSnowflake(1.1);
}
Copy the code
Create a Repository for entities
package org.mxx.pg.repository;
import io.smallrye.mutiny.Uni;
import io.vertx.mutiny.sqlclient.Tuple;
import java.time.LocalDateTime;
import java.util.Date;
import javax.inject.Singleton;
import org.mxx.config.base.BasePgRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
<br> * <p>Created Time: 2021/7/8 PM 2:27 </p> **@author<a href="mail to: [email protected]" rel="nofollow"> </a> */
@Singleton
public class DynamicInfoRepository extends BasePgRepository {
private static final Logger LOGGER = LoggerFactory.getLogger(DynamicInfoRepository.class);
public Uni<Long> addDynamicInfo(a) {
return pgPool.preparedQuery(
"insert into dynamic_info (id,dynamic_type,dynamic_desc,creator,created_time) values ($1,$2,$3,$4,$5) RETURNING id")
.execute(Tuple.of(
snowflake.nextId(),
1."Admin added dynamic"."admin",
LocalDateTime.now()))
.onItem()
.transform(pgRowSet -> pgRowSet.iterator().next().getLong("id")); }}Copy the code
To create the Resource
package org.mxx.pg.resource;
import io.quarkus.vertx.web.Route;
import io.smallrye.mutiny.Uni;
import io.vertx.core.http.HttpMethod;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import org.mxx.pg.repository.DynamicInfoRepository;
<br> * <p>Created Time: 2021/7/8 PM 2:19 </p> **@author<a href="mail to: [email protected]" rel="nofollow"> </a> */
@Singleton
@Tag(name = "dynamic")
public class DynamicResource {
@Inject
DynamicInfoRepository dynamicInfoRepository;
@Route(path = "/addDynamic", methods = HttpMethod.GET)
Uni<Long> addDynamic(a) {
returndynamicInfoRepository.addDynamicInfo(); }}Copy the code
Deployment way
First of all, you pack it
./mvnw package
Copy the code
Then drop the Quarkus-app folder in target into the server to start
nohup java -jar quarkus-app/quarkus-run.jar &
Copy the code
Unit testing
The curl http://127.0.0.1:8080/addDynamicCopy the code
Have normal accessDatabase persistence into
Performance testing (Insert)
[root@ecs-1b4c-0002 k6]# WRK c50 - d20s' http://127.0.0.1:8080/addDynamic '- latency
Running 20s test50 connections @ http://127.0.0.1:8080/addDynamic 2 threads and Thread Stats Avg Stdev Max + / - Stdev Latency 3.56 ms 12.06ms 214.33ms 98.54% Req/Sec 10.83k 1.47k 13.73k 75.88% Latency Distribution 50% 2.02ms 75% 2.65ms 90% 4.05ms 99% 29.37 ms 428896 requestsin20.01 s, 42.54 MBread
Requests/sec: 21438.03
Transfer/sec: 2.13MB
Copy the code
The database wrote 428936 pieces of data in 20 seconds.
Performance Test (Select)
At this point, 430,000 pieces of data already exist in the database
[root@ecs-1b4c-0002 k6]# wrk -c50 -d20s 'http://127.0.0.1:8080/findDynamicById?id=1413054691109113856' --latency
Running 20s test@ http://127.0.0.1:8080/findDynamicById? Id =1413054691109113856 2 threads and 50 connections Thread Stats Avg Stdev Max +/ -stdev Latency 1.16ms 1.07ms 48.74ms 97.63% Req/Sec 23.06k 1.26k 40.17k 95.51% Latency Distribution 50% 1.05ms 75% 1.28ms 90% 1.56ms 99% 3.88ms 920108 requestsin20.10 s, 194.80 MBread
Requests/sec: 45776.45
Transfer/sec: 9.69MB
Copy the code
In 20 seconds, 920,000 searches were performed, with a QPS of 45,000.
Process information in the pressure test
Top-16:51:39 up 247 days, 20:00, 2 users, load average: 0.77, 0.28, 0.26 Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie %Cpu(s): 35.7 US, 26.3 sy, 0.0Ni, 20.3 ID, 0.0WA, 0.0Hi, 17.8 Si, 0.0st KiB Mem: 8008324 total, 1016916 free, 4775628 used, 2215780 buff/cache KiB Swap: 0 total, 0 free, 0 used. 2645436 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 5222 root 20 0 5246408 439708 13716 S 265.0 5.5 understood. 46 JavaCopy the code
Process information after pressure testing
[root@ecs-1b4c-0002 k6]# jmap -J-d64 -heap 5222
Attaching to process ID 5222, please wait. Server Compiler detected. JVM version is 25.171-B11 using thread-local object allocation. Parallel GC with 4 thread(s) Heap Configuration: MinHeapFreeRatio = 0 MaxHeapFreeRatio = 100 MaxHeapSize = 2051014656 (1956.0MB) NewSize = 42991616 (41.0MB) MaxNewSize = 683671552 (652.0MB) OldSize = 87031808 (83.0MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB) Heap Usage: PS Young Generation Eden Space: Capacity = 136314880 (130.0MB) Used = 4515344 (4.3061676025390625MB) Free = 131799536 (125.69383239746094MB) capacity = 136314880 (130.0MB) Used = 4515344 (4.3061676025390625MB) Free = 131799536 (125.69383239746094MB) 3.3124366173377404%, informs the From Space: Capacity = 524288 (0.5MB) Used = 131072 (0.125MB) Free = 393216 (0.375MB) 25.0% used To Space: Capacity = 524288 (0.5MB) Used = 0 (0.0MB) Free = 524288 (0.5MB) 0.0% Used PS Old Generation Capacity = 100139008 (95.5MB) Used = 21208464 (20.225967407226562MB) Free = 78930544 (75.27403259277344MB) 21.179023463064464% used 11297 interned Strings occupying 1320912 bytes.Copy the code
gossip
Quarkus has advantages in Rest services, but obviously the performance of the database determines the performance upper limit of API services, so its performance advantage can be better reflected when calling Redis or memory.
The connection to the database uses the Reactive Client of vert. x, which makes more use of resources than the synchronous blocking JDBC.