1. 程式人生 > >RabbitMQ系列-實現RPC非同步呼叫

RabbitMQ系列-實現RPC非同步呼叫

使用Spring AMQP實現RPC非同步呼叫

示列

伺服器端

應用啟動類程式碼,

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

import java.util.concurrent.TimeUnit;

@ComponentScan
public class Application {
    public static void main(String[] args) throws Exception{
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
        System.out.println("===server startup======");
        TimeUnit.SECONDS.sleep(120);
        context.close();
    }
}

配置類:
監聽了sms佇列,這個佇列將會是客戶端請求訊息傳送到的佇列,配置了介面卡,介面卡中去呼叫服務,介面卡返回的值就是服務端返回給客戶端的RPC呼叫的結果

import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MQConfig {

    @Bean
    public ConnectionFactory connectionFactory(){
        CachingConnectionFactory factory = new CachingConnectionFactory();
        factory.setUri("amqp://zhihao.miao:
[email protected]
:5672"); return factory; } @Bean public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory){ RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory); return rabbitAdmin; } @Bean public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){ RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory); return rabbitTemplate; } @Bean public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory){ SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(); container.setConnectionFactory(connectionFactory); container.setQueueNames("sms"); container.setAcknowledgeMode(AcknowledgeMode.NONE); //使用介面卡的方式 container.setMessageListener(new MessageListenerAdapter(new SendSMSHandler())); return container; } }

處理器,處理器中呼叫具體的服務,我們此列子中處理器方法返回的值是boolean型別

import java.util.concurrent.TimeUnit;

public class SendSMSHandler {

    public boolean handleMessage(byte[] body){
        String _body = new String(body);
        System.out.println(_body);
        String[] sms = _body.split(":");
        String phone = sms[0];
        String content = sms[1];

        boolean is = SendSMSTool.sendSMS(phone,content);

        try {
            TimeUnit.SECONDS.sleep(6);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return is;
    }
}

服務介面

public class SendSMSTool {

    public static boolean sendSMS(String phone,String content){
        System.out.println("傳送簡訊內容:【"+content+"】到手機號:"+phone);
        return phone.length() > 6;
    }
}

服務端步驟

  1. 訊息處理方法,一定要有返回值,這個返回值就是就是server回覆客戶端的結果。比如我們SendSMSHandler.handleMessage方法返回的值。

客戶端
應用啟動類:

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@ComponentScan
public class Application {
    public static void main(String[] args) throws Exception{
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Application.class);

        RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);

        //設定超時時間,單位是ms
        rabbitTemplate.setReplyTimeout(10000);

        String phone = "15634344321";
        String content ="週年慶,五折優惠";

        MessageProperties messageProperties = new MessageProperties();
        Message message = new Message((phone+":"+content).getBytes(),messageProperties);

        //rabbitTemplate.send("","sms",message);

        Message reply = rabbitTemplate.sendAndReceive("","sms",message,
                new CorrelationData(UUID.randomUUID().toString()));

        System.out.println(reply);
        System.out.println("message,body:"+new String(reply.getBody()));
        System.out.println("message,properties:"+reply.getMessageProperties());

        TimeUnit.SECONDS.sleep(30);
        context.close();
    }
}

配置類程式碼:

import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MQConfig {

    @Bean
    public ConnectionFactory connectionFactory(){
        CachingConnectionFactory factory = new CachingConnectionFactory();
        factory.setUri("amqp://zhihao.miao:[email protected]:5672");
        return factory;
    }

    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory){
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        return rabbitAdmin;
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        return rabbitTemplate;
    }
}

如果服務端睡眠6s,則客戶端通過sendAndReceive方法接收到的Message物件為空,怎樣設定呢?
客戶端通過設定rabbitTemplate.setReplyTimeout(10000);就可以了。

客戶端步驟

  1. 使用sendAndReceive方法傳送訊息,該方法返回一個Message物件,該物件就是server返回的結果
  2. sendAndReceive如果超過5s還沒有收到結果,則返回null,這個超時時間可以通過rabbitTemplate.setReplyTimeout()來進行設定
  3. server端返回的結果一定要注意,和MessageConverter有關,預設的org.springframework.amqp.support.converter.SimpleMessageConverter會把基本的資料型別轉換成Serializable物件,這樣的話,client端接收的也是序列化的java物件,所以,需要合理設定MessageConverter

示列程式碼中服務端返回給客戶端的是Boolean型別,

啟動服務端客戶端程式碼:
伺服器列印控制檯列印:

15634344321:週年慶,五折優惠
傳送簡訊內容:【週年慶,五折優惠】到手機號:15634344321

客戶端控制檯列印:

message,body:����sr��java.lang.Boolean� r�՜�����Z��valuexp�
message,properties:MessageProperties [headers={}, timestamp=null, messageId=null, userId=null, receivedUserId=null, appId=null, clusterId=null, type=null, correlationId=null, correlationIdString=null, replyTo=null, contentType=application/x-java-serialized-object, contentEncoding=null, contentLength=0, deliveryMode=null, receivedDeliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=, receivedRoutingKey=amq.rabbitmq.reply-to.g2dkAB5yYWJiaXRAaVpicDFqY3d4N3NmYjFud3pyZWh5NloAAFu0AAAABwI=.kHL9zxtdQmtcxl0mQF8zrg==, receivedDelay=null, deliveryTag=1, messageCount=null, consumerTag=null, consumerQueue=null]

我們發現客戶端接收到的資料亂碼,將服務端的處理器的返回值改寫成String型別的,

import java.util.concurrent.TimeUnit;

public class SendSMSHandler {

    public String handleMessage(byte[] body){
        String _body = new String(body);
        System.out.println(_body);
        String[] sms = _body.split(":");
        String phone = sms[0];
        String content = sms[1];

        boolean is = SendSMSTool.sendSMS(phone,content);

        try {
            TimeUnit.SECONDS.sleep(6);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return is ? "success":"false";
    }
}

此時發現客戶端接收的訊息資料沒有亂碼,原因何在?我們總結一下就是伺服器端處理器返回給客戶端boolean型別,那麼返回的訊息資料就亂碼,如果返回的是String型別,那麼返回的訊息資料就不會亂碼。

之前我們學習了org.springframework.amqp.support.converter.MessageConverter介面,當客戶端向服務端傳送訊息的時候會進行訊息型別轉換,呼叫了fromMessage方法,而當伺服器返回給客戶端的時候會將服務端的物件轉換成Message物件,很明顯呼叫的是toMessage方法。

我們知道org.springframework.amqp.support.converter.MessageConverter介面的預設實現是org.springframework.amqp.support.converter.SimpleMessageConverter,而toMessage方法的實現是在其繼承的物件AbstractMessageConverter中,

我們看到其AbstractMessageConverter.toMessage方法的實現邏輯是:

    @Override
    public final Message toMessage(Object object, MessageProperties messageProperties)
            throws MessageConversionException {
        if (messageProperties == null) {
            messageProperties = new MessageProperties();
        }
        //將物件轉換成Message物件
        Message message = createMessage(object, messageProperties);
        messageProperties = message.getMessageProperties();
        if (this.createMessageIds && messageProperties.getMessageId() == null) {
            messageProperties.setMessageId(UUID.randomUUID().toString());
        }
        return message;
    }

createMessage方法就是將物件轉換成Message物件,

    /**
     * Creates an AMQP Message from the provided Object.
     */
    @Override
    protected Message createMessage(Object object, MessageProperties messageProperties) throws MessageConversionException {
        byte[] bytes = null;
        if (object instanceof byte[]) {
            bytes = (byte[]) object;
            messageProperties.setContentType(MessageProperties.CONTENT_TYPE_BYTES);
        }
        else if (object instanceof String) {
            try {
                bytes = ((String) object).getBytes(this.defaultCharset);
            }
            catch (UnsupportedEncodingException e) {
                throw new MessageConversionException(
                        "failed to convert to Message content", e);
            }
            messageProperties.setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN);
            messageProperties.setContentEncoding(this.defaultCharset);
        }
        //因為boolean型別實現Serializable介面,所以會將其序列化
        else if (object instanceof Serializable) {
            try {
                bytes = SerializationUtils.serialize(object);
            }
            catch (IllegalArgumentException e) {
                throw new MessageConversionException(
                        "failed to convert to serialized Message content", e);
            }
            messageProperties.setContentType(MessageProperties.CONTENT_TYPE_SERIALIZED_OBJECT);
        }
        if (bytes != null) {
            messageProperties.setContentLength(bytes.length);
        }
        return new Message(bytes, messageProperties);
    }

我們在程式中將序列化物件直接轉換成字串所以亂碼,而返回的是String型別的情形的時候先將字串轉換成相應的位元組陣列,然後返回new Message(bytes, messageProperties);就不會亂碼。

繼續探討,當我們服務端返回的是一個物件的時候,客戶端會返回空
返回的物件:

public class SendStatus {

    private String phone;

    private String result;

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }
}

將該物件返回:

public class SendSMSHandler {

    public SendStatus handleMessage(byte[] body){
        String _body = new String(body);
        System.out.println(_body);
        String[] sms = _body.split(":");
        String phone = sms[0];
        String content = sms[1];

        boolean is = SendSMSTool.sendSMS(phone,content);
        SendStatus sendStatus = new SendStatus();
        sendStatus.setPhone(phone);
        sendStatus.setResult(is ? "SUCCESS":"FAILURE");
        return sendStatus;
    }
}

服務端控制檯:

15634344321:週年慶,五折優惠
傳送簡訊內容:【週年慶,五折優惠】到手機號:15634344321

客戶端:

message,body:
message,properties:MessageProperties [headers={}, timestamp=null, messageId=null, userId=null, receivedUserId=null, appId=null, clusterId=null, type=null, correlationId=null, correlationIdString=null, replyTo=null, contentType=application/octet-stream, contentEncoding=null, contentLength=0, deliveryMode=null, receivedDeliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=, receivedRoutingKey=amq.rabbitmq.reply-to.g2dkAB5yYWJiaXRAaVpicDFqY3d4N3NmYjFud3pyZWh5NloAAFxBAAAABwI=.01fOGW/nvS2nz6gKza+cjg==, receivedDelay=null, deliveryTag=1, messageCount=null, consumerTag=null, consumerQueue=null]

原因何在,因為我們定義的SendStatus不走createMessage中的所有if分支,最後返回的是null,怎麼解決呢,要麼自己去定義一個org.springframework.amqp.support.converter.MessageConverter實現,要麼換一個預設的org.springframework.amqp.support.converter.MessageConverter實現。

改造後的示列

使用AMQP自帶的訊息型別轉換器Jackson2JsonMessageConverter
服務端

應用啟動類,

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

import java.util.concurrent.TimeUnit;

@ComponentScan
public class Application {
    public static void main(String[] args) throws Exception{
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
        System.out.println("===server startup======");
        TimeUnit.SECONDS.sleep(120);
        context.close();
    }
}

配置類,新增自定義的訊息轉換器

import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MQConfig {

    @Bean
    public ConnectionFactory connectionFactory(){
        CachingConnectionFactory factory = new CachingConnectionFactory();
        factory.setUri("amqp://zhihao.miao:[email protected]:5672");
        return factory;
    }

    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory){
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        return rabbitAdmin;
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        return rabbitTemplate;
    }

    @Bean
    public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory){
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames("sms");
        container.setAcknowledgeMode(AcknowledgeMode.NONE);
        //使用介面卡的方式
        container.setMessageListener(new MessageListenerAdapter(new SendSMSHandler(),new Jackson2JsonMessageConverter()));
        return container;
    }
}

處理器handler,返回自定義的SendStatus型別

import java.util.concurrent.TimeUnit;

public class SendSMSHandler {

    public SendStatus handleMessage(byte[] body){
        String _body = new String(body);
        System.out.println(_body);
        String[] sms = _body.split(":");
        String phone = sms[0];
        String content = sms[1];

        boolean is = SendSMSTool.sendSMS(phone,content);
        SendStatus sendStatus = new SendStatus();
        sendStatus.setPhone(phone);
        sendStatus.setResult(is ? "SUCCESS":"FAILURE");

        try {
            TimeUnit.SECONDS.sleep(6);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return sendStatus;
    }
}

介面服務,

public class SendSMSTool {

    public static boolean sendSMS(String phone,String content){
        System.out.println("傳送簡訊內容:【"+content+"】到手機號:"+phone);
        return phone.length() > 6;
    }
}

服務端返回的物件,

public class SendStatus {
    private String phone;

    private String result;

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }
}

客戶端
應用啟動類,

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@ComponentScan
public class Application {
    public static void main(String[] args) throws Exception{
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Application.class);

        RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);

        //設定超時時間,單位是ms
        rabbitTemplate.setReplyTimeout(10000);

        String phone = "15634344321";
        String content ="週年慶,五折優惠";

        MessageProperties messageProperties = new MessageProperties();
        Message message = new Message((phone+":"+content).getBytes(),messageProperties);

        //rabbitTemplate.send("","sms",message);

        Message reply = rabbitTemplate.sendAndReceive("","sms",message,
                new CorrelationData(UUID.randomUUID().toString()));

        System.out.println(reply);
        System.out.println("message,body:"+new String(reply.getBody()));
        System.out.println("message,properties:"+reply.getMessageProperties());

        TimeUnit.SECONDS.sleep(30);
        context.close();
    }
}

配置類

import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MQConfig {

    @Bean
    public ConnectionFactory connectionFactory(){
        CachingConnectionFactory factory = new CachingConnectionFactory();
        factory.setUri("amqp://zhihao.miao:[email protected]:5672");
        return factory;
    }

    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory){
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        return rabbitAdmin;
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        return rabbitTemplate;
    }
}

啟動伺服器客戶端,客戶端返回

message,body:{"phone":"15634344321","result":"SUCCESS"}
message,properties:MessageProperties [headers={__TypeId__=rpc.server.SendStatus}, timestamp=null, messageId=null, userId=null, receivedUserId=null, appId=null, clusterId=null, type=null, correlationId=null, correlationIdString=null, replyTo=null, contentType=application/json, contentEncoding=UTF-8, contentLength=0, deliveryMode=null, receivedDeliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=, receivedRoutingKey=amq.rabbitmq.reply-to

返回了SendStatus的JSON格式,因為使用了Jackson2JsonMessageConverter訊息型別轉換器。

相關推薦

RabbitMQ系列-實現RPC非同步呼叫

使用Spring AMQP實現RPC非同步呼叫 示列 伺服器端 應用啟動類程式碼, import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org

Spring-rabbitmq 實現RPC 風格呼叫例項

1.  背景 專案中原來利用rabbitmq的RPC實現遠端方法呼叫,比較簡陋,封裝的比較差,而且topic等模式均為阻塞,如今我負責進行改造,今天重點看看如何利用spring-rabbitmq實現RPC風格的呼叫 簡單說來,RPC,主要目的是利用message實現遠端方

徒手擼框架--實現 RPC 遠端呼叫

微服務,已經是每個網際網路開發者必須掌握的一項技術。而 RPC 框架,是構成微服務最重要的組成部分之一。趁最近有時間。又看了看 dubbo 的原始碼。dubbo 為了做到靈活和解耦,使用了大量的設計模式和 SPI機制,要看懂 dubbo 的程式碼也不太容易。 按

使用 ActiveMQ 實現JMS 非同步呼叫

目錄 簡介 啟動 ActiveMQ 伺服器 檢視控制檯 ActiveMQ 的訊息通道 Queue Topic 比較 開發生產者和消費者 開發服務端(消費者) 開發客戶端(生產者) 參考 簡介 服務之間的同步

在AngularJS中是如何實現資料非同步呼叫的?

     $q服務是AngularJS封裝的一種輕量級的 Promise實現。$q服務既可呼叫它的構造器(呼叫構造器時返回一個Promise物件),也可呼叫如下方法。      1.defer():建立一個deferred物件,這個物件可以執行幾個常用的方法,比如resolv

python實現rpc遠端呼叫

    遠端呼叫就是將物件名、函式名、引數等傳遞給遠端伺服器,伺服器將處理結果返回給客戶端。 遠端呼叫使得呼叫遠端伺服器的物件、方法的方式就和呼叫本地物件、方法的方式差不多,因為我們通過網路程式設計把這些都隱藏起來了。遠端呼叫是分散式系統的基礎。 遠端呼叫一般分為兩種,遠

RabbitMQ系列之六 Spring RabbitMQ整合實現案例之 非同步郵件傳送

摘要:給使用者傳送郵件的場景,其實也是比較常見的,比如使用者註冊需要郵箱驗證,使用者異地登入傳送郵件通知等等,在這裡我以 RabbitMQ 實現非同步傳送郵件。 專案git地址:https://github.com/gitcaiqing/RabbitMQ-Email 1.專案結構 2.

Spring Boot 基礎系列教程 | 第三十二篇:使用@Async實現非同步呼叫:自定義執行緒池

推薦 Spring Boot/Cloud 視訊: 在之前的Spring Boot基礎教程系列中,已經通過《Spring Boot中使用@Async實現非同步呼叫》一文介紹過如何使用@Async註解來實現非同步呼叫了。但是,對於這些非同步執行的控制是我們保障自身

Springboot+rabbitmq如何實現高併發的rpc呼叫

        一.背景         公司專案的收單前置服務A與收單服務B之間是通過rabbitmq來通訊的,而且A服務在給B服務傳送資訊後,必須收到返回結果(同步通知),於是使用了此方法: rabbitTemplate.convertSendAndReceive(r

使用 RabbitMQ 實現非同步呼叫

目錄 引言 啟動 RabbitMQ 伺服器 執行 rabbitmq 容器 RabbitMQ 控制檯 Exchange 和 Queue 開發服務端和客戶端 開發服務端 開發客戶端 Java Bean 型別傳輸 結語

Python操作rabbitmq系列(六):進行RPC調用

block 異常 遠程 轉換 調用 成了 mage chang 多少 此刻,我們已經進入第6章,是官方的最後一個環節,但是,並非本系列的最後一個環節。因為在實戰中還有一些經驗教訓,並沒體現出來。由於馬上要給同事沒培訓celery了。我也來不及寫太多。等後面,我們再慢慢補充。

RabbitMq初探——用隊列實現RPC

await 生產 通過 empty 分享 qos load lose ima rabbitmq構造rpc 前言 rpc——remote procedure call 遠程調用。在我接觸的使用過http協議、thrift框架來實現遠程調用。其實消息隊列rabbitmq也

Python-RabbitMQ消息隊列實現rpc

llb author bject roc read uuid tin rip rabbit 客戶端通過發送命令來調用服務端的某些服務,服務端把結果再返回給客戶端 這樣使得RabbitMQ的消息發送端和接收端都能發送消息 返回結果的時候需要指定另一個隊列 服務器端 # -

JAVA RPC遠端呼叫伺服器實現使用者登入、註冊

先來百科掃盲 : 什麼是 RPC(反正我也剛看的) RPC(Remote Procedure Call)—遠端過程呼叫,它是一種通過網路從遠端計算機程式上請求服務,而不需要了解底層網路技術的協議。RPC協議假定某些傳輸協議的存在,如TCP或UDP,為通訊程式之間攜帶資訊資料。在OSI

Spring Boot2.0之@Async實現非同步呼叫

 補充一個知識點: lombok底層原理使用的是: 位元組碼技術ASM修改位元組碼檔案,生成比如類似於get() set( )方法 一定要在開發工具安裝 在編譯時候修改位元組碼檔案(底層使用位元組碼技術),線上環境使用編譯好的檔案   下面我們學習 Spring Boot 非同步呼

Aittit rpc實現協議 JSON-RPC XML-RPC . Ws協議webservice 目錄 1. XML-RPC協議 1 1.1. JSON-RPC遠端呼叫協議 - CieloSun

Aittit rpc的實現協議  JSON-RPC XML-RPC . Ws協議webservice   目錄 1. XML-RPC協議 1 1.1. JSON-RPC遠端呼叫協議 - CieloSun - 部落格園.html 1 1.2.

java實現非同步呼叫例項

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Dubbo非同步呼叫實現

具體原理和介紹參看dubbo官方文件: http://dubbo.apache.org/zh-cn/docs/user/demos/async-call.html   1. 當使用非同步呼叫時建議要和原有api進行區別,即將同步呼叫和非同步呼叫的api介面分離 2.a

RabbitMQ系列之七 分散式訊息佇列應用場景之非同步處理、應用解耦、流量削鋒和訊息通訊理解分析

摘要:訊息佇列中介軟體是分散式系統中重要的元件,主要解決應用耦合,非同步訊息,流量削鋒等問題。實現高效能,高可用,可伸縮和最終一致性架構。是大型分散式系統不可缺少的中介軟體。 目前在生產環境,使用較多的訊息佇列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,

RabbitMQ的學習(五):(最全面)Spring整合RabbitMQ進行RPC遠端呼叫

前面用java簡單對rabbitmq進行了學習,但rabbitmq的功能遠非如此,配合Spring或Springboot進行開發,才是java工程師做的工作,下面直接進行實戰: 一、建立SSM專案 PS初期web專案下載地址(單純的web,用於練習): https://downloa