19

秒杀/抢购 如何比别人更快?

 2 years ago
source link: https://www.oschina.net/question/230311_2323969
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

秒杀/抢购 如何比别人更快?

wonailmy 发布于 09/26 10:37
阅读 3K+

最近在做一个平台的商品的抢购程序,但是始终没有另外一个大牛的速度快。我的抢购程序是采用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

想在这里寻求下一些大家的思路,首先大家不知是否觉得我是思路上存在问题。如果有类似经验的大神也希望能分享下经验,在此鄙人感激不尽。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK