系统设计 | golang如何实现服务端高并发设计

关键

1.高并发处理,网络连接过多server如何处理
2.设计模式,可以扩展,接受不同的规则
3.不同客户端消息的处理,如何识别room和user的消息顺序
4.代码风格,测试case

结果

1.耗时10小时完成,覆盖点1,2,未完成3,4

复盘

1.刚开始思路错了,没聚焦重点,没集中在问题1,反而关注问题2
2.一直没有跑起来的demo,先把很多代码堆积上,然后才调试的,浪费很多时间
3.对golang的并发编程不熟悉

思路

主要参考了:
handling-1-million-requests-per-minute-with-golang

  • 场景是服务器,traffic P个请求/s,每个请求需要耗时100s来完成(上传文件等任务)
    1.其实很简单,最原始的解法就是每来一个请求,新建立一个goroutine来处理;因为消费能力弱,建立P个goroutine肯定不行,需要建立100 * P个goroutine;可能会撑爆内存;
  1. 如何避免撑爆内存?
  • 怕撑爆内存,那怎么办呢?那就少一点的goroutine来处理呗,限制goroutine的数量,池化的思想。
  • 那goroutine少了,会不会处理不过来呢?不会的,建立那么多的gouroutine,大部分可能在排队等待,用到的线程实际少于goroutine数量,就是GSP里面P的数量(认为指定和cpu核数接近比较合理);所以看到没有,多建立的goroutine只是带着job的信息在排队,就是白白浪费了那么多的goroutine内存;
  • 那既然进来的job信息不被goroutine携带,又放在哪里呢?放在内存某个地方,抽象化成job队列,固定数量goroutine轮流去取job
  1. 如何池化,如何dispatch呢?
  • 抽象出一个worker,其实里面就是起一个goroutine,不断循环取job队列;最原始的就是这样就相当于池化了
  • 多个goroutine取job,如何同步呢?blockingqueue,但这样会涉及到很多worker同时竞争,类似鲸群效应,效率低;另外任务不多时,有的worker可能会一致饥饿,任务分配不公平;
  • 不是每个worker主动抢任务,worker怎么被动分配任务呢?把空闲worker队列化,第三方取worker,取job,然后把job分配给worker;这样会解决上面的两个问题:鲸群和公平;
  • worker如何能在空闲时进入队列呢?worker自己能知道任务完成时刻,然后自己塞入一个空闲channel;

你可能感兴趣的:(内功修炼)