-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: ensure that the generated short link is unique when the origina…
…l url is same (#25)
- Loading branch information
1 parent
6e74711
commit 3db9ca1
Showing
16 changed files
with
10,312 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
|
||
# 性能测试 | ||
|
||
对 API 的性能测试,主要是为了验证 API 的性能是否满足需求,以及在不同的并发情况下,API 的性能表现。 | ||
|
||
## 测试资源 | ||
|
||
服务器:Apple MacBook Pro14 M1 Pro 2021 16G 512G SSD | ||
|
||
## 测试方式 | ||
|
||
获取全球访问量前 10k 的域名,每个域名添加 10 个 API 后缀,共计 100k 条无重复数据。使用 100 个协程并发请求,统计写入耗时。 | ||
|
||
```shell | ||
Benchmark_Create | ||
api_benchmark_test.go:93: send requests: 4550 | ||
api_benchmark_test.go:93: send requests: 10040 | ||
api_benchmark_test.go:93: send requests: 15422 | ||
api_benchmark_test.go:93: send requests: 20977 | ||
api_benchmark_test.go:93: send requests: 26532 | ||
api_benchmark_test.go:93: send requests: 32452 | ||
api_benchmark_test.go:93: send requests: 38095 | ||
api_benchmark_test.go:93: send requests: 42921 | ||
api_benchmark_test.go:93: send requests: 47579 | ||
api_benchmark_test.go:93: send requests: 52629 | ||
api_benchmark_test.go:93: send requests: 58464 | ||
api_benchmark_test.go:93: send requests: 63961 | ||
api_benchmark_test.go:93: send requests: 69651 | ||
api_benchmark_test.go:93: send requests: 75325 | ||
api_benchmark_test.go:93: send requests: 80952 | ||
api_benchmark_test.go:93: send requests: 87016 | ||
api_benchmark_test.go:93: send requests: 92535 | ||
api_benchmark_test.go:93: send requests: 98344 | ||
api_benchmark_test.go:111: success requests: 100000 costs 18.365219458s | ||
``` | ||
综合来看,API 的性能表现良好,能够达到 5000+ QPS 的写入速度。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
-- auto-generated definition | ||
create table sequences | ||
( | ||
id bigint unsigned auto_increment | ||
primary key, | ||
created_at datetime(3) null, | ||
updated_at datetime(3) null, | ||
deleted_at datetime(3) null, | ||
name varchar(500) not null, | ||
sequence bigint not null, | ||
version bigint null, | ||
constraint idx_sequences_name | ||
unique (name) | ||
); | ||
|
||
create index idx_sequences_deleted_at | ||
on sequences (deleted_at); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
-- auto-generated definition | ||
create table tiny_urls | ||
( | ||
id bigint unsigned auto_increment | ||
primary key, | ||
created_at datetime(3) null, | ||
updated_at datetime(3) null, | ||
deleted_at datetime(3) null, | ||
long_url varchar(500) not null, | ||
short bigint not null, | ||
constraint idx_tiny_urls_long_url | ||
unique (long_url), | ||
constraint idx_tiny_urls_short | ||
unique (short) | ||
); | ||
|
||
create index idx_tiny_urls_deleted_at | ||
on tiny_urls (deleted_at); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package benchmark | ||
|
||
import ( | ||
"bufio" | ||
"crypto/sha256" | ||
"fmt" | ||
"io" | ||
"log" | ||
"net/http" | ||
"os" | ||
"strconv" | ||
"strings" | ||
"sync" | ||
"sync/atomic" | ||
"testing" | ||
"time" | ||
) | ||
|
||
const addr = "http://localhost:8080/api/shorten" | ||
|
||
func readDomain(b *testing.B) []string { | ||
file, err := os.Open("domain.txt") | ||
if err != nil { | ||
b.Error(err) | ||
} | ||
|
||
defer file.Close() | ||
|
||
var lines []string | ||
scanner := bufio.NewScanner(file) | ||
for scanner.Scan() { | ||
lines = append(lines, scanner.Text()) | ||
} | ||
|
||
return lines | ||
} | ||
|
||
func Benchmark_Create(b *testing.B) { | ||
domains := readDomain(b) | ||
|
||
wg, maxRequest := sync.WaitGroup{}, 100 | ||
count := atomic.Int64{} | ||
ch, stop := make(chan string, maxRequest), make(chan int) | ||
|
||
tr := &http.Transport{ | ||
MaxIdleConns: 200, | ||
MaxConnsPerHost: 200, | ||
IdleConnTimeout: 10 * time.Second, | ||
} | ||
|
||
client := &http.Client{ | ||
Transport: tr, | ||
} | ||
|
||
wg.Add(maxRequest) | ||
for range maxRequest { | ||
go func() { | ||
defer wg.Done() | ||
|
||
for { | ||
select { | ||
case <-stop: | ||
return | ||
case url := <-ch: | ||
func() { | ||
resp, err := client.Post(addr, "application/json", strings.NewReader(fmt.Sprintf(`{"long_url": "%s"}`, url))) | ||
if err != nil { | ||
b.Error(err) | ||
return | ||
} | ||
defer resp.Body.Close() | ||
|
||
body, err := io.ReadAll(resp.Body) | ||
if err != nil { | ||
log.Fatalln(err) | ||
} | ||
if resp.StatusCode != http.StatusOK { | ||
b.Errorf("Error: %d, resp body: %s", resp.StatusCode, body) | ||
return | ||
} | ||
|
||
count.Add(1) | ||
}() | ||
} | ||
} | ||
}() | ||
} | ||
|
||
b.ReportAllocs() | ||
b.ResetTimer() | ||
go func() { | ||
for range time.NewTicker(time.Second).C { | ||
b.Log("send requests:", count.Load()) | ||
} | ||
}() | ||
start := time.Now() | ||
for i := range 10 { | ||
s := sha256.Sum256([]byte(strconv.Itoa(i))) | ||
for j := range len(domains) { | ||
ch <- fmt.Sprintf("https://%s/test/api/image/1234567890/%x", domains[j], s) | ||
} | ||
} | ||
|
||
for len(ch) > 0 { | ||
time.Sleep(100 * time.Millisecond) | ||
} | ||
|
||
close(stop) | ||
wg.Wait() | ||
|
||
b.Log("success requests: ", count.Load(), "costs", time.Since(start).String()) | ||
} |
Oops, something went wrong.