AbstractXmppConnection 的静态实例:消息传递到 ejabberd 的速度很慢
Static instance of AbstractXmppConnection : slow delivery of messages to ejabberd
我正在将来自 smack 库 (Java) 的消息(自动)发送到 Ejabberd 中。它是如何完成的:-
-AbstractXmppConnection 的静态对象是为一个用户创建的
- 每次 api 命中,post 连接,都会通过连接
向 Ejabberd 发送一条消息
问题:python 脚本在 Java Play Framework 上有大约 400 次连续点击。脚本和 api 运行良好,通过日志检查。问题是消息延迟到达用户。在两次消息发送之间,有大约一分钟的延迟。如果我检查 mysql 数据库,存档 table,第一次命中只有 1 个条目,连续条目来得非常慢。
但是,如果我将 AbstractXmppConnection 设为 class 的一个实例,并在每次点击时遵循连接、shootMessage 和断开连接流程,则消息会立即发送。但是如此快速地连接和断开同一个帐户会增加 Ejabberd 的负载。
问题:为什么重用 AbstractXmppConnection 的同一个(静态)对象发送多条消息时传递消息的速度非常慢?当我必须为每个 api 命中创建新实例时,它的速度很快
代码(多实例:运行速度快但由于 connect/disconnect 频率而增加负载):
public synchronized void sendMessage(String senderId,String receiverId, String SERVER, Message message) throws IOException, XMPPException, SmackException {
+ Logger.debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@SENDING MESSAGE TO "+receiverId + " from "+senderId+ " Message "+message.toXML().toString());
+
+ AbstractXMPPConnection abstractXMPPConnection;
+
+ //Making connection
+ EjabberdConnectionQuote ejabberdConnection = new EjabberdConnectionQuote();
+ abstractXMPPConnection = ejabberdConnection.getConnection();
+ abstractXMPPConnection.login(senderId,"secret");
+
+ //Create chat
+ Chat chat = null;
+ ChatManager chatManager = null;
+ chatManager = ChatManager.getInstanceFor(abstractXMPPConnection); //$$$$$NEW INSTANCE$$$$
+ chat = chatManager.createChat(receiverId + SERVER);
+ chat.sendMessage(message);
+
+ abstractXMPPConnection.disconnect();
+
+ if (abstractXMPPConnection.isConnected() ){
+ Logger.info("Still Connected");
+ }else{
+ Logger.info("<---------Disconnected------->");
+ }
+ }
代码(所有api点击重用的静态连接对象,模仿一个用户并向名册中的多个用户射击):
AbstractXMPPConnection abstractXMPPConnection;
+ SingletonConnection obConn = SingletonConnection.getInstance();
+ if ( obConn.connectionMap.containsKey(senderId) ) {
+ Logger.info("Already Connected");
+ //Remove and update timer
+ obConn.updateTimer(senderId);
+ abstractXMPPConnection = obConn.connectionMap.get(senderId).abstractXMPPConnection;
+ }else{
+ Logger.info("Creating new connection");
+ //Create new connection and put it in map
+ EjabberdConnectionQuote ejabberdConnection = new EjabberdConnectionQuote();
+ abstractXMPPConnection = ejabberdConnection.getConnection();
+ abstractXMPPConnection.login(senderId,"secret");
+ RemoveConnectionTimer removeConnectionTimer = new RemoveConnectionTimer(senderId);
+ StoreData storeData = new StoreData(senderId,abstractXMPPConnection,removeConnectionTimer);
+ obConn.connectionMap.put(senderId,storeData);
+
+ }
Message message = createMessage(quote, returnDateInIst(), senderId, receiverId);
String key = receiverId + "$$$" + senderId;
- SingletonConnection.getInstance().sendMessage(senderId,receiverId,SERVER,message);
+ Chat chat = null;
+ ChatManager chatManager = null;
+ chatManager = ChatManager.getInstanceFor(abstractXMPPConnection); //$$$$$REUSE EXISTING connection$$$$
+ chat = chatManager.createChat(receiverId + SERVER);
+ chat.sendMessage(message);
+
+ //abstractXMPPConnection.disconnect();
+
+ if (abstractXMPPConnection.isConnected() ){
+ Logger.info("Still Connected");
+ }else{
+ Logger.info("<---------Disconnected------->");
+ }
经过多次登录和检查smack源代码,我找到了原因。
chatManager = ChatManager.getInstanceFor(abstractXMPPConnection);
chat = chatManager.createChat(receiverId + SERVER);
chat.sendMessage(message);
上面的代码片段returns一个只能被实例化abstractXMPPConnection对象的线程访问的聊天对象。如果从其他线程访问对象,则为空。
我正在将来自 smack 库 (Java) 的消息(自动)发送到 Ejabberd 中。它是如何完成的:-
-AbstractXmppConnection 的静态对象是为一个用户创建的 - 每次 api 命中,post 连接,都会通过连接
向 Ejabberd 发送一条消息问题:python 脚本在 Java Play Framework 上有大约 400 次连续点击。脚本和 api 运行良好,通过日志检查。问题是消息延迟到达用户。在两次消息发送之间,有大约一分钟的延迟。如果我检查 mysql 数据库,存档 table,第一次命中只有 1 个条目,连续条目来得非常慢。
但是,如果我将 AbstractXmppConnection 设为 class 的一个实例,并在每次点击时遵循连接、shootMessage 和断开连接流程,则消息会立即发送。但是如此快速地连接和断开同一个帐户会增加 Ejabberd 的负载。
问题:为什么重用 AbstractXmppConnection 的同一个(静态)对象发送多条消息时传递消息的速度非常慢?当我必须为每个 api 命中创建新实例时,它的速度很快
代码(多实例:运行速度快但由于 connect/disconnect 频率而增加负载):
public synchronized void sendMessage(String senderId,String receiverId, String SERVER, Message message) throws IOException, XMPPException, SmackException {
+ Logger.debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@SENDING MESSAGE TO "+receiverId + " from "+senderId+ " Message "+message.toXML().toString());
+
+ AbstractXMPPConnection abstractXMPPConnection;
+
+ //Making connection
+ EjabberdConnectionQuote ejabberdConnection = new EjabberdConnectionQuote();
+ abstractXMPPConnection = ejabberdConnection.getConnection();
+ abstractXMPPConnection.login(senderId,"secret");
+
+ //Create chat
+ Chat chat = null;
+ ChatManager chatManager = null;
+ chatManager = ChatManager.getInstanceFor(abstractXMPPConnection); //$$$$$NEW INSTANCE$$$$
+ chat = chatManager.createChat(receiverId + SERVER);
+ chat.sendMessage(message);
+
+ abstractXMPPConnection.disconnect();
+
+ if (abstractXMPPConnection.isConnected() ){
+ Logger.info("Still Connected");
+ }else{
+ Logger.info("<---------Disconnected------->");
+ }
+ }
代码(所有api点击重用的静态连接对象,模仿一个用户并向名册中的多个用户射击):
AbstractXMPPConnection abstractXMPPConnection;
+ SingletonConnection obConn = SingletonConnection.getInstance();
+ if ( obConn.connectionMap.containsKey(senderId) ) {
+ Logger.info("Already Connected");
+ //Remove and update timer
+ obConn.updateTimer(senderId);
+ abstractXMPPConnection = obConn.connectionMap.get(senderId).abstractXMPPConnection;
+ }else{
+ Logger.info("Creating new connection");
+ //Create new connection and put it in map
+ EjabberdConnectionQuote ejabberdConnection = new EjabberdConnectionQuote();
+ abstractXMPPConnection = ejabberdConnection.getConnection();
+ abstractXMPPConnection.login(senderId,"secret");
+ RemoveConnectionTimer removeConnectionTimer = new RemoveConnectionTimer(senderId);
+ StoreData storeData = new StoreData(senderId,abstractXMPPConnection,removeConnectionTimer);
+ obConn.connectionMap.put(senderId,storeData);
+
+ }
Message message = createMessage(quote, returnDateInIst(), senderId, receiverId);
String key = receiverId + "$$$" + senderId;
- SingletonConnection.getInstance().sendMessage(senderId,receiverId,SERVER,message);
+ Chat chat = null;
+ ChatManager chatManager = null;
+ chatManager = ChatManager.getInstanceFor(abstractXMPPConnection); //$$$$$REUSE EXISTING connection$$$$
+ chat = chatManager.createChat(receiverId + SERVER);
+ chat.sendMessage(message);
+
+ //abstractXMPPConnection.disconnect();
+
+ if (abstractXMPPConnection.isConnected() ){
+ Logger.info("Still Connected");
+ }else{
+ Logger.info("<---------Disconnected------->");
+ }
经过多次登录和检查smack源代码,我找到了原因。
chatManager = ChatManager.getInstanceFor(abstractXMPPConnection);
chat = chatManager.createChat(receiverId + SERVER);
chat.sendMessage(message);
上面的代码片段returns一个只能被实例化abstractXMPPConnection对象的线程访问的聊天对象。如果从其他线程访问对象,则为空。