在试验ZeroMQ Push/Pull(他们称之为Pipeline)套接字类型时,我很难理解这种模式的效用.它被称为"负载平衡器".
如果单个服务器向多个工作人员发送任务,推/拉将在所有客户端之间均匀地分发任务.3个客户端和30个任务,每个客户端获得10个任务:client1获取任务1,4,7,... client2,2,5,...等等.很公平.从字面上看.
但是,在实践中,通常存在任务复杂性或客户端计算资源(或可用性)的非同类混合,然后这种模式严重破坏.所有任务似乎都是事先安排好的,服务器不了解客户端的进度或者是否可用.如果client1发生故障,其余的任务不会发送到其他客户端,但仍会为client1排队.如果client1保持关闭状态,则永远不会处理这些任务.相反,如果客户端处理其任务的速度更快,则它不会获得进一步的任务并保持空闲状态,因为它们仍然安排在其他客户端上.
使用REQ/REP是一种可能的解决方案 然后,任务仅被提供给可用资源.
我错过了什么吗?如何Push/Pull有效地使用?有没有办法用这种套接字类型来处理客户端,任务等的不对称性?
谢谢!
这是一个简单的Python示例:
# server
import zmq
import time
context = zmq.Context()
socket = context.socket(zmq.PUSH)
#socket = context.socket(zmq.REP) # uncomment for Req/Rep
socket.bind("tcp://127.0.0.1:5555")
i = 0
time.sleep(1) # naive wait for clients to arrive
while True:
#msg = socket.recv() # uncomment for Req/Rep
socket.send(chr(i))
i += 1
if i == 100:
break
time.sleep(10) # naive wait for tasks to drain
Run Code Online (Sandbox Code Playgroud)
.
# client
import zmq …Run Code Online (Sandbox Code Playgroud) 我根据http://www.linux-nantes.org/~fmonnier/ocaml/ocaml-wrapping-c.php上的指南为CZMQ编写了一些OCaml绑定,这些绑定似乎运行得很好.例如,这是zstr_send:
CAMLprim value
caml_zstr_send(value socket_val, value string_val)
{
CAMLparam2 (socket_val, string_val);
void *sock = CAML_CZMQ_zsocket_val(socket_val);
char *string = String_val(string_val);
int rc = zstr_send(sock, string);
CAMLreturn (Val_int(rc));
}
Run Code Online (Sandbox Code Playgroud)
我可以在大多数代码中使用这些绑定发送和接收消息.但是,我有一个场景,我想在信号处理程序内部发送和接收,直到在其他代码的后台传递消息.举个简单的例子:
open ZMQ
exception SocketBindFailure
let bg_ctx = zctx_new ();;
let pub_sock = zsocket_new bg_ctx ZMQ_PUB;;
let handler _ =
print_endline "enter handler";
print_endline (string_of_int (zstr_send pub_sock "hello"));
print_endline "end handler";
;;
let () =
(try (
(* bind pub socket *)
let rc = zsocket_bind pub_sock "tcp://*:5556" in
if (rc …Run Code Online (Sandbox Code Playgroud) 我想比较一下grpc与zeromq及其模式的某些功能:我想创建一些比较(功能集) - 不知何故 - 0mq是"更好"的套接字 - 但无论如何 - 如果我应用0mq模式 - 我得到可比的'框架'我认为 - 这里0mq似乎更灵活......
主要要求是:
有任何想法吗?
谢谢!
这是我发送到ZeroMQ邮件列表的帖子的副本.然而,问题是它不是特定于ZeroMQ,而是更普遍的关于在WinRT中提供的网络功能的"映射"层的需要,以便在针对WinRT编译时为C++代码提供更正常的"Berkeley Socket facade":
大家好,我之前在移动应用程序中使用过ZeroMQ(请参阅http://www.ibuzzedfirst.com),对于iPhone和Android版本,因为这些平台支持本机/ C++/Socket开发,因此支持ZeroMQ.
对于WindowsPhone 7.5(OS 7.1)版本,我必须从头开始重新实现任何所需的ZeroMQ功能,因为WinPhone 7.5仅支持C#,而不支持C++(它实际上是C#Silverlight应用程序).此外,WinPhone 7.5仅提供其自己的"版本"Socket支持(http://msdn.microsoft.com/en-us/library/sb27wehh%28v=vs.95%29.aspx),它仅支持Async版本的功能,例如ConnectAsync,SendAync,ReceiveAsync等.然而,缺乏C++使得这个问题没有实际意义.
因此,对于WindowsPhone 7.5版本,我仅将应用程序限制为"客户端"(参赛者)功能,并且没有实现"服务器"(测验大师)部分.这是因为应用程序的客户端部分仅发送和接收对服务器的请求,回复和订阅,而服务器利用ZeroMQ的固有多线程多用户功能.为客户端使用重新创建ZeroMQ传输协议/标头(相对)简单,并使用WindowsPhone套接字支持来提供通信.
好的,现在我正在考虑将应用程序移植到Windows 8上的WinRT.(桌面/平板电脑版本首先 - Windows Phone 8 RT SDK还没有出来,但是会类似).好消息是WinRT支持C++,是的!(实际上,它仍然不是那么简单,当编写C#只有WinRT应用程序时,你可以编译'AnyCPU',只要你包含一个C++部分,你就必须构建3个不同的版本 - x86/Win32,x64和ARM版本,但这是一个不同的问题).
不幸的是,像Windows 7/8 Phone一样,WinRT不支持'普通'Berkeley Socket访问,而是提供自己的'版本'的Socket编程,带有用于不同套接字场景的离散类,例如用于连接TCP客户端的StreamSocket(http) ://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.sockets.streamsocket.aspx#methods),用于可绑定TCP服务器的StreamSocketListener(http://msdn.microsoft.com/en -us/library/windows/apps/windows.networking.sockets.streamsocketlistener.aspx#methods)和UDP版本的DatagramSocket/DatagramSocketListener.此外,仅提供所有方法的异步版本.
所以看起来,要让ZeroMQ在WinRT上成功编译,我将不得不编写一个Facade层来提供类似Berkeley Socket的C++接口,并在下面执行必要的映射到WinRT提供的Socket编程版本.
有没有其他人开始这个旅程或写一个类似的门面?有兴趣听取每个人的想法,特别是WinRT看起来非常"重要"!
ZeroMQ作为通用消息传递中间件的经验是什么?
sleep(1)退出前".ZeroMQ常见问题解答页面建议使用Google的protobuf作为序列化邮件内容的方法.
有没有人看到一个很好的用法示例?
我还需要得到"序列化消息的最大优势是什么?"的答案. - 它是否可能是我可以生活的东西,并利用更细长的管道.
我非常喜欢.proto文件和protoc编译器的想法.
此外,似乎另一个伟大的工具扔在操场上libev,欢迎任何评论:)
我知道Apache Thrift和ZeroMQ是属于不同类别的软件,并且要进行比较并不容易,因为它是一个苹果与橙色的比较.但我不知道他们为什么属于不同的类别.他们是不是都习惯在不同服务之间传递数据,这些服务可能会也可能不会用不同的语言编写?
我何时应该使用Thrift?何时应该使用消息队列?
我使用node.js,Python和Java为zeromq编写了一个简单的echo请求/回复测试.代码运行一个100K请求的循环.该平台是一款5yo MacBook Pro,具有2核和运行Snow Leopard的3G内存.
node.js始终比其他两个平台慢一个数量级.
Java的:
real 0m18.823s
user 0m2.735s
sys 0m6.042s
蟒蛇:
real 0m18.600s
user 0m2.656s
sys 0m5.857s
Node.js的:
real 3m19.034s
user 2m43.460s
sys 0m24.668s
有趣的是,使用Python和Java,客户端和服务器进程都使用了大约一半的CPU.node.js的客户端使用大约一个完整的CPU,服务器使用大约30%的CPU.客户端进程也有大量的页面错误导致我相信这是一个内存问题.此外,在10K请求节点只慢3倍; 它运行的时间越长越慢.
这是客户端代码(请注意,process.exit()行也不起作用,这就是除了使用time命令之外我还包括内部计时器的原因):
var zeromq = require("zeromq");
var counter = 0;
var startTime = new Date();
var maxnum = 10000;
var socket = zeromq.createSocket('req');
socket.connect("tcp://127.0.0.1:5502");
console.log("Connected to port 5502.");
function moo()
{
process.nextTick(function(){
socket.send('Hello');
if (counter < maxnum)
{
moo();
}
});
}
moo();
socket.on('message',
function(data)
{
if (counter % 1000 == 0)
{ …Run Code Online (Sandbox Code Playgroud) 我得到了一个用Laravel 4编写的web应用程序.这个应用程序使用了Ratchet,更具体地说,它使用了Latchet软件包.作为旁注,我使用以下技术:
现在我得到以下场景:
在我的routes.php中,我有以下代码,以便正确注册主题:
//routes.php
// Setup a connection and register a topic where clients can connect to.
Latchet::connection('Connection');
Latchet::topic('PhotoStream/{client}', 'PhotoStreamController');
Run Code Online (Sandbox Code Playgroud)然后,我启动棘轮服务器.
sudo php artisan latchet:listen
当照片上传后,我可以运行以下代码将更新推送到正在收听我主题的客户端(PhotoStream/client1在本例中):
// Create the object, save it to db and then publish it to my websockets
$photo = new Photo;
$photo->location = 'path/to/file';
$photo->save();
// Publish it through my websocket clients. (push from server).
Latchet::publish('PhotoStream/client1', array('msg' => $photo->toArray() ));
Run Code Online (Sandbox Code Playgroud)
这段代码都有效,但是在更新的情况下.我的问题如下:
我该如何处理客户端的初始化?
这两个选项中的后一个对我来说似乎是最好的选择,但我真的不知道如何以一种好的方式实现它.
我想知道协议ZeroMQ和协议之间的区别.WebSockets
我知道WebSockets是为Web浏览器客户端设计的,但我假设它也可以用于服务器到服务器.
而且,在这种情况下,我想知道,如果这将是很好用WebSockets的,而不是别的东西一样ZeroMQ的实时消息.
具体来说,我担心在发生临时网络故障时可靠性和丢失消息.