【mq】從零開始實現 mq-13-註冊鑑權 auth 前景回顧 註冊鑑權 生產者實現 Broker 的處理 小結 開源地址 拓展閱讀

前景回顧

【mq】從零開始實現 mq-01-生產者、消費者啓動

【mq】從零開始實現 mq-02-如何實現生產者調用消費者?

【mq】從零開始實現 mq-03-引入 broker 中間人

【mq】從零開始實現 mq-04-啓動檢測與實現優化

【mq】從零開始實現 mq-05-實現優雅停機

【mq】從零開始實現 mq-06-消費者心跳檢測 heartbeat

【mq】從零開始實現 mq-07-負載均衡 load balance

【mq】從零開始實現 mq-08-配置優化 fluent

【mq】從零開始實現 mq-09-消費者拉取消息 pull message

【mq】從零開始實現 mq-10-消費者拉取消息回執 pull message ack

【mq】從零開始實現 mq-11-消費者消息回執添加分組信息 pull message ack groupName

【mq】從零開始實現 mq-12-消息的批量發送與回執

【mq】從零開始實現 mq-13-註冊鑑權 auth

註冊鑑權

我們前面實現了 mq 的基本功能,不過還是存在一個問題,那就是 mq 沒有進行鑑權。

這就會導致如果部署在公網,任何一個機器都可以連接我們的服務,這顯然是不夠安全的。

生產者實現

屬性

生產者啓動時新增 2 個屬性:

/**
 * 賬戶標識
 * @since 0.1.4
 */
private String appKey;

/**
 * 賬戶密碼
 * @since 0.1.4
 */
private String appSecret;

註冊邏輯調整

註冊時,添加這兩個屬性到服務端。

public void registerToBroker() {
    int successCount = 0;
    for(RpcChannelFuture channelFuture : this.channelFutureList) {
        ServiceEntry serviceEntry = new ServiceEntry();
        serviceEntry.setGroupName(groupName);
        serviceEntry.setAddress(channelFuture.getAddress());
        serviceEntry.setPort(channelFuture.getPort());
        serviceEntry.setWeight(channelFuture.getWeight());

        BrokerRegisterReq brokerRegisterReq = new BrokerRegisterReq();
        brokerRegisterReq.setServiceEntry(serviceEntry);
        brokerRegisterReq.setMethodType(MethodType.P_REGISTER);
        brokerRegisterReq.setTraceId(IdHelper.uuid32());
        brokerRegisterReq.setAppKey(appKey);
        brokerRegisterReq.setAppSecret(appSecret);
        log.info("[Register] 開始註冊到 broker:{}", JSON.toJSON(brokerRegisterReq));
        final Channel channel = channelFuture.getChannelFuture().channel();
        MqCommonResp resp = callServer(channel, brokerRegisterReq, MqCommonResp.class);
        log.info("[Register] 完成註冊到 broker:{}", JSON.toJSON(resp));
        if(MqCommonRespCode.SUCCESS.getCode().equals(resp.getRespCode())) {
            successCount++;
        }
    }
    if(successCount <= 0 && check) {
        log.error("校驗 broker 可用性,可連接成功數爲 0");
        throw new MqException(MqCommonRespCode.P_REGISTER_TO_BROKER_FAILED);
    }
}

消費者

消費者連接到 broker 也是類似的,此處不做贅述。

Broker 的處理

註冊邏輯

以前註冊是直接成功,此處加一個業務判斷。

// 生產者註冊
if(MethodType.P_REGISTER.equals(methodType)) {
    BrokerRegisterReq registerReq = JSON.parseObject(json, BrokerRegisterReq.class);
    if(!brokerRegisterValidService.producerValid(registerReq)) {
        log.error("{} 生產者註冊驗證失敗", JSON.toJSON(registerReq));
        throw new MqException(MqBrokerRespCode.P_REGISTER_VALID_FAILED);
    }

    return registerProducerService.register(registerReq.getServiceEntry(), channel);
}

首先會校驗有效性,這個是一個接口,可自行靈活替換。

其他業務邏輯

其他業務處理時,都需要 registerProducerService.checkValid(channelId); 進行有效性判斷。

// 生產者註銷
if(MethodType.P_UN_REGISTER.equals(methodType)) {
    registerProducerService.checkValid(channelId);

    BrokerRegisterReq registerReq = JSON.parseObject(json, BrokerRegisterReq.class);
    return registerProducerService.unRegister(registerReq.getServiceEntry(), channel);
}

小結

註冊鑑權實現的原理非常簡單,不過可以爲安全性提供最基礎的保障。

希望本文對你有所幫助,如果喜歡,歡迎點贊收藏轉發一波。

我是老馬,期待與你的下次重逢。

開源地址

The message queue in java.(java 簡易版本 mq 實現) https://github.com/houbb/mq

拓展閱讀

rpc-從零開始實現 rpc https://github.com/houbb/rpc

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章