欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

如何在同一個(gè)Java進(jìn)程中連接多個(gè)RocketMQ服務(wù)器-創(chuàng)新互聯(lián)

前言

我們都知道,RocketMQ在代碼級(jí)別對(duì)連接服務(wù)器進(jìn)行了限制,基本上可以理解為一個(gè)JVM進(jìn)程中只能連接一個(gè)NameServer,但實(shí)際應(yīng)用場(chǎng)景中,我們可能會(huì)在架構(gòu)設(shè)計(jì)層面上對(duì)RocketMQ進(jìn)行了職能上的劃分,規(guī)定了A服務(wù)處理A類(lèi)消息,而B(niǎo)服務(wù)處理B類(lèi)消息,這時(shí)我們應(yīng)該如何解決這個(gè)問(wèn)題呢?

成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比寧江網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式寧江網(wǎng)站制作公司更省心,省錢(qián),快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋寧江地區(qū)。費(fèi)用合理售后完善,十年實(shí)體公司更值得信賴。

問(wèn)題的根源

我們從代碼層級(jí)來(lái)分析到底為什么會(huì)產(chǎn)生“一個(gè)JVM實(shí)例只能連接一個(gè)NameServer”。
RocketMQ Client有一個(gè)核心類(lèi)MQClientManager,在我們需要使用MQ Client實(shí)例的時(shí)候,實(shí)際上都是通過(guò)它的getAndCreateMQClientInstance方法進(jìn)行創(chuàng)建的;名稱比較拗口,同時(shí)是GetCreate,這不太符合我們所說(shuō)的設(shè)計(jì)單一性原則,但這不是我們討論的重點(diǎn),我們看一看這個(gè)方法的實(shí)現(xiàn)

public MQClientInstance getAndCreateMQClientInstance(ClientConfig clientConfig, RPCHook rpcHook) {
        String clientId = clientConfig.buildMQClientId();
        MQClientInstance instance = (MQClientInstance)this.factoryTable.get(clientId);
        if (null == instance) {
            instance = new MQClientInstance(clientConfig.cloneClientConfig(), this.factoryIndexGenerator.getAndIncrement(), clientId, rpcHook);
            MQClientInstance prev = (MQClientInstance)this.factoryTable.putIfAbsent(clientId, instance);
            if (prev != null) {
                instance = prev;
                log.warn("Returned Previous MQClientInstance for clientId:[{}]", clientId);
            } else {
                log.info("Created new MQClientInstance for clientId:[{}]", clientId);
            }
        }

        return instance;
    }

代碼不復(fù)雜,我們可以看到它利用客戶的配置信息生成一個(gè)固定的clientId,以此去緩存factoryTable中查找,不存在才會(huì)創(chuàng)建全新一個(gè)實(shí)例。
那么,可以理解一個(gè)clientID僅能存在一個(gè)連接實(shí)例了,可這個(gè)clientId是怎么產(chǎn)生的呢?繼續(xù)跟蹤看看這段代碼

public String buildMQClientId() {
        StringBuilder sb = new StringBuilder();
        sb.append(this.getClientIP());
        sb.append("@");
        sb.append(this.getInstanceName());
        if (!UtilAll.isBlank(this.unitName)) {
            sb.append("@");
            sb.append(this.unitName);
        }

        return sb.toString();
    }

代碼層面上對(duì)clientId進(jìn)行了約定,格式為“ClientIp@InstanceName”格式,當(dāng)unitName不為空的時(shí)候還會(huì)在后面加上“@unitName”。

怎么解決?

從代碼分析上我們可以知道,為了創(chuàng)建多實(shí)例,我們可以

  1. 設(shè)定不同的instanceName:

    instanceName從哪來(lái)的?

    instanceName = System.getProperty("rocketmq.client.name", "DEFAULT");

    從系統(tǒng)屬性中讀取出來(lái)的,也就是一般在JVM啟動(dòng)時(shí)設(shè)定的。。。
    可以變嗎?當(dāng)然,你可以通過(guò)代碼去做到,但這么做的話,你會(huì)失去讓人理解你代碼的能力的,哈哈
    這就是為什么多少RocketMQ Client都只能連接一個(gè)服務(wù)器的原因了,它根本不考慮服務(wù)器是誰(shuí),僅關(guān)心自己,自私的家伙!

  2. 設(shè)定不同的unitName

除此之外還有其它解決方案嗎?我仔細(xì)從網(wǎng)絡(luò)上翻了一輪,沒(méi)看到什么好方法,是大家都沒(méi)這個(gè)場(chǎng)景還是有其它好辦法解決了呢?歡迎大家討論~

方法3

在上一篇博文來(lái)自平行世界的救贖里面,我做了個(gè)工具sandbox,我提供的方法3就是依托于這個(gè)工具。
sandbox通過(guò)代碼隔離的方式,將另一份類(lèi)定義放入沙箱中運(yùn)行,從而實(shí)現(xiàn)多個(gè)實(shí)例完全隔離的效果。
MQClientManager通過(guò)緩存方式,以clientId作為key值存儲(chǔ)到自身實(shí)例當(dāng)中,為了實(shí)現(xiàn)多個(gè)Client,那么前兩種方法的邏輯是修改clientId實(shí)現(xiàn)多個(gè)實(shí)例,而方法3的邏輯則是“既然你的緩存已經(jīng)有這個(gè)key,我就換個(gè)緩存”,本質(zhì)就是“你這個(gè)鍋不裝我,我就換個(gè)鍋”。

怎么做?

這里我使用一個(gè)springboot項(xiàng)目作為演示案例。
通過(guò)springboot的Configuration將多個(gè)RocketMQ Client進(jìn)行注冊(cè),再定義一個(gè)Controller接收不同請(qǐng)求去發(fā)送MQ消息,最后加上啟動(dòng)類(lèi)。
如何在同一個(gè)Java進(jìn)程中連接多個(gè)RocketMQ服務(wù)器
我們先從pom文件中引入包(我沒(méi)有推上maven倉(cāng)庫(kù),各位可以從github/gitee上下載),代碼如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>me.van</groupId>
    <artifactId>rocket-mq-multi-client-test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>測(cè)試多個(gè)rocketmq client共存</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <start-class>me.van.App</start-class>
        <java.version>1.8</java.version>
        <lombok.version>1.14.8</lombok.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-client</artifactId>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>me.van</groupId>
            <artifactId>sandbox</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

此處引入了apache的rocketmq-client組件作為mq客戶端,也就是存在前面所說(shuō)的問(wèn)題的組件。

啟動(dòng)類(lèi)

package me.van;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

非常的簡(jiǎn)單,沒(méi)什么好介紹的。

配置類(lèi)

package me.van;

import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MQProducer;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean(autowire = Autowire.BY_NAME, value = "producer")
    MQProducer producer() throws MQClientException {
        DefaultMQProducer producer = new DefaultMQProducer();
        initProducer(producer, "a.io:9876;b.io:9876");
        return producer;
    }

    @Bean(autowire = Autowire.BY_NAME, value = "producer_sandbox1")
    MQProducer producerSandbox1() throws MQClientException, SandboxCannotCreateObjectException {
        DefaultMQProducer producer = createProducerInSandbox();
        initProducer(producer, "x.io:9876;y.io:9876");
        return producer;
    }

    @Bean(autowire = Autowire.BY_NAME, value = "producer_sandbox2")
    MQProducer producerSandbox2() throws MQClientException, SandboxCannotCreateObjectException {
        DefaultMQProducer producer = createProducerInSandbox();
        initProducer(producer, "1.io:9876;2.io:9876");
        return producer;
    }

    private DefaultMQProducer createProducerInSandbox() throws SandboxCannotCreateObjectException {
        Sandbox sandbox = new Sandbox("org.apache.rocketmq.client");
        return sandbox.createObject(DefaultMQProducer.class);
    }

    private void initProducer(DefaultMQProducer producer, String namesrvAddr) throws MQClientException {
        producer.setNamesrvAddr(namesrvAddr);
        producer.setProducerGroup("test-group");
        producer.setRetryAnotherBrokerWhenNotStoreOK(true);
        producer.start();
    }
}

這里可以看到,producer對(duì)象是直接new 出來(lái)的DefaultMQProducer,而producer_sandbox1producer_sandbox2是通過(guò)不同的沙箱創(chuàng)建出來(lái)的;三個(gè)client分別連接到不同的NameServer中,同時(shí)其它屬性保持一致。

Controller

package me.van;

import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.MQProducer;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @Autowired
    MQProducer producer;
    @Autowired
    MQProducer producer_sandbox1;
    @Autowired
    MQProducer producer_sandbox2;

    @GetMapping("/")
    public String hello(){
        return "hello world";
    }

    @GetMapping("/send")
    public String send(String msg){
        if(null == msg) return "msg is null";

        String returnMsg = "";
        Message message = new Message("topic-test-multi-mq-client", msg.getBytes());
        try {
            producer.send(message);
            returnMsg += "原生producer發(fā)送完成<br/>";

            producer_sandbox1.send(message);
            returnMsg += "第一個(gè)沙箱內(nèi)producer發(fā)送完成<br/>";

            producer_sandbox2.send(message);
            returnMsg += "第二個(gè)沙箱內(nèi)producer發(fā)送完成<br/>";
        } catch (MQClientException | InterruptedException | RemotingException | MQBrokerException e) {
            returnMsg += "發(fā)送過(guò)程出現(xiàn)異常:" + e.getMessage();
        }
        return returnMsg;
    }
}

通過(guò)send方法同時(shí)向三個(gè)producer發(fā)送消息。

測(cè)試一下

運(yùn)行App,等幾秒鐘啟動(dòng)完畢,訪問(wèn)http://localhost:8080/send,返回

msg is null

訪問(wèn),http://localhost:8080/send?msg=test

如何在同一個(gè)Java進(jìn)程中連接多個(gè)RocketMQ服務(wù)器

代碼地址

github: https://github.com/vancoo/multi-mq-demo
gitee: https://gitee.com/vancoo/multi-mq-demo

參考文檔: 來(lái)自平行世界的救贖

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

網(wǎng)站題目:如何在同一個(gè)Java進(jìn)程中連接多個(gè)RocketMQ服務(wù)器-創(chuàng)新互聯(lián)
文章起源:http://aaarwkj.com/article30/peeso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、網(wǎng)站營(yíng)銷(xiāo)、商城網(wǎng)站、網(wǎng)站導(dǎo)航虛擬主機(jī)、網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)
亚洲免费麻豆一区二区三区| 91午夜福利视频在线观看| 天堂中文在线免费观看av| 国产尤物直播在线观看| 成人黄片免费在线播放| 国产一区二区三区百合| 欧美日韩国产一下老妇| 国产午夜视频成人无遮挡 | 视频一区中文字幕在线| 国产午夜精品福利爽爽| 日韩精品中文字幕影视 | 日韩av在线免费在线观看| 国产亚洲中文字幕无线乱码| 中文乱幕亚洲无套内射| 国产精品一区巨乳人妻| 少妇38p高潮在线| 国产亚洲精品久久综合阿香 | 国产精品青青草原在线| 欧美丰满老妇性猛交| 欧美aⅴ精品一区二区三区| 成人黄色三级免费网站| 免费在线观看做性小视频| 青娱乐青青草91在线| 啊啊啊用力好大视频| 日韩中文字幕一区二区不卡| 少妇互射视频免费视频| 国产黄a三级三级三级老师绑| 中文字幕亚洲入口久久| 午夜精品视频免费91| 老熟女露脸吞精一二三四区| 日本少妇人妻中文字幕| 亚洲国产精品二区三区| 国产精品久久久久精品三级下载| 天堂av在线播放观看| 国产亚洲av麻豆精品推荐| 天天干天天干夜夜操| 91人妻精品一区二区| 久久精品一偷一偷国产| 91在线观看高清免费| 人妻日韩精品综合一二三四| 亚洲一区二区精品自拍|