版本声明
com.rabbitmq:amqp-client:4.3.0
RabbitMQ
版本声明: 3.6.15
Connection
- 这里的连接其实就表示的是TCP/IP socket连接,一个
Connection
有多个Channel
,意味Connection
会被设计为长连接,并且每个Channel
一定有一个唯一标识,客户端请求和服务端响应都会携带这个标识,以区分是哪个通道。
连接过程分析
- client打开与服务器的TCP/IP连接并发送一个协议头(
protocol header
).这只是client发送的数据,而不是作为方法格式的数据. - server使用其协议版本和其它属性,包括它支持安全机制列表(Start方法)进行响应.
- client选择一种安全机制(Start-Ok).
- server开始认证过程, 它使用SASL的质询-响应模型(challenge-response model). 它向客户端发送一个质询(Secure).
- client向server发送一个认证响应(Secure-Ok). 例如,对于使用"plain"机制,响应会包含登录用户名和密码.
server 重复质询(Secure) 或转到协商,发送一系列参数,如最大帧大小(Tune). - client接受或降低这些参数(Tune-Ok).
- client 正式打开连接并选择一个虚拟主机(Open).
- 服务器确认虚拟主机是一个有效的选择 (Open-Ok).
- 客户端现在使用希望的连接.
- 一个节点(client 或 server) 结束连接(Close).
- 另一个节点对连接结束握手(Close-Ok).
- server 和 client关闭它们的套接字连接.
- 连接流转图
连接过程抓包分析
-
整个连接过程,我们从抓包结果来分析,只关注
AMQP
协议即可
-
第一步客户端发送
Protocol-Hearder
-
服务端响应
Connection.start
-
客户端发送
Connection.Start-Ok
-
服务端发送
Connection.Tune
-
客户端发送
Connection.Tune-Ok
-
客户端发送
Connection.Open
-
服务端发送
Connection.Open-Ok
源码分析
- uml图
- 创建连接时序图
ConnectionFactory
-
创建连接的工厂ConnectionFactory,包含创建连接的一些必备参数。
-
核心方法
newConnection()
public Connection newConnection(ExecutorService executor, AddressResolver addressResolver, String clientProvidedName) throws IOException, TimeoutException { if(this.metricsCollector == null) { //这是一个空的收集,没有任何操作 this.metricsCollector = new NoOpMetricsCollector(); } // make sure we respect the provided thread factory //根据参数创建FrameHandlerFactory,BIO和NIO FrameHandlerFactory fhFactory = createFrameHandlerFactory(); //此executor是用于消费者消费使用的(consumerWorkServiceExecutor) ConnectionParams params = params(executor); // set client-provided via a client property if (clientProvidedName != null) { Map<String, Object> properties = new HashMap<String, Object>(params.getClientProperties()); properties.put("connection_name", clientProvidedName); params.setClientProperties(properties); } //默认自动恢复连接 if (isAutomaticRecoveryEnabled()) { // see com.rabbitmq.client.impl.recovery.RecoveryAwareAMQConnectionFactory#newConnection AutorecoveringConnection conn = new AutorecoveringConnection(params, fhFactory, addressResolver, metricsCollector); conn.init(); return conn; } else { List<Address> addrs = addressResolver.getAddresses(); Exception lastException = null; for (Address addr : addrs) { try { FrameHandler handler = fhFactory.create(addr); AMQConnection conn = createConnection(param