Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rate limit #2674

Closed
wants to merge 7 commits into from
Closed

Add rate limit #2674

wants to merge 7 commits into from

Conversation

HikaruChang
Copy link

Add rate limit feature, but I don't know how to get the value from level entry.

"levels": {
"0": {
...
"rate": 100
}
}

@kslr
Copy link
Contributor

kslr commented Aug 11, 2020

such as

type RouterRulesConfig struct {
RuleList []json.RawMessage `json:"rules"`
DomainStrategy string `json:"domainStrategy"`
}

  1. Is this location suitable?
  2. Use readable format, such as 1K 1M 1G etc

@HikaruChang
Copy link
Author

HikaruChang commented Aug 11, 2020

  • Is this location suitable?
  • Use readable format, such as 1K 1M 1G etc

The unit is KB/s, if you need, I can add the readable format feature.
I tried to read the configuration file, but failed.
You can see it here

https://github.com/hikaruchang/v2ray-core/blob/8fe194931972494186506ca1314fff9f78e19e55/app/dispatcher/default.go#L156-L162

Please add it under policy - level
For example:
"levels": { "0": { ... "rate": 100 } }

@kslr
Copy link
Contributor

kslr commented Aug 13, 2020

Please add formatting and move to https://github.com/v2fly/v2ray-core

@HikaruChang
Copy link
Author

Please add formatting and move to https://github.com/v2fly/v2ray-core

What is the difference between v2ray and v2fly?

@ArcCal
Copy link

ArcCal commented Aug 13, 2020

Please add formatting and move to https://github.com/v2fly/v2ray-core

What is the difference between v2ray and v2fly?

v2ray is dead. Long live v2fly.

@zhaoyadong00
Copy link

多用户 有内存泄露问题

@HikaruChang
Copy link
Author

多用户 有内存泄露问题

临时做了一个,没有做安全考虑,之后有时间会写个优化的。

@zhaoyadong00
Copy link

rate.go
package dispatcher

import (
"github.com/juju/ratelimit"
"io"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
)

type Writer struct {
writer buf.Writer
limiter *ratelimit.Bucket
w io.Writer
}

func RateWriter(writer buf.Writer, limiter *ratelimit.Bucket) buf.Writer {
return &Writer{
writer: writer,
limiter: limiter,
}
}

func (w *Writer) Close() error {
return common.Close(w.writer)
}

func (w *Writer) WriteMultiBuffer(mb buf.MultiBuffer) error {
w.limiter.Wait(int64(len(mb)))
return w.writer.WriteMultiBuffer(mb)
}

default.go

if p.Buffer.Rate != 0 {
bucket := ratelimit.NewBucket(time.Duration((int64(time.Second)/int64(p.Buffer.Rate))*2), 1024)
inboundLink.Writer = RateWriter(inboundLink.Writer, bucket)
outboundLink.Writer = RateWriter(outboundLink.Writer, bucket)
}

@zhaoyadong00
Copy link

我修改了一版 测试下来 没啥问题

@ifworldok
Copy link

@HikaruChang 感谢作者付出,能正常使用,发现限速后,每隔一分钟左右网速会突然窜高,几秒钟后恢复正常,一直循环此过程

@ifworldok
Copy link

@zhaoyadong00 试了下你的修改版,限速单位跟原作者的一样吗,我测试后大部分时间基本没速度,有时又突然窜高

@zhaoyadong00
Copy link

@zhaoyadong00 试了下你的修改版,限速单位跟原作者的一样吗,我测试后大部分时间基本没速度,有时又突然窜高

func (l *RateLimiter) RateWait(count int64) {
l.count += count
t := time.Duration(l.count)*time.Second/l.rate - time.Since(l.t)
if t > 0 {
time.Sleep(t)
}
}
作者的逻辑是 time.sleep

@zhaoyadong00
Copy link

@zhaoyadong00 试了下你的修改版,限速单位跟原作者的一样吗,我测试后大部分时间基本没速度,有时又突然窜高

单位不一样 等等 会在发一个稳定版本

@zhaoyadong00
Copy link

rate.go 新增
type Bucket struct {
User *protocol.MemoryUser
Bucket *ratelimit.Bucket
}
type BucketManage struct {
Users map[string]*Bucket
sync.RWMutex
}

func (b *BucketManage) GetUserBucket(u *protocol.MemoryUser, rate int64) ratelimit.Bucket {
if len(u.Email) > 0 && b.Users[u.Email] != nil {
return b.Users[u.Email].Bucket
} else {
bucket := ratelimit.NewBucket(time.Duration(int64(time.Second)/rate
8), 1024)
bu := &Bucket{
User: u,
Bucket: bucket,
}
b.Lock()
defer b.Unlock()
b.Users[u.Email] = bu
return bucket
}
}
func NewBucketMange() *BucketManage {
return newBucketMange
}

var newBucketMange *BucketManage

func init() {
newBucketMange = new(BucketManage)
newBucketMange.Users = make(map[string]*Bucket)
}

default.go 更新

bm := NewBucketMange()
bucket := bm.GetUserBucket(user, int64(p.Buffer.Rate))
inboundLink.Writer = RateWriter(inboundLink.Writer, bucket)
outboundLink.Writer = RateWriter(outboundLink.Writer, bucket)

@ifworldok
Copy link

@zhaoyadong00 水桶算法可以正常工做了,另外请教下动态添加 routing rules 有办法实现吗, 比如下面三条 blocked 的tag 实时的添加到路由规则并生效
[tag:"blocked" protocol:"bittorrent" tag:"blocked" user_email:"[email protected]" tag:"blocked" source_geoip:{cidr:{ip:":\xf1\xd6\x23" prefix:32}}]

@zhaoyadong00
Copy link

@zhaoyadong00 水桶算法可以正常工做了,另外请教下动态添加 routing rules 有办法实现吗, 比如下面三条 blocked 的tag 实时的添加到路由规则并生效
[tag:"blocked" protocol:"bittorrent" tag:"blocked" user_email:"[email protected]" tag:"blocked" source_geoip:{cidr:{ip:":\xf1\xd6\x23" prefix:32}}]

看了下 需要操作添加一下rpc接口 操作Router.rules 这个slice

@HikaruChang
Copy link
Author

rate.go 新增
type Bucket struct {
User *protocol.MemoryUser
Bucket *ratelimit.Bucket
}
type BucketManage struct {
Users map[string]*Bucket
sync.RWMutex
}

func (b *BucketManage) GetUserBucket(u *protocol.MemoryUser, rate int64) _ratelimit.Bucket { if len(u.Email) > 0 && b.Users[u.Email] != nil { return b.Users[u.Email].Bucket } else { bucket := ratelimit.NewBucket(time.Duration(int64(time.Second)/rate_8), 1024)
bu := &Bucket{
User: u,
Bucket: bucket,
}
b.Lock()
defer b.Unlock()
b.Users[u.Email] = bu
return bucket
}
}
func NewBucketMange() *BucketManage {
return newBucketMange
}

var newBucketMange *BucketManage

func init() {
newBucketMange = new(BucketManage)
newBucketMange.Users = make(map[string]*Bucket)
}

default.go 更新

bm := NewBucketMange()
bucket := bm.GetUserBucket(user, int64(p.Buffer.Rate))
inboundLink.Writer = RateWriter(inboundLink.Writer, bucket)
outboundLink.Writer = RateWriter(outboundLink.Writer, bucket)

学习了,感谢指正

@ghost
Copy link

ghost commented Nov 2, 2020

此pr的作者还在工作为此吗?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants