监控openfire数据

Openfire XMPP服务器在Debian/Ubuntu VPS上的生产级部署指南 XMPP(Extensible Messaging and Presence Protocol)是一种开放、去中心化的实时通信协议,其核心原理基于XML流、SASL认证、TLS加密及分布式路由机制。作为成熟稳定的IM基础设施,XMPP具备天然的数据主权保障能力与协议透明性,技术价值体现在可审计、可定制、可私有化部署,广泛应用于企业内网通讯、合规消息系统、客服集成及物联网设备信令交互等场景。本文聚焦于在Debian 12或Ubuntu 22.04 LTS系统的VPS上,通过原生APT安装+手动升级Openfi 阅读详情

策划和开发需求openfire数据

(1)使用jvm暴露接口进行监控:
jvm接口介绍:http://blog.youkuaiyun.com/linghunhong/article/details/6438409

在ServerStarter.java中start方法最后添加mbean注册:

 <span style="white-space:pre">	</span>/**
             * 注册jmx
             * 
             */
            MBeanServer ms =  ManagementFactory.getPlatformMBeanServer();
	        ObjectName ofJmxName = new ObjectName("******:type=***");
            Class jmxClass = loader.loadClass(
                    "org.jmx.你的mbean实现");
            ms.registerMBean(jmxClass.newInstance(),ofJmxName);
            //注册结束

你的mbean注册中可以实现对已有统计的接口,openfire统计相关都在StatisticsManager.java中

然后可以使用jdk提供的jconsole.exe监控查看

(2)数据库连接监控:

安装Load Statistic插件

(3)数据包聊天、登陆用户监控:

安装Monitoring Service插件

(4)

要求:统计消息转发的最长时长、最短时长、平均时长
统计IQ最长时长、最短时长、平均时长

方案:

1、利用openfire提供的PacketInterceptor,在interceptPacket方法中实现对IQ和Message的日志打印(具体打印内容自定义)。可以每个一段时间对日志内容进行分析

2、利用Monitoring Service提供的接口进行仿照开发

制作插件,主体部分逻辑如下:


import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import org.jivesoftware.openfire.interceptor.InterceptorManager;
import org.jivesoftware.openfire.interceptor.PacketInterceptor;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.openfire.stats.Statistic;
import org.jivesoftware.openfire.stats.StatisticsManager;
import org.jivesoftware.openfire.stats.i18nStatistic;
import org.picocontainer.Startable;
import org.xmpp.packet.IQ;
import org.xmpp.packet.Message;
import org.xmpp.packet.Packet;

/**
 * Creates and manages Enteprise-specific statistics, specifically: <ul>
 *      message 转发最长时间、最短时间、平均时间、所有时间、数目
 *      
 * </ul>
 *
 * @author 
 */
public class StatisticsModule implements Startable {
	//message 统计相关key
    public static final String MESSAGE_COUNT_KEY = "m_count";
    public static final String MESSAGE_LONGEST_TIME_KEY = "m_longest_time";
    public static final String MESSAGE_SHORTEST_TIME_KEY = "m_shortest_time";
    public static final String MESSAGE_ALL_TIME_KEY = "m_all_time";
    public static final String MESSAGE_AVG_TIME_KEY = "m_avg_time";
   
    //message统计存储
    private ConcurrentHashMap<String,AtomicLong> m_timeHash = new ConcurrentHashMap<String,AtomicLong>() ;
    private AtomicInteger message_Count = new AtomicInteger();
    private AtomicLong messgae_longestTime = new AtomicLong();
    private AtomicLong message_shortestTime = new AtomicLong(100000l);
    private AtomicLong message_allTime = new AtomicLong();
    
    
    
    private StatisticsManager statisticsManager;
    private PacketInterceptor packetInterceptor;
    
    
    
//    private long 
    public void start() {
        // Retrieve instance of StatisticsManager
        statisticsManager = StatisticsManager.getInstance();

        // Register a packet listener so that we can track packet traffic.
        packetInterceptor = new PacketInterceptor() {
            public void interceptPacket(Packet packet, Session session, boolean incoming,
                                        boolean processed)
            {
            	if(null==packet.getID()){
            		//没有id的不能统计
            		return;
            	}
                // Only track processed packets so that we don't count them twice.
                if (incoming&&!processed) {
                	if (packet instanceof Message) {
                		m_timeHash.put(packet.getID(),new AtomicLong(System.currentTimeMillis()));
                	}else if(packet instanceof IQ){
                		iq_timeHash.put(packet.getID(), new AtomicLong(System.currentTimeMillis()));
                	}
                    
                }else if(incoming&&processed){
                	if (packet instanceof Message) {
                		AtomicLong time = m_timeHash.get(packet.getID());
                		if(time!=null){
                			//end-start
                			//获取longest时间和shortest时间,比较,如果需要的话保存
                			//获取all,进行加法操作
                			//获取count进行自增1操作
                			//删除这个map
                			long t = System.currentTimeMillis()-time.longValue();
                			if(messgae_longestTime.longValue()<t){
                				messgae_longestTime.set(t);
                			}
                			if(message_shortestTime.longValue()>t){
                				message_shortestTime.set(t);
                			}
                			message_allTime.getAndAdd(t);
                			message_Count.incrementAndGet();
                			m_timeHash.remove(packet.getID());
                		}
                	}
                }
            }
        };
        InterceptorManager.getInstance().addInterceptor(packetInterceptor);

        // Register all statistics.
        addPacketNumberStatistic();
        addPacketAllTimeStatistic();
        addPacketLongestTimeStatistic();
        addPacketShortestTimeStatistic();
        addPacketAvgTimeStatistic();
        
      
    }

    /**
     * Remove all registered statistics.
     */
    public void stop() {


        // Remove Statistic
        statisticsManager.removeStatistic(MESSAGE_COUNT_KEY);
        statisticsManager.removeStatistic(MESSAGE_LONGEST_TIME_KEY);
        statisticsManager.removeStatistic(MESSAGE_SHORTEST_TIME_KEY);
        statisticsManager.removeStatistic(MESSAGE_ALL_TIME_KEY);
        statisticsManager.removeStatistic(MESSAGE_AVG_TIME_KEY);
      

        statisticsManager = null;

        // Remove the packet listener.
        InterceptorManager.getInstance().removeInterceptor(packetInterceptor);
        packetInterceptor = null;
        message_Count = null;
        messgae_longestTime = null;
        message_shortestTime = null;
        message_allTime = null;
        m_timeHash = null;
        
      
    }

   
    /**
     * Tracks the total number of message
     */
    private void addPacketAvgTimeStatistic() {
        // Register a statistic.
        Statistic packetTrafficStatistic = new i18nStatistic(MESSAGE_AVG_TIME_KEY, null, Statistic.Type.count) {
            public double sample() {
            	if(message_Count.longValue()==0){
            		return 0;
            	}
                return message_allTime.longValue()/message_Count.longValue();
            }

            public boolean isPartialSample() {
                return true;
            }
        };
        statisticsManager.addStatistic(MESSAGE_AVG_TIME_KEY, packetTrafficStatistic);
    }

    /**
     * Tracks the total number of message
     */
    private void addPacketNumberStatistic() {
        // Register a statistic.
        Statistic packetTrafficStatistic = new i18nStatistic(MESSAGE_COUNT_KEY, null, Statistic.Type.count) {
            public double sample() {
                return message_Count.get();
            }

            public boolean isPartialSample() {
                return true;
            }
        };
        statisticsManager.addStatistic(MESSAGE_COUNT_KEY, packetTrafficStatistic);
    }
    /**
     * Tracks the total time of message
     */
    private void addPacketAllTimeStatistic() {
        // Register a statistic.
        Statistic packetTrafficStatistic = new i18nStatistic(MESSAGE_ALL_TIME_KEY, null, Statistic.Type.count) {
            public double sample() {
                return message_allTime.get();
            }

            public boolean isPartialSample() {
                return true;
            }
        };
        statisticsManager.addStatistic(MESSAGE_ALL_TIME_KEY, packetTrafficStatistic);
    }
    /**
     * Tracks the longestTime of message
     */
    private void addPacketLongestTimeStatistic() {
        // Register a statistic.
        Statistic packetTrafficStatistic = new i18nStatistic(MESSAGE_LONGEST_TIME_KEY, null, Statistic.Type.count) {
            public double sample() {
                return messgae_longestTime.get();
            }

            public boolean isPartialSample() {
                return true;
            }
        };
        statisticsManager.addStatistic(MESSAGE_LONGEST_TIME_KEY, packetTrafficStatistic);
    }
    
    /**
     * Tracks the shortestTime of message
     */
    private void addPacketShortestTimeStatistic() {
        // Register a statistic.
        Statistic packetTrafficStatistic = new i18nStatistic(MESSAGE_SHORTEST_TIME_KEY, null, Statistic.Type.count) {
            public double sample() {
                return message_shortestTime.get();
            }

            public boolean isPartialSample() {
                return true;
            }
        };
        statisticsManager.addStatistic(MESSAGE_SHORTEST_TIME_KEY, packetTrafficStatistic);
    }
    
    
}

这样,以上信息就能在jmx接口中暴露出来了


Linux下OpenFire+Spark即时通讯环境搭建全攻略(含证书错误解决方案) 本文提供了一份详尽的Linux环境下OpenFire服务器与Spark客户端即时通讯系统的搭建与配置全攻略。内容涵盖从环境规划、服务端部署、数据库配置到客户端连接的全流程,并重点解决了Spark连接时常见的证书验证错误问题,为企业构建私有化、高可用的XMPP通讯平台提供了实战指导。 阅读详情

相关推荐

Openfire 自建即时通讯实战:XMPP 协议、Java 服务端搭建与集群调优

XMPP 作为开放的即时通讯协议,通过 XML 流和 Stanza 机制实现消息路由与状态同步,为自建 IM 提供了标准化基础。Java 生态下的开源服务端方案借助 Maven 构建和插件化架构,在会话管理、消息归档、文件传输等环节具备灵活扩展能力。这类方案的核心价值在于数据自主可控、协议无厂商锁定,适合企业内部协作、物联网设备消息通道等场景。围绕 Openfire 的源码编译、数据库选型、集群部署与性能调优,可系统掌握 Java 服务端架构设计与 XMPP 协议落地的工程实践。

weixin_31714129的博客 172

Openfire插件

1、Client Control 客户端管理,

有点小小的理想【一步一步似爪牙,似魔鬼的步伐】 979

openfire的用户接收消息计数器

openfire的用户接收消息计数器,应用很方便,通过填写openfire的用户user_no号与密码,还有服务器的ip地址,点击登录就可以等待消息的接收,并且统计接收消息的数量.

openfire中事件监听器使用

1、知识点 openfire中提供了部分事件监听器用于监听部分事件。使用时需要按照具体需要实现openfire中提供的事件监听器接口,然后调用个监听器对应的事件分发器类添加事件绑定,当指定事件发生时用户的实现类中相应的方法就能被调用到。事件监听器的接口在如下包中可以找到: org.jivesoftware.openfire.event如下为部分官方API截图。 从图中可见open

三言两语 2787

openfire插件,用户入群加web接口

openfire插件,用户入群加web接口,史上最全,下载即用

org.xmpp.packet.JID

在使用android openfire 作为IM服务的时候 利用第三方账号 如果第三方账号中含有@符号的话 登录会报错 可以利用这个代码进行escapeNode 一下 然后传递到openfire 在查询数据库之前进行解析 这是在openfire的源代码中找出来的 去掉了绝大部分代码 只保留了 escapeNode 和 unescapeNode 两个方法 经测试 可以使用 希望给大家带来帮助 ">在使用android openfire 作为IM服务的时候 利用第三方账号 如果第三方账号中含有@符号的话 登录会报错 可以利用这个代码进行escapeNode 一下 然后传递到openfire 在查询数据库之前进行解析 这是在openfire的源代码中找出来 [更多]

openfire hazelcast jmx 监控配置

这鬼东西配置真是麻烦,看了我整整一下午的英语.... 脖子痛,差不多下班的时候配置好了,先做个总结。 1:openfire安装hazelcast插件(openfire要3.8.1) 2:修改openfire启动文件,加入jvm追加配置:(在management.propreties里修改的方式不知道为什么不行) [code="java"] "-Djava.net.preferIPv4S...

码农一个 385

openfire记录在线统计人数插件

openfire记录在线统计人数插件

python远程监控jvm_jvm远程监控配置,以openfire为例,jmx方式监控

我们有时候需要远程的监控jvm,监控jvm有两种方式:1.jmx #测试能监控cpu和内存,线程2.jstatd #测试后发现无法监控cpu和内存,线程由此用jmx来监控,jmx的连接有两种方式rmi和jmxmp1.以生产环境openfire3.10为例:openfire采用源码的形式安装:修改 openfire的启动脚本 /var/openfire/...

weixin_39862716的博客 324

ExcelVBA批量添加PDF文件

如图1所示,"BOM-01.xlsx"工作簿中的Sheet1工作表根据B列图号单元格中的内容,在图2所示的文件夹中找到对应的PDF文件,然后嵌入到相应的N列,双击N列中所示的图标,会打开PDF文件,是源文件的副本,即删除源文件,也可以打开N列的文件。 图1 根据B列的图号在N列嵌入对应的PDF文件 图2 PDF文件 图3 文件格式 Sub 导入文件() Ap...

qq389445046的博客 5578

layui 监听单元格点击事件,获取当前点击单元格的内容以及 所在的表头内容

特别是后台的一些管理系统中 业务中还是会碰见这样的需求呢 如果你的后台使用layui写的话 在表格中 layui 也给我们提供了监听单元格的事件 但是好像不能直接获取到单元格内容个 和 对应的表头 其实 还是可以解决 换个角度使劲就会发现新的世界 不是吗 event: 'username' 在每个表头中加一个 event 属性 这样就可以监听表头事件 记住个 event 和 当前列的字段最好保持一样 table.render({ e...

业余前端的职业经历 1万+

openfire消息服务器引入druid数据库连接池

由于项目需要,需要在openfire消息服务器中引入druid数据库连接池。刚开始做的时候,一头雾水,只在网络上检索到jndi的改造方式,以及纯java语言引入druid数据库连接池的方式。在和openfire结合的时候,不知道该如何下手。 首先需要了解的是,openfire内部提供了三个实现ConnectionProvider的Provider,分别是JNDIDataSourceProvide...

u014529211的博客 434

PX4从放弃到精通(三):使用qt编译PX4

1 下载px4源码 2在Firmware所在目录下执行 mkdir Firmware-build cd Firmware-build cmake …/Firmware -G “CodeBlocks - Unix Makefiles” -DCONFIG=nuttx_px4_fmu-v5_default 第三步最后的px4_fmu-v5_default根据自己的情况修改 执行完后如图 打开QT 点击打开工程 选择源码的CmakeLists.txt文件 选择imported Kit 打开项目那一栏,构建目

超维空间科技的博客 1万+

OpenFire源码学习之四:openfire的启动流程

openfire启动 ServerStarter 启动流程图: 启动的总入口在ServerStarter的main方法中。通过上图首先它会先加载它所需要的jar文件。最后通过java反射机制将XMPPServer加入当前线程。 Thread.currentThread().setContextClassLoader(loader); Class cont

峰哥的专栏 3万+

微信终于支持“多设备同时在线”?我用 NAS + Docker 搭了一个云端微信系统,多端共享24小时在线

通过Docker 容器,将微信运行在云端并通过浏览器访问,实现多设备共享同一微信会话 📱。本文详细介绍完整部署流程、docker-compose 配置及资源控制方案,让微信变成“可访问的云桌面应用” ✨

XiaoqiangClub的博客 872

锂电池的充电和放电曲线解读

锂电池充放电曲线是反映其性能的关键指标。充电曲线分为恒流和恒压两阶段:恒流阶段电压快速上升,恒压阶段电流逐渐降低;放电曲线则呈现平台期和快速衰减期特征。这些曲线受温度、充放电倍率及材料体系(如三元锂或磷酸铁锂)显著影响。通过分析曲线特征,可优化电池管理系统,实现精准的SOC估算、快充策略制定及故障诊断,从而在电池性能与安全性间取得平衡。不同应用场景(如新能源汽车或消费电子)对曲线形态有特定要求。

start_up_go的博客 5070

Openfire插件开发实例

目的:主要是为了监控Openfire各类message,然后对message body做进一步扩展,让Openfire更适合当前的业务需求。 局限:因为时间有限,本插件并没有对Openfire message协议进行扩展,都是基于原生的xml协议,因此后续开发还需要进行更加深入的二次开发操作。 实例下载:http://download.youkuaiyun.com/detail/qiu_11/9719268

Stop Tears 2396

高数15种常见特殊曲线:星形线、心形线、摆线、对数螺线、双曲螺线、阿基米德螺线、伯努利双纽线、三叶玫瑰线、四叶玫瑰线、六叶玫瑰线、三次抛物线、半立方抛物线、箕舌线、蔓叶线、笛卡儿叶形线、概率曲线

4.1 对数螺线(等角螺线、生长螺线)三叶玫瑰线、四叶玫瑰线、六叶玫瑰线。​7.2 半立方抛物线(尼尔曲线)10.笛卡儿叶形线(茉莉花瓣曲线)常考选择题、填空题,大题也涉及。​4.2 双曲螺线(倒数螺线)11.阿基米德螺线(等速螺线)3.摆线(圆滚线、旋轮线)5.双纽线(伯努利双纽线)1.星形线(四尖瓣线)2.心形线(心脏线)..................

刘鑫磊 1万+

Openfire Docker容器化部署:现代化微服务架构实践终极指南

Openfire是一个基于Apache许可证开源的XMPP即时通讯服务器,它采用Docker容器化部署可以极大地简化部署流程、提升系统可维护性,并实现现代化微服务架构的弹性扩展。作为一款成熟的实时协作服务器,Openfire通过容器化技术让企业能够快速搭建高可用的即时通讯平台。 ## 📦 Openfire容器化架构解析 Openfire的Docker容器化架构采用多层构建策略,确保构建过程的

gitblog_00917的博客 1054

山东大学机试试题合集

山东大学机试试题合集

qq_63349644的博客 2622

把 SAP GUI 做成可维护的应用:Module Pool 基础与 Table Control 深入实战

SAP Module Pool 与 Table Control 开发要点 摘要:Module Pool 作为 SAP GUI 交互的核心技术,由程序、屏幕(Dynpro)和流逻辑(Flow Logic)组成,通过 PBO/PAI 事件驱动数据流。Table Control 是其中处理多行数据的核心控件,其开发关键在于: 正确理解 PBO/PAI 数据流机制 掌握 CXTAB_CONTROL 结构的关键属性(LINES、TOP_LINE 等) 合理设置列控制属性(CXTAB_COLUMN) 采用 LOOP W

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 243

openfire开发笔记三-openfire主要插件介绍

这次我们来介绍下openfire提供的可选插件,方便大家在开发中使用。 openfire插件下载地址: http://www.igniterealtime.org/projects/openfire/plugins.jsp 使用插件时大家请一定要注意插件支持的openfire版本,不要搞错了,否则是不能运行的。  Broadcast   最新版本 1.8.2   广播消息插件,主要是将

chals115的专栏 2691

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Openfire API开发接口:RESTful服务集成与自定义功能开发

Openfire是一款基于XMPP协议的开源即时通讯服务器,提供了丰富的API接口支持服务集成与功能扩展。本文将详细介绍如何通过Openfire的HTTP绑定(BOSH)接口实现RESTful服务集成,以及如何开发自定义功能插件,帮助开发者快速构建实时通讯应用。 ## Openfire API架构概览 📊 Openfire的API体系主要基于HTTP绑定(BOSH)协议实现,通过`servl

gitblog_01037的博客 888

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Openfire安装说明

l  下载对应系统的安装包。安装tar.gz,解压后即可使用,tar –zxvf  *.tar.gz l  运行openfire,bin/openfire start|stop|restart。 l  打开9090端口 l  访问http://IP:9090,直接next ,在选择数据库有内嵌和外部两种,选外部数据库mysql时的连接地址要加characterEncoding=utf8,不加

qin的专栏 400

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

【即时通信】Openfire与Spark集成实战:从安装到客户端配置

本文详细介绍了开源即时通信解决方案Openfire服务器与Spark客户端的集成实战。从Java环境准备、Openfire安装部署、数据库配置,到Spark客户端连接、解决自签名证书错误等关键步骤,提供了完整的搭建指南。文章还涵盖了用户管理、插件推荐、性能调优及常见问题排查,帮助读者快速构建自主可控的企业级XMPP即时通讯系统。

code8的博客 207
上一篇: openfire mongo ofuser表 批量插入删除脚本
下一篇: 图像压缩研究
ldwtill
博客等级 码龄18年 49粉丝 84原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值