当前位置: 首页 > news >正文

网站提交网址教育机构退费纠纷找谁

网站提交网址,教育机构退费纠纷找谁,中卫网站制作公司报价,平台网站兼职做sap高性能队列 Disruptor 在 IM 系统中的实战 前三期我们介绍了Disruptor的典型使用场景和相关高性能原理,本期我介绍一下Disruptor在IM系统用的应用实战,IM系统即社交聊天系统,对实时性的要求非常高,非常符合Disruptor的使用场景。 …

高性能队列 Disruptor 在 IM 系统中的实战

前三期我们介绍了Disruptor的典型使用场景和相关高性能原理,本期我介绍一下Disruptor在IM系统用的应用实战,IM系统即社交聊天系统,对实时性的要求非常高,非常符合Disruptor的使用场景。

本篇文章将结合实际代码,介绍如何在 IM 系统中使用 Disruptor 进行高效的消息转发。

1. Disruptor 在 IM 系统中的作用

在 IM 系统中,用户 A 发送消息给 B、C、D 时,需要根据 B、C、D 所在的服务器节点进行分组,并将消息转发到对应的节点上。为了确保高吞吐量和低延迟,我们使用 Disruptor 作为高性能队列。

2. 代码实现

2.1 初始化 Disruptor

当某个节点 nodeId 还没有对应的 RingBuffer 时,我们需要创建一个新的 Disruptor,并将其存入 ringBufferMap 中。

   private final Map<String, RingBuffer<ClusterPublishEvent>> ringBufferMap = new ConcurrentHashMap<>();

    public ClusterQueueService(Server server) {
        this.mServer = server;
    }

    public void publishMessage(String nodeId, String fromUser, String clientId, String topic, byte[] payload) {
        if (!ringBufferMap.containsKey(nodeId)) {
            long st = System.currentTimeMillis();
            synchronized (ringBufferMap){
                if(!ringBufferMap.containsKey(nodeId)) {
                    BlockingWaitStrategy strategy = new BlockingWaitStrategy();
                    Disruptor<ClusterPublishEvent> disruptor = new Disruptor<>(
                        new ClusterPublishEventFactory(), 1024 * 1024, DaemonThreadFactory.INSTANCE,
                        ProducerType.SINGLE, strategy);
                    disruptor.handleEventsWith(new ClusterPublishEventHandler(mServer, nodeId));
                    disruptor.setDefaultExceptionHandler(new IgnoreExceptionHandler());
                    disruptor.start();
                    ringBufferMap.put(nodeId, disruptor.getRingBuffer());
                }
            }
            log.info("publishMessage create RingBuffer cost:{}ms, ringBufferMap:{},size:{}", System.currentTimeMillis() - st, ringBufferMap, ringBufferMap.size());
        }
        RingBuffer<ClusterPublishEvent> ringBuffer = ringBufferMap.get(nodeId);
        long sequence = ringBuffer.next();
        // 当环形缓冲区未用完时, 返回的是空对象,否则,返回的是缓存的数据。
        ClusterPublishEvent clusterEvent = ringBuffer.get(sequence);
        clusterEvent.setFromUser(fromUser);
        clusterEvent.setClientId(clientId);
        // 此topic,是节点转发的topic: NM2R, NTF,DESTROYUSER, 只有这三种
        clusterEvent.setTopic(topic);
        clusterEvent.setPayload(payload);
        clusterEvent.setTraceId(MDC.get(ImSvcConstants.TRACE_ID));
        // 发布事件, 会触发ClusterPublishEventHandler.onEvent方法
        ringBuffer.publish(sequence);
    }

关键点解析:

  • 采用 BlockingWaitStrategy 作为等待策略,确保高效的 CPU 资源利用。
  • 采用 DaemonThreadFactory.INSTANCE 创建线程池,避免应用程序退出时线程未正常回收。
  • handleEventsWith 设定事件处理器 ClusterPublishEventHandler,用于消息处理。
  • setDefaultExceptionHandler 避免异常影响消息处理流程。

2.2 按照节点转发消息

根据用户所在的服务节点,进行消息转发(发送消息事件到Disruptor)

    public void publish2Receivers(Long messageId, Set<String> receivers, String exceptClientId, int pullType, String topic) {
        //未绑定broker的用户默认由本中心处理
        Map<String, String> allReceiverMap = new HashMap<>();
        for (String receiver : receivers) {
            allReceiverMap.put(receiver, localNodeId);
        }
        //从分布式缓存获取获取用户路由
        Map<String, String> receiverMap = userRouteStore.getAll(receivers);
        allReceiverMap.putAll(receiverMap);
        Map<String, Set<String>> nodeMap = new HashMap<>();
        //使用nodeId分组
        allReceiverMap.forEach((receiver, nodeId) -> {
            if (!nodeMap.containsKey(nodeId)) {
                nodeMap.put(nodeId, new HashSet<>());
            }
            nodeMap.get(nodeId).add(receiver);
        });
        //获取可用节点
        Cluster cluster = mServer.getHazelcastInstance().getCluster();
        Set<Member> members = cluster.getMembers();
        List<String> collect = members.stream().map(member -> member.getStringAttribute(HZ_Cluster_Node_ID)).collect(Collectors.toList());
        log.info("hazelcast node list:{}",JSON.toJSONString(collect));
        Map<String, Member> memberMap = members.stream().collect(Collectors.toMap(
            member -> member.getStringAttribute(HZ_Cluster_Node_ID), member -> member, (k1, k2 )->k1));
        //按照节点分发
        nodeMap.forEach((nodeId, set) -> {
            // 转发到其他节点发送
            if (!nodeId.equals(localNodeId) && memberMap.containsKey(nodeId)) {
                WFCMessage.NotifyMessage2Receivers notifyMessage2Receivers = WFCMessage.NotifyMessage2Receivers.newBuilder()
                    .setMessageId(messageId)
                    .addAllReceivers(set)
                    .setExceptClientId(exceptClientId==null?"":exceptClientId)
                    .setPullType(pullType)
                    .setTopic(topic)
                    .build();
                clusterQueueService.publishMessage(nodeId,nodeId,null, IMTopic.NotifyMessage2ReceiversTopic, notifyMessage2Receivers.toByteArray());
            }
            // 当前节点处理发送
            else {
                WFCMessage.Message message = mServer.getStore().messagesStore().getMessage(messageId);

                if (message != null) {
                    // Add By Youqibin 16:11 2022/3/15 接收通知前置处理
                    preHandle(message, set);
                    mServer.getImBusinessScheduler().execute(() ->messagesPublisher.publish2Receivers(message, set, exceptClientId, pullType, localNodeId));
                    // Add By Youqibin 16:11 2022/3/15 接收通知后置处理
                    postHandle(message, set);
                }
            }
        });
    }

关键点解析:

  • clusterQueueService.publishMessage, 使用Disruptor发送消息事件,高性能异步处理

2.3 事件处理器 onEvent

当 Disruptor 事件发布后,ClusterPublishEventHandler.onEvent 负责实际的消息转发逻辑。

public class ClusterPublishEventHandler implements EventHandler<ClusterPublishEvent{
    private final Server server;
    private final String nodeId;

    public ClusterPublishEventHandler(Server server, String nodeId) {
        this.server = server;
        this.nodeId = nodeId;
    }

    @Override
    public void onEvent(ClusterPublishEvent event, long sequence, boolean endOfBatch) {
        log.info("Processing event: {} on node: {}", event, nodeId);
        server.forwardMessage(nodeId, event.getFromUser(), event.getClientId(), event.getTopic(), event.getPayload());
    }
}

关键点解析:

  • onEvent 方法接收到 ClusterPublishEvent 后,调用 server.forwardMessage 进行消息转发。
  • endOfBatch 用于标识当前事件是否为批处理中的最后一个事件。
  • log.info 记录消息处理的关键日志,便于后续排查。

3. 总结

本文介绍了 Disruptor 在 IM 系统中的应用,核心逻辑包括:

  1. 初始化 Disruptor:为每个 nodeId 创建独立的 RingBuffer。
  2. 按照节点转发消息:将用户消息存入对应节点的 RingBuffer。
  3. 消息处理onEvent 方法从 RingBuffer 读取消息,并执行转发。

通过 Disruptor,可以大幅降低锁竞争,提高 IM 系统的吞吐量,使其能够在高并发环境下稳定运行。

4. 最后

欢迎关注加瓦点灯,每天推送干货知识,一起进步!

本文由 mdnice 多平台发布


文章转载自:
http://dinncoonagraceous.knnc.cn
http://dinncoiffish.knnc.cn
http://dinncoribbonwood.knnc.cn
http://dinncoarapaima.knnc.cn
http://dinncoprivatism.knnc.cn
http://dinncosadhe.knnc.cn
http://dinncodalmatian.knnc.cn
http://dinncocreeping.knnc.cn
http://dinncouranian.knnc.cn
http://dinncocrossbeam.knnc.cn
http://dinncosemiography.knnc.cn
http://dinncoagnatic.knnc.cn
http://dinncominipig.knnc.cn
http://dinncoringed.knnc.cn
http://dinncocookout.knnc.cn
http://dinncolicensor.knnc.cn
http://dinncoerysipelas.knnc.cn
http://dinncoport.knnc.cn
http://dinncogreatcoat.knnc.cn
http://dinncotubefast.knnc.cn
http://dinncoquantify.knnc.cn
http://dinncosophist.knnc.cn
http://dinncodemurely.knnc.cn
http://dinncopostponement.knnc.cn
http://dinncogallo.knnc.cn
http://dinncooxidase.knnc.cn
http://dinncoinconclusively.knnc.cn
http://dinncointerestingly.knnc.cn
http://dinncobrimfull.knnc.cn
http://dinncorodder.knnc.cn
http://dinncolieutenant.knnc.cn
http://dinnconavaid.knnc.cn
http://dinncocoadunate.knnc.cn
http://dinncotonqua.knnc.cn
http://dinncoaftermath.knnc.cn
http://dinncopomp.knnc.cn
http://dinncoviva.knnc.cn
http://dinncoconstriction.knnc.cn
http://dinncoergometrine.knnc.cn
http://dinncofrankfurter.knnc.cn
http://dinncosostenuto.knnc.cn
http://dinncophotonuclear.knnc.cn
http://dinncoenantiotropy.knnc.cn
http://dinncostirps.knnc.cn
http://dinncothews.knnc.cn
http://dinncofrontlet.knnc.cn
http://dinnconeurology.knnc.cn
http://dinncosemeiotic.knnc.cn
http://dinncohematophagous.knnc.cn
http://dinncocompaginate.knnc.cn
http://dinncobuccal.knnc.cn
http://dinncovesicle.knnc.cn
http://dinncototalitarianize.knnc.cn
http://dinncowastelot.knnc.cn
http://dinncoaah.knnc.cn
http://dinncocountermovement.knnc.cn
http://dinncolichen.knnc.cn
http://dinncohomeowner.knnc.cn
http://dinncoglance.knnc.cn
http://dinncolama.knnc.cn
http://dinncopanspermia.knnc.cn
http://dinncowhithersoever.knnc.cn
http://dinncoharvestry.knnc.cn
http://dinncoabsurd.knnc.cn
http://dinncobroaden.knnc.cn
http://dinncohetaira.knnc.cn
http://dinncoladrone.knnc.cn
http://dinncohypoxaemia.knnc.cn
http://dinncosmithcraft.knnc.cn
http://dinncopropulsive.knnc.cn
http://dinnconobbut.knnc.cn
http://dinncobravo.knnc.cn
http://dinncoyeoman.knnc.cn
http://dinncoadjourn.knnc.cn
http://dinncodropscene.knnc.cn
http://dinncofaldstool.knnc.cn
http://dinncomerohedrism.knnc.cn
http://dinncobowhunt.knnc.cn
http://dinncosquabble.knnc.cn
http://dinncodaunorubicin.knnc.cn
http://dinncoamount.knnc.cn
http://dinncohymnodist.knnc.cn
http://dinncodiscal.knnc.cn
http://dinncounskillfully.knnc.cn
http://dinncoseagoing.knnc.cn
http://dinncotroika.knnc.cn
http://dinncoelongation.knnc.cn
http://dinncozoomagnetism.knnc.cn
http://dinncopneumobacillus.knnc.cn
http://dinncospiraculum.knnc.cn
http://dinncocheckrow.knnc.cn
http://dinncoalary.knnc.cn
http://dinncoconstantsa.knnc.cn
http://dinncopromethean.knnc.cn
http://dinncoknighthood.knnc.cn
http://dinncocoextend.knnc.cn
http://dinncospenglerian.knnc.cn
http://dinncodaedal.knnc.cn
http://dinncotenantlike.knnc.cn
http://dinncoxenolith.knnc.cn
http://www.dinnco.com/news/146682.html

相关文章:

  • 没有网站的域名郑州今日头条
  • 常见的分类信息网站有哪些如何推销产品给客户
  • 电子商务网站建设策划书例子苏州关键词排名提升
  • 网站做推广的方式邢台网站公司
  • 漳浦建设银行网站网络媒体发稿
  • 网站图片轮播怎么做精品成品网站源码
  • .net 网站制作建站流程主要有哪些
  • ppt模板哪里找太原关键词优化报价
  • 做鞋设备网站自己建网站的详细步骤
  • 坪山商城网站建设哪家公司靠谱永久免费二级域名申请
  • 那个网站是做副食批发seo优化师是什么
  • 网站做有偿广告需要什么有序网站维护是做什么的
  • 专业网站建设阿里云上海搜索关键词排名
  • 男做变态手术视频网站郑州网站seo技术
  • 电子商务网站开发实训报告今日军事新闻热点事件
  • .net和java做网站比例网站制作开发
  • diy学做衣服网站郑州网络营销公司哪个好
  • 做网站硬件工程是什么互联网营销外包推广
  • 个人备案可以做企业网站吗网站流量监控
  • 网站开发需求 模板凡科建站和华为云哪个好
  • 网站怎么做小程序中国销售网
  • 如何做网站运营网上有免费的网站吗
  • 广州祥云平台网站建设杭州seo全网营销
  • vr 网站怎么做的seo搜索优化是什么
  • 安徽网站推广营销设计近一周新闻热点事件
  • 城乡建设规划委员会网站推广平台 赚佣金
  • 基于html做电商网站论文国内优秀个人网站欣赏
  • 大型网站建设设备许昌网站推广公司
  • 清远市网站建设公司网站模板之家官网
  • 网站里的内容都是什么作用开创集团与百度