中间件notify

 

基本概念

Topic和MessageType

二者都是用来区别不同业务发送方发送的消息:

  • Topic:一级消息类型(又名消息主题)。如TRADE,ic-common等不同的消息主题;
  • MessageType:二级消息类型,区别同一Topic主题下的不同类型的消息; 如:TRADE(交易主题)下有2300-trade-created-done(交易创建),2300-trade-success(交易成功)等不同类型的消息

GroupId

又称组名, notify server根据groupId来识别客户端机器, 配置为同一groupId视为同一集群的机器.

因此, 各个业务之间,发送方和订阅方之间的GroupId不能重复.

MessageType和GroupId命名长度最大为64个字符, 且不能包含空格.

消息ID

消息ID是消息唯一标识.

发送方和订阅最好都在日志中记录消息ID,便于排查问题,获取消息ID方法

UniqId.getInstance().bytes2string(stringMessage.getMessageId()) 如果可以建议同时记录下TOPIC、MessageType

订阅关系

订阅方的GroupId和Topic的映射关系.

一个GroupId可以对应多个Topic.

客户端通过spring配置文件配置订阅方需要订阅的消息,在应用启动时,订阅关系会推送到Notify Server.

Notify Server端将这份订阅关系保存,并根据保存在Server上的订阅关系将不断到达消息投给订阅方.

接入申请

申请须知

  • 日常和线上分开申请。预发、线上环境会同时配置到位。

申请地址

日常申请地址 (新平台新规范)

线上申请地址 (线上配置自动同步到预发环境)

预发问题排查地址 (仅供问题排查,接入申请直接在线上完成,会自动同步到预发)

项目接入示例

maven依赖

maven依赖版本详见 (推荐使用Pandora容器2.x + notify-tr-client)

demo工程

  • com.taobao.notify.example.publish.SimplePublisher 发送消息示例
  • com.taobao.notify.example.subscribe.SimpleSubscriber 订阅消息示例
  • com.taobao.notify.example.subscribe.HeaderSubscriber 订阅消息(消息属性过滤表达式订阅)示例
  • com.taobao.notify.example.subscribe.unit.SimpleUnitSubscriber 单元化订阅示例

http://gitlab.alibaba-inc.com/middleware/notify-example

注意

如果是使用HSF1.x老版本,注意要使用com.taobao.hsf.notify.client.NotifyManagerBean

发消息

spring配置片段

<beans>
    <bean id="notifyPublishManager" class="com.taobao.notify.remotingclient.NotifyManagerBean" init-method="init">
        <property name="publishTopics"> <!-- 配置所需发布的topics -->
            <list>
                <value>TOPIC-01</value>
                <value>TOPIC-02</value>
            </list>
        </property>
        <property name="groupId" value="${GroupID}"/> <!-- 发送方的GroupId -->
    </bean>
</beans>

java代码片段

private NotifyManagerBean notifyPublishManager;  

public void sendMessage() {   
    StringMessage stringMessage = new StringMessage();

    //必填属性
    stringMessage.setBody("测试发送消息");
    stringMessage.setTopic(topic);
    stringMessage.setMessageType(messageType);

    //可选属性
    stringMessage.setStringProperty("customHeader", "customValue"); // 设置用户自定义的属性值
    stringMessage.setStringProperty("bizOrderId", "业务主健、方便通过消息轨迹查询");//用long型数字,不支持字符串 
    SendResult result = notifyManager.sendMessage(stringMessage);

    if (result.isSuccess()) {
        // 发送成功后处理
        System.out.println("消息发送成功");
    }else {
        log.warn("消息发送失败,原因:" + result.getErrorMessage()+"messageId:" + UniqId.getInstance().bytes2string(stringMessage.getMessageId()));
    }
}

public NotifyManagerBean getNotifyPublishManager() {
    return notifyPublishManager;
}
public void setNotifyPublishManager(NotifyManagerBean notifyPublishManager) {
    this.notifyPublishManager = notifyPublishManager;
}

收消息

保证消息不丢 就必然可能出现重投的情况,需要订阅者在消息监听器里做好 幂等 ,保证消息收到一次和收到多次的结果是一样的,需要对消息id去重 spring代码片段

<beans>
    <bean id="notifySubscribeManager" class="com.taobao.notify.remotingclient.NotifyManagerBean" init-method="init">
        <property name="subscribeMessages">
            <map>
                <entry key="Topic-01">  <!-- topic -->
                    <map>
                        <entry key="messageType-01">  <!-- messageType-->
                            <bean class="com.taobao.notify.config.SubscriptMsgDetailInfo" />
                        </entry>
                    </map>
                </entry>
            </map>
        </property>
        <property name="groupId" value="${GroupID}"/> <!-- 订阅方的GroupId -->
        <property name="messageListener" ref="messageListener" />   <!-- 消息监听处理器 -->
    </bean>
    <bean id="messageListener" class="com.taobao.notify.comexample.SimpleMessageListener" />
</beans>

订阅方消息监听处理器 SimpleMessageListener.java

import com.taobao.notify.remotingclient.MessageListener;
import com.taobao.notify.remotingclient.MessageStatus;
import com.taobao.notify.message.BytesMessage;
import com.taobao.notify.message.Message;
import com.taobao.notify.message.StringMessage;

public class SimpleMessageListener implements MessageListener{

    public void receiveMessage(Message message, MessageStatus status){
        StringBuilder generalInfo = new StringBuilder();
        generalInfo.append("收到消息");
        generalInfo.append("messageId is:").append(UniqId.getInstance().bytes2string(message.getMessageId()));
        generalInfo.append("topic is:").append(message.getTopic());
        generalInfo.append("messageType is:").append(message.getMessageType());
        generalInfo.append("用户自定义属性:").append(message.getStringProperty("customHeader"));

        /**
         * 只读属性
         */
        generalInfo.append("消息在客户端产生时间:").append(message.getBornTime());
        generalInfo.append("消息到达notify server时间:").append(message.getGMTCreate());
        generalInfo.append("消息最后一次投递时间:").append(message.getGMTLastDelivery());

        //消息 body 处理
        if (message instanceof StringMessage) {
            generalInfo.append("String消息body内容:");
            StringMessage stringMessage = (StringMessage) message;
            generalInfo.append(stringMessage.getBody());
        }
        else if (message instanceof BytesMessage) {
            generalInfo.append("Byte消息body内容:");
            BytesMessage bytesMessage = (BytesMessage) message;
            generalInfo.append(new String(bytesMessage.getBody()));
        }

        System.out.println(generalInfo.toString());

        if(业务处理失败,需要重投){
            status.setRollbackOnly();
            status.setReason("失败原因");
        }
    }
}

关于发送消息超时及重试次数

推荐不修改

1.默认是重试三次

在发送配置里可以配置重试次数

<property name="maxRetry"   value="n"></property>

n为重试次数

2.超时时间是3秒

可以在发送消息手动设置超时时间:message.setClientPostTimeout(MILLISECONDS);

 

 

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/u/185811/blog/877135

### 中间件 Notify 使用方法 #### 1. 基本概念 Notify 是阿里巴巴开发的一款消息中间件,主要用于支持分布式系统的异步通信和事务处理。它特别适合用于实现 BASE 理论中的最终一致性模型[^2]。 #### 2. 配置环境 在使用 Notify 中间件之前,需要配置以下几个核心组件: - **Config Server**: 负责维护 Notify Server 的地址列表。 - **Diamond**: 维护订阅关系,包括 Topic、Message Type 和 Group ID 等信息[^3]。 这些组件可以通过以下方式集成到项目中: ```xml <dependency> <groupId>com.taobao.hsf</groupId> <artifactId>hsf-client</artifactId> <version>1.x</version> </dependency> ``` 如果使用的 HSF 版本较旧(如 HSF 1.x),则需显式引入 `com.taobao.hsf.notify.client.NotifyManagerBean` 来管理消息发送逻辑[^1]。 #### 3. 初始化 Notify 客户端 初始化客户端时,通常会涉及以下参数设置: - **Topic**: 主题名称,定义消息分类。 - **MessageType**: 消息类型,区分不同业务场景的消息。 - **GroupID**: 订阅组标识符,用于分组不同的消费者实例。 以下是初始化代码示例: ```java import com.taobao.hsf.notify.client.NotifyManagerBean; public class NotifyClient { private static final String TOPIC = "example_topic"; private static final String MESSAGE_TYPE = "example_message_type"; private static final String GROUP_ID = "example_group_id"; public void init() { NotifyManagerBean notifyManager = new NotifyManagerBean(); notifyManager.setTopic(TOPIC); notifyManager.setMessageType(MESSAGE_TYPE); notifyManager.setGroupId(GROUP_ID); try { notifyManager.start(); // 启动 Notify 客户端 } catch (Exception e) { System.err.println("Failed to start Notify client: " + e.getMessage()); } } public void sendMessage(String messageContent) { boolean success = notifyManager.sendMessage(messageContent); if (!success) { System.err.println("Failed to send message: " + messageContent); } } } ``` 上述代码展示了如何创建并启动一个 Notify 客户端,并提供了一个简单的消息发送接口。 #### 4. 实现分布式事务 Notify 支持基于消息的分布式事务机制,在某些情况下可以用来替代强一致性的两阶段提交协议。具体来说,通过生产者先写本地日志再发消息的方式,配合消费者的幂等消费能力,可实现最终一致性[^5]。 例如,在用户注册流程中,当用户成功注册后,系统可通过 Notify 将事件广播给其他模块(如支付服务或通知服务)。即使部分下游服务暂时不可用,也不会影响主流程的执行结果。 #### 5. 注意事项 - 如果项目的重点在于顺序消息传递或者实时流计算,则建议考虑 MetaQ 或 RocketMQ 等更适合该场景的产品[^4]。 - 对于 Notify 的部署与运维工作量较大,因为它依赖多个外部服务(如 Config Server 和 Diamond)来协同运作。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值