最近写一个类似SS服务端代理的服务,碰到几个坑,直接把自己坑死,都想引疚辞职。
在写之前,选择开源架构 libuv 作为IO架构,libuv功能强大毋庸置疑,但也很难驾驭,而且时常调用关闭句柄的时候没有回调,不确定是自己的问题还是什么,再加上回调资源时,资源的访问记数在业务代码复杂的时候容易错,结果要么资源释放异常,要么资源泄漏,时间问题,直接放弃 libuv,改换自己写select ,结果在这里挖了一个最大的坑,把自己坑死。select 模型由于自己测试的时候并发量少,所有业务正常,但项目上线后,随机出现终端连接成功,但数据请求超时,没转发代理到应用服务器。到处找问题,没找到(大坑还没发现)问题,初步确定是select 模型的问题,花了半天时间,换成 epoll 模型,问题解决了,但由于偷懒,在listen 线程还是用的select ,问题来了,大并发一来,用户连接失败,再重连接又能连接上,不用说这是listen 的消息队列满了,马上把listen的线程业务移出去,连接上来权限认证业务独立,想着认证业务并发量不大,在这里又偷懒用了 select 模型,结果大并发上来的时候,日志显示连接接收成功,句柄入了 select ,终端也有数据上来,但认证超时,服务端显示没收到数据,大坑终于在这里发现:当socket 句柄大于 1024 的时候,select 显示无效句柄,也就是大于 1024 的句柄,select 不识别,晕!!!! 以前看书,说的是select 最大并发量不能超过1024,当时理解的是select 总句柄数有不能超过1024,但实际是句柄大小不能超过 1024。