文档章节

说说ejabberd离线消息踩过的坑

cisiqo
 cisiqo
发布于 2016/08/29 13:10
字数 975
阅读 104
收藏 0

使用过ejabberd的或许知道,也许踩过这个坑。那么就说说我们踩过的ejabberd的离线消息的坑吧。

ejabberd原生的离线消息的机制是,一般用户保存100条离线消息,管理员保存5000条离线消息。超过之后竟然没有删除老的离线消息的机制。😓 仅仅是报一个警告。

1

2

3

max_user_offline_messages:

    - 5000: admin

    - 100

1

2

<<"Your contact offline message queue is "

"full. The message has been discarded.">>

  

ejabberd原生的群聊是没有离线消息的,只要用户不在线,这期间其他群成员在群里面的聊天,不在线的用户上线后收不到这些消息的。

完全跟现在的一些即时聊天软件不一样,太不好耍了,而且一些客户都是按照某信的要求来看待的,对比一下就会发现这些问题,然后就是一堆的需求。

 

按照现在的即时聊天软件,我们在原来的基础上实现了群聊离线消息的机制,还添加多客户端消息同步的机制,那么一条离线消息就咬保存好几份了,然后的条数限制远远不够了,即使调了离线消息的配置(由原来的100改为2000),在一个群里面疯狂的聊天,一下子就满了。

好吧,那么就添加删除的机制吧,只要用户的离线消息大于配置的条数,那么就删除超出配置的老的离线消息。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

%% Warn senders that their messages have been discarded:

% discard_warn_sender(Msgs) ->

%     lists:foreach(fun (#offline_msg{from = From, to = To,

%                   packet = Packet}) ->

%             ErrText = <<"Your contact offline message queue is "

%                     "full. The message has been discarded.">>,

%             Lang = xml:get_tag_attr_s(<<"xml:lang">>, Packet),

%             Err = jlib:make_error_reply(Packet,

%                             ?ERRT_RESOURCE_CONSTRAINT(Lang,

%                                       ErrText)),

%             ejabberd_router:route(To, From, Err)

%         end,

%         Msgs).

discard_warn_sender(USMsgsCountMaxOfflineMsgs, mnesia) ->

    ?INFO_MSG("Begin to discard offline msgs at time:~s", [erlang:timestamp()]),

    R = mnesia:select(offline_msg,[{#offline_msg{us = US, _='_'},[],['$_']}]),

    Rsort lists:sort(fun(A, B) -> A#offline_msg.timestamp < B#offline_msg.timestamp end,R),

    {M, _} = lists:split(Count MaxOfflineMsgsRsort),

    F = fun() ->

        lists:foreach(fun(X) ->

            mnesia:delete_object(X)

        end,M),

        if Count MaxOfflineMsgs >= (?OFFLINE_TABLE_LOCK_THRESHOLD) ->

                  mnesia:write_lock_table(offline_msg);

            true -> ok

        end,

        lists:foreach(fun (N) -> mnesia:write(N) endMsgs)

    end,

    mnesia:transaction(F),

    ?INFO_MSG("Discard offline msgs:~w", [M]),

    ?INFO_MSG("End to discard offline msgs at time:~s", [erlang:timestamp()]);

改造了一些源代码,思路就是先查询到所有的离线消息,排序删除老的离线消息。(本来不熟悉erlang的,业务需求硬着头皮改的。大家轻喷)

 

然后呢,又有效率问题。只要用户离线消息满了,就会一直循环这个删除动作,不停的查询所有的离线消息,删掉超出的部分。

既然这样,那就不限制离线消息的条数了。注释掉这个方法,测试一下静观其变吧。

 

好吧,即使这样还是有问题。mnsia的offline_msg表只要超过2G,模块就会奔溃。

1

As far as I know dets can only handle 2GB files not 4GB, which will be the limit for disc_copies. There is an experimental 64-bit dets which can handle much larger files but no one has used it in production yet. – Happi 

查到一些资料,Mnesia 单表的存储容量(Dets)目前只能处理2G。由于现在我们是 disc_only_copies,即现在离线消息占用的应该是磁盘。目前 Offline Mod 崩溃都是离线消息存储到达 2G 的时候,所以推测是触到 Mnesia 单表处理上线了。

这个就真的没有办法,那就只能将离线消息保存到MySQL中了,原生的本来就支持ODBC。

 

按照一些教程配置吧,很快就好了。主要是在mod_offline模块添加db_type:odbc就行。

额,又有小问题,emoji问题,那就又搜教程配置MySQL数据库,改表吧。

 

一路磕磕碰碰的,献给那些走在路上的人和那些即将走到路上的人。

© 著作权归作者所有

cisiqo
粉丝 33
博文 28
码字总数 5919
作品 0
武汉
程序员
私信 提问
企业级 XMPP 通信工具--ttalk.im

说到 IM 通信,一般首选都是 XMPP,并且首推 Ejabberd。国内使用 Ejabberd 厂家很多,对企业级的 IM 有需求的厂家很多,同时希望能快速集成一个 IM 的厂家就更多了。但是在这些厂家中很多都抱...

匿名
2016/01/14
2.4K
0
ejabberd 2.1.2 发布,即时通讯

该版本修正了 PubSub、PEP、WebAdmin 离线消息显示和服务器停止时的一些bug。 下载地址: http://www.process-one.net/en/ejabberd/downloads/...

红薯
2010/01/19
421
0
Android即时通讯--YiIM

基于Xmpp的Android即时通讯手机应用软件YiIM第二版 功能日志: 登录 好友获取 文本消息发送与接收,离线消息接收 消息记录,会话记录 添加好友 发送语音短消息 发送大表情 发送文字表情混合消...

bjhongping
2014/09/16
7.9K
0
基于ejabberd实现各个客户端消息同步

先上图再说(左侧是web端,右侧是ios端) ![在此输入图片描述][1] ![在此输入图片描述][2] 要实现上面的功能,如果所有设备都在线的话,那么carboncopy(xmpp xep-0280协议)这个模块是可以实...

nidongwo-
2015/03/28
0
0
ejabberd中的http反向推送

http的反向推送通常使用"长轮询"或"长连接"的方式。 所谓"长轮询"是指客户端发送请求给服务器,服务器发现没有数据需要发送给客户端于是hold住不及时返回,等有数据需要发送给客户端时,进行...

hncscwc
2013/11/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

研究下这代码,用到了guava和线程池

import com.google.common.util.concurrent.FutureCallback;import com.google.common.util.concurrent.Futures;import com.google.common.util.concurrent.ListenableFuture;import c......

暗中观察
11分钟前
0
0
《css 揭秘》 之垂直居中的实现

最近看了 Lea Verou 的 《css揭秘》一书,让我对自己的 css学习产生了深深的怀疑。这本书真是太棒了,里面涉及到很多优雅又有趣的效果实现,真的是非常棒。如果你有时间,十分建议你去看看。...

IrisHuang
17分钟前
1
0
java 抽象类(2)

/*需求: 描述一个图形、圆形、 矩形三个类。不管哪种图形都会具备计算面积与周长的行为,但是每种图形计算的方式不一致而已。常量的命名规范:全部字母大写,单词与单词 之间 使用下...

hellation_
19分钟前
0
0
总结:堆和栈

堆 堆比较好理解,即存放对象的地方。这里的对象由GC管理 1、类变量(static修饰的变量):在程序加载时系统就为它在堆中开辟了内存,堆中的内存地址存放于栈以便于高速访问。静态变量的生命...

浮躁的码农
25分钟前
1
0
JavaScript 新语法详解:Class 的私有属性与私有方法

译者按: 为什么偏要用**#**符号? 原文:JavaScript's new #private class fields 译者:Fundebug 本文采用意译,版权归原作者所有 proposal-class-fields与proposal-private-methods定义了 ...

Fundebug
27分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部