文档章节

RabbitMQ(10)-性能与安全

你我他有个梦
 你我他有个梦
发布于 2015/12/24 16:51
字数 1772
阅读 2927
收藏 70
点赞 1
评论 0

一.性能

1.速度需求


1.消息持久化

服务器会把消息写到磁盘上,性能最高可以达到10倍,一般正常运行也会达到三四倍

2.消息确认

订阅队列时,no-ack设置为true,那么处理完消息之后就无须再发送确认消息回服务器,这样就能极大加快消费者消费消息的速度

3.路由算法和绑定规则

在服务器端,交换器和绑定作为记录存储在Mnesia,会将这些信息复制到集群其他节点,基于ETSErlang Term Storage  Erlang数据存储基于内存)和DETS表(基于磁盘的存储方案),ETS表的访问时间与数据库条目成对数关系,RabbitMQ路由表是由Mnesia提供一致性,而由普通ETS来提供数据查询速度的保证

directfanout交换器的区别在于后者忽略了路由键

topic交换器是RabbitMQ实现了trie数据结构(多叉树结构,详情请看http://dongxicheng.org/structure/trietree/)用来存储绑定路由模式以支持快速查询,在2.3GHZ的机器上,11秒左右的时间针对2000个模式匹配1000000topic,但是他的绑定比directfanout交换器占用更多内存

4.消息投递

消息不持久化的情况下内存不足时,会将消息写入到磁盘存储到瞬态存储中,持久化的情况下会写入到磁盘和内存,如果内存不足则刷出磁盘,表现为消费者开始滞后,队列被填满,某一段时间之后服务器收到内存警告然后刷出到磁盘

消息投递流程如下图所示:


2.内存使用率和限制

持久化队列绑定到持久化的交换器占用234个字 1872个字节(64OS

x:代表向哪些表添加记录

队列元数据:


rabbit_queue rabbit_durable_queue
持久化队列 x x
瞬时队列 x
/记录 29 29

交换器元数据:


rabbit_exchange rabbit_durable_exchange
持久化交换器 x x
瞬时交换器 x
/记录 29 29

绑定元数据:


rabbit_route(绑定信息) rabbit_durable_ route(绑定信息) rabbit_semi_durable_ route(瞬时记录) Rabbit_reverse_route(绑定信息)

持久化队列绑定到

持久化交换器
x x x x

持久化队列绑定到

瞬时交换器
x
x x

瞬时队列绑定到

瞬时交换器
x

x

瞬时队列绑定到

持久化交换器
x

x
/记录 44 44 44 44

Erlang进程数默认设置是每个节点2^20=1048576,而进程数是通过以下事件增加:

到服务器的连接、创建新的信道和队列声明


进程数
新建连接 4
新建信道 4
队列声明 1

3.SSL连接

4.安全(密钥、证书、CA证书)

1).文件创建

使用rmqca作为RabbitMQ的认证中心,certs文件用于存放CA产生的证书,private存放CA的密钥,改变其权限不允许第三方访问,serial存放CA证书的序列号,index.txt存放CA颁发的证书

# mkdir rmqca
# cd rmqca
# mkdir certs private
# chmod 700 private
# echo 01 > serial
# touch index.txt



2).创建openssl.conf

[ ca ]
default_ca = rmqca
[rmqca]
dir = .
certificate = $dir/cacert.pem
database = $dir/index.txt
new_certs_dir = $dir/certs
private_key = $dir/private/cakey.pem
serial = $dir/serial
 
default_crl_days = 7
default_days = 365
default_md = sha1
 
policy = rmqca _policy
x509_extensions = certificate_extensions
 
[ rmqca _policy ]
commonName = supplied
stateOrProvinceName = optional
countryName = optional
emailAddress = optional
organizationName = optional
organizationalUnitName = optional
 
[ certificate_extensions ]
basicConstraints = CA:false
 
[ req ]
default_bits = 2048
default_keyfile = ./private/cakey.pem
default_md = sha1
prompt = yes
distinguished_name = root_ca_distinguished_name
x509_extensions = root_ca_extensions
 
[ root_ca_distinguished_name ]
commonName = hostname
 
[ root_ca_extensions ]
basicConstraints = CA:true
keyUsage = keyCertSign, cRLSign
 
[ client_ca_extensions ]
basicConstraints = CA:false
keyUsage = digitalSignature
extendedKeyUsage = 1.3.6.1.5.5.7.3.2
 
[ server_ca_extensions ]
basicConstraints = CA:false
keyUsage = keyEncipherment
extendedKeyUsage = 1.3.6.1.5.5.7.3.1


[ ca ]

ca的名称设置,

[rmqca]

设置CA颁发证书和密钥存放路径以及过期时间 365天),每隔7天提供一个CRL文件,并且使用shal作为哈希函数生成证书;

[ rmqca _policy ]

告诉openssl在证书中哪些是必填项,supplied为必选,optional为可选

[ certificate_extensions ]

false值代表CA不能将自己作为CA----无法用于签名和颁发新证书

[ req ]

指明书生成2048位的密钥,密钥安全方面来说这是最小的数字,,密钥被写入private下的cakey.pem文件,默认使用shal作为默认的哈希函数

[ root_ca_extensions ]

根扩展用于签名其他证书

[ client_ca_extensions ]

用于客户端的证书认证

[ server_ca_extensions ]

用于加密数据以及认证服务器

3).生成CA证书

# openssl req -x509 -config openssl.cnf -newkey rsa:2048 -days 365 \
    -out cacert.pem -outform PEM -subj /CN=MyRmqca/ -nodes
# openssl x509 -in cacert.pem -out cacert.cer -outform DER

4).生成服务端证书

生成RSA密钥然后为其提供证书

# cd ..
# ls
rmqca
# mkdir server
# cd server
# openssl genrsa -out key.pem 2048
# openssl req -new -key key.pem -out req.pem -outform PEM \
    -subj /CN=$(hostname)/O=server/ -nodes
# cd ../rmqca
# openssl ca -config openssl.cnf -in ../server/req.pem -out \
    ../server/cert.pem -notext -batch -extensions server_ca_extensions
# cd ../server
# openssl pkcs12 -export -out keycert.p12 -in cert.pem -inkey key.pem -passout pass:MySecretPassword

5).生成客户端证书

生成RSA密钥然后为其提供证书

# cd ..
# ls
rmqca
# mkdir server
# cd server
# openssl genrsa -out key.pem 2048
# openssl req -new -key key.pem -out req.pem -outform PEM \
    -subj /CN=$(hostname)/O=server/ -nodes
# cd ../rmqca
# openssl ca -config openssl.cnf -in ../server/req.pem -out \
    ../server/cert.pem -notext -batch -extensions server_ca_extensions
# cd ../server
# openssl pkcs12 -export -out keycert.p12 -in cert.pem -inkey key.pem -passout pass:MySecretPassword

这样就生成了三份证书,此时serial已经变为03index.txt也列出了你颁发过的证书

6).启动RabbitMQ的SSL监听器

为方便,将生成的目录拷贝到/etc/rabbitmq/ssl

# cp -r rmqca /etc/rabbitmq/ssl
# cp -r server /etc/rabbitmq/ssl
# cp -r client /etc/rabbitmq/ssl

启用:

# vim rabbitmq.config


[
    {ssl, [{versions, ['tlsv1.2', 'tlsv1.1']}]},
    {rabbit, [
        {tcp_listeners, [5672]},
        {ssl_listeners, [5671]},
        {ssl_options, [{cacertfile,"/etc/rabbitmq/ssl/rmqca/cacert.pem"},
            {certfile,"/etc/rabbitmq/ssl/server/cert.pem"},
            {keyfile,"/etc/rabbitmq/ssl/server/key.pem"},
            {verify, verify_peer},
            {fail_if_no_peer_cert, true},
            {versions, ['tlsv1.2', 'tlsv1.1']}
        ]}
    ]}
].

这样就可以支持普通连接和ssl连接,端口分别为56725671

重启rabbitmq服务即可看到已经监听5671端口

7).使用keytool导入证书

将连接服务器所需要的证书导入到密钥库中

# keytool -import -alias server1 -file /etc/rabbitmq/ssl/server/cert.pem -keystore /etc/rabbitmq/ssl/rabbitstore

5.JAVA实现

util类:

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.*;
import java.security.cert.CertificateException;


public class RabbitMQUtils extends ConnectionFactory{

    /**
     * 使用我们的密钥存储密钥管理器和信任管理器
     * @return
     */
    public static SSLContext getSSLContext(){
        char[] keyPassphrase = "MySecretPassword".toCharArray();
        KeyStore ks = null;
        SSLContext c = null;
        try {
            //通过PKCS12的证书格式得到密钥对象
            ks = KeyStore.getInstance("PKCS12");//交换数字证书的标准
            //keycert.p12包含客户端的证书和key
            String clientName = "F:" + File.separator + "git-root" + File.separator + "keycert.p12";
            ks.load(new FileInputStream(clientName), keyPassphrase);
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            kmf.init(ks, keyPassphrase);
            char[] trustPassphrase = "rabbitlzq".toCharArray();
            KeyStore tks = KeyStore.getInstance("JKS");
            //用CA为服务器提供证书,若想连接服务器则将他添加到密钥库中
            String storeName = "F:" + File.separator + "git-root" + File.separator +  "rabbitstore";
            tks.load(new FileInputStream(storeName), trustPassphrase);
            TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
            tmf.init(tks);
            c = SSLContext.getInstance("TLSv1.1");
            c.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return c;
    }
}

SSLConnection:

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.GetResponse;
import com.rayootech.rabbitmq.demo.inaction.utils.RabbitMQUtils;

import javax.net.ssl.SSLContext;

public class SSLConnection {
    public static void main(String[] args) throws Exception {
        SSLContext c = RabbitMQUtils.getSSLContext();
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.111.128");
        factory.setPort(5671);
        factory.setUsername("admin");
        factory.setPassword("admin");
        //使用SSL连接服务器
        factory.useSslProtocol(c);

        Connection conn = factory.newConnection();
        Channel channel = conn.createChannel();

        channel.queueDeclare("rabbitmq-java-test", false, true, true, null);
        channel.basicPublish("", "rabbitmq-java-test", null, "Hello, World".getBytes());
        GetResponse chResponse = channel.basicGet("rabbitmq-java-test", false);
        if (chResponse == null) {
            System.out.println("No message retrieved");
        } else {
            byte[] body = chResponse.getBody();
            System.out.println("Recieved: " + new String(body));
        }

        channel.close();
        conn.close();
    }
}




© 著作权归作者所有

共有 人打赏支持
你我他有个梦

你我他有个梦

粉丝 92
博文 110
码字总数 98858
作品 0
昌平
程序员
RabbitMQ 内存控制 硬盘控制

一、内存控制: vmmemoryhigh_watermark 该值为内存阈值,默认为0.4。意思为物理内存的40%。40%的内存并不是内存的最大的限制,它是一个发布的节制,当达到40%时Erlang会做GC。最坏的情况是使...

andrewniu ⋅ 05/10 ⋅ 0

消息中间件—RabbitMQ(集群原理与搭建篇)

摘要:实际生产应用中都会采用消息队列的集群方案,如果选择RabbitMQ那么有必要了解下它的集群方案原理 一般来说,如果只是为了学习RabbitMQ或者验证业务工程的正确性那么在本地环境或者测试...

癫狂侠 ⋅ 05/25 ⋅ 0

RabbitMQ 远程 IP 访问 解决办法 -摘自网络

刚刚安装的RabbitMQ-Server-3.3.5,并且也已经开启了Web管理功能,但是现在存在一个问题: 出于安全的考虑,guest这个默认的用户只能通过http://localhost:15672 来登录,不能使用IP地址登录...

andrewniu ⋅ 05/10 ⋅ 0

消息中间件—RabbitMQ(集群监控篇1)

摘要:任何没有监控的系统上线,一旦在生产环境发生故障,那么排查和修复问题的及时性将无法得到保证 一、为何要对消息中间件进行监控? 上线的业务系统需要监控,然而诸如消息队列、数据库、...

癫狂侠 ⋅ 05/28 ⋅ 0

消息中间件—RabbitMQ(初探篇)

文章摘要:本篇文章为RabbitMQ的入门文章,不像其他一些程序代码和应用实战性的文章会带着大家从一个“Hello World”的简单例子出发,在该篇幅中主要给大家讲下RabbitMQ消息队列的起源、为何...

癫狂侠 ⋅ 05/23 ⋅ 0

RabbitMQ 3.7.5-beta.3 发布,带来多处 bug 修复

RabbitMQ 3.7.5-beta.3 发布,此版本是维护版本的预览版,主要带来了多处 bug 修复,涉及模块包括: Core Server CLI Tools Management Plugin LDAP Plugin Shovel Plugin Peer Discovery A...

雨田桑 ⋅ 04/30 ⋅ 0

RabbitMQ 3.7.5-rc.1 发布,bug 修复版本

RabbitMQ 3.7.5-rc.1 发布,此版本是维护版本的候选版本,主要是对一些 bug 进行了修复。 更新涉及模块包括: Core Server CLI Tools Management Plugin Federation Plugin LDAP Plugin Shov...

雨田桑 ⋅ 05/04 ⋅ 0

ActiveMQ RabbitMQ KafKa对比

前言: ActiveMQ和 RabbitMq 以及Kafka在之前的项目中都有陆续使用过,当然对于三者没有进行过具体的对比,以下摘抄了一些网上关于这三者的对比情况,我自己看过之后感觉还 是可以的,比较清...

xiaomin0322 ⋅ 05/11 ⋅ 0

RabbitMQ-理解消息通信-虚拟主机和隔离

每个RabbitMQ服务器都能创建虚拟的消息服务器,我们称之为虚拟主机(vhost)每一个vhost本质上是一个mini版的RabbitMQ服务器,拥有自己的队列、交换器和绑定等等 更重要的是,他拥有自己的权限...

yzy121403725 ⋅ 05/21 ⋅ 0

RabbitMQ学习系列(六): RabbitMQ 高可用集群

前面讲过一些RabbitMQ的安装和用法,也说了说RabbitMQ在一般的业务场景下如何使用。不知道的可以看我前面的博客,http://www.cnblogs.com/zhangweizhong/category/855479.html 本来一直想写一...

andrewniu ⋅ 05/09 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Kubeflow实战系列:利用TFJob导出分布式TensorFlow模型

介绍 本系列将介绍如何在阿里云容器服务上运行Kubeflow, 本文介绍如何使用TfJob导出分布式模型训练模型。 第一篇:阿里云上使用JupyterHub 第二篇:阿里云上小试TFJob 第三篇:利用TFJob运行...

全部原谅 ⋅ 23分钟前 ⋅ 0

007. 深入JVM学习—老年代

老年代空间的主要目的是用于存储由Eden发送来的对象,一般在经历好几次“Minor GC”还会保存下来的对象,才会被复制到老年代,这样就可以存放更多的对象,同时在老年代中执行GC的次数也相对较...

影狼 ⋅ 24分钟前 ⋅ 0

常见的一些C#开源框架或者开源项目

原:https://blog.csdn.net/qq_27825451/article/details/70666044 Json.NET http://json.codeplex.com/ Json.Net 是一个读写Json效率比较高的.Net框架.Json.Net 使得在.Net环境下使用Json更......

whoisliang ⋅ 25分钟前 ⋅ 0

设计模式基本原理

刚开始接触编程这行的时候看过设计模式,当时感觉学这些模式没有太大的用处,当时也看不太懂。但是随着慢慢接触这一行,经过一段时间的编程以后,再回过头来看设计模式,发现设计模式的确是太...

王子城 ⋅ 28分钟前 ⋅ 0

阿里云全面支持IPv6!一文揽尽4位大咖精彩演讲

摘要: 自从去年11月以来,阿里巴巴高度重视数据中心的网络改造、云产品改造、应用及网络改造等多个维度,经过半年以来的建设,阿里云已经完成了域名解析等关键产品的分析,现在阿里云已经完...

传授知识的天使 ⋅ 39分钟前 ⋅ 0

windows Android sdk 配置

1、下载Android SDK,点击安装,直接默认路径即可! 下载地址:http://developer.android.com/sdk/index.html 2、默认路径安装后,安装完成,开始配置环境变量。 3、打开计算机属性——高级系...

阿豪boy ⋅ 42分钟前 ⋅ 0

bash shell script 简明教程

User <--> bash <--> kernel shell is not kernel or part of kernel various shells: tcsh, csh, bash, ksh find the using shell: echo $SHELL find all the shells: cat /etc/shells what......

mskk ⋅ 44分钟前 ⋅ 0

Service Mesh简史

William Morgan Service Mesh是一个相当新的概念,讲它的“历史”似乎有些勉强。就目前而言,Service Mesh已经在部分企业生产环境中运行了超过18个月,它的源头可以追溯到2010年前后互联网公...

好雨云帮 ⋅ 44分钟前 ⋅ 0

10个免费的服务器监控工具

监控你的WEB服务器或者WEB主机运行是否正常与健康是非常重要的。你要确保用户始终可以打开你的网站并且网速不慢。服务器监控工具允许你收集和分析有关你的Web服务器的数据。 有许多非常好的服...

李朝强 ⋅ 57分钟前 ⋅ 0

压缩工具之zip-tar

zip 支持目录压缩。使用yum安装zip包,使用yum安装unzip包 zip 1.txt.zip 1.txt #将1.txt文件压缩,新生成的压缩文件为1.txt.zip,原文件保留 zip -r 123.zip 123/ #-r对目录操作。将123/目录...

ZHENG-JY ⋅ 57分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部