访问外网的时候为了避免被风控,所以长久以来,我是用了一台廉价的vps作为固定出口ip的,有多廉价呢,每月1T流量,192M内存,单核,OpenVZ,每年15刀。因为是几年前买的,现在甚至都停售了。但是日前使用上出了问题,表现为网速过快的时候会断网几分钟,遇到后还觉得挺神奇,后来登陆上去用wget下载文件测试了下,稳定复现,下载热门资源,速度很容易跑到50M/s+,最后询问客服得知,对外部进入的流量做了限制,说是防止DDOS攻击…. 但是说真的,明眼人都能看得出来,是觉得价格太低,所以服务降级,不允许大流量下载
因为贫穷,加上它这个网络质量+ip质量还可以,我就琢磨着自我限速得了,一开始打算用tc之类的,后来发现openvz对这方面有很大限制,后来,就直接改一下代理源码得了
得益于ss的源码质量挺高,也挺好改,直接在对外部进行read的时候限速就好,在令牌桶和漏桶之间选择了漏桶,因为令牌桶允许瞬时流量超过阈值,漏桶没有这个情况,添加代码如下
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 
 | import (
 "go.uber.org/ratelimit"
 )
 
 type GlobalLimit struct {
 limiter   ratelimit.Limiter
 readBytes int
 lock      sync.Mutex
 }
 
 var globalLimit = GlobalLimit{
 limiter: ratelimit.New(1024 * 25),
 }
 
 type RateLimitedConn struct {
 net.Conn
 }
 
 func (rlc *RateLimitedConn) Read(p []byte) (int, error) {
 
 n, err := rlc.Conn.Read(p)
 globalLimit.lock.Lock()
 defer globalLimit.lock.Unlock()
 globalLimit.readBytes += n
 
 loop := int(float64(globalLimit.readBytes) / 1024)
 for i := 0; i < loop; i++ {
 globalLimit.limiter.Take()
 globalLimit.readBytes -= 1024
 }
 return n, err
 }
 
 func NewRateLimitedConn(conn net.Conn) *RateLimitedConn {
 return &RateLimitedConn{
 Conn: conn,
 }
 }
 
 | 
以上限制下载速度为25M/s
最后,在tcpRemote函数内部defer rc.Close()下面添加rc = NewRateLimitedConn(rc)就OK了
                    
                        
                    
                    
                        
                            
                                评论和共享