- 浏览: 471847 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
kc_hxd_jp:
博主问个问题,这个篇幅下的python代码无法达到应有的作用, ...
zeroMQ初体验-14.命名机制 进阶 -
kobe1029:
Map<String, Object> args ...
rabbitmq 队列长度预设的曲线方案 -
Sasoritattoo:
LZ,这都13年了,抽空把这篇文章的下文给表完了吧,这一口气喘 ...
nginx + gridfs + mongodb 大事记(残) -
3GQQ2012:
引用前文已经说过,XREP其实用以平衡负载,所以这里由它对请求 ...
zeroMQ初体验-15.应答模式进阶(一)-数据的封装 -
iyuan:
ustclz 写道图片怎么显示不了了。。我这看是可以显示的。不 ...
zeroMQ初体验-1.简介及C/S模式
好吧,本以为这可能是一个更靠谱的模式,谁知(其实是我一厢情愿了)。
所谓自由模式,自然是--爱咋咋地 呃。。
作为还算靠谱的官方,终是给出了一些经过验证的"自由模式"的模型。下面就来一一拆解吧。
简单重试和故障转移
好像有点眼熟,其实有用到"懒人模式"的简单重试,并且对服务器端做了重写,使其可适用于多服务器的情况。不过,这可不比之前的"主从模式",而是由客户端连接多个服务器,一次性发出n个同样的请求,先得到谁的返回就用谁的应答。(真是有够简单的,难道是简陋?)
服务器端:
客户端:
客户端的代码做了些封装,使用到了api的引用结构,这也是作者所推崇的代码方式。
这种模型的优点:
1.简单!易于理解和使用
2.故障冗余不错(除非你的服务器全挂了)
缺点:
1.过多的冗余流量
2.服务器的使用没有优先级
3.所有的服务器同一时间内只能做一件事,还是同样的事
复杂到令人生厌
单词有一解释为“龌龊”。其实,可以理解为除了上面那种模型之外的模型。因为现实环境总是复杂的,那么模型相应也会越来越让人生厌,却又不得不如此。(果然龌龊)
通常来说,一个客户端知道一堆服务器模型虽然简单,可是业务运营未必,那么只让他知道一个路由地址呢。业务的代价就转移到技术上了(挺悲催的)。每多一层中间件,都会多一倍的复杂逻辑。
服务器端:
客户端:
客户端api:
呼呼,这个api有够复杂吧,它包含了:
异步机制
链路稳固机制
ping机制
计时器
终于,可靠性章节终于结束了。按官网的说法:比较靠谱,现实可用的就是上面那个令人生厌的模式了,当然“管家模式”也是可以一试的。
(未完待续)
所谓自由模式,自然是--爱咋咋地 呃。。
作为还算靠谱的官方,终是给出了一些经过验证的"自由模式"的模型。下面就来一一拆解吧。
简单重试和故障转移
好像有点眼熟,其实有用到"懒人模式"的简单重试,并且对服务器端做了重写,使其可适用于多服务器的情况。不过,这可不比之前的"主从模式",而是由客户端连接多个服务器,一次性发出n个同样的请求,先得到谁的返回就用谁的应答。(真是有够简单的,难道是简陋?)
服务器端:
// // Freelance server - Model 2 // Does some work, replies OK, with message sequencing // #include "czmq.h" int main (int argc, char *argv []) { if (argc < 2) { printf ("I: syntax: %s <endpoint>\n", argv [0]); exit (EXIT_SUCCESS); } zctx_t *ctx = zctx_new (); void *server = zsocket_new (ctx, ZMQ_REP); zsocket_bind (server, argv [1]); printf ("I: service is ready at %s\n", argv [1]); while (TRUE) { zmsg_t *request = zmsg_recv (server); if (!request) break; // Interrupted // Fail nastily if run against wrong client assert (zmsg_size (request) == 2); zframe_t *address = zmsg_pop (request); zmsg_destroy (&request); zmsg_t *reply = zmsg_new (); zmsg_add (reply, address); zmsg_addstr (reply, "OK"); zmsg_send (&reply, server); } if (zctx_interrupted) printf ("W: interrupted\n"); zctx_destroy (&ctx); return 0;
客户端:
// // Freelance client - Model 2 // Uses DEALER socket to blast one or more services // #include "czmq.h" // If not a single service replies within this time, give up #define GLOBAL_TIMEOUT 2500 // We design our client API as a class #ifdef __cplusplus extern "C" { #endif // Opaque class structure typedef struct _flclient_t flclient_t; flclient_t * flclient_new (void); void flclient_destroy (flclient_t **self_p); void flclient_connect (flclient_t *self, char *endpoint); zmsg_t * flclient_request (flclient_t *self, zmsg_t **request_p); #ifdef __cplusplus } #endif int main (int argc, char *argv []) { if (argc == 1) { printf ("I: syntax: %s <endpoint> …\n", argv [0]); exit (EXIT_SUCCESS); } // Create new freelance client object flclient_t *client = flclient_new (); // Connect to each endpoint int argn; for (argn = 1; argn < argc; argn++) flclient_connect (client, argv [argn]); // Send a bunch of name resolution 'requests', measure time int requests = 10000; uint64_t start = zclock_time (); while (requests--) { zmsg_t *request = zmsg_new (); zmsg_addstr (request, "random name"); zmsg_t *reply = flclient_request (client, &request); if (!reply) { printf ("E: name service not available, aborting\n"); break; } zmsg_destroy (&reply); } printf ("Average round trip cost: %d usec\n", (int) (zclock_time () - start) / 10); flclient_destroy (&client); return 0; } // -------------------------------------------------------------------- // Structure of our class struct _flclient_t { zctx_t *ctx; // Our context wrapper void *socket; // DEALER socket talking to servers size_t servers; // How many servers we have connected to uint sequence; // Number of requests ever sent }; // -------------------------------------------------------------------- // Constructor flclient_t * flclient_new (void) { flclient_t *self; self = (flclient_t *) zmalloc (sizeof (flclient_t)); self->ctx = zctx_new (); self->socket = zsocket_new (self->ctx, ZMQ_DEALER); return self; } // -------------------------------------------------------------------- // Destructor void flclient_destroy (flclient_t **self_p) { assert (self_p); if (*self_p) { flclient_t *self = *self_p; zctx_destroy (&self->ctx); free (self); *self_p = NULL; } } // -------------------------------------------------------------------- // Connect to new server endpoint void flclient_connect (flclient_t *self, char *endpoint) { assert (self); zsocket_connect (self->socket, endpoint); self->servers++; } // -------------------------------------------------------------------- // Send request, get reply // Destroys request after sending zmsg_t * flclient_request (flclient_t *self, zmsg_t **request_p) { assert (self); assert (*request_p); zmsg_t *request = *request_p; // Prefix request with sequence number and empty envelope char sequence_text [10]; sprintf (sequence_text, "%u", ++self->sequence); zmsg_pushstr (request, sequence_text); zmsg_pushstr (request, ""); // Blast the request to all connected servers int server; for (server = 0; server < self->servers; server++) { zmsg_t *msg = zmsg_dup (request); zmsg_send (&msg, self->socket); } // Wait for a matching reply to arrive from anywhere // Since we can poll several times, calculate each one zmsg_t *reply = NULL; uint64_t endtime = zclock_time () + GLOBAL_TIMEOUT; while (zclock_time () < endtime) { zmq_pollitem_t items [] = { { self->socket, 0, ZMQ_POLLIN, 0 } }; zmq_poll (items, 1, (endtime - zclock_time ()) * ZMQ_POLL_MSEC); if (items [0].revents & ZMQ_POLLIN) { // Reply is [empty][sequence][OK] reply = zmsg_recv (self->socket); assert (zmsg_size (reply) == 3); free (zmsg_popstr (reply)); char *sequence = zmsg_popstr (reply); int sequence_nbr = atoi (sequence); free (sequence); if (sequence_nbr == self->sequence) break; } } zmsg_destroy (request_p); return reply; }
客户端的代码做了些封装,使用到了api的引用结构,这也是作者所推崇的代码方式。
这种模型的优点:
1.简单!易于理解和使用
2.故障冗余不错(除非你的服务器全挂了)
缺点:
1.过多的冗余流量
2.服务器的使用没有优先级
3.所有的服务器同一时间内只能做一件事,还是同样的事
复杂到令人生厌
单词有一解释为“龌龊”。其实,可以理解为除了上面那种模型之外的模型。因为现实环境总是复杂的,那么模型相应也会越来越让人生厌,却又不得不如此。(果然龌龊)
通常来说,一个客户端知道一堆服务器模型虽然简单,可是业务运营未必,那么只让他知道一个路由地址呢。业务的代价就转移到技术上了(挺悲催的)。每多一层中间件,都会多一倍的复杂逻辑。
服务器端:
// // Freelance server - Model 3 // Uses an ROUTER/ROUTER socket but just one thread // #include "czmq.h" int main (int argc, char *argv []) { int verbose = (argc > 1 && streq (argv [1], "-v")); zctx_t *ctx = zctx_new (); // Prepare server socket with predictable identity char *bind_endpoint = "tcp://*:5555"; char *connect_endpoint = "tcp://localhost:5555"; void *server = zsocket_new (ctx, ZMQ_ROUTER); zmq_setsockopt (server, ZMQ_IDENTITY, connect_endpoint, strlen (connect_endpoint)); zsocket_bind (server, bind_endpoint); printf ("I: service is ready at %s\n", bind_endpoint); while (!zctx_interrupted) { zmsg_t *request = zmsg_recv (server); if (verbose && request) zmsg_dump (request); if (!request) break; // Interrupted // Frame 0: identity of client // Frame 1: PING, or client control frame // Frame 2: request body zframe_t *address = zmsg_pop (request); zframe_t *control = zmsg_pop (request); zmsg_t *reply = zmsg_new (); if (zframe_streq (control, "PONG")) zmsg_addstr (reply, "PONG"); else { zmsg_add (reply, control); zmsg_addstr (reply, "OK"); } zmsg_destroy (&request); zmsg_push (reply, address); if (verbose && reply) zmsg_dump (reply); zmsg_send (&reply, server); } if (zctx_interrupted) printf ("W: interrupted\n"); zctx_destroy (&ctx); return 0; }
客户端:
// // Freelance client - Model 3 // Uses flcliapi class to encapsulate Freelance pattern // // Lets us build this source without creating a library #include "flcliapi.c" int main (void) { // Create new freelance client object flcliapi_t *client = flcliapi_new (); // Connect to several endpoints flcliapi_connect (client, "tcp://localhost:5555"); flcliapi_connect (client, "tcp://localhost:5556"); flcliapi_connect (client, "tcp://localhost:5557"); // Send a bunch of name resolution 'requests', measure time int requests = 1000; uint64_t start = zclock_time (); while (requests--) { zmsg_t *request = zmsg_new (); zmsg_addstr (request, "random name"); zmsg_t *reply = flcliapi_request (client, &request); if (!reply) { printf ("E: name service not available, aborting\n"); break; } zmsg_destroy (&reply); } printf ("Average round trip cost: %d usec\n", (int) (zclock_time () - start) / 10); puts ("flclient 1"); flcliapi_destroy (&client); puts ("flclient 2"); return 0; }
客户端api:
/* ===================================================================== flcliapi - Freelance Pattern agent class Model 3: uses ROUTER socket to address specific services --------------------------------------------------------------------- Copyright (c) 1991-2011 iMatix Corporation <www.imatix.com> Copyright other contributors as noted in the AUTHORS file. This file is part of the ZeroMQ Guide: http://zguide.zeromq.org This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. ===================================================================== */ #include "flcliapi.h" // If no server replies within this time, abandon request #define GLOBAL_TIMEOUT 3000 // msecs // PING interval for servers we think are alive #define PING_INTERVAL 2000 // msecs // Server considered dead if silent for this long #define SERVER_TTL 6000 // msecs // ===================================================================== // Synchronous part, works in our application thread // --------------------------------------------------------------------- // Structure of our class struct _flcliapi_t { zctx_t *ctx; // Our context wrapper void *pipe; // Pipe through to flcliapi agent }; // This is the thread that handles our real flcliapi class static void flcliapi_agent (void *args, zctx_t *ctx, void *pipe); // --------------------------------------------------------------------- // Constructor flcliapi_t * flcliapi_new (void) { flcliapi_t *self; self = (flcliapi_t *) zmalloc (sizeof (flcliapi_t)); self->ctx = zctx_new (); self->pipe = zthread_fork (self->ctx, flcliapi_agent, NULL); return self; } // --------------------------------------------------------------------- // Destructor void flcliapi_destroy (flcliapi_t **self_p) { assert (self_p); if (*self_p) { flcliapi_t *self = *self_p; zctx_destroy (&self->ctx); free (self); *self_p = NULL; } } // --------------------------------------------------------------------- // Connect to new server endpoint // Sends [CONNECT][endpoint] to the agent void flcliapi_connect (flcliapi_t *self, char *endpoint) { assert (self); assert (endpoint); zmsg_t *msg = zmsg_new (); zmsg_addstr (msg, "CONNECT"); zmsg_addstr (msg, endpoint); zmsg_send (&msg, self->pipe); zclock_sleep (100); // Allow connection to come up } // --------------------------------------------------------------------- // Send & destroy request, get reply zmsg_t * flcliapi_request (flcliapi_t *self, zmsg_t **request_p) { assert (self); assert (*request_p); zmsg_pushstr (*request_p, "REQUEST"); zmsg_send (request_p, self->pipe); zmsg_t *reply = zmsg_recv (self->pipe); if (reply) { char *status = zmsg_popstr (reply); if (streq (status, "FAILED")) zmsg_destroy (&reply); free (status); } return reply; } // ===================================================================== // Asynchronous part, works in the background // --------------------------------------------------------------------- // Simple class for one server we talk to typedef struct { char *endpoint; // Server identity/endpoint uint alive; // 1 if known to be alive int64_t ping_at; // Next ping at this time int64_t expires; // Expires at this time } server_t; server_t * server_new (char *endpoint) { server_t *self = (server_t *) zmalloc (sizeof (server_t)); self->endpoint = strdup (endpoint); self->alive = 0; self->ping_at = zclock_time () + PING_INTERVAL; self->expires = zclock_time () + SERVER_TTL; return self; } void server_destroy (server_t **self_p) { assert (self_p); if (*self_p) { server_t *self = *self_p; free (self->endpoint); free (self); *self_p = NULL; } } int server_ping (char *key, void *server, void *socket) { server_t *self = (server_t *) server; if (zclock_time () >= self->ping_at) { zmsg_t *ping = zmsg_new (); zmsg_addstr (ping, self->endpoint); zmsg_addstr (ping, "PING"); zmsg_send (&ping, socket); self->ping_at = zclock_time () + PING_INTERVAL; } return 0; } int server_tickless (char *key, void *server, void *arg) { server_t *self = (server_t *) server; uint64_t *tickless = (uint64_t *) arg; if (*tickless > self->ping_at) *tickless = self->ping_at; return 0; } // --------------------------------------------------------------------- // Simple class for one background agent typedef struct { zctx_t *ctx; // Own context void *pipe; // Socket to talk back to application void *router; // Socket to talk to servers zhash_t *servers; // Servers we've connected to zlist_t *actives; // Servers we know are alive uint sequence; // Number of requests ever sent zmsg_t *request; // Current request if any zmsg_t *reply; // Current reply if any int64_t expires; // Timeout for request/reply } agent_t; agent_t * agent_new (zctx_t *ctx, void *pipe) { agent_t *self = (agent_t *) zmalloc (sizeof (agent_t)); self->ctx = ctx; self->pipe = pipe; self->router = zsocket_new (self->ctx, ZMQ_ROUTER); self->servers = zhash_new (); self->actives = zlist_new (); return self; } void agent_destroy (agent_t **self_p) { assert (self_p); if (*self_p) { agent_t *self = *self_p; zhash_destroy (&self->servers); zlist_destroy (&self->actives); zmsg_destroy (&self->request); zmsg_destroy (&self->reply); free (self); *self_p = NULL; } } // Callback when we remove server from agent 'servers' hash table static void s_server_free (void *argument) { server_t *server = (server_t *) argument; server_destroy (&server); } void agent_control_message (agent_t *self) { zmsg_t *msg = zmsg_recv (self->pipe); char *command = zmsg_popstr (msg); if (streq (command, "CONNECT")) { char *endpoint = zmsg_popstr (msg); printf ("I: connecting to %s…\n", endpoint); int rc = zmq_connect (self->router, endpoint); assert (rc == 0); server_t *server = server_new (endpoint); zhash_insert (self->servers, endpoint, server); zhash_freefn (self->servers, endpoint, s_server_free); zlist_append (self->actives, server); server->ping_at = zclock_time () + PING_INTERVAL; server->expires = zclock_time () + SERVER_TTL; free (endpoint); } else if (streq (command, "REQUEST")) { assert (!self->request); // Strict request-reply cycle // Prefix request with sequence number and empty envelope char sequence_text [10]; sprintf (sequence_text, "%u", ++self->sequence); zmsg_pushstr (msg, sequence_text); // Take ownership of request message self->request = msg; msg = NULL; // Request expires after global timeout self->expires = zclock_time () + GLOBAL_TIMEOUT; } free (command); zmsg_destroy (&msg); } void agent_router_message (agent_t *self) { zmsg_t *reply = zmsg_recv (self->router); // Frame 0 is server that replied char *endpoint = zmsg_popstr (reply); server_t *server = (server_t *) zhash_lookup (self->servers, endpoint); assert (server); free (endpoint); if (!server->alive) { zlist_append (self->actives, server); server->alive = 1; } server->ping_at = zclock_time () + PING_INTERVAL; server->expires = zclock_time () + SERVER_TTL; // Frame 1 may be sequence number for reply char *sequence = zmsg_popstr (reply); if (atoi (sequence) == self->sequence) { zmsg_pushstr (reply, "OK"); zmsg_send (&reply, self->pipe); zmsg_destroy (&self->request); } else zmsg_destroy (&reply); } // --------------------------------------------------------------------- // Asynchronous agent manages server pool and handles request/reply // dialog when the application asks for it. static void flcliapi_agent (void *args, zctx_t *ctx, void *pipe) { agent_t *self = agent_new (ctx, pipe); zmq_pollitem_t items [] = { { self->pipe, 0, ZMQ_POLLIN, 0 }, { self->router, 0, ZMQ_POLLIN, 0 } }; while (!zctx_interrupted) { // Calculate tickless timer, up to 1 hour uint64_t tickless = zclock_time () + 1000 * 3600; if (self->request && tickless > self->expires) tickless = self->expires; zhash_foreach (self->servers, server_tickless, &tickless); int rc = zmq_poll (items, 2, (tickless - zclock_time ()) * ZMQ_POLL_MSEC); if (rc == -1) break; // Context has been shut down if (items [0].revents & ZMQ_POLLIN) agent_control_message (self); if (items [1].revents & ZMQ_POLLIN) agent_router_message (self); // If we're processing a request, dispatch to next server if (self->request) { if (zclock_time () >= self->expires) { // Request expired, kill it zstr_send (self->pipe, "FAILED"); zmsg_destroy (&self->request); } else { // Find server to talk to, remove any expired ones while (zlist_size (self->actives)) { server_t *server = (server_t *) zlist_first (self->actives); if (zclock_time () >= server->expires) { zlist_pop (self->actives); server->alive = 0; } else { zmsg_t *request = zmsg_dup (self->request); zmsg_pushstr (request, server->endpoint); zmsg_send (&request, self->router); break; } } } } // Disconnect and delete any expired servers // Send heartbeats to idle servers if needed zhash_foreach (self->servers, server_ping, self->router); } agent_destroy (&self); }
呼呼,这个api有够复杂吧,它包含了:
异步机制
链路稳固机制
ping机制
计时器
终于,可靠性章节终于结束了。按官网的说法:比较靠谱,现实可用的就是上面那个令人生厌的模式了,当然“管家模式”也是可以一试的。
(未完待续)
发表评论
-
IM选型(初)
2016-08-23 19:12 1643主要参考文章: https://r ... -
关于python和rabbitmq的那点事儿
2011-10-19 14:15 7963rabbitmq是一个消息中间件,在之前的zmq介绍中有略带提 ... -
zeroMQ初体验-34.发布/订阅模式进阶-克隆模式-下,结言
2011-05-26 16:09 4197服务器: // // Clone server Mod ... -
zeroMQ初体验-33.发布/订阅模式进阶-克隆模式-中
2011-05-26 15:37 2929临时缓存 现实中,比如 ... -
zeroMQ初体验-32.发布/订阅模式进阶-克隆模式-上
2011-05-26 15:04 3657在发布/订阅模式中,特别是现实应用中,总会因为这样那样的问题导 ... -
zeroMQ初体验-31.发布/订阅模式进阶-黑盒的高速订阅者
2011-05-25 16:55 2756作为发布/订阅模式的一个常用场景,大数据量的组播是有必要的。虽 ... -
zeroMQ初体验-30.发布/订阅模式进阶-自裁的蜗牛订阅者
2011-05-25 16:24 4548在初次介绍发布/订阅模式的时候,就已经抖出了这个包袱:如果订阅 ... -
zeroMQ初体验-28.可靠性-主从模式
2011-05-23 14:47 5540虽然"硬盘模式" ... -
zeroMQ初体验-27.可靠性-硬盘模式
2011-05-23 13:44 3794在之前的种种模式中, ... -
zeroMQ初体验-26.可靠性-管家模式
2011-05-12 19:05 5653上一节末尾有说到协议,zeromq自然做了充沛的封装,&quo ... -
zeroMQ初体验-26.可靠性-管家模式
2011-05-12 19:03 1上一节末尾有说到协议,zeromq自然做了充沛的封装,&quo ... -
zeroMQ初体验-25.可靠性-偏执的海盗模式
2011-05-05 19:05 3591虽然说“简单的海盗模 ... -
zeroMQ初体验-24.可靠性-简单的海盗模式
2011-05-05 16:41 3216相较于“懒惰的”做了 ... -
zeroMQ初体验-23.可靠性-懒惰的海盗模式
2011-05-05 16:15 5066相较于通常的阻塞模式,这里只是做了一点简单的动作来加强系统的可 ... -
zeroMQ初体验-22.可靠性-总览
2011-04-26 19:25 5938在开篇就从曾对zeromq的可靠性做过质疑,不过,作为一个雄心 ... -
rabbitmq 队列长度预设的曲线方案
2011-04-21 14:36 3400zeromq中倒是直接支持这个功能的。 类似于设定队列长度或 ... -
zeroMQ初体验-21.应答模式进阶(七)-云计算
2011-04-18 19:14 3535这里给出了一个最近很火的"云计算"案例。 ... -
zeroMQ初体验-20.应答模式进阶(六)-多对多路由模式
2011-04-18 17:22 3879某些时候,为了冗余的需要,可能会有这样的需求: impo ... -
zeroMQ初体验-19.应答模式进阶(五)-异步式应答
2011-04-15 15:23 4846恩,这应该算是比较实 ... -
zeroMQ初体验-18.应答模式进阶(四)-定制路由3
2011-04-02 15:39 5186从经典到超越经典。 首 ...
相关推荐
总的来说,zeromq-2.1.7提供了在Linux环境下进行高效、可靠的消息传递功能,是构建大规模分布式系统的一个重要工具。虽然这是一个较旧的版本,但在某些特定场景下,旧版本可能更稳定,更适合于已知的工作负载和环境...
这里提供的四个压缩包文件,Python-2.6.6.tar.bz2、zeromq-3.2.5.tar.gz、jzmq.tar.gz以及storm-0.8.0.zip,都是与Storm搭建和运行相关的资源。 首先,我们来详细了解一下每个文件的作用: 1. **Python-2.6.6.tar....
zeromq-4.0.3.tar.gz 是一个包含了 ZeroMQ 4.0.3 版本源代码的压缩文件。ZeroMQ,也被称为“零消息队列”或“0MQ”,是一个开源的消息中间件,它提供了一种高效、灵活且可扩展的方式来处理分布式系统中的数据通信。...
zeromq-4.2.3.tar.gz 是ZeroMQ 4.2.3版本的源代码包,这个稳定版本确保了良好的兼容性和可靠性。 首先,让我们深入了解ZeroMQ的核心概念和功能: 1. **套接字(Sockets)**:在ZeroMQ中,套接字不仅仅是传统网络...
标题中的"zeromq-4.1.8.tar.gz"指的是ZeroMQ的4.1.8版本的源代码包,通常以tar.gz格式压缩,这是一种在Linux和类Unix系统中常见的归档和压缩方式。 zeromq的核心特性包括点对点连接、发布/订阅模式、请求/响应模式...
`zeromq-2.1.9.tar.gz` 是zeromq的一个特定版本,即2.1.9版,通常以源码形式提供,需要通过编译来安装。 首先,让我们深入了解zeromq的核心概念。zeromq设计了一个灵活的套接字模型,它允许开发者构建复杂的网络...
官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装
zeromq-4.1.3 是一个针对 ZeroMQ 的特定版本的开发工具包,ZeroMQ 是一个开源的消息中间件库,它为分布式计算提供了一种高性能、轻量级的通信框架。ZeroMQ 提供了多种编程语言的绑定,使得开发者能够方便地在不同的...
0MQ(也称为 ZeroMQ 或 ØMQ)是一个开源的消息中间件,它提供了一种轻量级、高性能的异步消息...通过使用“zeromq-4.3.4.tar.gz”,你可以享受到这个版本带来的稳定性和优化,从而更高效地实现跨进程、跨网络的通信。
- **错误修复**:修复了前一版本中已知的bug,增强了系统的稳定性和可靠性。 - **新功能**:可能添加了新的API或功能,以满足更广泛的需求。 - **安全性增强**:可能加强了安全措施,比如加密传输或身份验证机制的...
在zeromq-4.2.0源码包中,你可以找到以下主要组成部分: 1. **源代码**:包含了zeromq的核心库和各种语言的绑定。核心库通常用C++编写,提供了跨平台的API,而绑定则允许开发者使用Python、Java、C#等其他语言与...
标题中的"zeromq-4.2.0.tar.zip"是指ZeroMQ库的4.2.0版本,它被封装在一个ZIP压缩包中,而内部包含的文件是tar归档格式。ZeroMQ是一个开源的消息中间件,它提供了一个高级的消息队列模型,允许应用程序之间进行高效...
ZeroMQ是一个网络通讯库,其主要用来为分布式应用程序开发提供进程间通信(此处的进程既可以是同一台机器上的两个进程也可以是不同机器上的两个进程)。ZeroMQ的特点在于灵活的通信手段和丰富的连接模型,并且它可以...
ZeroMQ是一个网络通讯库,其主要用来为分布式应用程序开发提供进程间通信(此处的进程既可以是同一台机器上的两个进程也可以是不同机器上的两个进程)。ZeroMQ的特点在于灵活的通信手段和丰富的连接模型,并且它可以...
ZMQ(以下ZeroMQ简称ZMQ)是一个简单好用的传输层,像框架一样的一个socket library,他使得Socket编程更加简单、简洁和性能更高。是一个消息处理队列库,可在多个线程、内核和主机盒之间弹性伸缩。
总的来说,zeromq-4.3.2是一个强大且可靠的工具,它简化了网络编程,提高了应用的性能和效率。对于需要进行高效、灵活消息传递的开发者来说,它是一个理想的选择。通过合理利用其特性,开发者可以构建出高并发、可...
这个“zeromq-4.1.0-rc1.zip”压缩包包含了ZeroMQ 4.1.0版本的源代码,这是一个预发布版本(Release Candidate),意味着它是正式版发布前的最后一个测试版本。 ZeroMQ的核心概念是提供一种抽象的网络通信层,允许...
zeromq-3.12.5.tar.gz, libzmq-3.1.2.tar.gz 在Linux环境中,构建和部署分布式计算系统时,Storm是一个常用的选择,它是一个开源的流处理框架,用于实时数据处理。这个压缩包"zeromq-3.12.5.zip"包含了与Storm集群...
这个“zeromq-4.0.1.tar.gz”文件是ZeroMQ的4.0.1版本源代码包,适用于那些需要在网络通信、并发处理或构建微服务架构的开发者。由于从官方网站下载可能速度较慢,此压缩包提供了方便的下载渠道。 ZeroMQ的核心特性...
- 可靠性:支持消息确认和重试机制,确保消息的可靠传输。 - 负载均衡:发布/订阅模式下,消息可以广播给所有订阅者,而推送/拉取模式则可以实现负载均衡。 总的来说,zeromq是一个功能强大、性能优异的开源消息...