golang/net包与epoll

  • linux下go的网络包底层如tcp也是采用epoll来实现, 你可以从Accept方法一路追下去, 追到尽头你会看到internal/poll/fd_poll_runtime.go里面这些在runtime实现的方法:
  • 此时到src/runtime/netpoll.go就能看到上述这些方法的实现, 再往下追下去就可以看到各个平台的具体实现了, 如netpoll_epoll.go netpoll_kqueue.go netpoll_windows.go, 看到netpoll_epoll.go里面的epollcreate, epollctl, epollwait了吧, 多么熟悉的几个函数!
  • 虽然net包底层用epoll实现了, 但是实际我们在用tcp还是开goroutine来serve
  • net包就是推荐我们用goroutine来玩tcp, 应对大部分场景妥妥的
  • 面对比较变态的场景并发量贼高时, goroutine尽管只有消耗2k~8k的栈空间, 连接一多还是耗不起, 此时就只能用一些黑魔法来使用epoll了
  • 具体怎么玩可以参照 https://github.com/mailru/easygo
阅读更多

OTP动态口令及底层实现

  • 最近用到了OTP, 遂mark一下
  • 我们常用的那种倒计时验证码就是TOTP, 既不是叫OTP也不是叫MFA, 经常听有人这么说所以提一嘴
  • 动态口令验证可以看作是服务端和客户端之间通过约定相同的算法来实现验证功能, 也即你在客户端看到的动态口令是客户端通过算法生成的无需请求服务端获取
阅读更多

Redis源码阅读-事件模型ae

  • src/ae.c
  • src/ae.c下的void aeMain(aeEventLoop *eventLoop)函数; 推荐从这个函数开始阅读
  • 我们着重看下aeMain里面aeProcessEvents(eventLoop, AE_ALL_EVENTS)做了什么; 这里我们留意一下里面的aeApiPoll函数, 该函数用于获取可执行的事件, 获取之后在下面的for循环中处理事件, 执行事件处理器 fe->rfileProc(eventLoop,fd,fe->clientData,mask)
  • aeApiPoll函数是ae模块提供的一个接口, 在ae_epoll.c ae_kqueue.c ae_select.c ae_evport.c都做了相应的具体实现, 也是所谓IO多路复用各平台的具体实现, 目的为了兼容不同平台
  • 备注: 也许你会好奇为啥IO多路复用没有iocp的实现难道windows就没人权吗, 其实redis的官方版本是不支持windows的, windows版本在https://github.com/microsoftarchive/redis由微软团队自己维护, 里面就有ae_wsiocp.ciocp版的实现
  • 通常说的redis的reactor模型(反应堆)其实说的就是aeMain的大循环中aeProcessEvents做的那些事情: 监听网络连接的FD的文件事件---> 获取事件---> 执行事件回调
  • 剩下具体细节不多赘述, 顺着思路看源码即可
阅读更多