Skip to content

huiming23344/balanceAPI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BalanceAPI

wakatime

  • 使用gin框架进行API的开发
    • gin框架每一个请求都会开启一个goroutine进行处理,所以不需要额外的goroutine管理就可以保证较高性能
  • 数据部分使用sync.Map进行索引
    • map的value为读写锁保护的结构体,降低锁的粒度,保证并发读写的安全
  • payFund的每个账户都会开启一个goroutine进行处理
    • 对于每个开起的goroutine
      • 使用channel控制全局worker的数量
      • 根据账户的金额不同动态的调整goroutine的数量
      • 对于小于一万的部分,开启2个goroutine进行处理

性能分析

通过Flame Graph进行性能分析,可以看到占用cpu时间较大的主要是两部分,sync.Waitgroup同步等待的时间和runtime.kevent主要是网络epoll的等待时间 后续的性能优化可以考虑异步的方式进行处理,减少sync.Waitgroup的同步等待

Benchmarks

onePass/batchPay

单个大数据测试

单个一亿的账户处理时间5s左右,payFunds use time: 4.374602958s

单个十亿的账户处理时间50s左右,payFunds use time: 50.013073s

// 测试数据
iF := []Fund{
    {
        Uid:    100001,
        Amount: 100000000.53,
    },
}

多账户测试

使用test-file/ininFund100.json初始化funds, 100个账户数据获取支付的时间为 use time: 1.2026825s

// 计时方法
var timeStart time.Time
func BatchPay(c *gin.Context) {
    timeStart = time.Now()
    ...
    go BatchPay()
    return
}
 
func BatchPay() {
    ...
    batchPayFinish()
    fmt.Printf("use time: %v\n", time.Since(timeStart))
    return
}

在超过500个用户数据时,服务端会返回成功的报文,但是不会注册账户,所以没有进行更多的测试。

onePass/transfers

使用外部API进行转账数据源为:test-file/ininFund100.json, 100个账户数据转账到同一个账户 Transfer time: 24.312625ms, 测试结果正确,除了id为100001的账户其他全部账户余额均为0,10001账户金额多次相同,且数额正确

// 计时方法
func transferFundsToOneAccount(funds []Fund) {
	timeStart := time.Now()
	// transfer the funds to one account
	for _, f := range funds {
		if f.Uid == 100001 {
			continue
		}
		err := transferApi(f.Uid, 100001, f.Amount)
		if err != nil {
			log.Fatalf("Error transfering fund: %s", err)
		}
	}
	fmt.Println("Transfer time: ", time.Since(timeStart))
}

About

balance account sys api with better performance

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors