作家
登录

服务端I/O性能:Node、PHP、Java、Go的对比

作者: 来源: 2017-10-31 11:46:44 阅读 我要评论

这些你明白了么?如今来到了真正有趣的部分:我们来看看一些风行的说话对那些对象的应用,并得出关于易用性和机能之间衡量的结论,以及一些其他有趣小器械。

声明,本文中显示的示例是零碎的(单方面的,只能表现相干的信息); 数据库拜访、外部缓存体系( memcache 等等)以及任何须要 I/O 的器械都将履行某种类型的 I/O 调用,其本质与膳绫擎所示的简单示例效不雅雷同。此外,对于将 I/O 描述为“壅塞”( PHP、Java )的情况,HTTP 要乞降响应攫取和写入本身就是浊宣调用:体系中隐蔽着更多 I/O 及其伴生的机能问题须要推敲。

为一个项目选择编程说话要推敲很多身分。甚至当你只推敲效力时,也有很多身分。然则,如不雅你担心你的法度榜样将重要受到 I/O 的限制,如不雅 I/O 机能影响到项目标成败,那么这些是你须要懂得的。

早在 90 年代,很多人都穿戴 Converse 鞋,用 Perl 写着 CGI 脚本。然后 PHP 来了,就像一些人爱好咒骂的一样,它使得动态网页更轻易。

PHP 应用的模型相当简单。虽有一些进出,但你的 PHP 办事器根本上是如许:

HTTP 请求来自用户的浏览器,并拜访你的 Apache Web 办事器。Apache 为每个请求创建一个零丁的过程,有一些优化方法可以从新应用它们,以最大年夜限度地削减创建次数( 相对而言,创建过程较慢 )。Apache 调用 PHP 并告诉它运行磁盘上合适的 .php 文件。PHP 代码履行并壅塞 I/O 调用。你在 PHP 中调用 file_get_contents() ,其底层会调用 read() 体系调用处等待结不雅。

当然,实际的代码是直接嵌入到你的页面,并且该操作被壅塞:

  1. <?php 
  2. // blocking file I/O 
  3. $file_data = file_get_contents(‘/path/to/file.dat’); 
  4. // blocking network I/O 
  5. $curl = curl_init('http://example.com/example-microservice'); 
  6. $result = curl_exec($curl); 
  7. // some more blocking network I/O 
  8. $result = $db->query('SELECT id, data FROM examples ORDER BY id DESC limit 100'); 
  9. ?> 

关于若何与体系集成,就像如许:

I/O Model PHP

很简单:每个请求一个过程。 I/O 调用就壅塞。长处是简单可工作,缺点是,同时与 20,000 个客户端连接,你的办事器将会崩溃。这种办法不克不及很好地扩大,因为内核供给的用于处理安闲量 I/O (epoll 等) 的对象没有被应用。 落井下石的是,为每个请求运行一个零丁的过程往往会应用大年夜量的体系资本,特别是内存,这平日是你在如许的场景中碰到的第一个问题。

留意:Ruby 应用的办法与 PHP 异常类似,在大年夜致的方面上,它们可以被认为是雷同的。

多线程办法: Java

就在你购买你的第一个域名,在某个句子后很酷地随机说出 “dot com” 的那个时刻,Java 来了。而 Java 具有内置于该说话中的多线程功能,它异常棒(特别是在创建时)。

大年夜多半 Java Web 办事器经由过程为每个请求启动一个新的履行线程,然后在该线程中最终调用你(作为应用法度榜样开辟人员)编写的函数。

  1. public void doGet(HttpServletRequest request, 
  2.     HttpServletResponse response) throws ServletException, IOException 
  3.     // blocking file I/O 
  4.     InputStream fileIs = new FileInputStream("/path/to/file"); 
  5.     // blocking network I/O 
  6.     URLConnection urlConnection = (new URL("http://example.com/example-microservice")).openConnection(); 
  7.     InputStream netIs = urlConnection.getInputStream(); 
  8.     // some more blocking network I/O 
  9. out.println("..."); 

因为我们膳绫擎的 doGet 办法对应于一个请求,并且在其本身的线程中运行,而不是每个请求一个零丁的过程,申请本身的内存。如许有一些好处,比如在线程之间共享状况、缓存数据等,因为它们可以拜访彼此的内存,然则它与调及?交淮竽暌拱响与之前的 PHP 的例子几乎雷同。每个请求获得一个新线程,该线程内的各类 I/O 操作壅塞在线程内,直到请求被完全处理为止。线程被池化以最小化创建和烧毁它们的成本,然则数千个连接仍然意味着数千个线程,这对调剂法度榜样是晦气的。


  推荐阅读

  2017 Web 开发安全风险 TOP10,看看中枪了没?

2017年架构师最重要的48个小时 | 8折倒计时 Open Web Application Security Project (OWASP)每隔3-4年会颁布一次 “Web 开辟安然问题 TOP10 ” ,经由过程找出企业组织所面对的>>>详细阅读


本文标题:服务端I/O性能:Node、PHP、Java、Go的对比

地址:http://www.17bianji.com/lsqh/38300.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)