day1学习 | 青训营笔记

84 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天

限流的实现:

1.计数器

1.可以在程序中设置一个变量 count,当过来一个请求我就将这个数 +1,同时记录请求时间。
2.当下一个请求来的时候判断 count 的计数值是否超过设定的频次,以及当前请求的时间和第一次请求时间是否在 1 分钟内。
3.如果在 1 分钟内并且超过设定的频次则证明请求过多,后面的请求就拒绝掉。
4.如果该请求与第一个请求的间隔时间大于计数周期,且 count 值还在限流范围内,就重置 count。
​

弊端

如果在最后一秒内发送200次请求,在下一秒后又被刷新。

img

2.滑动窗口

为了解决临界问题,滑动窗口把固定时间片进行划分,并且随着时间的流逝,进行移动,固定数量的可以移动的格子,进行计数并判断阀值。

但是,格子的数量影响着滑动窗口算法的精度,依然有时间片的概念,无法根本解决临界点问题。

3.漏桶

原理就是一个固定容量的漏桶,按照固定速率流出水滴。(有点像消息队列)

4.令牌桶

我们有一个固定的桶,桶里存放着令牌(token)。一开始桶是空的,系统按固定的时间(rate)往桶里添加令牌,直到桶里的令牌数满,多余的请求会被丢弃。当请求来的时候,从桶里移除一个令牌,如果桶是空的则拒绝请求或者阻塞。

lua代码

local key = "rate.limit:" .. KEYS[1]
local limit = tonumber(ARGV[1])       
local current = tonumber(redis.call('get', key) or "0")
if current + 1 > limit then 
  return 0
else  
  redis.call("INCRBY", key,"1")
   redis.call("expire", key,"1")
   return current + 1
end
public static boolean accquire() throws IOException, URISyntaxException {
    Jedis jedis = new Jedis("127.0.0.1");
    File luaFile = new File(RedisLimitRateWithLUA.class.getResource("/").toURI().getPath() + "limit.lua");
    String luaScript = FileUtils.readFileToString(luaFile);
    String key = "ip:" + System.currentTimeMillis()/1000
    String limit = "5"
    List<String> keys = new ArrayList<String>();
    keys.add(key);
    List<String> args = new ArrayList<String>();
    args.add(limit);
    Long result = (Long)(jedis.eval(luaScript, keys, args))
    return result == 1;
}
​

go语言学习

map类型

 m:=make(map[string]int)
 m["one"] =1
 fmt.Println(r,ok);
 delete(m,"one")

rang 遍历

nums := []int{2,3,4}
for i num := rang nums{
    fmt.Println(k,v)
}

函数

func add(int a,int b) int{
    return a+b
}
go中函数返回多个值
func exists(m map[string]string ,k string) (v string,ok bool){
    v,ok = m[k]
    return v,ok
}
指针
func add(n * int){
    *n+=2
}
自增2

结构体

type user struct{
    name string
    password string
}
func main(){
    a:=user {name:"wang",password:"1024"}
}
使用指针减少开销
成员方法
func (u user) checkPassword(password string)bool{
    return u.password == password
}

错误处理

find Finduser(users []user)(v *user,err error){
    return nil,errors.New("not")
}

Json处理

只需要保证 结构体中每个成员变量名以大写开头

使用 json.Marshal()即可

打印时需要string(json.Marshal(xxx))

时间处理

time.Now()