最近在做一个平台的商品的抢购程序,但是始终没有另外一个大牛的速度快。我的抢购程序是采用java编写,技术栈经历了3个阶段,第一个阶段采用hutool作为http客户端,第二个阶段采用netty手动实现http协议,第三个阶段使用httpclient5作为客户端。这里简单介绍下我三个阶段的思路,希望有懂行的大牛能一起探讨下。个人也一直从事网络编程工作,也希望能结交点志同道合的兄弟一起学习进步。
第一阶段
想法很简单,就是采用hutool作为http客户端发起http预约请求进行抢购,简单粗暴。但是效率非常低,究其原因无非两点:第一,hutool本身就是作为一个工具库,主要是为了简化开发,让开发者用着很爽,在性能上不一定是很优秀的。第二,并未运用连接池、连接复用这种技术,每次请求都需要建立连接,这个网络成本太高。
第二阶段
有了第一次的经验,第二阶段考虑使用连接复用这种方案,第一次建立连接后,后续的请求都在这一个连接有效期内完成。由于自身有过TCP+IOT的项目经验,自然选择了netty作为httpclient工具。实现逻辑自然很简单,比如在8点进行预约抢购,那netty则在7点59分50秒建立好tcp连接通道(提前多久建立连接主要看平台的http超时时间,本次由于对方服务器的超时时间是30s所以我就提前10s建立连接,留20s给我做业务数据的传输)。在8点0分0秒准时传输预约事情的http请求。
这种方式跟第一种方式差别非常明显,由于减少了tcp连接建立的消耗,预约申请请求能更快的到达对方服务器。大概每次能比之前快60ms-100ms。但最终结果是还是没干过另外一个开发者。所以在这个基础上,每次请求我会进行适当提前,一般提前30ms-70ms。
第三阶段
虽然第二阶段已经进步很明显了,而且netty由于较底层,在一些细节控制上非常方便。比如缓冲池的一些buffer大小控制等。但是仍然未抢到,所以过程或许很牛逼,结果是失败的,那一切都是垃圾。所以我又对程序不停优化,但是这个过程较痛苦。netty的一些麻烦事情出现了,虽然个人已经比较熟悉netty了,但是仍然只能算熟悉运用netty而且,每次程序的改动都会带来对netty封装的打动,导致每次迭代周期较长且每次改动需要非常细心的测试才能确保程序稳定。
第三阶段所以又放弃netty了,继而采用httpcliet5+连接池这个技术。其实本质上没有差别,都是想达到连接复用的目的。只是httpcliet不必要我再去考虑很多细节,而且这个框架可定制性也较高。最终在用了这个框架后,效率上与前者并无多大差别。但是还是抢不过别人,不过后期打算基于这个版本进行升级迭代。
HTLP
想在这里寻求下一些大家的思路,首先大家不知是否觉得我是思路上存在问题。如果有类似经验的大神也希望能分享下经验,在此鄙人感激不尽。
排除风控,还要考虑云厂商、区域、运营商、机房、网段等相关因素,择最优选路径或最佳网络节点发起请求;技术上的优化,已经差距不会太大,还是得靠物理路径上的优化最直接;个人的一点见解;
其实还是钞能力的问题,你的网速不够快,运营商要选电信的,什么移动联通都不行,延迟要低,宽带不行得上光纤,网速太慢上下行都要至少300M以上,连接的节点要近,你如果在广东连什么北京的服务器?
可以参考jmeter这款压测工具的实现。
服务器节点是一个问题, 还有一个点. 网站到底有没有想让你抢到. 像是JD一些抢购你是不可能抢到的. 因为根本就没货, 仅存的那点货都被内部消化了.
如同压测一般,基本都是在内网完成,即网络是最大的耗时。外网,能做的,太局限了。
DDOS,准备好成千上万的肉鸡,各自JMeter