Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
wang
/
go_supplier_task
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
b204f919
authored
Feb 07, 2021
by
wang
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
修改锁相关代码
parent
339584ee
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
190 additions
and
49 deletions
conf/dev/redis.ini
doc/openTest/test.go
doc/redis_config_generate.go
open/business.go
open/dao.go
open/flowmeter.go
open/validate.go
conf/dev/redis.ini
View file @
b204f919
...
@@ -2,14 +2,14 @@
...
@@ -2,14 +2,14 @@
[default_redis_read]
[default_redis_read]
host
=
192.168.1.235:6379
host
=
192.168.1.235:6379
password
=
icDb29mLy2s
password
=
icDb29mLy2s
max_idle
=
100
0
max_idle
=
5
0
max_active
=
5000
max_active
=
5000
idle_timeout
=
20
idle_timeout
=
20
[default_redis_write]
[default_redis_write]
host
=
192.168.1.235:6379
host
=
192.168.1.235:6379
password
=
icDb29mLy2s
password
=
icDb29mLy2s
max_idle
=
100
0
max_idle
=
5
0
max_active
=
5000
max_active
=
5000
idle_timeout
=
20
idle_timeout
=
20
...
...
doc/openTest/test.go
0 → 100644
View file @
b204f919
package
main
import
(
"fmt"
"github.com/guonaihong/gout"
"github.com/ichunt2019/log"
"sync"
"time"
)
type
Glimit
struct
{
n
int
c
chan
struct
{}
}
// initialization Glimit struct
func
New
(
n
int
)
*
Glimit
{
return
&
Glimit
{
n
:
n
,
c
:
make
(
chan
struct
{},
n
),
}
}
// Run f in a new goroutine but with limit.
func
(
g
*
Glimit
)
Run
(
f
func
(
n
int
),
n
int
)
{
g
.
c
<-
struct
{}{}
//fmt.Println(n)
go
func
(
n
int
)
{
f
(
n
)
<-
g
.
c
}(
n
)
}
var
wg2
=
sync
.
WaitGroup
{}
var
log
=
NewLog
()
/**
测试结果1 1000个请求,并发50 完成时间 36.1955874s
*/
func
main
()
{
//main2()
//return
start
:=
time
.
Now
()
number
:=
2001
g
:=
New
(
200
)
for
i
:=
0
;
i
<
number
;
i
++
{
wg2
.
Add
(
1
)
s
:=
1000
+
i
//log.Info("d")
goFunc
:=
func
(
n
int
)
{
log
.
Info
(
"d"
)
// 做一些业务逻辑处理
value
:=
fmt
.
Sprintf
(
"%d"
,
n
)
SkuHandle
(
value
)
wg2
.
Done
()
}
g
.
Run
(
goFunc
,
s
)
}
wg2
.
Wait
()
//log.SyncWait()
end
:=
time
.
Now
()
fmt
.
Println
(
end
.
Sub
(
start
))
}
func
main2
()
{
var
log
=
NewLog
()
for
i
:=
0
;
i
<
500
;
i
++
{
fmt
.
Println
(
i
)
log
.
Info
(
"d"
)
fmt
.
Println
(
i
,
"end"
)
}
log
.
SyncWait
()
}
func
testHandle
(
value
string
)
{
println
(
value
)
}
func
SkuHandle
(
value
string
)
{
//url:="192.168.1.237:8005/saveSpu"
//gout.POST(config.Get("sku_server.api_domain").String()+"/synchronization")/*.Debug(true)*/.SetForm(gout.H{"goods_id": ids}).BindBody(&resStr).Do()
resStr
:=
""
url
:=
"http://localhost:60006/GetSkuListPrice"
err
:=
gout
.
GET
(
url
)
.
SetForm
(
gout
.
H
{
"token"
:
"AbopJDAbopdu800820mcspcq=="
,
"goods_id"
:
"1160558405670174605,1160558403263797403,10048"
})
.
BindBody
(
&
resStr
)
.
Do
()
if
(
err
!=
nil
){
panic
(
"调用sku server saveSpu接口报错"
+
err
.
Error
())
}
fmt
.
Println
(
resStr
)
}
func
NewLog
()
logger
.
LogInterface
{
logConfig
:=
make
(
map
[
string
]
string
)
logConfig
[
"log_path"
]
=
"logs/testSpu"
logConfig
[
"log_chan_size"
]
=
"100"
logConfig
[
"open_sync"
]
=
"1"
log
,
err
:=
logger
.
InitLogger
(
"file"
,
logConfig
)
if
err
!=
nil
{
panic
(
err
.
Error
())
}
log
.
Init
()
return
log
}
\ No newline at end of file
doc/redis_config_generate.go
View file @
b204f919
...
@@ -61,6 +61,8 @@ func whiteIp() {
...
@@ -61,6 +61,8 @@ func whiteIp() {
"192.168.2.72"
,
"192.168.2.72"
,
"::1"
,
"::1"
,
"192.168.2.241"
,
"192.168.2.241"
,
"192.168.1.1"
,
"192.168.2.129"
,
}
}
fmt
.
Println
(
"白名单配置:"
+
redisKey
)
fmt
.
Println
(
"白名单配置:"
+
redisKey
)
...
@@ -93,13 +95,13 @@ func businessInterfaceList() {
...
@@ -93,13 +95,13 @@ func businessInterfaceList() {
"totalMaxNum"
:
10000
,
"totalMaxNum"
:
10000
,
},
},
jdToken
+
"_"
+
GetSkuListFull
:
map
[
string
]
interface
{}{
jdToken
+
"_"
+
GetSkuListFull
:
map
[
string
]
interface
{}{
"dayMaxNum"
:
1
1
,
"dayMaxNum"
:
1
,
"minMaxNum"
:
5
,
"minMaxNum"
:
1
,
"totalMaxNum"
:
10000
,
"totalMaxNum"
:
10000
,
},
},
jdToken
+
"_"
+
GetSkuListPrice
:
map
[
string
]
interface
{}{
jdToken
+
"_"
+
GetSkuListPrice
:
map
[
string
]
interface
{}{
"dayMaxNum"
:
11
,
"dayMaxNum"
:
6100
,
"minMaxNum"
:
5
,
"minMaxNum"
:
2000
,
"totalMaxNum"
:
10000
,
"totalMaxNum"
:
10000
,
},
},
/*baiduToken+"_"+getSkuListByClass: map[string]interface{}{
/*baiduToken+"_"+getSkuListByClass: map[string]interface{}{
...
...
open/business.go
View file @
b204f919
...
@@ -50,9 +50,4 @@ func (this *business) GetInterfaceConfig(interfaceName string) (configOne *inter
...
@@ -50,9 +50,4 @@ func (this *business) GetInterfaceConfig(interfaceName string) (configOne *inter
}
}
func
UsedMinNum
()
{
}
func
UsedDayNum
()
{
}
open/dao.go
View file @
b204f919
...
@@ -84,5 +84,5 @@ func (this *Dao)incrRedisFlowNum(key string) (num int,err error){
...
@@ -84,5 +84,5 @@ func (this *Dao)incrRedisFlowNum(key string) (num int,err error){
common
.
PrintStdout
()
.
Printf
(
"INCR redis "
+
key
+
"错误"
)
common
.
PrintStdout
()
.
Printf
(
"INCR redis "
+
key
+
"错误"
)
return
0
,
e
.
NewApiError
(
"service err"
,
FLOWERR1
)
return
0
,
e
.
NewApiError
(
"service err"
,
FLOWERR1
)
}
}
return
num
,
err
return
num
,
nil
}
}
open/flowmeter.go
View file @
b204f919
...
@@ -2,7 +2,9 @@ package open
...
@@ -2,7 +2,9 @@ package open
import
(
import
(
"golang_open_platform/pkg/common"
"golang_open_platform/pkg/common"
"golang_open_platform/pkg/e"
"golang_open_platform/pkg/gredis"
"golang_open_platform/pkg/gredis"
"sync"
"time"
"time"
)
)
...
@@ -10,7 +12,7 @@ const (
...
@@ -10,7 +12,7 @@ const (
INCRTYPEMIN
=
iota
//分
INCRTYPEMIN
=
iota
//分
INCRTYPEDAY
//天
INCRTYPEDAY
//天
)
)
var
lock
sync
.
Mutex
type
flowmeter
struct
{
type
flowmeter
struct
{
dao
*
Dao
dao
*
Dao
flowLimitType
int
//INCRTYPEMIN 分限制 INCRTYPEDAY 天限制
flowLimitType
int
//INCRTYPEMIN 分限制 INCRTYPEDAY 天限制
...
@@ -22,7 +24,7 @@ func NewFlow(token string,interfaceName string) *flowmeter{
...
@@ -22,7 +24,7 @@ func NewFlow(token string,interfaceName string) *flowmeter{
return
&
flowmeter
{
dao
:&
Dao
{},
token
:
token
,
interfaceName
:
interfaceName
}
return
&
flowmeter
{
dao
:&
Dao
{},
token
:
token
,
interfaceName
:
interfaceName
}
}
}
//获取redis key 和过期时间
//获取
对应的计数
redis key 和过期时间
func
(
this
*
flowmeter
)
getFlowKeyAndEx
()
(
key
string
,
expireTime
int64
){
func
(
this
*
flowmeter
)
getFlowKeyAndEx
()
(
key
string
,
expireTime
int64
){
key
=
"flowUse_"
+
this
.
token
+
"_"
+
this
.
interfaceName
key
=
"flowUse_"
+
this
.
token
+
"_"
+
this
.
interfaceName
switch
this
.
flowLimitType
{
switch
this
.
flowLimitType
{
...
@@ -43,41 +45,100 @@ func (this *flowmeter) getFlowKeyAndEx() (key string,expireTime int64){
...
@@ -43,41 +45,100 @@ func (this *flowmeter) getFlowKeyAndEx() (key string,expireTime int64){
}
}
//设置流量限制类型 INCRTYPEMIN 分限制 INCRTYPEDAY 天限制
//设置流量限制类型 INCRTYPEMIN 分限制 INCRTYPEDAY 天限制
func
(
this
*
flowmeter
)
S
etFlowKey
(
flowLimitType
int
)
{
func
(
this
*
flowmeter
)
s
etFlowKey
(
flowLimitType
int
)
{
this
.
flowLimitType
=
flowLimitType
this
.
flowLimitType
=
flowLimitType
}
}
//获取 已使用的流量数
func
(
this
*
flowmeter
)
GetNum
()(
int
,
error
){
func
(
this
*
flowmeter
)
getNum
()(
int
,
error
){
key
,
expireTime
:=
this
.
getFlowKeyAndEx
()
key
,
expireTime
:=
this
.
getFlowKeyAndEx
()
this
.
addOnlyLock
(
key
)
//加锁
//获取计数 (读 redis key)
//获取计数 (读 redis key)
num
,
err
:=
this
.
dao
.
getRedisFlowNum
(
key
)
num
,
err
:=
this
.
dao
.
getRedisFlowNum
(
key
)
//common.PrintStdout().Printf("读取 计数key:%s,num 为: %d",key,num)
//common.PrintStdout().Printf("读取 计数key:%s,num 为: %d",key,num)
if
(
err
!=
nil
){
if
(
err
!=
nil
){
this
.
delOnlyLock
(
key
)
//解锁
return
0
,
err
return
0
,
err
}
}
if
(
num
==
0
){
//计数不存在(redis没有此key),就新建一个带有超时的key
if
(
num
==
0
){
//计数不存在(redis没有此key),就新建一个带有超时的key
err
:=
this
.
dao
.
setRedisFlowEx
(
key
,
expireTime
)
err
:=
this
.
dao
.
setRedisFlowEx
(
key
,
expireTime
)
//common.PrintStdout().Printf("计数key:%s,不存在,创建超时%d 的key",key,expireTime)
if
(
err
!=
nil
){
if
(
err
!=
nil
){
this
.
delOnlyLock
(
key
)
//解锁
return
0
,
err
return
0
,
err
}
}
}
}
this
.
delOnlyLock
(
key
)
return
num
,
nil
return
num
,
nil
}
}
/**
比较
*/
func
(
this
*
flowmeter
)
compare
(
maxNum
int64
)
(
error
,
bool
){
num
,
err
:=
this
.
getNum
()
if
(
err
!=
nil
){
return
err
,
false
}
if
(
int64
(
num
)
>=
maxNum
){
common
.
PrintStdout
()
.
Printf
(
"最大流量为: %d < %d"
,
int
(
maxNum
),
num
)
return
nil
,
false
}
return
nil
,
true
}
/**
验证
*/
func
(
this
*
flowmeter
)
checkout
(
business
*
business
)
error
{
interfaceConfig
,
err
:=
business
.
GetInterfaceConfig
(
this
.
interfaceName
)
//商家接口配置,包含一小时最大流量,一天最大流量
key
,
_
:=
this
.
getFlowKeyAndEx
()
defer
this
.
delOnlyLock
(
key
)
this
.
addOnlyLock
(
key
)
//加锁
//lock.Lock()
//defer lock.Unlock()
//验证天流量限制
this
.
setFlowKey
(
INCRTYPEDAY
)
err
,
isPass
:=
this
.
compare
(
interfaceConfig
.
dayMaxNum
)
if
(
err
!=
nil
){
return
err
}
if
(
err
!=
nil
){
return
err
}
if
(
isPass
==
false
){
return
e
.
NewApiError
(
"触发天级流控"
,
FLOWERR4
)
}
//分钟流量验证
this
.
setFlowKey
(
INCRTYPEMIN
)
err
,
isPass
=
this
.
compare
(
interfaceConfig
.
minMaxNum
)
if
(
err
!=
nil
){
return
err
}
if
(
isPass
==
false
){
return
e
.
NewApiError
(
"触发分钟级流控"
,
FLOWERR4
)
}
//增加分钟计数
err
=
this
.
incr
()
if
(
err
!=
nil
){
return
nil
}
//增加天计数
this
.
setFlowKey
(
INCRTYPEDAY
)
err
=
this
.
incr
()
if
(
err
!=
nil
){
return
err
}
return
nil
}
//自增
//自增
func
(
this
*
flowmeter
)
incr
()
(
err
error
)
{
func
(
this
*
flowmeter
)
incr
()
(
err
error
)
{
key
,
_
:=
this
.
getFlowKeyAndEx
()
key
,
_
:=
this
.
getFlowKeyAndEx
()
_
,
err
=
this
.
dao
.
incrRedisFlowNum
(
key
)
_
,
err
=
this
.
dao
.
incrRedisFlowNum
(
key
)
if
(
err
!=
nil
){
if
(
err
!=
nil
){
return
err
return
err
}
}
//common.PrintStdout().Printf("加1后的值是 %d",num)
//common.PrintStdout().Printf("加1后的值是 %d",num)
return
nil
return
nil
...
@@ -92,7 +153,7 @@ func (this *flowmeter)addOnlyLock(key string){
...
@@ -92,7 +153,7 @@ func (this *flowmeter)addOnlyLock(key string){
//common.PrintStdout().Printf("加锁 key:%s",name)
//common.PrintStdout().Printf("加锁 key:%s",name)
for
{
for
{
s
,
err
:=
redisWriteConn
.
Do
(
"SET"
,
name
,
"1"
,
"EX"
,
"
2
"
,
"NX"
)
//锁两秒没主动删就自动关闭(防止某个流程卡死,没执行到删除锁)
s
,
err
:=
redisWriteConn
.
Do
(
"SET"
,
name
,
"1"
,
"EX"
,
"
10000000
"
,
"NX"
)
//锁两秒没主动删就自动关闭(防止某个流程卡死,没执行到删除锁)
if
(
err
!=
nil
){
if
(
err
!=
nil
){
common
.
PrintStdout
()
.
Printf
(
"读取redis 锁 key:%d 报错"
,
key
)
common
.
PrintStdout
()
.
Printf
(
"读取redis 锁 key:%d 报错"
,
key
)
}
}
...
...
open/validate.go
View file @
b204f919
...
@@ -74,34 +74,10 @@ func (this *openValidate) permissionValidate(interfaceName string) error{
...
@@ -74,34 +74,10 @@ func (this *openValidate) permissionValidate(interfaceName string) error{
//请求次数限制
//请求次数限制
func
(
this
*
openValidate
)
requestsNumValidate
(
token
string
,
interfaceName
string
)
error
{
func
(
this
*
openValidate
)
requestsNumValidate
(
token
string
,
interfaceName
string
)
error
{
interfaceConfig
,
err
:=
this
.
business
.
GetInterfaceConfig
(
interfaceName
)
//商家接口配置,包含一小时最大流量,一天最大流量
err
:=
NewFlow
(
token
,
interfaceName
)
.
checkout
(
this
.
business
)
flow
:=
NewFlow
(
token
,
interfaceName
)
//流控对象
//一天最大流量验证
flow
.
SetFlowKey
(
INCRTYPEDAY
)
num
,
err
:=
flow
.
GetNum
()
if
(
err
!=
nil
){
if
(
err
!=
nil
){
return
err
return
err
}
}
if
(
num
>=
int
(
interfaceConfig
.
dayMaxNum
)){
common
.
PrintStdout
()
.
Printf
(
"一天最大流量为: %d > %d"
,
int
(
interfaceConfig
.
dayMaxNum
),
num
)
return
e
.
NewApiError
(
"触发天级流控"
,
FLOWERR4
)
}
//一分钟最大流量验证
flow
.
SetFlowKey
(
INCRTYPEMIN
)
num
,
err
=
flow
.
GetNum
()
//获取分钟使用流量
if
(
err
!=
nil
){
return
err
}
if
(
num
>=
int
(
interfaceConfig
.
minMaxNum
)){
common
.
PrintStdout
()
.
Printf
(
"一分钟最大流量为: %d >%d"
,
int
(
interfaceConfig
.
minMaxNum
),
num
)
return
e
.
NewApiError
(
"触发分钟级流控"
,
FLOWERR3
)
}
else
{
flow
.
incr
()
//验证成功,自增1
flow
.
SetFlowKey
(
INCRTYPEDAY
)
flow
.
incr
()
//同时天也自增1
}
return
nil
return
nil
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment