文章目录
  1. 1. 概述
  2. 2. RabbitMQ
  3. 3. Redis
    1. 3.1. Redis常用的命令有:
  4. 4. kafka
  5. 5. 扩展阅读
  6. 6. 尾声

概述

其实进程之间的消息队列的通信方式说白了就是一个消息链表,有足够写权限的进程能够往队列中放置消息,有足够读权限的进程可从队列中取走消息。再泛化一点,数据库Mysql也可以用于进程间的通信,一个进程往Mysql当中写数据,另外的进程从Mysql当中读数据。

对于linux的System V消息队列,其实并不比使用第三方的企业级软件(比如RabbitMQ)显得更加高效,而且还有诸多限制。我自己实现这个message_queue只是为了复习一下书本,真正在架构当中使用的话,即使自己写的消息队列足够轻量级,但是也不一定就比专业的消息队列软件更快,而且System V消息队列也不是没有限制。
《UNPv2》当中明确指出了消息队列的限制:
System V 消息队列典型限制
那么写的消息队列还要时刻记住有哪些限制,维护起来又不方便。

记得在我高中毕业的时候,曾近一段时间对围棋很感兴趣。当时上网特意看了邱百瑞的视频。他教棋的时候说:“围棋有两种下法,一种是圈实地,一种是拿棋势。他建议初学者多拿棋势,为什么呢,因为只有这样才能够判断当前的棋势是不是对自己有利。如果每次下棋都只知道拿实地,这样很难有进步。”虽然我的围棋已经完全荒废了,但是这句话却时常从我脑中冒出来。我想如果自己为了练手写个框架,那么IPC就可以用自己造的轮子,因为出了什么问题自己马上就知道了,如果每次遇到问题都去网上找别人写好的程序下来用,那么自己会很难进步。

RabbitMQ

我上一家公司的一套系统上跑的就是RabbitMQ,我并没有用过它,但是据我的同事和我说它的性能不错。
RabbitMQ是使用Erlang编写的一个开源的消息队列,本身支持很多的协议:AMQPXMPP, SMTP, STOMP。它非常重量级,更适合于企业级的开发。

RabbitMQ的6个功能

RabbitMQ的C接口:rabbitmq-c

Erlang是爱立信开发的高度并行的语言,它的高并发性的起源是它的actor模式。C++也有actor模式的库:TheronCAF

Redis

Redis(REmote DIctionary Server)这种key-value类型的NoSQL数据库拥有很强大的应用场景。除了作为缓存之外,使用Redis也能作为跨机器的消息队列来使用。

我公司以前用的是memcached做缓存,不过现在都换成Redis了。原因是我们看了stackoverflow的一篇文章:Memcached vs. Redis?。目前memcachedRedis没有任何的优势可言了,但是Redismemcached不曾有的优点。

Redis常用的命令有:

1,启动Redis的命令特别简单:

1
redis-server

2,如果要根据特定的配置文件来启动Redis的话,那么只要在后面跟上配置文件的路径就可以了:

1
redis-server redis.conf

3,设置Redis的密码,修改配置文件,加上这句话:

1
requirepass mima //设置密码为mima,记得重启redis

4,连接本机Redis

1
redis-cli

5,连接远程Redis

1
redis-cli -h host -p port -a password

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

6,设置string类型的键值对,使用set就可以了:

1
set myKey abc

获取键值对

1
get myKey

7,hash 是一个键值对集合。使用hmsethmget
将username,password,cellphone放入user:1这个哈希表当中:

1
hmset user:1 username password cellphone
1
hmgetall user:1

8,list是一个列表,使用lpushlrange
将redis,rabbitmq放入mylist这个列表当中:

1
2
lpush mylist redis
lpush mylist rabbitmq
1
lrange mylist 0 2

9,set是一个无重复值的集合,使用saddsmembers

1
2
3
sadd myset redis
sadd myset redis
sadd myset rabbitmq
1
smembers myset 

10,zset,也就是sorted set,和set一样无重复值,不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序,排序命令为zrangescore

1
2
3
zadd sortset 0 redis
zadd sortset 5 rabbitmq
zadd sortset 2 mysql
1
zrangescore sortset 0 10

11,使用del加上key可以删除任何数据结构

1
2
3
4
5
del mykey
del user:1
del mylist
del myset
del sortset

之所以使用Redis加上Mysql两套数据库的原因是因为Redis是内存型数据库,数据保存在内存中,通过tcp直接存取,速度快,并发高。还有就是因为实时更新 MySQL可能导致性能问题,让查询变慢,对于开发期货的交易平台,实时获取到行情是非常重要的,使用Redis将通过CTP接口获取到的行情放到Redis当中去,因为恰好行情也是一种key-value模式的数据,所以从Redis当中取出行情也比在关系型数据库当中取行情要快许多,关系型数据库强大的SQL查询在这里的作用不大。Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。之所以还用Mysql是由于遗留问题,有一部分其他业务用到了mysql,而且需要联合使用Redismysql这两部分的数据,需要聚合数据,简单的聚合数据可以在程序里完成,但是这里的业务有它的特殊性,并不需要及时获取Redis上存储的数据。那么经过我们的讨论,想了一个耦合度很低的解决方案,就是每天收盘之后,把Redis的数据复制到mysql当中去做数据迁移,让聚合数据直接发生在数据库层面,这样就算Redis设计的key-value结构变了,只需要改数据迁移的代码就可以了,并不需要动业务逻辑的代码。

kafka

如果要用分布式消息系统的话,kafka首当其冲。它最初由LinkedIn公司开发,使用Scala编写,之后成为Apache项目的一部分。这个消息队列我也没有使用过,我用过Apache的东西目前只有tomcathadoopzookeeper,连http的服务器我用的都是nginx。之所以把这个写在这里是因为ApacheStormSpark都支持与Kafka集成,名声大噪的Spark的应用将会越来越多,那么与Spark集成的kafka也将迎来它的繁荣时期。

扩展阅读

RabbitMQ官网
RabbitMQ 使用参考
Redis官网
新浪微博开放平台Redis实践
Apache Kafka
你应该知道的 RPC 原理

尾声

单机上的进程间通信使用System V 消息队列的真不是很多,因为有很多很好的替代方案,那么是不是linux系统调用级别的 IPC就没用用处了呢?当然不是,IPC有个重中之重,是其他应用软件替代不了的,也就是下一篇文章要介绍的,更快的方式—共享内存。

文章目录
  1. 1. 概述
  2. 2. RabbitMQ
  3. 3. Redis
    1. 3.1. Redis常用的命令有:
  4. 4. kafka
  5. 5. 扩展阅读
  6. 6. 尾声