精华内容
下载资源
问答
  • 深入理解TCP握手过程中建连接的流程和队列 如果TCP连接队列溢出,有哪些指标可以看呢? 实践验证下上面的理解 容器中的Accept队列参数 进一步思考 过程中发现的一个奇怪问题 那么全连接队列满了会影响半连接...

    目录

    问题描述

    分析问题

    深入理解TCP握手过程中建连接的流程和队列

    如果TCP连接队列溢出,有哪些指标可以看呢?

    实践验证下上面的理解

    容器中的Accept队列参数

    进一步思考

    过程中发现的一个奇怪问题

    那么全连接队列满了会影响半连接队列吗?

    总结


    最近碰到一个client端连接异常问题,然后定位分析并查阅各种资料文章,对TCP连接队列有个深入的理解

    查资料过程中发现没有文章把这两个队列以及怎么观察他们的指标说清楚,希望通过这篇文章能把他们说清楚一点

    问题描述

    JAVA的client和server,使用socket通信。server使用NIO。
    1.间歇性的出现client向server建立连接三次握手已经完成,但server的selector没有响应到这连接。
    2.出问题的时间点,会同时有很多连接出现这个问题。
    3.selector没有销毁重建,一直用的都是一个。
    4.程序刚启动的时候必会出现一些,之后会间歇性出现。
    

    分析问题

    正常TCP建连接三次握手过程:

    image.pngimage.png

    • 第一步:client 发送 syn 到server 发起握手;
    • 第二步:server 收到 syn后回复syn+ack给client;
    • 第三步:client 收到syn+ack后,回复server一个ack表示收到了server的syn+ack(此时client的56911端口的连接已经是established)

    从问题的描述来看,有点像TCP建连接的时候全连接队列(accept队列)满了,尤其是症状2、4. 为了证明是这个原因,马上通过 ss -s 去看队列的溢出统计数据:

    667399 times the listen queue of a socket overflowed
    

    反复看了几次之后发现这个overflowed 一直在增加,那么可以明确的是server上全连接队列一定溢出了

    接着查看溢出后,OS怎么处理:

    # cat /proc/sys/net/ipv4/tcp_abort_on_overflow
    0
    

    tcp_abort_on_overflow 为0表示如果三次握手第三步的时候全连接队列满了那么server扔掉client 发过来的ack(在server端认为连接还没建立起来)

    为了证明客户端应用代码的异常跟全连接队列满有关系,我先把tcp_abort_on_overflow修改成 1,1表示第三步的时候如果全连接队列满了,server发送一个reset包给client,表示废掉这个握手过程和这个连接(本来在server端这个连接就还没建立起来)。

    接着测试然后在客户端异常中可以看到很多connection reset by peer的错误,到此证明客户端错误是这个原因导致的。

    于是开发同学翻看java 源代码发现socket 默认的backlog(这个值控制全连接队列的大小,后面再详述)是50,于是改大重新跑,经过12个小时以上的压测,这个错误一次都没出现过,同时 overflowed 也不再增加了。

    到此问题解决,简单来说TCP三次握手后有个accept队列,进到这个队列才能从Listen变成accept,默认backlog 值是50,很容易就满了。满了之后握手第三步的时候server就忽略了client发过来的ack包(隔一段时间server重发握手第二步的syn+ack包给client),如果这个连接一直排不上队就异常了。

    深入理解TCP握手过程中建连接的流程和队列


    (图片来源:http://www.cnxct.com/something-about-phpfpm-s-backlog/)

    如上图所示,这里有两个队列:syns queue(半连接队列);accept queue(全连接队列)

    三次握手中,在第一步server收到client的syn后,把相关信息放到半连接队列中,同时回复syn+ack给client(第二步);

    比如syn floods 攻击就是针对半连接队列的,攻击方不停地建连接,但是建连接的时候只做第一步,第二步中攻击方收到server的syn+ack后故意扔掉什么也不做,导致server上这个队列满其它正常请求无法进来
    

    第三步的时候server收到client的ack,如果这时全连接队列没满,那么从半连接队列拿出相关信息放入到全连接队列中,否则按tcp_abort_on_overflow指示的执行。

    这时如果全连接队列满了并且tcp_abort_on_overflow是0的话,server过一段时间再次发送syn+ack给client(也就是重新走握手的第二步),如果client超时等待比较短,就很容易异常了。

    在我们的os中retry 第二步的默认次数是2(centos默认是5次):

    net.ipv4.tcp_synack_retries = 2
    

    如果TCP连接队列溢出,有哪些指标可以看呢?

    上述解决过程有点绕,那么下次再出现类似问题有什么更快更明确的手段来确认这个问题呢?

    netstat -s

    [root@server ~]#  netstat -s | egrep "listen|LISTEN" 
    667399 times the listen queue of a socket overflowed
    667399 SYNs to LISTEN sockets ignored
    

    比如上面看到的 667399 times ,表示全连接队列溢出的次数,隔几秒钟执行下,如果这个数字一直在增加的话肯定全连接队列偶尔满了。

    ss 命令

    [root@server ~]# ss -lnt
    Recv-Q Send-Q Local Address:Port  Peer Address:Port 
    0        50               *:3306             *:* 
    

    上面看到的第二列Send-Q 表示第三列的listen端口上的全连接队列最大为50,第一列Recv-Q为全连接队列当前使用了多少

    全连接队列的大小取决于:min(backlog, somaxconn) . backlog是在socket创建的时候传入的,somaxconn是一个os级别的系统参数

    半连接队列的大小取决于:max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog)。 不同版本的os会有些差异

    实践验证下上面的理解

    把java中backlog改成10(越小越容易溢出),继续跑压力,这个时候client又开始报异常了,然后在server上通过 ss 命令观察到:

    Fri May  5 13:50:23 CST 2017
    Recv-Q Send-QLocal Address:Port  Peer Address:Port
    11         10         *:3306               *:*
    

    按照前面的理解,这个时候我们能看到3306这个端口上的服务全连接队列最大是10,但是现在有11个在队列中和等待进队列的,肯定有一个连接进不去队列要overflow掉

    容器中的Accept队列参数

    Tomcat默认短连接,backlog(Tomcat里面的术语是Accept count)Ali-tomcat默认是200, Apache Tomcat默认100.

    #ss -lnt
    Recv-Q Send-Q   Local Address:Port Peer Address:Port
    0       100                 *:8080            *:*
    

    Nginx默认是511

    $sudo ss -lnt
    State  Recv-Q Send-Q Local Address:PortPeer Address:Port
    LISTEN    0     511              *:8085           *:*
    LISTEN    0     511              *:8085           *:*
    

    因为Nginx是多进程模式,也就是多个进程都监听同一个端口以尽量避免上下文切换来提升性能

    进一步思考

    如果client走完第三步在client看来连接已经建立好了,但是server上的对应连接实际没有准备好,这个时候如果client发数据给server,server会怎么处理呢?(有同学说会reset,还是实践看看)

    先来看一个例子:

    image.pngimage.png
    (图片来自:http://blog.chinaunix.net/uid-20662820-id-4154399.html)

    如上图,150166号包是三次握手中的第三步client发送ack给server,然后150167号包中client发送了一个长度为816的包给server,因为在这个时候client认为连接建立成功,但是server上这个连接实际没有ready,所以server没有回复,一段时间后client认为丢包了然后重传这816个字节的包,一直到超时,client主动发fin包断开该连接。

    这个问题也叫client fooling,可以看这里:https://github.com/torvalds/linux/commit/5ea8ea2cb7f1d0db15762c9b0bb9e7330425a071 (感谢浅奕的提示)

    从上面的实际抓包来看不是reset,而是server忽略这些包,然后client重传,一定次数后client认为异常,然后断开连接。

    过程中发现的一个奇怪问题

    [root@server ~]# date; netstat -s | egrep "listen|LISTEN" 
    Fri May  5 15:39:58 CST 2017
    1641685 times the listen queue of a socket overflowed
    1641685 SYNs to LISTEN sockets ignored
    
    [root@server ~]# date; netstat -s | egrep "listen|LISTEN" 
    Fri May  5 15:39:59 CST 2017
    1641906 times the listen queue of a socket overflowed
    1641906 SYNs to LISTEN sockets ignored
    

    如上所示:
    overflowed和ignored居然总是一样多,并且都是同步增加,overflowed表示全连接队列溢出次数,socket ignored表示半连接队列溢出次数,没这么巧吧。

    翻看内核源代码(http://elixir.free-electrons.com/linux/v3.18/source/net/ipv4/tcp_ipv4.c):

    image.pngimage.png

    可以看到overflow的时候一定会drop++(socket ignored),也就是drop一定大于等于overflow。

    同时我也查看了另外几台server的这两个值来证明drop一定大于等于overflow:

    server1
    150 SYNs to LISTEN sockets dropped
    
    server2
    193 SYNs to LISTEN sockets dropped
    
    server3
    16329 times the listen queue of a socket overflowed
    16422 SYNs to LISTEN sockets dropped
    
    server4
    20 times the listen queue of a socket overflowed
    51 SYNs to LISTEN sockets dropped
    
    server5
    984932 times the listen queue of a socket overflowed
    988003 SYNs to LISTEN sockets dropped
    

    那么全连接队列满了会影响半连接队列吗?

    来看三次握手第一步的源代码(http://elixir.free-electrons.com/linux/v2.6.33/source/net/ipv4/tcp_ipv4.c#L1249):

    image.pngimage.png

    TCP三次握手第一步的时候如果全连接队列满了会影响第一步drop 半连接的发生。大概流程的如下:

    tcp_v4_do_rcv->tcp_rcv_state_process->tcp_v4_conn_request
    //如果accept backlog队列已满,且未超时的request socket的数量大于1,则丢弃当前请求  
      if(sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_yong(sk)>1)
          goto drop;
    

    总结

    全连接队列、半连接队列溢出这种问题很容易被忽视,但是又很关键,特别是对于一些短连接应用(比如Nginx、PHP,当然他们也是支持长连接的)更容易爆发。 一旦溢出,从cpu、线程状态看起来都比较正常,但是压力上不去,在client看来rt也比较高(rt=网络+排队+真正服务时间),但是从server日志记录的真正服务时间来看rt又很短。

    希望通过本文能够帮大家理解TCP连接过程中的半连接队列和全连接队列的概念、原理和作用,更关键的是有哪些指标可以明确看到这些问题。

    另外每个具体问题都是最好学习的机会,光看书理解肯定是不够深刻的,请珍惜每个具体问题,碰到后能够把来龙去脉弄清楚。


    参考文章:

    http://veithen.github.io/2014/01/01/how-tcp-backlog-works-in-linux.html

    http://www.cnblogs.com/zengkefu/p/5606696.html

    http://www.cnxct.com/something-about-phpfpm-s-backlog/

    http://jaseywang.me/2014/07/20/tcp-queue-%E7%9A%84%E4%B8%80%E4%BA%9B%E9%97%AE%E9%A2%98/

    http://jin-yang.github.io/blog/network-synack-queue.html#

    http://blog.chinaunix.net/uid-20662820-id-4154399.html

    https://www.atatech.org/articles/12919

    展开全文
  • 某个项目中,根据上传EXCEL文件,读取其中的数据并生成订单(分为总订单子订单),如商品编码,收货人等信息,进行各种条件验证,并返回验证结果。用户根据返回的结果选择支付方式进行付款操作。 Excel 中最多有...

    本文只做为php微服务案例,其他更多功能请自行添加。

    项目介绍

    某个项目中,根据上传EXCEL文件,读取其中的数据并生成订单(分为总订单和子订单),如商品编码,收货人等信息,进行各种条件验证,并返回验证结果。用户根据返回的结果选择支付方式进行付款操作。

    • Excel 中最多有10000行,多用户同时上传
    • 国外用户访问国内服务器
    • 创建订单时并减少库存
    • 发送待付款邮件
    • 待付款邮件中有当前总订单下所有子订单信息的PDF文件
    • 等等更多

    了解这么多需求后,那么就可以设计一个基本需要的架构了。
    微服务这是肯定需要了->swoole,服务发现和注册呢->consul,一次性处理那么多数据不现实,必然要拆分处理,处理一部分,返回一部分结果,那么这个需要用到数据持久化,消息队列可以解决这个问题->rabbitmq,在验证的过程中数据查询频繁可以用elasticsearch,日志收集分析等可以用elasticsearch全家桶(elasticsearch logstash kibana) 。。。。。。。

    近期做了 docker 版案例,给大家提供一个思路吧

    风.fox

    消息队列 RabbitMQ

    消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,由消息系统来确保消息的可靠传递。消息发布者只管把消息发布到 MQ 中而不用管谁来取,消息使用者只管从 MQ 中取消息而不管是谁发布的。这样发布者和使用者都不用知道对方的存在。
    更多请看
    https://www.jianshu.com/p/79ca08116d57
    https://blog.csdn.net/whoamiyang/article/details/54954780

    服务管理(服务发现,注册,健康检查) consul

    consul 是一个服务管理软件。
    - 支持多数据中心下,分布式高可用的,服务发现和配置共享。
    - consul支持健康检查,允许存储键值对。
    - 一致性协议采用 Raft 算法,用来保证服务的高可用.
    - 成员管理和消息广播 采用GOSSIP协议,支持ACL访问控制。
    ACL技术在路由器中被广泛采用,它是一种基于包过滤的流控制技术。控制列表通过把源地址、目的地址及端口号作为数据包检查的基本元素,并可以规定符合条件的数据包是否允许通过。
    gossip就是p2p协议。他主要要做的事情是,去中心化。
    这个协议就是模拟人类中传播谣言的行为而来。首先要传播谣言就要有种子节点。种子节点每秒都会随机向其他节点发送自己所拥有的节点列表,以及需要传播的消息。任何新加入的节点,就在这种传播方式下很快地被全网所知道。
    更多请看
    https://blog.csdn.net/viewcode/article/details/45915179
    https://www.jianshu.com/p/28c6bd590ca0

    swoole-php异步网络通信引擎

    Swoole:面向生产环境的 PHP 异步网络通信引擎
    使 PHP 开发人员可以编写高性能的异步并发 TCP、UDP、Unix Socket、HTTP,WebSocket 服务。Swoole 可以广泛应用于互联网、移动通信、企业软件、云计算、网络游戏、物联网(IOT)、车联网、智能家居等领域。 使用 PHP + Swoole 作为网络通信框架,可以使企业 IT 研发团队的效率大大提升,更加专注于开发创新产品。
    更多请看
    https://www.swoole.com/
    https://wiki.swoole.com/



    下载docker 环境

    https://github.com/foxiswho/docker-nginx-php-swoole-rabbitmq-consul

    git clone https://github.com/foxiswho/docker-nginx-php-swoole-rabbitmq-consul.git

    下载案例文件

    进入上面下载的目录wwwroot

    cd wwwroot

    然后下载 案例文件

    git clone https://github.com/foxiswho/php-swoole-rabbitmq-consul-demo.git "dpsrc"

    启动docker compose

    到根目录(有docker-compose.yml的那个目录),然后执行

    docker-compose up 

    如果你需要关闭或者删除docker-compose up建立的所有容器,请在docker-compose.yml的目录下,执行如下命令

    docker-compose down 

    启动成功后

    docker compose 启动成功后,先在浏览器访问http://localhost/demo/service_demo_mq_client/index,有程序自动创建消息队列的交换机,队列,路由KEY等。
    然后再启动如下2个DOCKER:

    docker-nginx-php-swoole-rabbitmq-consul_phpmqsub_1
    docker-nginx-php-swoole-rabbitmq-consul_phpmqsub002_1

    为什么要其中这2个docker呢,因为在docker compose创建时,消息队列里面全部是空的,没有建立测试里面的测试用的交换机,队列,路由KEY。执行一次后,就会自动创建这些

    直接访问浏览器网址 即可
    http://localhost/demo/service_demo_client/index

    http://localhost/demo/service_demo_mq_client/index

    其他

    注册中心访问

    浏览器打开

    http://localhost:8500/ui/

    消息队列web 管理

    http://localhost:15672/

    默认用户及密码
    guest
    guest

    说明

    访问php微服务返回数据

    在浏览器中打开如下网址

    http://localhost/demo/service_demo_client/index

    此处是到服务注册中心去获取php-demo微服务信息,会返回该微服务的ip端口等信息, swoole_client 根据返回的ip端口去访问微服务,微服务php-demo处理后返回数据,此处就是显示处理后的数据

    源码如下

    <?php
    
    namespace app\demo\controller;
    
    use app\module\consul;
    
    //本demo处理 app\service\controller\Demo
    class ServiceDemoClient
    {
        /**
         * 获取指定服务,发送数据,服务端处理数据,并返回数据
         */
        public function index()
        {
            //获取指定服务
            $services = consul::getServicesOne('php-demo');
            if (isset($services) && $services) {
                trace($services);
                //                $ser->ID;
                //                $ser->Address;
                //                $ser->Service;
                //                $ser->Port;
                $client = new \swoole_client(SWOOLE_SOCK_TCP);
                //连接到服务器
                if (!$client->connect($services->Address, $services->Port, 0.5)) {
                    throw new \Exception("swoole_client connect failed.");
                }
                //向服务器发送数据
                if (!$client->send("hello world")) {
                    throw new \Exception("swoole_client send failed.");
                }
                //从服务器接收数据
                $data = $client->recv();
                if (!$data) {
                    throw new \Exception("swoole_client recv failed.");
                }
                echo $data;
                //关闭连接
                $client->close();
            } else {
                throw new \Exception("Consul service not find.");
            }
        }
    
        /**
         * 获取指定服务
         */
        public function getService()
        {
            ......
        }
    }

    php微服务

    代码位置

    app\service\controller\Demo.php

    启动该微服务,与app目录同级目录下执行

    php public/index.php service/demo/start

    源码

    //默认action start
    class Demo extends Server
    {
        // 监听所有地址
        protected $host = '0.0.0.0';
        // 监听 9501 端口
        protected $port = 9501;
        // 指定运行模式为多进程
        protected $mode = SWOOLE_PROCESS;
        // 指定 socket 的类型为 ipv4 的 tcp socket
        protected $sockType = SWOOLE_SOCK_TCP;
        // 配置项
        protected $option = [
            /**
             *  设置启动的worker进程数
             *  业务代码是全异步非阻塞的,这里设置为CPU的1-4倍最合理
             *  业务代码为同步阻塞,需要根据请求响应时间和系统负载来调整
             */
            'worker_num' => 1,
            // 守护进程化
            'daemonize'  => false,
            // 监听队列的长度
            'backlog'    => 128
        ];
    
        /**
         * 收到信息时回调函数
         * @param \swoole_server $server swoole_server对象
         * @param $fd TCP客户端连接的文件描述符
         * @param $from_id TCP连接所在的Reactor线程ID
         * @param $data 收到的数据内容
         */
        public function onReceive(\swoole_server $server, $fd, $from_id, $data)
        {
            //返回数据
            $server->send($fd, 'onReceive: ' . $data);
        }
    }

    消息队列

    都是大同小异,
    略,请自行看案例
    空了时候再添加更多案例说明

    展开全文
  • 暴力分就不说了,直接无脑枚举头尾,讲一下...= R,观察发现我们将a[i]全部减去x,重新求sum数组,就等同于求取满足sum[r] - sum[l] >= 0并且L <= r - l <= R的rl,我们枚举右端点r,那么可行的l为(r - .

    **Description**给一个长度为n的数组A,给定L;R,求所有满足长度大等于L,小等于R的A数组的子区间的平均值的最大值
    暴力分就不说了,直接无脑枚举头和尾,讲一下正解。

    首先这种求最值问题不难想到二分,然后观察数据需要O(n)的验证。思考如何暴力验证,定义个前缀和数组sum[],那么我们就是要找到满足sum[r] - sum[l] >= x * (r - l) 并且L <= r - l <= R,观察发现我们将a[i]全部减去x,重新求sum数组,就等同于求取满足sum[r] - sum[l] >= 0并且L <= r - l <= R的r和l,我们枚举右端点r,那么可行的l为(r - R ~ r - L),我们只需要判断这个区间中的sum的最小值是否比sum[r]小即可,那么我们相当于要求一段长度固定的区间中的最小值,并且需要移动区间加入下一个位置或者去掉上一个位置,这个不就是标准的单调队列了吗,直接扫一遍就可以判断了,所以算法就是二分枚举x,利用单调队列判断是否可行,复杂度为O(nlogn)

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    int n,l,r,a[N],ll,rr,q[N];
    double L,R,mid,sum[N];
    bool check(double x)
    {
    	memset(sum,0,sizeof(sum));
    	memset(q,0,sizeof(q));
    	for(int i=1;i<=n;i++) sum[i]=a[i]*1.0-x+sum[i-1];
    	ll=1,rr=0;
    	for(int i=l;i<=n;i++)
    	{
    		while(ll<=rr&&sum[i-l]<=sum[q[rr]]) rr--;
    		q[++rr]=i-l;
    		while(ll<=rr&&q[ll]+r<i) ll++;
    		if(sum[i]-sum[q[ll]]>=0) return true;
    	}
    	return false;
    } 
    int main()
    {
    	scanf("%d%d%d",&n,&l,&r);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    	L=0,R=1e6;
    	for(int i=1;i<=100;i++)
    	{
    		mid=(L+R)/2;
    		if(check(mid)) L=mid;
    		else R=mid;
    	}
    	cout<<fixed<<setprecision(4)<<mid<<endl;
    }
    
    展开全文
  • 验证码识别研究能及时发现验证码的安全漏洞,使其变得更加安全. 扭曲粘连字符验证码能抵抗字符分 割,是验证码识别中的难点.针对由扭曲粘连字符构成的验证码,提出一种基于密集尺度不变特征变换( DENSE SIFT) ...
  • 在此前的实验中发现一个现象,感觉有些奇怪,所以设立此实验进行验证,现象是:用程序建 Q 之后后再建镜像策略,Q master 在原来的节点上,而策略所指定的节点成为从节点。但是在控制台上建的 Q 在策略生效后 Q ...

    目的

    在此前的实验中发现一个现象,感觉有些奇怪,所以设立此实验进行验证,现象是:用程序建 Q 之后后再建镜像策略,Q master 在原来的节点上,而策略所指定的节点成为从节点。但是在控制台上建的 Q 在策略生效后 Q master 会自动跳到镜像内的节点上。

    在多次实验后发现,主队列是否会依照策略所指定的节点变化,不取决于 队列 与 策略 创建的顺序,也不取决于队列是由控制台创建的还是由程序创建的。发生上述现象的原因是:代码在创建队列后随即就向队列里面写入消息。之后建立策略,Rabbit MQ 会遵循策略,但是由于原来的队列里面已经有消息了,这些消息并未同步到实施策略后的镜像上,所以原来的队列并未删除,主队列也没有迁移至策略所指定的节点。Rabbit MQ 不默认采用同步的方式是因为:同步的方式会导致在同步期间系统对外是无响应的,这会降低系统的可用性,而不同步的时间通常会非常短暂,因为随着消息被消费,未同步的消息很快就消失了。两者相权,前者弊多利少,所以就采用非同步的方法。此时开启消费端程序,将未同步的消息消费掉,再看队列状态就已经完全符合策略要求了。

    因此,本实验用于演示以上论述。

    环境

    实验室环境的 3 台 Rabbit MQ 服务器,已经配置好集群。

    过程

    1. 查看集群时候正常运行
    $rabbitmqctl cluster_status
    
    Cluster status of node 'rabbit@TK-RABBITMQ1' ...
    [{nodes,[{disc,['rabbit@TK-RABBITMQ1','rabbit@TK-RABBITMQ2',
                    'rabbit@TK-RABBITMQ3']}]},
     {running_nodes,['rabbit@TK-RABBITMQ2','rabbit@TK-RABBITMQ3',
                     'rabbit@TK-RABBITMQ1']},
     {cluster_name,<<"rabbit@TK-RABBITMQ1">>},
     {partitions,[]},
     {alarms,[{'rabbit@TK-RABBITMQ2',[]},
              {'rabbit@TK-RABBITMQ3',[]},
              {'rabbit@TK-RABBITMQ1',[]}]}]
    
    
    
    

    2 清空所有的消息和策略 3 新建消息

    使用控制台新建name为test.64_1 Node为rabbit@TK-RABBITMQ1的队列

    使用控制台新建name为test.65_1 Node为rabbit@TK-RABBITMQ2的队列

    使用控制台新建name为test.66_1 Node为rabbit@TK-RABBITMQ3的队列

    使用客户端代码新建name为test.64_111 Node为rabbit@TK-RABBITMQ1的队列

    使用客户端代码新建name为test.65_111 Node为rabbit@TK-RABBITMQ2的队列

    使用客户端代码新建name为test.66_111 Node为rabbit@TK-RABBITMQ3的队列

    注意:控制台和客户端新建队列区别是 客户端新建的队列有消息内容

    4 查看队列信息

    rabbitmqctl list_queues name policy pid slave_pids
    呈现代码宏出错: 参数'firstline'的值无效
    test.64_1		<rabbit@TK-RABBITMQ1.3.18018.20>	
    test.66_111		<rabbit@TK-RABBITMQ3.2.13477.170>	
    test.65_111		<rabbit@TK-RABBITMQ2.2.29265.20>	
    test.65_1		<rabbit@TK-RABBITMQ2.2.27457.20>	
    test.66_1		<rabbit@TK-RABBITMQ3.2.11610.170>	
    test.64_111		<rabbit@TK-RABBITMQ1.3.19994.20>

    5 新建建立一个名为 test_policy 的策略,内容为:名称为 “test.” 开头的队列,镜像到集群里面的 TK-RABBITMQ2 和 TK-RABBITMQ3 节点。

    rabbitmqctl set_policy test_policy "^test\."  '{"ha-mode":"nodes","ha-params":["rabbit@TK-RABBITMQ2","rabbit@TK-RABBITMQ3"]}'
    Setting policy "test_policy" for pattern "^test\\." to "{\"ha-mode\":\"nodes\",\"ha-params\":[\"rabbit@TK-RABBITMQ2\",\"rabbit@TK-RABBITMQ3\"]}" with priority "0" ...
    

    6 再次查看队列信息

    rabbitmqctl list_queues name policy pid slave_pids
    test.64_1   test_policy <rabbit@TK-RABBITMQ2.2.2879.21>   [<rabbit@TK-RABBITMQ3.2.19827.170>]
    test.66_111 test_policy <rabbit@TK-RABBITMQ3.2.13477.170> [<rabbit@TK-RABBITMQ2.2.2861.21>]
    test.65_111 test_policy <rabbit@TK-RABBITMQ2.2.29265.20>  [<rabbit@TK-RABBITMQ3.2.19847.170>]
    test.65_1   test_policy <rabbit@TK-RABBITMQ2.2.27457.20>  [<rabbit@TK-RABBITMQ3.2.19840.170>]
    test.66_1   test_policy <rabbit@TK-RABBITMQ3.2.11610.170> [<rabbit@TK-RABBITMQ2.2.2858.21>]
    test.64_111 test_policy <rabbit@TK-RABBITMQ1.3.19994.20>  [<rabbit@TK-RABBITMQ2.2.2873.21>, <rabbit@TK-RABBITMQ3.2.19842.170>]

    此时发现队列名为 test.64_1 的 Node 改变为 rabbit@TK-RABBITMQ2 ,也就是没有消息内容的队列的 Node 变成有镜像的 Node。

    7 把队列名为 test.64_111 的队列里面的消息消费完毕

    8 再次查看队列信息

    rabbitmqctl list_queues name policy pid slave_pids
    test.64_1   test_policy <rabbit@TK-RABBITMQ2.2.2879.21>   [<rabbit@TK-RABBITMQ3.2.19827.170>]
    test.66_111 test_policy <rabbit@TK-RABBITMQ3.2.13477.170> [<rabbit@TK-RABBITMQ2.2.2861.21>]
    test.65_111 test_policy <rabbit@TK-RABBITMQ2.2.29265.20>  [<rabbit@TK-RABBITMQ3.2.19847.170>]
    test.65_1   test_policy <rabbit@TK-RABBITMQ2.2.27457.20>  [<rabbit@TK-RABBITMQ3.2.19840.170>]
    test.66_1   test_policy <rabbit@TK-RABBITMQ3.2.11610.170> [<rabbit@TK-RABBITMQ2.2.2858.21>]
    test.64_111 test_policy <rabbit@TK-RABBITMQ2.2.2873.21>   [<rabbit@TK-RABBITMQ3.2.19842.170>]

    此时发现队列名为 test.64_111 的 Node 变成 rabbit@TK-RABBITMQ2,也就是没有消息内容的队列的 Node 变成有镜像的 Node。

    结论

    本来想通过实验发现 程序 和 控制台 创建队列的区别,多次实验后发现并无不同,但是意外的验证了队列主从同步的细节。

     

    更多实验可点击:Rabbitmq 实验

    转载于:https://my.oschina.net/u/3568300/blog/3005573

    展开全文
  • 大年初一中午在群里同学们抢红包。...输入红包的大小个数,应该是一个类似于循环/递归的模式,放出一个模型,利用栈/队列的模型输出。查阅过资料以后给出两个东西:1.大的数据验证:截尾正态...
  • 在用自定义线程池的时候,遇到cpu100%,经过验证后,发现问题来源于我定义的子线程。 子线程的主要功能是从任务队列(LinkedBlockingQueue)里面持续拿出任务,并且执行。 以下为令CPU100的代码。 private class ...
  • C 语言泛型Array数组封装

    千次阅读 2016-07-10 20:45:36
    还利用这些数据结构实现了一个简单的json解析器,已经成为C工具箱的最基础工具,可以验证这些结构的可用性稳定性,以后将逐步介绍。    这个泛型数组分为代码实现宏定义两部分,主要完成以下功能。 可存储...
  • Laravel试图通过减轻大多数Web项目中使用的常见任务(例如身份验证,路由,会话,队列和缓存)来减轻开发的痛苦。 Laravel易于访问,但功能强大,可提供大型,强大的应用程序所需的工具。 出色的控制容器版本,...
  • 特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过。如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/mao2080/ 1、Mosquitto...
  • 论文研究-基于(.pdf

    2019-07-22 19:15:48
    NWR数据库的写延时估计,可用于发现实现集群构建和运行成本最小化的节点数量、副本因子的配置组合。现有基于基准测试或模拟队列...分别在模拟队列和Cassandra集群上验证了(n,r,k)队列解析解和写延时模型的准确性。
  • 之后再在浏览器node下验证。如果答案一致,那么可以关闭当前文档了hhh) 下文中对这段代码会再做分析 <pre><code>js setTimeout(() => console.log('setTimeout1'), 0); setTimeout(...
  • 5.4总结

    2019-05-04 23:30:46
    上周一学习了单调队列,个人感觉还是挺难的。 单调队列队列中元素之间的关系具有单调性,而且,队首和...关于二分法在做题中发现,二分查找类型的题最关键的两个部分就是查找连续函数和验证条件的函数。验证条件函...
  • 目的:本研究旨在通过旋转血栓弹力图(ROTEM)评估泰国高危人群的术前高凝状态,并验证以下假设:冠状动脉搭桥术后1、12、60个月,术前ROTEM状况与MACCE相关手术(CABG)。 方法:这是2013年至2015年间接受泵上CABG...
  • Rabbit 集群指南

    2019-03-19 14:01:48
    本指南涵盖与RabbitMQ群集相关的基本主题: ...群集构建对等发现是一个密切相关的主题,对等发现和群集构建都侧重于自动化相关主题。有关队列内容(消息)复制,请参阅“镜像队列”指南。 A Ra...
  • 传统的 t-sql书籍不同,本书以独特的 “技巧 ”形式来介绍知识点,涵盖了数据处理(增删改、视图、索引、存储过程、触发器等)、数据应用(web服务、 clr集成、分布式查询等)数据库配置(主体、安全、数据库...
  • 75. sigverif-------文件签名验证程序 76. ciadv.msc------索引服务程序 77. shrpubw--------创建共享文件夹 78. secpol.msc-----本地安全策略 79. syskey---------系统加密,一旦加密就不能解开,保护windows ...
  • 第06节、并发队列ConcurrentLinkedDeque、BlockingQueue阻塞队列用法 第07节、使用并发阻塞队列实现生产者与消费者 资料+源码.rar 0005-蚂蚁课堂(每特学院)-2期-线程池原理剖析&锁的深度化 第01节、线程池概述 第02...
  • 例子一、疯狂写日志导致 iowait 超过了 90% 1. top命令查询状态  发现CPU0的 wa (iowait)非常之大,属于异常。...超慢的响应时间特长的请求队列长度,进一步验证了 I/O 已经饱和的猜想。 3. pi...
  • 在四个独立的队列中有效地验证了5-lncRNA的特征,并且预后分析结果表明,5-lncRNA的特征与临床预后因素无关,例如BC亚型辅助治疗。 此外,GSEA建议5-lncRNA信号参与BC转移相关的途径。 我们的发现表明,这五个...
  • SystemVerilog queue的初始化以及绿书上面的错误 前言:在《SystemVerilog...放在小环境中验证,我们会发现上述写法并没有报语法错误,但是queue的初始化并没有实现,对于q2q,它的szie任然是0。(上述验证使...
  • GPUSim 的调试

    千次阅读 2016-05-26 12:39:12
    研究者可以通过阅读、修改其源代码来实现自己对GPU硬件或者调度策略的设计改进,从而验证自己的设计对性能的影响。 修改源码可能造成各种错误,尤其是逻辑错误无法在编译时发现,使得动态调试成为必要的研究手段...
  • LMS-轻量级音乐服务器 LMS是一种自托管的音乐流软件:可使用...用户管理带有可选的PAM身份验证后端 Subsonic API,具有以下附加功能: 播放清单 书签 音乐发现 LMS提供了多种方法来帮助您找到喜欢的音乐: 基于标签
  • STL c++ stack与queue容器

    2018-04-12 21:14:24
    之前一直用纯C打代码,繁杂的调用指针、创建结构体来模拟栈和队列,不仅做题速度慢而且正确率也不高,需要频繁的对自己的代码进行验证,通过对于c++的学习知道了两种容器stackqueue,发现之前做过的题目得到很大...
  • SurpriseLabWeb-源码

    2021-02-24 10:15:24
    Laravel试图通过减轻大多数Web项目中使用的常见任务(例如身份验证,路由,会话,队列和缓存)来减轻开发的痛苦。 Laravel易于访问,但功能强大,可提供大型,强大的应用程序所需的强大工具。 出色的控制容器版本...
  • LaraAdmin-源码

    2021-02-21 06:52:57
    Laravel试图通过减轻大多数Web项目中使用的常见任务(例如身份验证,路由,会话,队列和缓存)来减轻开发的痛苦。 Laravel易于访问,但功能强大,可提供大型,强大的应用程序所需的工具。 出色的控制容器版本,...
  • Laravel试图通过减轻大多数Web项目中使用的常见任务(例如身份验证,路由,会话,队列和缓存)来减轻开发的痛苦。 Laravel易于访问,但功能强大,可提供大型,强大的应用程序所需的工具。 出色的控制容器版本,...

空空如也

空空如也

1 2 3 4 5 6
收藏数 106
精华内容 42
关键字:

发现队列和验证队列