我正在try 用DART编写一个可以并行处理多个请求的HTTP服务器.到目前为止,我还没有成功地实现"平行"部分.

以下是我最初try 的:

import 'dart:io';

main() {
  HttpServer.bind(InternetAddress.ANY_IP_V4, 8080).then((HttpServer server) {
    server.listen((HttpRequest request) {
      Stopwatch stopwatch = new Stopwatch();
      stopwatch.start();
      while (stopwatch.elapsedMilliseconds < 1000) { /* do nothing */ }
      request.response.statusCode = HttpStatus.OK;
      request.response.write(stopwatch.elapsedMilliseconds.toString());
      request.response.close().catchError(print);
    });
  });
}

对于每个请求,它将忙碌工作一秒钟,然后完成.我让它以这种方式处理请求,这样它的时间将是可预测的,因此我可以很容易地在Windows任务管理器中看到请求的效果(CPU核心 skip 到100%的使用率).

我可以看出这不是并行处理请求,因为:

  1. 如果我将几个浏览器选项卡加载到http://example:8080/,然后将它们全部刷新,则这些选项卡会依次加载,每个选项卡之间大约相隔1秒.

  2. 如果我使用负载测试工具wrk进行这些设置...wrk -d 10 -c 8 -t 8 http://example:8080/ ...它在我给它的10秒内完成了5到8个请求.如果服务器使用的是我所有的8个内核,我预计会有接近80个请求.

  3. 当我在WRK测试期间打开Windows任务管理器时,我观察到只有一个内核的使用率接近100%,而睡觉几乎处于空闲状态.

因此,然后我try 使用隔离,希望 for each 请求手动生成一个新的隔离/线程:

import 'dart:io';
import 'dart:isolate';

main() {
  HttpServer.bind(InternetAddress.ANY_IP_V4, 8080).then((HttpServer server) {
    server.listen((HttpRequest request) {
      spawnFunction(handleRequest).send(request);
    });
  });
}

handleRequest() {
  port.receive((HttpRequest request, SendPort sender) {
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.start();
    while (stopwatch.elapsedMilliseconds < 1000) { /* do nothing */ }
    request.response.statusCode = HttpStatus.OK;
    request.response.write(stopwatch.elapsedMilliseconds.toString());
    request.response.close().catchError(print);
  });
}

这根本不起作用.我不想把一个HttpRequest作为消息发送给隔离区.以下是错误:

#0      _SendPortImpl._sendInternal (dart:isolate-patch/isolate_patch.dart:122:3)
#1      _SendPortImpl._sendNow (dart:isolate-patch/isolate_patch.dart:95:18)
#2      _SendPortImpl.send (dart:isolate-patch/isolate_patch.dart:91:18)
#3      main.<anonymous closure>.<anonymous closure> (file:///C:/Development/dartbenchmark/simple2.dart:7:40)
#4      _StreamSubscriptionImpl._sendData (dart:async/stream_impl.dart:475:12)
#5      _StreamImpl._sendData.<anonymous closure> (dart:async/stream_impl.dart:251:29)
#6      _SingleStreamImpl._forEachSubscriber (dart:async/stream_impl.dart:335:11)
#7      _StreamImpl._sendData (dart:async/stream_impl.dart:249:23)
#8      _StreamImpl._add (dart:async/stream_impl.dart:51:16)
#9      StreamController.add (dart:async/stream_controller.dart:10:35)
#10     _HttpServer._handleRequest (http_impl.dart:1261:20)
#11     _HttpConnection._HttpConnection.<anonymous closure> (http_impl.dart:1188:33)
#12     _StreamSubscriptionImpl._sendData (dart:async/stream_impl.dart:475:12)
#13     _StreamImpl._sendData.<anonymous closure> (dart:async/stream_impl.dart:251:29)
#14     _SingleStreamImpl._forEachSubscriber (dart:async/stream_impl.dart:335:11)
#15     _StreamImpl._sendData (dart:async/stream_impl.dart:249:23)
#16     _StreamImpl._add (dart:async/stream_impl.dart:51:16)
#17     StreamController.add (dart:async/stream_controller.dart:10:35)
#18     _HttpParser._doParse (http_parser.dart:415:26)
#19     _HttpParser._parse (http_parser.dart:161:15)
#20     _HttpParser._onData._onData (http_parser.dart:509:11)
#21     _StreamSubscriptionImpl._sendData (dart:async/stream_impl.dart:475:12)
#22     _StreamImpl._sendData.<anonymous closure> (dart:async/stream_impl.dart:251:29)
#23     _SingleStreamImpl._forEachSubscriber (dart:async/stream_impl.dart:335:11)
#24     _StreamImpl._sendData (dart:async/stream_impl.dart:249:23)
#25     _StreamImpl._add (dart:async/stream_impl.dart:51:16)
#26     StreamController.add (dart:async/stream_controller.dart:10:35)
#27     _Socket._onData._onData (dart:io-patch/socket_patch.dart:726:42)
#28     _StreamSubscriptionImpl._sendData (dart:async/stream_impl.dart:475:12)
#29     _StreamImpl._sendData.<anonymous closure> (dart:async/stream_impl.dart:251:29)
#30     _SingleStreamImpl._forEachSubscriber (dart:async/stream_impl.dart:335:11)
#31     _StreamImpl._sendData (dart:async/stream_impl.dart:249:23)
#32     _StreamImpl._add (dart:async/stream_impl.dart:51:16)
#33     StreamController.add (dart:async/stream_controller.dart:10:35)
#34     _RawSocket._RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:452:52)
#35     _NativeSocket.multiplex (dart:io-patch/socket_patch.dart:253:18)
#36     _NativeSocket.connectToEventHandler.<anonymous closure> (dart:io-patch/socket_patch.dart:338:54)
#37     _ReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:81:92)

Unhandled exception:
Illegal argument(s): Illegal argument in isolate message : (object is a closure)
#0      _throwDelayed.<anonymous closure> (dart:async/stream_impl.dart:22:5)
#1      _asyncRunCallback._asyncRunCallback (dart:async/event_loop.dart:15:17)
#2      _asyncRunCallback._asyncRunCallback (dart:async/event_loop.dart:25:9)
#3      Timer.run.<anonymous closure> (dart:async/timer.dart:17:21)
#4      Timer.run.<anonymous closure> (dart:async/timer.dart:25:13)
#5      Timer.Timer.<anonymous closure> (dart:async-patch/timer_patch.dart:9:15)
#6      _Timer._createTimerHandler._handleTimeout (timer_impl.dart:99:28)
#7      _Timer._createTimerHandler._handleTimeout (timer_impl.dart:107:7)
#8      _Timer._createTimerHandler.<anonymous closure> (timer_impl.dart:115:23)
#9      _ReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:81:92)

使用的版本:

  • Dart编辑器版本0.5.9uR22879
  • DART SDK版本0.5.9.0_r22879

是否可以使用DART在我的计算机的所有可用内核中并行处理这些请求?

推荐答案

不久前,我编写了一个名为DART-isserver的库来做这件事.它现在已经严重腐烂了,但你可以看到它的方法.

https://code.google.com/p/dart-isoserver/

我所做的是通过隔离端口代理HttpRequest和HttpResponse,因为您无法直接发送它们.虽然有一些警告,但它还是奏效了:

  1. 请求和响应上的I/O通过主隔离,因此该部分不平行.不过,在工人分离株中所做的其他工作并没有将挡路作为主要分离株.真正应该发生的是套接字连接应该可以在隔离之间传输.
  2. 隔离中的异常会导致整个服务器宕机.spawnFunction()现在有一个未捕获的异常处理程序参数,因此这在某种程度上是可以修复的,但是spawnUri()没有.dart-isoserver使用spawnUri()来实现热加载,因此必须将其删除.
  3. 隔离启动有点慢,对于nginx和node.js面向的数千个并发连接用例,您可能不希望每个连接都有一个.具有工作队列的隔离池可能会执行得更好,尽管这会消除您可以在工作进程中使用阻塞I/O的良好特性.

关于您的第一个代码示例的注释.正如您注意到的,这肯定不会并行运行,因为DART是单线程的.同一隔离中的任何DART代码都不会并发运行.

Dart相关问答推荐

为什么 Dart 程序在使用词法作用域时会根据声明变量的位置而表现不同?

空值判断运算符 - Flutter

在 Flutter 中以间隔自动获取 API 数据

在Dart中进行系统调用?

在Flutter中解析 JSON 到 Map

Flutter-创建value和name数组

如何删除ios上的overscroll?

在向下滚动时隐藏底部导航栏,反之亦然

iOS 上 Flutter 的代码设计错误

如何在 Flutter 中让 Android 状态栏变亮

Dart-对base64字符串进行编码和解码

Flutter-当文本字段有焦点时隐藏提示文本

在字符串中查找字母 (charAt)

Flutter – 连续两个文本,左边一个溢出

Dart 中的动态类方法调用

Dart Nodejs 和 Socketio

Dart:异步抽象方法

Dart如何将逗号添加到字符串编号

在 Dart 和 Pub 中,我应该将 pubspec.lock 添加到我的 .gitignore 吗?

如何在 Dart 中生成随机数?