问题是,我想要开发一个应用程序(可能是 PHP?),能够快速连接到 SSL 安全服务器并从中发送/获取数据。我的目标是让它尽快发送查询并读取结果。我正在尝试各种解决方案并对它们进行基准测试。但是,我尝试过 fsockopen() 和 CURL,想知道是否有任何解决方案可以改进它们?
结果如下:
fsockopen():
- 发送的标头:0.26755499839783;
- 收到的页面:0.48934602737427;
CURL 结果:
- [total_time] => 0.484
- [预传输时间] => 0.281
- [开始传输时间] => 0.437
问题是:
1)当查询开始在我连接的服务器上执行时 - 在发送标头之后或在我获取页面并且连接关闭之后?
2) 我应该将 fsockopen() 结果与 CURL 的确切时间哪个进行比较? starttransfer_time 是否在标头发送到服务器之前?这意味着 fsockopen() 更快,不是吗?
3)有什么解决方案可以调整执行代码的服务器上的 SSL 连接吗?是否可以对 PHP 的 OpenSSL 模块进行任何调整(任何可能的加密降级?)以使其更快?
4) 有什么解决方案可以在没有 SSL 的情况下使用 SSL 安全服务器吗?
5)在这种情况下,C++ 或其他解决方案会更快吗?
欢迎任何想法:)我对这场“女士”比赛着迷:)
谢谢,
乔纳斯
The problem is, what I want to develop an application (probably PHP?), capable of making quick connection to a SSL secured server and send/get data from it. My aim is to make it send the query and read the result as quick as possible. I am trying various solutions and benchmarking them all. I have tried fsockopen() and CURL, however, wondering if there are any solutions how I could improve them?
Results are as follows:
fsockopen():
- Headers sent: 0.26755499839783;
- Page received: 0.48934602737427;
CURL results:
- [total_time] => 0.484
- [pretransfer_time] => 0.281
- [starttransfer_time] => 0.437
Questions are:
1) When the query is started to execute on the server, to which I connect - after headers are sent or after I get the page and connections closes?
2) Which is the exect time of CURL to which I should compare the fsockopen() result? Is starttransfer_time even before the headers are sent to server? This would mean that fsockopen() is faster, isn't it?
3) Any solutions how to tweak SSL connectivity on the server, on which the code is executed? Any tweaks possible to OpenSSL module of PHP (any possible downgrades of crypto?) to make it faster?
4) Any solution to go without SSL to SSL secured server?
5) Would C++ or other solution be any quicker in this case?
Any ideas are welcome :) I got obsessed by this "ms" race :)
Thanks,
Jonas
发布评论
评论(3)
您的问题没有封闭形式的解决方案。
关于C++,确实PHP是解释型的,C++是编译+优化的,但是PHP中的所有加密库都是纯C语言的,所以是编译+优化的。
根据服务器硬件,制作较短的服务器密钥会稍微加快握手阶段的速度。此外,最重要的是,所有依赖 TCP 的网络协议在处理事务时都会受到网络延迟的影响,这与数据传输(如 FTP)的行为不同,因为它们是同步的。
无论如何...
1.你必须手动关闭连接
4.除非你想自己编写完整的 SSL 协议,否则最好使用可用的性能最高的库,openSSL
5.是或否,至少你可能会获得性能提升但也许并不重要。总的来说,我会推荐它
There is no close-form solution to your question.
About C++, it's true that PHP is interpreted and C++ is compiled+optimized, but all crypto libraries in PHP are in plain C, so compiled+optimized.
Making a shorter server key fastens the handshake phase a little, according to the server hardware. Also, most important, all network protocols that rely on TCP are affected by network delays when processing transactions, which are different in behaviour from data transfers (like FTP) because of the fact that they are synchronized.
Anyway...
1.You have to close the connection manually
4.Unless you want to write the full SSL protocol by yourself, better use the most performant library available, openSSL
5.Yes and no, at least you may get a performance increase but maybe not significant. In general, I would recommend it
一般而言,对您的方法的评论以及对问题#2的答复:
当您创建基准时(即比较两种或多种不同技术选项的相对性能),您不应该依赖报告的计时信息由技术本身。主要原因是很难(除非您深入研究第 3 方代码)确切地了解正在报告的内容,当然,无法在两个值之间进行精确比较不能保证代表相同的测量结果。
相反,您应该执行以下操作:
编写两段功能相同的代码 - 换句话说,它们执行完全相同的操作,使用相同的算法,对相同的数据进行操作,等等...... -唯一的区别是一个使用一种技术(例如 fsockopen),而另一个使用另一种技术(例如 CURL)。
现在,将两段代码包装在相同的循环中,该循环将重复调用代码大量次(例如 1000 次)。您希望每批试验的总执行时间在 10 秒或更长的范围内。
最后,将每个循环(一个尝试 CURL 的循环和一个尝试 fsockopen 的单独循环)包装在两个相同的计时代码中。只需在开始循环之前捕获时间(以毫秒或微为单位),然后运行循环的所有周期,然后再次捕获时间并减去。
这将使您对这两种技术的实际性能有一个更具代表性的了解。如果需要,您可以将最终时间除以循环中的迭代次数,但只要两个测试运行相同的迭代次数,就没有必要这样做。
旁注:您可能已经知道这一点,但是在 php 中编写基准代码时,您应该使用带有可选参数的 microtime 函数,如下所示:
microtime 上的可选参数仅在 php > 5.0 中可用,所以如果您是仍然在 php 4.x 上,那么您必须将这两个时间存储为字符串,然后在事后进行一些解析,以便将它们转换为数字,以便您可以用它们进行数学运算。有关更多详细信息,请参阅 microtime() 的 PHP 文档。
A comment on your approach, in general, and a response to your question #2:
When you're creating benchmarks (i.e. comparing the relative performance of two or more different technology options), you should not be relying on timing information that is reported by the technology itself. The main reason is that it's difficult (unless you go digging through 3rd party code) to know exactly what is being reported, and of course, there is no way to make an exact comparison between two values that can not be guaranteed to represent the same measurement.
Instead, you should do the following:
write two pieces of code that are functionally identical—in other words, they do the exact same thing, with the same algorithm, operating on the same data, etc, etc... —with the only difference being that one uses one technology (eg. fsockopen), while the other uses the other technology (eg. CURL).
now, wrap both pieces of code in identical loops that will call the code repeatedly for some large number of times (eg. 1000). You want your total execution time to be something in the range of 10-seconds or more for each batch of trials.
finally, wrap each loop (one that tries CURL, and a separate one that tries fsockopen) in two identical bits of timing code. Just capture the time (in millis, or micros) before you start the loop, then run all the cycles of the loop, then capture the time again, and subtract.
This will give you a much more representative picture of how well the two technologies actually perform. You can divide your final times by the number of iterations in your loop if you want, but its not necessary to do so as long as both tests ran the same number of iterations.
Side note: You may already know this, but when writing benchmark code in php, you should use the microtime function with the optional parameter, as follows:
the optional parameter on microtime is only available in php >5.0, so if you're still on php 4.x, then you'll have to store the two times as strings, then do some parsing after the fact in order to get them into numbers so you can do math with them. See php docs for microtime() for more details.
您可以使用 fopen() https 包装器(使用 stream_context_create()) ,虽然我不知道它是否比其他两个更快。
You could use the fopen() https wrapper (with stream_context_create()) , although I don't know if it's faster than the other two or not.