(转)OpenFire源码学习之十:连接管理(上)
Posted wangle100
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(转)OpenFire源码学习之十:连接管理(上)相关的知识,希望对你有一定的参考价值。
转:http://blog.csdn.net/huwenfeng_2011/article/details/43415827
关于连接管理分为上下两部分
连接管理
在大并发环境下,连接资源 需要随着用户并发访问量的增加而增加,所以可伸缩的连接资源就是支持大访问量的关键技术。openfire系统通过增加独立部署的连接管理器程序提高并发的能力,连接管理的前端是一台负载均衡设备,它负责把用户访问分配到指定连接管理器,多台连接管理器在访问服务器。使用连接管理器后,服务器的连接池是提供给连接管理器连 接,而一台连接管理器也提供指定数量的连接给客户端访问,这样通过添加连接管理器,以适应用户访问量。
l 它是啥?
你部署的每个openfire连接管理单元,依靠处理一部分客户端连接,来提高openfire服 务器的容量。它适用于大规模的openfire安装(几千的在线用户)。
l 每个连接管理能够处理多少用户呢?
每个连接管理应该只是能够处理5000的在线用户。对于无绑定的实验性支持正在被提 高,用以更多的提高每个连接管理单元所能处理的连接数量。
l 连接管理可以被用在其他服务器上吗?
当然(理论上)。连接管理协议正在通过开放的XEP处理来提高。我们希望和其他服务 器供应商一起协作,以便全部的XMPPP/Jabber协会支持这个协 议。我们同样期望会 有其他的兼容openfire的连接管理实现。例如,一个用本地代码编写的连接管理可以在 一个特殊的平台上达到一个非常高的容量。
l openfire连接管理用的许可和openfire本身一样吗?
当然,这个模块是是在开源GPL下的dual-licensed,或者是Jive Software同意授权的一 个商业软件许可。
连接配置
Of配置Connection Manager——So easy!
第一步:服务器设置
在服务器设置/连接管理中,将连接管理设置为启动。并设置端口号和密码。如图
第二步:配置manager.xml文件
配置<domain>xxxx</domain>节点,这里面的内容为of服务器域名
配置<password></password>节点,这里密码填写在控制台的密码。
第三步:启动连接管理器
找到connection_manager\bin目录下的cmanager.bat(windows环境)文件点击启动。 如图:
启动完后,在of控制台将出现如图信息:
第四步:测试连接
使用Spark登陆连接管理器,如果配置成功,控制台“客户端回会话”值将变为“1”
Connection
Connection是一个接口代表在服务器上的一个连接。该接口的主要方法:
方法名 |
说明 |
validate |
验证连接,通常这样做是通过发送一个数据包之间的空格字符。 |
init |
初始化会话连接,允许连接类与会话相关信息配置 |
deliver |
发送数据包 |
deliverRawText |
发送文本字节 |
类图:
Connection接口下面有三个实现类:NIOConnection、SocketConnection、VirtualConnection。其中VirtualConnection是个抽象接口,而它又派生两个子类:
ClientSessionConnection、HttpVirtualConnection。
NIOConnection
该类中最为常用的方法是deliver()。
代码清代:
- public void deliver(Packet packet) throws UnauthorizedException {
- if (isClosed()) {
- backupDeliverer.deliver(packet);
- }
- else {
- ByteBuffer buffer = ByteBuffer.allocate(4096);
- buffer.setAutoExpand(true);
- boolean errorDelivering = false;
- try {
- XMLWriter xmlSerializer =
- new XMLWriter(new ByteBufferWriter(buffer, encoder.get()), new
- OutputFormat());
- xmlSerializer.write(packet.getElement());
- xmlSerializer.flush();
- if (flashClient) {
- buffer.put((byte) ‘\0‘);
- }
- buffer.flip();
- iosession.write(buffer);
- }
- catch (Exception e) {
- Log.debug("NIOConnection: Error delivering packet" + "\n" + this.toString(), e);
- errorDelivering = true;
- }
- 。。。。。。。
- }
- }
该方法中用了Mina框架的字节缓冲类ByteBuffer。ByteBuffer是最常用的缓冲区,它提供了读写其他数据类型的方法,且信道的读写方法只接收ByteBuffer。
1.创建ByteBuffer
ByteBufferbuffer = ByteBuffer.allocate(4096);
以上方法将创建一个容量为4096字节的ByteBuffer,如果发现创建的缓冲区容量太小,
唯一的选择就是重新创建一个大小合适的缓冲区。
2.设置自动扩张,of在这里设置了true
buffer.setAutoExpand(true);
3.回绕缓冲区
buffer.flip();
这个方法用来将缓冲区准备为数据传出状态,执行以上方法后,输出通道会从数据的开头
而不是末尾开始。回绕保持缓冲区中的数据不变,只是准备写入而不是读取。
ConnectionManager
Openfire Connection Manager是Openfire服务器的扩展,它可以透明的处理大规模并发XMPP客户端对Openfire服务器的联接。根据Connection Manager主页介绍,每个Connection Manager可以处理至少五千个并发用户。Openfire服务器可以连接一个或多个Connection Manager。每个Connection Manager可以处理一个或多个支持XMPP的客户端。为Openfire配置Connection Manager后,支持XMPP的客户端仅需要连接Connection Manager,由Connection Manager负责管理对来自XMPP客户端对Openfire服务器的连接。
连接管理的端口说明:
5222 |
默认端口为客户XMPP。这个端口可以用于担保和无担保的连接。客户将首先使用一个未加密的连接,连接可能安全使用StartTLS。 |
5223 |
Jabbe默认SSL通行遗留的端口。这个老方法,很快被弃用,使用加密的连接就被创建。 |
5275 |
默认的XMPP端口外部组件。 |
5269 |
默认端口为服务端对服务端的 XMPP通信。 |
5262 |
默认XMPP连接多路传输端口 |
管理流程
1. 打开 Openfire Admin Console
2. 点击 Server 选项卡下面的 Server Settings 页面
3. 点击左侧的 Connection Managers 页面
4. 选择 Enable 单选按钮以打开 Connection Manager 监听服务
5. 设置 password 。例如, 123 。
通过以上配置,完成了开启 Openfire 监听Connection Manager 服务。下面是对连接管理的源码分析。
通过控制台页面connection-managers-settings.jsp,会调用如下两个方法来启动连接管理:
步骤一:connectionManager.enableConnectionManagerListener(true);
这是一个启动服务端对服务端通信的端口侦听器:
1.设置xmpp socket有效值true.
JiveGlobals.setProperty("xmpp.multiplex.socket.active", "true");
2.创建连接管理的监听程序createConnectionManagerListener()
- private void createConnectionManagerListener() {
- // Start多路复用器soket
- if (isConnectionManagerListenerEnabled()) {
- // Create SocketAcceptor with correct number of processors
- multiplexerSocketAcceptor = buildSocketAcceptor();
- // Customize Executor that will be used by processors to process incoming stanzas
- ExecutorThreadModel threadModel = ExecutorThreadModel.getInstance("connectionManager");
- int eventThreads = JiveGlobals.getIntProperty("xmpp.multiplex.processing.threads", 16);
- ThreadPoolExecutor eventExecutor = (ThreadPoolExecutor) threadModel.getExecutor();//固定大小线程池
- eventExecutor.setCorePoolSize(eventThreads + 1);
- eventExecutor.setMaximumPoolSize(eventThreads + 1);
- eventExecutor.setKeepAliveTime(60, TimeUnit.SECONDS);
- multiplexerSocketAcceptor.getDefaultConfig().setThreadModel(threadModel);
- // Add the XMPP codec filter
- multiplexerSocketAcceptor.getFilterChain().addFirst("xmpp", new ProtocolCodecFilter(new XMPPCodecFactory()));
- }
3.启动连接管理的监听程序
步骤二:connectionManager.setConnectionManagerListenerPort(port);
设置启动监听端口
ConnectionManagerImpl
ConnectionManager声明了五种连接:client、clientssl、external component、other server、connectionmanager,它们有各自的端口并且可禁用。ConnectionManagerImpl创建多个SocketAcceptor监听各个端口,并绑定不 同的ConnectionHandlerOpenfire连接管理配置服务端配置步骤。
创建监听的方法:
- private synchronized void createListeners() {
- if (isSocketStarted || sessionManager == null || deliverer == null || router == null || serverName == null)
- {
- return;
- }
- //创建s2s通信端口监听
- createServerListener(localIPAddress);
- // 创建连接管理监听
- createConnectionManagerListener();
- // 创建外部组件监听
- createComponentListener();
- // 创建客户端监听
- createClientListeners();
- // 创建SSL监听
- createClientSSLListeners();
- }
启动监听的方法:
- private synchronized void startListeners() {
- if (isSocketStarted || sessionManager == null || deliverer == null || router == null || serverName == null) {
- return;
- }
- // 检查插件是否被加载
- PluginManager pluginManager = XMPPServer.getInstance().getPluginManager();
- if (!pluginManager.isExecuted()) {
- pluginManager.addPluginManagerListener(new PluginManagerListener() {
- public void pluginsMonitored() {
- // 停止插件监听事件
- XMPPServer.getInstance().getPluginManager().removePluginManagerListener(this);
- // 启动监听
- startListeners();
- }
- });
- return;
- }
- isSocketStarted = true;
- // Setup port info
- try {
- localIPAddress = InetAddress.getLocalHost().getHostAddress();
- }
- catch (UnknownHostException e) {
- if (localIPAddress == null) {
- localIPAddress = "Unknown";
- }
- }
- // 启动s2s端口监听
- startServerListener();
- // 启动连接管理端口监听
- startConnectionManagerListener(localIPAddress);
- // 启动外部组件监听
- startComponentListener();
- // 启动客户端监听
- startClientListeners(localIPAddress);
- // 启动SSL监听
- startClientSSLListeners(localIPAddress);
- // 启动http监听
- startHTTPBindListeners();
- }
以上是关于(转)OpenFire源码学习之十:连接管理(上)的主要内容,如果未能解决你的问题,请参考以下文章
(转)OpenFire源码学习之四:openfire的启动流程