├── .gitignore ├── amqp-cpp11-demo ├── .gitignore ├── CMakeLists.txt ├── README.md ├── demos │ ├── Consumer.cpp │ └── Producer.cpp └── include │ ├── AmqpDemo.h │ └── DemoHandler.h ├── amqp-dotnet-demo ├── .gitignore ├── Receive │ ├── Receive.cs │ └── Receive.csproj └── Send │ ├── Send.cs │ └── Send.csproj ├── amqp-go-demo ├── amqp091 │ ├── pub │ │ └── producer.go │ └── sub │ │ └── consumer.go ├── demo │ ├── Consumer.go │ └── Publisher.go ├── go.mod └── go.sum ├── amqp-java-demo ├── pom.xml └── src │ └── main │ └── java │ ├── Config.java │ ├── ConnectionFactory.java │ ├── Consumer.java │ └── Producer.java ├── amqp-node-demo ├── README.md ├── consume.js ├── package.json └── send.js ├── amqp-php-demo ├── composer.json ├── composer.lock ├── config.php ├── demos │ ├── receive.php │ ├── receiveWithProp.php │ ├── send.php │ └── sendWithProp.php └── index.php ├── amqp-python-celery-demo ├── README.md └── test_celery │ ├── __init__.py │ ├── __init__.pyc │ ├── celery.py │ ├── celery.pyc │ ├── run_tasks.py │ ├── tasks.py │ └── tasks.pyc ├── amqp-python-demo ├── README.md ├── blockingConnectionConsumeWithRecovery.py ├── connection.py ├── connection.pyc ├── receive.py └── send.py ├── amqp-ruby-demo ├── receive.rb └── send.rb ├── amqp-springboot-demo └── SprintBootDemo │ ├── .gitignore │ ├── .idea │ ├── compiler.xml │ ├── encodings.xml │ ├── inspectionProfiles │ │ └── Project_Default.xml │ ├── libraries │ │ ├── Maven__ch_qos_logback_logback_classic_1_2_3.xml │ │ ├── Maven__ch_qos_logback_logback_core_1_2_3.xml │ │ ├── Maven__com_google_guava_guava_19_0.xml │ │ ├── Maven__com_jayway_jsonpath_json_path_2_4_0.xml │ │ ├── Maven__com_rabbitmq_amqp_client_5_4_3.xml │ │ ├── Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml │ │ ├── Maven__javax_annotation_javax_annotation_api_1_3_2.xml │ │ ├── Maven__junit_junit_4_12.xml │ │ ├── Maven__net_bytebuddy_byte_buddy_1_9_7.xml │ │ ├── Maven__net_bytebuddy_byte_buddy_agent_1_9_7.xml │ │ ├── Maven__net_minidev_accessors_smart_1_2.xml │ │ ├── Maven__net_minidev_json_smart_2_3.xml │ │ ├── Maven__org_apache_commons_commons_lang3_3_4.xml │ │ ├── Maven__org_apache_logging_log4j_log4j_api_2_11_1.xml │ │ ├── Maven__org_apache_logging_log4j_log4j_to_slf4j_2_11_1.xml │ │ ├── Maven__org_assertj_assertj_core_3_11_1.xml │ │ ├── Maven__org_hamcrest_hamcrest_core_1_3.xml │ │ ├── Maven__org_hamcrest_hamcrest_library_1_3.xml │ │ ├── Maven__org_mockito_mockito_core_2_23_4.xml │ │ ├── Maven__org_objenesis_objenesis_2_6.xml │ │ ├── Maven__org_ow2_asm_asm_5_0_4.xml │ │ ├── Maven__org_skyscreamer_jsonassert_1_5_0.xml │ │ ├── Maven__org_slf4j_jul_to_slf4j_1_7_25.xml │ │ ├── Maven__org_slf4j_slf4j_api_1_7_25.xml │ │ ├── Maven__org_springframework_amqp_spring_amqp_2_1_3_RELEASE.xml │ │ ├── Maven__org_springframework_amqp_spring_rabbit_2_1_3_RELEASE.xml │ │ ├── Maven__org_springframework_boot_spring_boot_2_1_2_RELEASE.xml │ │ ├── Maven__org_springframework_boot_spring_boot_autoconfigure_2_1_2_RELEASE.xml │ │ ├── Maven__org_springframework_boot_spring_boot_starter_2_1_2_RELEASE.xml │ │ ├── Maven__org_springframework_boot_spring_boot_starter_amqp_2_1_2_RELEASE.xml │ │ ├── Maven__org_springframework_boot_spring_boot_starter_logging_2_1_2_RELEASE.xml │ │ ├── Maven__org_springframework_boot_spring_boot_starter_test_2_1_2_RELEASE.xml │ │ ├── Maven__org_springframework_boot_spring_boot_test_2_1_2_RELEASE.xml │ │ ├── Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_1_2_RELEASE.xml │ │ ├── Maven__org_springframework_retry_spring_retry_1_2_3_RELEASE.xml │ │ ├── Maven__org_springframework_spring_aop_5_1_4_RELEASE.xml │ │ ├── Maven__org_springframework_spring_beans_5_1_4_RELEASE.xml │ │ ├── Maven__org_springframework_spring_context_5_1_4_RELEASE.xml │ │ ├── Maven__org_springframework_spring_core_5_1_4_RELEASE.xml │ │ ├── Maven__org_springframework_spring_expression_5_1_4_RELEASE.xml │ │ ├── Maven__org_springframework_spring_jcl_5_1_4_RELEASE.xml │ │ ├── Maven__org_springframework_spring_messaging_5_1_4_RELEASE.xml │ │ ├── Maven__org_springframework_spring_test_5_1_4_RELEASE.xml │ │ ├── Maven__org_springframework_spring_tx_5_1_4_RELEASE.xml │ │ ├── Maven__org_xmlunit_xmlunit_core_2_6_2.xml │ │ └── Maven__org_yaml_snakeyaml_1_23.xml │ ├── misc.xml │ ├── modules.xml │ ├── uiDesigner.xml │ └── workspace.xml │ ├── pom.xml │ ├── readme │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── alibaba │ │ │ ├── DemoApplication.java │ │ │ └── rabbit │ │ │ ├── RabbitConfig.java │ │ │ ├── RabbitConfirmCallback.java │ │ │ ├── RabbitReturnCallback.java │ │ │ ├── Receiver.java │ │ │ ├── Sender.java │ │ │ ├── SenderWithCallback.java │ │ │ └── TestSenderController.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── alibaba │ └── DemoApplicationTests.java ├── amqp-springcloud-stream-demo └── amqp-demo │ ├── pom.xml │ ├── readme │ └── src │ └── main │ ├── java │ └── com │ │ └── mynotes │ │ └── spring │ │ ├── Application.java │ │ ├── channel │ │ └── AmqpGreetingChannel.java │ │ ├── config │ │ └── RabbitConfig.java │ │ ├── consumer │ │ ├── AckModelChecker.java │ │ └── ConsumerReceiver.java │ │ ├── producer │ │ └── ProducerController.java │ │ └── service │ │ ├── AmqpConsumeService.java │ │ ├── AmqpConsumeServiceImpl.java │ │ ├── AmqpGreetingService.java │ │ └── AmqpGreetingServiceImpl.java │ └── resources │ └── application.properties ├── amqp-springcloudbus-demo ├── config-client │ ├── pom.xml │ ├── readme │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── alibaba │ │ │ │ ├── ConfigClientApplication.java │ │ │ │ └── rabbit │ │ │ │ └── RabbitConfig.java │ │ └── resources │ │ │ └── bootstrap.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── alibaba │ │ └── ConfigClientApplicationTests.java ├── config-server │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── alibaba │ │ │ │ └── ConfigServerApplication.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── alibaba │ │ └── ConfigServerApplicationTests.java ├── eureka-server │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── alibaba │ │ │ │ └── EurekaServerApplication.java │ │ └── resources │ │ │ └── application.yml │ │ └── test │ │ └── java │ │ └── com │ │ └── alibaba │ │ └── EurekaServerApplicationTests.java ├── pom.xml └── readme └── spring-rabbit-demo ├── .idea ├── compiler.xml ├── inspectionProfiles │ └── Project_Default.xml ├── libraries │ ├── Maven__aopalliance_aopalliance_1_0.xml │ ├── Maven__com_fasterxml_jackson_core_jackson_annotations_2_5_0.xml │ ├── Maven__com_fasterxml_jackson_core_jackson_core_2_5_1.xml │ ├── Maven__com_fasterxml_jackson_core_jackson_databind_2_5_1.xml │ ├── Maven__com_rabbitmq_amqp_client_3_6_3.xml │ ├── Maven__com_rabbitmq_http_client_1_0_0_RELEASE.xml │ ├── Maven__commons_codec_commons_codec_1_6.xml │ ├── Maven__commons_logging_commons_logging_1_2.xml │ ├── Maven__org_apache_httpcomponents_httpclient_4_3_6.xml │ ├── Maven__org_apache_httpcomponents_httpcore_4_3_3.xml │ ├── Maven__org_springframework_amqp_spring_amqp_1_6_1_RELEASE.xml │ ├── Maven__org_springframework_amqp_spring_rabbit_1_6_1_RELEASE.xml │ ├── Maven__org_springframework_retry_spring_retry_1_1_3_RELEASE.xml │ ├── Maven__org_springframework_spring_aop_4_2_7_RELEASE.xml │ ├── Maven__org_springframework_spring_beans_4_2_7_RELEASE.xml │ ├── Maven__org_springframework_spring_context_4_2_7_RELEASE.xml │ ├── Maven__org_springframework_spring_core_4_2_7_RELEASE.xml │ ├── Maven__org_springframework_spring_expression_4_2_7_RELEASE.xml │ ├── Maven__org_springframework_spring_messaging_4_2_7_RELEASE.xml │ ├── Maven__org_springframework_spring_tx_4_2_7_RELEASE.xml │ └── Maven__org_springframework_spring_web_4_2_7_RELEASE.xml ├── misc.xml └── modules.xml ├── pom.xml └── src └── main ├── java └── com │ └── alibaba │ └── rabbit │ └── spring │ ├── MessageReceiver.java │ └── SpringMain.java └── resources └── spring-rabbitmq.xml /.gitignore: -------------------------------------------------------------------------------- 1 | *dependency-reduced-pom.xml 2 | .classpath 3 | .project 4 | .settings/ 5 | target/ 6 | devenv 7 | *.log* 8 | *.iml 9 | *.pid 10 | .idea/ 11 | *.versionsBackup 12 | !NOTICE-BIN 13 | !LICENSE-BIN 14 | .DS_Store 15 | vendor 16 | -------------------------------------------------------------------------------- /amqp-cpp11-demo/.gitignore: -------------------------------------------------------------------------------- 1 | cmake-build-debug/ 2 | build/ 3 | -------------------------------------------------------------------------------- /amqp-cpp11-demo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.27) 2 | project(amqp_cpp11_demo) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build/bin) 6 | 7 | # 设置正确的依赖安装路径 8 | #find_package(amqpcpp REQUIRED) 9 | #find_package(uv REQUIRED) 10 | 11 | set(AMQPCPP_INCLUDE_DIR /usr/local/include) 12 | set(AMQPCPP_LIBRARY_DIRS /usr/local/lib/) 13 | 14 | set(UV_INCLUDE_DIR /usr/local/include) 15 | set(UV_LIBRARY_DIRS /usr/local/lib/) 16 | 17 | include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/include) 18 | include_directories(${AMQPCPP_INCLUDE_DIR}) 19 | include_directories(${UV_INCLUDE_DIR}) 20 | 21 | link_directories(${AMQPCPP_LIBRARY_DIRS}) 22 | link_directories(${UV_LIBRARY_DIRS}) 23 | 24 | link_libraries("amqpcpp") 25 | link_libraries("uv") 26 | 27 | add_executable(amqp_cpp_producer_demo 28 | demos/Producer.cpp 29 | ) 30 | add_executable(amqp_cpp_consumer_demo 31 | demos/Consumer.cpp 32 | ) 33 | -------------------------------------------------------------------------------- /amqp-cpp11-demo/README.md: -------------------------------------------------------------------------------- 1 | amqp-cpp11-demo 2 | ======== 3 | 4 | 如何使用amqpcpp库连接aliyun RabbitMQ收发消息的示例. 5 | 6 | 依赖 7 | ======== 8 | Demo工程使用cmake构建工具,确保已经安装cmake。 9 | 确保你已经安装 amqp-cpp, libuv库。确保CMakeList.txt中设置正确的依赖安装路径。 10 | ```` 11 | 12 | #设置正确的依赖安装路径 13 | 14 | #find_package(amqpcpp REQUIRED) 15 | #find_package(uv REQUIRED) 16 | 17 | set(AMQPCPP_INCLUDE_DIR /usr/local/include) 18 | set(AMQPCPP_LIBRARY_DIRS /usr/local/lib/) 19 | 20 | set(UV_INCLUDE_DIR /usr/local/include) 21 | set(UV_LIBRARY_DIRS /usr/local/lib/) 22 | ```` 23 | 24 | 编译 25 | ======== 26 | 27 | 进入目录文件夹,创建build目录,并执行: 28 | 29 | ```bash 30 | mkdir build && cd build 31 | cmake .. 32 | make 33 | ```` 34 | 35 | 构建完成后,在build/bin目录下会出现可执行文件: 36 | 37 | ```` 38 | amqp_cpp_consumer_demo 39 | amqp_cpp_producer_demo 40 | ```` 41 | 42 | 直接运行就可以收发消息。 43 | 44 | 45 | -------------------------------------------------------------------------------- /amqp-cpp11-demo/demos/Consumer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "DemoHandler.h" 6 | #include "AmqpDemo.h" 7 | 8 | int main(int argc, char *argv[]) { 9 | auto *mainLoop = uv_default_loop(); 10 | DemoHandler handler(mainLoop); 11 | AMQP::Address address(AmqpDemo::AmqpDemoUtil::BuildAliyunRabbitMQConnectionUrl()); 12 | AMQP::TcpConnection connection(&handler, address); 13 | AMQP::TcpChannel channel(&connection); 14 | channel.consume(AmqpDemo::AMQP_QUEUE_NAME) 15 | .onSuccess([](const std::string &consumerTag) { 16 | std::cout << "Consumer registered with tag: " << consumerTag << std::endl; 17 | }) 18 | .onReceived([&channel](const AMQP::Message &message, uint64_t deliveryTag, bool redelivered) { 19 | std::string msgBody(message.body()); 20 | msgBody.resize(message.bodySize()); 21 | std::cout << "Received message: " << msgBody << std::endl; 22 | channel.ack(deliveryTag); 23 | }); 24 | 25 | uv_run(mainLoop, UV_RUN_DEFAULT); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /amqp-cpp11-demo/demos/Producer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "DemoHandler.h" 7 | #include "AmqpDemo.h" 8 | 9 | const int COUNT = 10; 10 | const int INTERVAL = 1; 11 | 12 | int main(int argc, char *argv[]) { 13 | auto *mainLoop = uv_default_loop(); 14 | DemoHandler handler(mainLoop); 15 | AMQP::Address address(AmqpDemo::AmqpDemoUtil::BuildAliyunRabbitMQConnectionUrl()); 16 | AMQP::TcpConnection connection(&handler, address); 17 | AMQP::TcpChannel channel(&connection); 18 | channel.declareExchange(AmqpDemo::AMQP_EXCHANGE_NAME, AMQP::ExchangeType::direct, AMQP::durable) 19 | .onSuccess([&channel]() { 20 | std::cout << "Declare exchange success." << std::endl; 21 | }) 22 | .onError([](const char *message) { 23 | std::cerr << "Declare exchange error:" << message << std::endl; 24 | }); 25 | channel.declareQueue(AmqpDemo::AMQP_QUEUE_NAME, AMQP::durable) 26 | .onSuccess([&channel](const std::string &name, uint32_t messagecount, uint32_t consumercount) { 27 | std::cout << "Declare queue success." << std::endl; 28 | }).onError([](const char *message) { 29 | std::cerr << "Declare queue error:" << message << std::endl; 30 | }); 31 | channel.bindQueue(AmqpDemo::AMQP_EXCHANGE_NAME, AmqpDemo::AMQP_QUEUE_NAME, AmqpDemo::AMQP_ROUTING_KEY) 32 | .onSuccess([]() { 33 | std::cout << "Bind queue success." << std::endl; 34 | }).onError([](const char *message) { 35 | std::cerr << "Bind queue error:" << message << std::endl; 36 | }); 37 | 38 | std::cout << "Producer demo Started, Press CTRL + C to stop." << std::endl; 39 | std::atomic running(true); 40 | 41 | // 启动定时器线程定期发送消息 42 | std::thread timerThread([](std::atomic &running, int interval, AMQP::TcpChannel *channel) { 43 | int count = 0; 44 | while (running.load() && count < COUNT) { 45 | std::this_thread::sleep_for(std::chrono::seconds(interval)); 46 | if (running.load()) { 47 | std::string msg = 48 | "Hello World [" + AmqpDemo::AmqpDemoUtil::GetCurrentTimeString() + "]! I am CPP AMQP[" + 49 | std::to_string(count) + "]"; 50 | bool success = channel->publish(AmqpDemo::AMQP_EXCHANGE_NAME, AmqpDemo::AMQP_ROUTING_KEY, msg); 51 | std::cout << std::boolalpha << " [x] Sent " << msg << "' :" << success << std::endl; 52 | count++; 53 | } 54 | } 55 | running.store(false); // 停止定时器 56 | }, std::ref(running), INTERVAL, &channel); 57 | uv_run(mainLoop, UV_RUN_DEFAULT); 58 | timerThread.join(); 59 | std::cout << std::noboolalpha << "Producer demo finished." << std::endl; 60 | 61 | uv_loop_close(mainLoop); 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /amqp-cpp11-demo/include/AmqpDemo.h: -------------------------------------------------------------------------------- 1 | #ifndef AMQP_CPP_DEMO_AMQPDEMO_H 2 | #define AMQP_CPP_DEMO_AMQPDEMO_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace AmqpDemo { 9 | 10 | const std::string AMQP_ENDPOINT = "rabbitmq-xxxxx.mq.amqp.aliyuncs.com"; // AMQP控制台获取 11 | const int AMQP_PORT = 5672; 12 | const std::string AMQP_VHOST = "your-vhost"; // AMQP控制台获取 13 | const std::string AMQP_USERNAME = "user_name"; // AMQP控制台获取 14 | const std::string AMQP_PASSWORD = "password"; // AMQP控制台获取 15 | const std::string AMQP_EXCHANGE_NAME = "your-exchange"; // AMQP控制台获取 16 | const std::string AMQP_QUEUE_NAME = "your-queue"; // AMQP控制台获取 17 | const std::string AMQP_ROUTING_KEY = "your-routing-key"; // AMQP控制台获取 18 | 19 | class AmqpDemoUtil { 20 | public: 21 | static std::string BuildAliyunRabbitMQConnectionUrl() { 22 | return "amqp://" + AMQP_USERNAME + ":" + AMQP_PASSWORD + "@" + AMQP_ENDPOINT + ":" + 23 | std::to_string(AMQP_PORT) + "/" + AMQP_VHOST; 24 | } 25 | 26 | static std::string GetCurrentTimeString() { 27 | // 获取当前时间点 28 | auto now = std::chrono::system_clock::now(); 29 | 30 | // 转换为 time_t 类型 31 | std::time_t now_time_t = std::chrono::system_clock::to_time_t(now); 32 | 33 | // 转换为 tm 结构体 34 | std::tm now_tm = *std::localtime(&now_time_t); 35 | 36 | // 使用 stringstream 格式化时间 37 | std::ostringstream oss; 38 | oss << std::put_time(&now_tm, "%Y-%m-%d %H:%M:%S"); 39 | 40 | return oss.str(); 41 | } 42 | }; 43 | 44 | 45 | } 46 | #endif //AMQP_CPP_DEMO_AMQPDEMO_H 47 | -------------------------------------------------------------------------------- /amqp-cpp11-demo/include/DemoHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef AMQP_CPP_DEMO_DEMOHANDLER_H 2 | #define AMQP_CPP_DEMO_DEMOHANDLER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class DemoHandler : public AMQP::LibUvHandler { 9 | public: 10 | DemoHandler(uv_loop_t *loop); 11 | virtual ~DemoHandler() = default; 12 | 13 | private: 14 | virtual void onConnected(AMQP::TcpConnection *connection) override { 15 | std::cout << "Connected." << std::endl; 16 | } 17 | 18 | virtual void onError(AMQP::TcpConnection *connection, const char *message) override { 19 | std::cout << "Error: " << message << std::endl; 20 | } 21 | 22 | virtual void onClosed(AMQP::TcpConnection *connection) override { 23 | std::cout << "Closed." << std::endl; 24 | } 25 | 26 | virtual void onReady(AMQP::TcpConnection *connection) override { 27 | std::cout << "Ready." << std::endl; 28 | } 29 | }; 30 | 31 | DemoHandler::DemoHandler(uv_loop_t *loop) : LibUvHandler(loop) { 32 | 33 | } 34 | 35 | #endif //AMQP_CPP_DEMO_DEMOHANDLER_H 36 | -------------------------------------------------------------------------------- /amqp-dotnet-demo/.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj 3 | -------------------------------------------------------------------------------- /amqp-dotnet-demo/Receive/Receive.cs: -------------------------------------------------------------------------------- 1 | using RabbitMQ.Client; 2 | using RabbitMQ.Client.Events; 3 | using System; 4 | using System.Security.Authentication; 5 | using System.Text; 6 | 7 | class Receive 8 | { 9 | public static void Main() 10 | { 11 | var factory = new ConnectionFactory(); 12 | /*接入点*/ 13 | factory.HostName = "rabbitmq-xxxxx.mq.amqp.aliyuncs.com"; 14 | /*阿里云AMQP的UserNAme*/ 15 | factory.UserName = "UserName"; 16 | /*阿里云AMQO的Password*/ 17 | factory.Password = "pwd"; 18 | factory.VirtualHost = "your-vhost"; 19 | /*默认端口*/ 20 | factory.Port = 5672; 21 | factory.TopologyRecoveryEnabled = true; 22 | 23 | String yourQueue = "your-queue"; 24 | 25 | if (factory.Port == 5671) 26 | { 27 | var Ssl = new SslOption 28 | { 29 | Enabled = true, 30 | AcceptablePolicyErrors = System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors 31 | | System.Net.Security.SslPolicyErrors.RemoteCertificateNameMismatch 32 | | System.Net.Security.SslPolicyErrors.RemoteCertificateNotAvailable, 33 | Version = SslProtocols.Tls12 34 | }; 35 | factory.Ssl = Ssl; 36 | } 37 | 38 | using (var connection = factory.CreateConnection()) 39 | using (var channel = connection.CreateModel()) 40 | { 41 | channel.QueueDeclare(queue: yourQueue, durable: true, exclusive: false, autoDelete: false, arguments: null); 42 | 43 | var consumer = new EventingBasicConsumer(channel); 44 | String consumerTag = "myConsumerTag"; 45 | consumer.Received += (model, ea) => 46 | { 47 | var body = ea.Body; 48 | var message = Encoding.UTF8.GetString(body); 49 | Console.WriteLine(" [x] Received {0}", message); 50 | }; 51 | channel.BasicConsume(queue: yourQueue, autoAck: true, consumerTag: consumerTag, consumer: consumer); 52 | 53 | Console.WriteLine(" Press [enter] to exit."); 54 | Console.ReadLine(); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /amqp-dotnet-demo/Receive/Receive.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-dotnet-demo/Send/Send.cs: -------------------------------------------------------------------------------- 1 | using RabbitMQ.Client; 2 | using RabbitMQ.Client.Exceptions; 3 | using System; 4 | using System.Security.Authentication; 5 | using System.Text; 6 | using System.Threading; 7 | 8 | class Send 9 | { 10 | public static void Main() 11 | { 12 | var factory = new ConnectionFactory(); 13 | /*接入点*/ 14 | factory.HostName = "rabbitmq-xxxx.mq.amqp.aliyuncs.com"; 15 | /*阿里云AMQP的UserNAme*/ 16 | factory.UserName = "username"; 17 | /*阿里云AMQO的Password*/ 18 | factory.Password = "pwd"; 19 | factory.VirtualHost = "your-vhost"; 20 | /*默认端口*/ 21 | factory.Port = 5672; 22 | factory.TopologyRecoveryEnabled = true; 23 | 24 | String yourQueue = "your-queue"; 25 | String yourExchange = "your-exchange"; 26 | String yourRouterKey = "your-routing-key"; 27 | 28 | 29 | if (factory.Port == 5671) 30 | { 31 | var Ssl = new SslOption 32 | { 33 | Enabled = true, 34 | AcceptablePolicyErrors = System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors 35 | | System.Net.Security.SslPolicyErrors.RemoteCertificateNameMismatch 36 | | System.Net.Security.SslPolicyErrors.RemoteCertificateNotAvailable, 37 | Version = SslProtocols.Tls12 38 | }; 39 | factory.Ssl = Ssl; 40 | } 41 | 42 | 43 | var connection = factory.CreateConnection(); 44 | var channel = connection.CreateModel(); 45 | 46 | channel.QueueDeclare(queue: yourQueue, durable: true, exclusive: false, autoDelete: false, arguments: null); 47 | Int32 i = 0; 48 | while (i < 10) 49 | { 50 | i++; 51 | try 52 | { 53 | if (!connection.IsOpen) 54 | { 55 | connection.Close(); 56 | connection = factory.CreateConnection(); 57 | channel = connection.CreateModel(); 58 | } 59 | 60 | string message = Guid.NewGuid().ToString(); 61 | var body = Encoding.UTF8.GetBytes(message); 62 | 63 | channel.BasicPublish(exchange: yourExchange, routingKey: yourRouterKey, basicProperties: null, 64 | body: body); 65 | Console.WriteLine(" [x] Sent {0}", message); 66 | Thread.Sleep(1000); 67 | } 68 | catch (BrokerUnreachableException e) 69 | { 70 | Thread.Sleep(3000); 71 | Console.WriteLine(e); 72 | continue; 73 | } 74 | catch (Exception e) 75 | { 76 | Console.WriteLine(e); 77 | continue; 78 | } 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /amqp-dotnet-demo/Send/Send.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-go-demo/amqp091/pub/producer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/tls" 5 | "flag" 6 | amqp "github.com/rabbitmq/amqp091-go" 7 | "log" 8 | "os" 9 | "os/signal" 10 | "strings" 11 | "syscall" 12 | "time" 13 | ) 14 | 15 | var ( 16 | uri = flag.String("uri", "amqp://guest:guest@localhost:5672/", "AMQP URI") 17 | exchange = flag.String("exchange", "test-exchange", "Durable AMQP exchange name") 18 | exchangeType = flag.String("exchange-type", "direct", "Exchange type - direct|fanout|topic|x-custom") 19 | queue = flag.String("queue", "test-queue", "Ephemeral AMQP queue name") 20 | routingKey = flag.String("key", "test-key", "AMQP routing key") 21 | body = flag.String("body", "foobar", "Body of message") 22 | vhost = flag.String("vhost", "/", "vhost") 23 | continuous = flag.Bool("continuous", false, "Keep publishing messages at a 1msg/sec rate") 24 | WarnLog = log.New(os.Stderr, "[WARNING] ", log.LstdFlags|log.Lmsgprefix) 25 | ErrLog = log.New(os.Stderr, "[ERROR] ", log.LstdFlags|log.Lmsgprefix) 26 | Log = log.New(os.Stdout, "[INFO] ", log.LstdFlags|log.Lmsgprefix) 27 | ) 28 | 29 | func init() { 30 | flag.Parse() 31 | } 32 | 33 | func main() { 34 | exitCh := make(chan struct{}) 35 | confirmsCh := make(chan *amqp.DeferredConfirmation) 36 | confirmsDoneCh := make(chan struct{}) 37 | // Note: this is a buffered channel so that indicating OK to 38 | // publish does not block the confirm handler 39 | publishOkCh := make(chan struct{}, 1) 40 | 41 | setupCloseHandler(exitCh) 42 | 43 | startConfirmHandler(publishOkCh, confirmsCh, confirmsDoneCh, exitCh) 44 | 45 | publish(publishOkCh, confirmsCh, confirmsDoneCh, exitCh) 46 | } 47 | 48 | func setupCloseHandler(exitCh chan struct{}) { 49 | c := make(chan os.Signal, 2) 50 | signal.Notify(c, os.Interrupt, syscall.SIGTERM) 51 | go func() { 52 | <-c 53 | Log.Printf("close handler: Ctrl+C pressed in Terminal") 54 | close(exitCh) 55 | }() 56 | } 57 | 58 | func publish(publishOkCh <-chan struct{}, confirmsCh chan<- *amqp.DeferredConfirmation, confirmsDoneCh <-chan struct{}, exitCh chan struct{}) { 59 | config := amqp.Config{ 60 | Vhost: *vhost, 61 | Properties: amqp.NewConnectionProperties(), 62 | } 63 | 64 | config.Properties.SetClientConnectionName("producer-with-confirms") 65 | Log.Printf("producer: dialing %s", *uri) 66 | 67 | var conn *amqp.Connection 68 | var err error 69 | // Set SSL with your certificate paths 70 | if strings.Contains(*uri, "amqps://") { 71 | tlsfg := &tls.Config{InsecureSkipVerify: true} 72 | conn, err = amqp.DialTLS(*uri, tlsfg) 73 | } else { 74 | conn, err = amqp.DialConfig(*uri, config) 75 | if err != nil { 76 | ErrLog.Fatalf("producer: error in dial: %s", err) 77 | } 78 | } 79 | 80 | defer conn.Close() 81 | 82 | Log.Println("producer: got Connection, getting Channel") 83 | channel, err := conn.Channel() 84 | if err != nil { 85 | ErrLog.Fatalf("error getting a channel: %s", err) 86 | } 87 | defer channel.Close() 88 | 89 | Log.Printf("producer: declaring exchange") 90 | if err := channel.ExchangeDeclare( 91 | *exchange, // name 92 | *exchangeType, // type 93 | true, // durable 94 | false, // auto-delete 95 | false, // internal 96 | false, // noWait 97 | nil, // arguments 98 | ); err != nil { 99 | ErrLog.Fatalf("producer: Exchange Declare: %s", err) 100 | } 101 | 102 | Log.Printf("producer: declaring queue '%s'", *queue) 103 | queue, err := channel.QueueDeclare( 104 | *queue, // name of the queue 105 | true, // durable 106 | false, // delete when unused 107 | false, // exclusive 108 | false, // noWait 109 | nil, // arguments 110 | ) 111 | if err == nil { 112 | Log.Printf("producer: declared queue (%q %d messages, %d consumers), binding to Exchange (key %q)", 113 | queue.Name, queue.Messages, queue.Consumers, *routingKey) 114 | } else { 115 | ErrLog.Fatalf("producer: Queue Declare: %s", err) 116 | } 117 | 118 | Log.Printf("producer: declaring binding") 119 | if err := channel.QueueBind(queue.Name, *routingKey, *exchange, false, nil); err != nil { 120 | ErrLog.Fatalf("producer: Queue Bind: %s", err) 121 | } 122 | 123 | // Reliable publisher confirms require confirm.select support from the 124 | // connection. 125 | Log.Printf("producer: enabling publisher confirms.") 126 | if err := channel.Confirm(false); err != nil { 127 | ErrLog.Fatalf("producer: channel could not be put into confirm mode: %s", err) 128 | } 129 | 130 | for { 131 | canPublish := false 132 | Log.Println("producer: waiting on the OK to publish...") 133 | for { 134 | select { 135 | case <-confirmsDoneCh: 136 | Log.Println("producer: stopping, all confirms seen") 137 | return 138 | case <-publishOkCh: 139 | Log.Println("producer: got the OK to publish") 140 | canPublish = true 141 | break 142 | case <-time.After(time.Second): 143 | WarnLog.Println("producer: still waiting on the OK to publish...") 144 | continue 145 | } 146 | if canPublish { 147 | break 148 | } 149 | } 150 | 151 | Log.Printf("producer: publishing %dB body (%q)", len(*body), *body) 152 | dConfirmation, err := channel.PublishWithDeferredConfirm( 153 | *exchange, 154 | *routingKey, 155 | true, 156 | false, 157 | amqp.Publishing{ 158 | Headers: amqp.Table{}, 159 | ContentType: "text/plain", 160 | ContentEncoding: "", 161 | DeliveryMode: amqp.Persistent, 162 | Priority: 0, 163 | AppId: "sequential-producer", 164 | Body: []byte(*body), 165 | }, 166 | ) 167 | if err != nil { 168 | ErrLog.Fatalf("producer: error in publish: %s", err) 169 | } 170 | 171 | select { 172 | case <-confirmsDoneCh: 173 | Log.Println("producer: stopping, all confirms seen") 174 | return 175 | case confirmsCh <- dConfirmation: 176 | Log.Println("producer: delivered deferred confirm to handler") 177 | break 178 | } 179 | 180 | select { 181 | case <-confirmsDoneCh: 182 | Log.Println("producer: stopping, all confirms seen") 183 | return 184 | case <-time.After(time.Millisecond * 250): 185 | if *continuous { 186 | continue 187 | } else { 188 | Log.Println("producer: initiating stop") 189 | close(exitCh) 190 | select { 191 | case <-confirmsDoneCh: 192 | Log.Println("producer: stopping, all confirms seen") 193 | return 194 | case <-time.After(time.Second * 10): 195 | WarnLog.Println("producer: may be stopping with outstanding confirmations") 196 | return 197 | } 198 | } 199 | } 200 | } 201 | } 202 | 203 | func startConfirmHandler(publishOkCh chan<- struct{}, confirmsCh <-chan *amqp.DeferredConfirmation, confirmsDoneCh chan struct{}, exitCh <-chan struct{}) { 204 | go func() { 205 | confirms := make(map[uint64]*amqp.DeferredConfirmation) 206 | 207 | for { 208 | select { 209 | case <-exitCh: 210 | exitConfirmHandler(confirms, confirmsDoneCh) 211 | return 212 | default: 213 | break 214 | } 215 | 216 | outstandingConfirmationCount := len(confirms) 217 | 218 | // Note: 8 is arbitrary, you may wish to allow more outstanding confirms before blocking publish 219 | if outstandingConfirmationCount <= 8 { 220 | select { 221 | case publishOkCh <- struct{}{}: 222 | Log.Println("confirm handler: sent OK to publish") 223 | case <-time.After(time.Second * 5): 224 | WarnLog.Println("confirm handler: timeout indicating OK to publish (this should never happen!)") 225 | } 226 | } else { 227 | WarnLog.Printf("confirm handler: waiting on %d outstanding confirmations, blocking publish", outstandingConfirmationCount) 228 | } 229 | 230 | select { 231 | case confirmation := <-confirmsCh: 232 | dtag := confirmation.DeliveryTag 233 | confirms[dtag] = confirmation 234 | case <-exitCh: 235 | exitConfirmHandler(confirms, confirmsDoneCh) 236 | return 237 | } 238 | 239 | checkConfirmations(confirms) 240 | } 241 | }() 242 | } 243 | 244 | func exitConfirmHandler(confirms map[uint64]*amqp.DeferredConfirmation, confirmsDoneCh chan struct{}) { 245 | Log.Println("confirm handler: exit requested") 246 | waitConfirmations(confirms) 247 | close(confirmsDoneCh) 248 | Log.Println("confirm handler: exiting") 249 | } 250 | 251 | func checkConfirmations(confirms map[uint64]*amqp.DeferredConfirmation) { 252 | Log.Printf("confirm handler: checking %d outstanding confirmations", len(confirms)) 253 | for k, v := range confirms { 254 | if v.Acked() { 255 | Log.Printf("confirm handler: confirmed delivery with tag: %d", k) 256 | delete(confirms, k) 257 | } 258 | } 259 | } 260 | 261 | func waitConfirmations(confirms map[uint64]*amqp.DeferredConfirmation) { 262 | Log.Printf("confirm handler: waiting on %d outstanding confirmations", len(confirms)) 263 | 264 | checkConfirmations(confirms) 265 | 266 | for k, v := range confirms { 267 | select { 268 | case <-v.Done(): 269 | Log.Printf("confirm handler: confirmed delivery with tag: %d", k) 270 | delete(confirms, k) 271 | case <-time.After(time.Second): 272 | WarnLog.Printf("confirm handler: did not receive confirmation for tag %d", k) 273 | } 274 | } 275 | 276 | outstandingConfirmationCount := len(confirms) 277 | if outstandingConfirmationCount > 0 { 278 | ErrLog.Printf("confirm handler: exiting with %d outstanding confirmations", outstandingConfirmationCount) 279 | } else { 280 | Log.Println("confirm handler: done waiting on outstanding confirmations") 281 | } 282 | } 283 | -------------------------------------------------------------------------------- /amqp-go-demo/amqp091/sub/consumer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/tls" 5 | "flag" 6 | "fmt" 7 | "log" 8 | "os" 9 | "os/signal" 10 | "strings" 11 | "syscall" 12 | "time" 13 | 14 | amqp "github.com/rabbitmq/amqp091-go" 15 | ) 16 | 17 | var ( 18 | uri = flag.String("uri", "amqp://guest:guest@localhost:5672/", "AMQP URI") 19 | exchange = flag.String("exchange", "test-exchange", "Durable, non-auto-deleted AMQP exchange name") 20 | exchangeType = flag.String("exchange-type", "direct", "Exchange type - direct|fanout|topic|x-custom") 21 | queue = flag.String("queue", "test-queue", "Ephemeral AMQP queue name") 22 | bindingKey = flag.String("key", "test-key", "AMQP binding key") 23 | consumerTag = flag.String("consumer-tag", "simple-consumer", "AMQP consumer tag (should not be blank)") 24 | vhost = flag.String("vhost", "/", "AMQP consumer tag (should not be blank)") 25 | lifetime = flag.Duration("lifetime", 5*time.Second, "lifetime of process before shutdown (0s=infinite)") 26 | verbose = flag.Bool("verbose", true, "enable verbose output of message data") 27 | autoAck = flag.Bool("auto_ack", false, "enable message auto-ack") 28 | ErrLog = log.New(os.Stderr, "[ERROR] ", log.LstdFlags|log.Lmsgprefix) 29 | Log = log.New(os.Stdout, "[INFO] ", log.LstdFlags|log.Lmsgprefix) 30 | deliveryCount int = 0 31 | ) 32 | 33 | func init() { 34 | flag.Parse() 35 | } 36 | 37 | func main() { 38 | c, err := NewConsumer(*uri, *exchange, *exchangeType, *queue, *bindingKey, *consumerTag) 39 | if err != nil { 40 | ErrLog.Fatalf("%s", err) 41 | } 42 | 43 | SetupCloseHandler(c) 44 | 45 | if *lifetime > 0 { 46 | Log.Printf("running for %s", *lifetime) 47 | time.Sleep(*lifetime) 48 | } else { 49 | Log.Printf("running until Consumer is done") 50 | <-c.done 51 | } 52 | 53 | Log.Printf("shutting down") 54 | 55 | if err := c.Shutdown(); err != nil { 56 | ErrLog.Fatalf("error during shutdown: %s", err) 57 | } 58 | } 59 | 60 | type Consumer struct { 61 | conn *amqp.Connection 62 | channel *amqp.Channel 63 | tag string 64 | done chan error 65 | } 66 | 67 | func SetupCloseHandler(consumer *Consumer) { 68 | c := make(chan os.Signal, 2) 69 | signal.Notify(c, os.Interrupt, syscall.SIGTERM) 70 | go func() { 71 | <-c 72 | Log.Printf("Ctrl+C pressed in Terminal") 73 | if err := consumer.Shutdown(); err != nil { 74 | ErrLog.Fatalf("error during shutdown: %s", err) 75 | } 76 | os.Exit(0) 77 | }() 78 | } 79 | 80 | func NewConsumer(amqpURI, exchange, exchangeType, queueName, key, ctag string) (*Consumer, error) { 81 | c := &Consumer{ 82 | conn: nil, 83 | channel: nil, 84 | tag: ctag, 85 | done: make(chan error), 86 | } 87 | 88 | var err error 89 | 90 | config := amqp.Config{Properties: amqp.NewConnectionProperties()} 91 | config.Vhost = *vhost 92 | config.Properties.SetClientConnectionName("sample-consumer") 93 | Log.Printf("dialing %q", amqpURI) 94 | var conn *amqp.Connection 95 | // Set SSL with your certificate paths 96 | if strings.Contains(*uri, "amqps://") { 97 | tlsfg := &tls.Config{InsecureSkipVerify: true} 98 | conn, err = amqp.DialTLS(*uri, tlsfg) 99 | } else { 100 | conn, err = amqp.DialConfig(*uri, config) 101 | if err != nil { 102 | ErrLog.Fatalf("producer: error in dial: %s", err) 103 | } 104 | } 105 | 106 | c.conn, err = conn, err 107 | if err != nil { 108 | return nil, fmt.Errorf("Dial: %s", err) 109 | } 110 | 111 | go func() { 112 | Log.Printf("closing: %s", <-c.conn.NotifyClose(make(chan *amqp.Error))) 113 | }() 114 | 115 | Log.Printf("got Connection, getting Channel") 116 | c.channel, err = c.conn.Channel() 117 | if err != nil { 118 | return nil, fmt.Errorf("Channel: %s", err) 119 | } 120 | 121 | Log.Printf("got Channel, declaring Exchange (%q)", exchange) 122 | if err = c.channel.ExchangeDeclare( 123 | exchange, // name of the exchange 124 | exchangeType, // type 125 | true, // durable 126 | false, // delete when complete 127 | false, // internal 128 | false, // noWait 129 | nil, // arguments 130 | ); err != nil { 131 | return nil, fmt.Errorf("Exchange Declare: %s", err) 132 | } 133 | 134 | Log.Printf("declared Exchange, declaring Queue %q", queueName) 135 | queue, err := c.channel.QueueDeclare( 136 | queueName, // name of the queue 137 | true, // durable 138 | false, // delete when unused 139 | false, // exclusive 140 | false, // noWait 141 | nil, // arguments 142 | ) 143 | if err != nil { 144 | return nil, fmt.Errorf("Queue Declare: %s", err) 145 | } 146 | 147 | Log.Printf("declared Queue (%q %d messages, %d consumers), binding to Exchange (key %q)", 148 | queue.Name, queue.Messages, queue.Consumers, key) 149 | 150 | if err = c.channel.QueueBind( 151 | queue.Name, // name of the queue 152 | key, // bindingKey 153 | exchange, // sourceExchange 154 | false, // noWait 155 | nil, // arguments 156 | ); err != nil { 157 | return nil, fmt.Errorf("Queue Bind: %s", err) 158 | } 159 | 160 | Log.Printf("Queue bound to Exchange, starting Consume (consumer tag %q)", c.tag) 161 | deliveries, err := c.channel.Consume( 162 | queue.Name, // name 163 | c.tag, // consumerTag, 164 | *autoAck, // autoAck 165 | false, // exclusive 166 | false, // noLocal 167 | false, // noWait 168 | nil, // arguments 169 | ) 170 | if err != nil { 171 | return nil, fmt.Errorf("Queue Consume: %s", err) 172 | } 173 | 174 | go handle(deliveries, c.done) 175 | 176 | return c, nil 177 | } 178 | 179 | func (c *Consumer) Shutdown() error { 180 | // will close() the deliveries channel 181 | if err := c.channel.Cancel(c.tag, true); err != nil { 182 | return fmt.Errorf("Consumer cancel failed: %s", err) 183 | } 184 | 185 | if err := c.conn.Close(); err != nil { 186 | return fmt.Errorf("AMQP connection close error: %s", err) 187 | } 188 | 189 | defer Log.Printf("AMQP shutdown OK") 190 | 191 | // wait for handle() to exit 192 | return <-c.done 193 | } 194 | 195 | func handle(deliveries <-chan amqp.Delivery, done chan error) { 196 | cleanup := func() { 197 | Log.Printf("handle: deliveries channel closed") 198 | done <- nil 199 | } 200 | 201 | defer cleanup() 202 | 203 | for d := range deliveries { 204 | deliveryCount++ 205 | if *verbose == true { 206 | Log.Printf( 207 | "got %s delivery: [%v] %q", 208 | string(d.Body), 209 | d.DeliveryTag, 210 | d.Body, 211 | ) 212 | } else { 213 | if deliveryCount%65536 == 0 { 214 | Log.Printf("delivery count %d", deliveryCount) 215 | } 216 | } 217 | if *autoAck == false { 218 | d.Ack(false) 219 | } 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /amqp-go-demo/demo/Consumer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "github.com/streadway/amqp" 6 | "log" 7 | ) 8 | 9 | func main() { 10 | 11 | var buf bytes.Buffer 12 | 13 | userName := "username" // 请替换成您阿里云AMQP控制台Username 14 | password := "password" // 请替换成您阿里云AMQP控制台Username 15 | endpoint := "rabbitmq-xxx.mq.amqp.aliyuncs.com" // 请从控制台获取。 16 | vhost := "your-vhost" // 请从控制台获取。 17 | exchangeName := "your-exchangeName" // 请从控制台获取。 18 | exchangeType := "direct" 19 | queueName := "your-queueName" // 请从控制台获取。 20 | routeKey := "your-routing-key" // 请从控制台获取。 21 | durable := true 22 | consumerTag := "testConsumer" 23 | 24 | buf.WriteString("amqp://") 25 | buf.WriteString(userName) 26 | buf.WriteString(":") 27 | buf.WriteString(password) 28 | buf.WriteString("@") 29 | buf.WriteString(endpoint) 30 | buf.WriteString(":5672/") 31 | buf.WriteString(vhost) 32 | url := buf.String() 33 | 34 | conn, err := amqp.Dial(url) 35 | failConsumerOnError(err, "Failed to connect to RabbitMQ") 36 | defer conn.Close() 37 | 38 | ch, err := conn.Channel() 39 | failConsumerOnError(err, "Failed to open a channel") 40 | defer ch.Close() 41 | 42 | err = ch.ExchangeDeclare(exchangeName, exchangeType, durable, false, false, false, nil) 43 | failConsumerOnError(err, "Failed to Declare a exchangeName") 44 | 45 | q, err := ch.QueueDeclare( 46 | queueName, // name 47 | durable, // durable 48 | false, // delete when unused 49 | false, // exclusive 50 | false, // no-wait 51 | nil, // arguments 52 | ) 53 | failConsumerOnError(err, "Failed to declare a queueName"+q.Name) 54 | 55 | err = ch.QueueBind(queueName, routeKey, exchangeName, false, nil) 56 | failConsumerOnError(err, "Failed to bind a queueName") 57 | 58 | msgs, err := ch.Consume( 59 | queueName, // queueName 60 | consumerTag, // consumer 61 | true, // auto-ack 62 | false, // exclusive 63 | false, // no-local 64 | false, // no-wait 65 | nil, // args 66 | ) 67 | failConsumerOnError(err, "Failed to register a consumer") 68 | 69 | forever := make(chan bool) 70 | 71 | go func() { 72 | for d := range msgs { 73 | log.Printf("Received a message: %s", d.Body) 74 | } 75 | }() 76 | 77 | log.Printf(" [*] Waiting for messages. To exit press CTRL+C") 78 | <-forever 79 | 80 | } 81 | 82 | func failConsumerOnError(err error, msg string) { 83 | if err != nil { 84 | log.Fatalf("%s: %s", msg, err) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /amqp-go-demo/demo/Publisher.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "github.com/streadway/amqp" 7 | "log" 8 | "time" 9 | ) 10 | 11 | func main() { 12 | 13 | var buf bytes.Buffer 14 | 15 | userName := "username" // 请替换成您阿里云AMQP控制台Username 16 | password := "password" // 请替换成您阿里云AMQP控制台Username 17 | endpoint := "rabbitmq-xxx.mq.amqp.aliyuncs.com" // 请从控制台获取。 18 | vhost := "your-vhost" // 请从控制台获取。 19 | exchangeName := "your-exchangeName" // 请从控制台获取。 20 | exchangeType := "direct" 21 | queueName := "your-queueName" // 请从控制台获取。 22 | routeKey := "your-routing-key" // 请从控制台获取。 23 | durable := true 24 | 25 | buf.WriteString("amqp://") 26 | buf.WriteString(userName) 27 | buf.WriteString(":") 28 | buf.WriteString(password) 29 | buf.WriteString("@") 30 | buf.WriteString(endpoint) 31 | buf.WriteString(":5672/") 32 | buf.WriteString(vhost) 33 | url := buf.String() 34 | 35 | conn, err := amqp.Dial(url) 36 | failPublishOnError(err, "Failed to connect to RabbitMQ") 37 | defer conn.Close() 38 | 39 | ch, err := conn.Channel() 40 | failPublishOnError(err, "Failed to open a channel") 41 | defer ch.Close() 42 | 43 | err = ch.ExchangeDeclare(exchangeName, exchangeType, durable, false, false, false, nil) 44 | failPublishOnError(err, "Failed to Declare a exchangeName") 45 | 46 | q, err := ch.QueueDeclare( 47 | queueName, // name 48 | durable, // durable 49 | false, // delete when unused 50 | false, // exclusive 51 | false, // no-wait 52 | nil, // arguments 53 | ) 54 | failPublishOnError(err, "Failed to declare a queueName"+q.Name) 55 | 56 | err = ch.QueueBind(queueName, routeKey, exchangeName, false, nil) 57 | failPublishOnError(err, "Failed to bind a queueName") 58 | 59 | /* 60 | * rabbitmq client 向Server发起connection,新建channel大约需要进行15+个TCP报文的传输,会消耗大量网络资源和Server端的资源,甚至引起Server端SYN flooding 攻击保护。 61 | * 因此我们建议消息的发送和消费尽量采用长链接的模式。 62 | */ 63 | for i := 0; i < 10; i++ { 64 | body := fmt.Sprintf("Hello GO AMQP[%d]", i+1) 65 | err = ch.Publish( 66 | exchangeName, // exchangeName 67 | routeKey, // routing key 68 | false, // mandatory 69 | false, // immediate 70 | amqp.Publishing{ 71 | ContentType: "text/plain", 72 | Body: []byte(body), 73 | DeliveryMode: amqp.Persistent, 74 | }) 75 | 76 | failPublishOnError(err, "Failed to publish a message") 77 | fmt.Printf("Go Message [%d] sent and confirmed.\n", i+1) 78 | time.Sleep(1 * time.Second) 79 | } 80 | time.Sleep(3 * time.Second) 81 | 82 | } 83 | 84 | func failPublishOnError(err error, msg string) { 85 | if err != nil { 86 | log.Fatalf("%s: %s", msg, err) 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /amqp-go-demo/go.mod: -------------------------------------------------------------------------------- 1 | module aliyun.com/amqp-go-demo/v2 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/rabbitmq/amqp091-go v1.10.0 7 | github.com/streadway/amqp v1.1.0 8 | ) 9 | -------------------------------------------------------------------------------- /amqp-go-demo/go.sum: -------------------------------------------------------------------------------- 1 | github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw= 2 | github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o= 3 | github.com/streadway/amqp v1.1.0 h1:py12iX8XSyI7aN/3dUT8DFIDJazNJsVJdxNVEpnQTZM= 4 | github.com/streadway/amqp v1.1.0/go.mod h1:WYSrTEYHOXHd0nwFeUXAe2G2hRnQT+deZJJf88uS9Bg= 5 | go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= 6 | -------------------------------------------------------------------------------- /amqp-java-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | amqp-java-demo 9 | 1.0-SNAPSHOT 10 | 11 | 12 | com.rabbitmq 13 | amqp-client 14 | 5.13.0 15 | 16 | 17 | ch.qos.logback 18 | logback-classic 19 | 1.2.11 20 | 21 | 22 | 23 | 8 24 | 8 25 | 26 | 27 | -------------------------------------------------------------------------------- /amqp-java-demo/src/main/java/Config.java: -------------------------------------------------------------------------------- 1 | public class Config { 2 | protected static final String HOSTNAME = "your-instance-endpoint"; // 替换为配置的阿里云MQ实例的公网接入点 3 | protected static final String USERNAME = "your-username"; // 替换为配置的静态用户名 4 | protected static final String PASSWORD = "your-password"; // 替换为配置的静态密码 5 | } 6 | -------------------------------------------------------------------------------- /amqp-java-demo/src/main/java/ConnectionFactory.java: -------------------------------------------------------------------------------- 1 | 2 | import com.rabbitmq.client.Channel; 3 | import com.rabbitmq.client.Connection; 4 | import java.io.IOException; 5 | import java.security.KeyManagementException; 6 | import java.security.KeyStore; 7 | import java.security.KeyStoreException; 8 | import java.security.NoSuchAlgorithmException; 9 | import java.util.concurrent.TimeoutException; 10 | import javax.net.ssl.SSLContext; 11 | import javax.net.ssl.TrustManagerFactory; 12 | 13 | public class ConnectionFactory { 14 | private final String hostName; 15 | private final int port; 16 | private final String userName; 17 | private final String password; 18 | private final String virtualHost; 19 | private final boolean enableSSL; 20 | 21 | public ConnectionFactory(String hostName, int port, String userName, 22 | String password, String virtualHost, boolean enableSSL) { 23 | this.hostName = hostName; 24 | this.port = port; 25 | this.userName = userName; 26 | this.password = password; 27 | this.virtualHost = virtualHost; 28 | this.enableSSL = enableSSL; 29 | } 30 | 31 | public Channel createChannel() throws IOException, TimeoutException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { 32 | //create a new con 33 | Connection con = createCon(); 34 | 35 | //create a new channel 36 | return con.createChannel(); 37 | } 38 | 39 | private Connection createCon() throws IOException, TimeoutException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { 40 | com.rabbitmq.client.ConnectionFactory factory = new com.rabbitmq.client.ConnectionFactory(); 41 | 42 | factory.setHost(hostName); 43 | factory.setUsername(userName); 44 | factory.setPassword(password); 45 | 46 | //设置为true,开启Connection自动恢复功能;设置为false,关闭Connection自动恢复功能。 47 | factory.setAutomaticRecoveryEnabled(true); 48 | factory.setNetworkRecoveryInterval(5000); 49 | factory.setVirtualHost(virtualHost); 50 | // 默认端口。 51 | factory.setPort(port); 52 | 53 | if (enableSSL) { 54 | setSSL(factory); 55 | } 56 | 57 | // 基于网络环境合理设置超时时间。 58 | factory.setConnectionTimeout(30 * 1000); 59 | factory.setHandshakeTimeout(30 * 1000); 60 | factory.setShutdownTimeout(0); 61 | 62 | return factory.newConnection(); 63 | } 64 | 65 | private void setSSL( 66 | com.rabbitmq.client.ConnectionFactory factory) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { 67 | SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); 68 | TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 69 | trustManagerFactory.init((KeyStore) null); 70 | sslContext.init(null, trustManagerFactory.getTrustManagers(), null); 71 | factory.useSslProtocol(sslContext); 72 | } 73 | 74 | public void closeCon(Channel channel) { 75 | if (channel != null && channel.getConnection() != null) { 76 | try { 77 | channel.getConnection().close(); 78 | } catch (Throwable t) { 79 | } 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /amqp-java-demo/src/main/java/Consumer.java: -------------------------------------------------------------------------------- 1 | import com.rabbitmq.client.AMQP; 2 | import com.rabbitmq.client.Channel; 3 | import com.rabbitmq.client.DefaultConsumer; 4 | import com.rabbitmq.client.Envelope; 5 | import java.io.IOException; 6 | import java.security.KeyManagementException; 7 | import java.security.KeyStoreException; 8 | import java.security.NoSuchAlgorithmException; 9 | import java.util.concurrent.CountDownLatch; 10 | import java.util.concurrent.TimeoutException; 11 | 12 | public class Consumer { 13 | private static final String QUEUE_NAME = "yunQi-queue"; 14 | private static final String VHOST = "yunQi-vhost"; 15 | private static final String CONSUMER_TAG = "yunQi-consumerTag"; 16 | private static final String HOSTNAME = Config.HOSTNAME; 17 | private static final String USERNAME = Config.USERNAME; 18 | private static final String PASSWORD = Config.PASSWORD; 19 | 20 | //如果需要使用 TLS 加密,改为 5671 端口,并且enableSSL设置为true。。 21 | public static final int PORT = 5672; 22 | public static final boolean enableSSL = false; 23 | 24 | private final Channel channel; 25 | private final String queue; 26 | 27 | public Consumer(Channel channel, String queue) { 28 | this.channel = channel; 29 | this.queue = queue; 30 | } 31 | 32 | public static void main( 33 | String[] args) throws IOException, TimeoutException, InterruptedException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { 34 | ConnectionFactory factory = new ConnectionFactory(HOSTNAME, PORT, USERNAME, PASSWORD, VHOST, enableSSL); 35 | Channel channel = factory.createChannel(); 36 | channel.basicQos(50); 37 | 38 | //设置为云消息队列 RabbitMQ 版实例的Queue名称。需要和生产者中设置的Queue名称一致。 39 | Consumer consumer = new Consumer(channel, QUEUE_NAME); 40 | 41 | consumer.consume(); 42 | } 43 | 44 | public void consume() throws IOException, InterruptedException { 45 | channel.basicConsume(queue, false, CONSUMER_TAG, new DefaultConsumer(channel) { 46 | @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, 47 | byte[] body) throws IOException { 48 | 49 | //业务处理。 50 | System.out.println("receive: msgId=" + properties.getMessageId()); 51 | 52 | //消费者需要在有效时间内提交ack,否则消息会重新推送,最多推送16次。 53 | //若推送16次还未成功,则消息被丢弃或者进入死信Exchange。 54 | //专业版实例的有效时间为1分钟,企业版和Serverless实例为5分钟,铂金版实例为30分钟。 55 | channel.basicAck(envelope.getDeliveryTag(), false); 56 | } 57 | }); 58 | 59 | //向Java虚拟机注册了一个关闭钩子(shutdown hook)。当JVM接收到终止信号(如通过系统中断或System.exit()调用)时,会执行这个钩子中的代码,关闭connection,退出程序 60 | CountDownLatch latch = new CountDownLatch(1); 61 | Runtime.getRuntime().addShutdownHook(new Thread(() -> { 62 | try { 63 | channel.getConnection().close(); 64 | } catch (IOException e) { 65 | System.out.println("close connection error." + e); 66 | } 67 | latch.countDown(); 68 | })); 69 | latch.await(); 70 | } 71 | } 72 | 73 | -------------------------------------------------------------------------------- /amqp-java-demo/src/main/java/Producer.java: -------------------------------------------------------------------------------- 1 | import com.rabbitmq.client.AMQP; 2 | import com.rabbitmq.client.AlreadyClosedException; 3 | import com.rabbitmq.client.Channel; 4 | import com.rabbitmq.client.ConfirmCallback; 5 | import java.io.IOException; 6 | import java.nio.charset.StandardCharsets; 7 | import java.security.KeyManagementException; 8 | import java.security.KeyStoreException; 9 | import java.security.NoSuchAlgorithmException; 10 | import java.util.UUID; 11 | import java.util.concurrent.ConcurrentNavigableMap; 12 | import java.util.concurrent.ConcurrentSkipListMap; 13 | import java.util.concurrent.TimeoutException; 14 | 15 | public class Producer { 16 | private static final String QUEUE_NAME = "yunQi-queue"; 17 | private static final String EXCHANGE_NAME = "yunQi-exchange"; 18 | private static final String ROUTING_KEY = "yunQi-routing-key"; 19 | private static final String VHOST = "yunQi-vhost"; 20 | private static final String HOSTNAME = Config.HOSTNAME; 21 | private static final String USERNAME = Config.USERNAME; 22 | private static final String PASSWORD = Config.PASSWORD; 23 | //如果需要使用 TLS 加密,改为 5671 端口,并且enableSSL设置为true。 24 | public static final int PORT = 5672; 25 | public static final boolean enableSSL = false; 26 | 27 | private Channel channel; 28 | private final ConcurrentNavigableMap outstandingConfirms; 29 | private final ConnectionFactory factory; 30 | 31 | public Producer( 32 | ConnectionFactory factory) throws IOException, TimeoutException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { 33 | this.factory = factory; 34 | this.outstandingConfirms = new ConcurrentSkipListMap<>(); 35 | this.channel = factory.createChannel(); 36 | } 37 | 38 | public static void main( 39 | String[] args) throws IOException, TimeoutException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, InterruptedException { 40 | //构建连接工厂。 41 | ConnectionFactory factory = new ConnectionFactory(HOSTNAME, PORT, USERNAME, PASSWORD, VHOST, enableSSL); 42 | 43 | //初始化生产者。 44 | Producer producer = new Producer(factory); 45 | 46 | //declare。 47 | producer.declare(); 48 | 49 | producer.initChannel(); 50 | 51 | for (int i = 0; i < 10000000; i++) { 52 | //发送消息。 53 | producer.doSend("hello,amqp"); 54 | Thread.sleep(100); 55 | } 56 | } 57 | 58 | private void initChannel() throws IOException { 59 | channel.confirmSelect(); 60 | 61 | ConfirmCallback cleanOutstandingConfirms = (deliveryTag, multiple) -> { 62 | if (multiple) { 63 | ConcurrentNavigableMap confirmed = outstandingConfirms.headMap(deliveryTag, true); 64 | 65 | for (Long tag : confirmed.keySet()) { 66 | String msgId = confirmed.get(tag); 67 | System.out.format("Message with msgId %s has been ack-ed. deliveryTag: %d, multiple: %b%n", msgId, tag, true); 68 | } 69 | 70 | confirmed.clear(); 71 | } else { 72 | String msgId = outstandingConfirms.remove(deliveryTag); 73 | System.out.format("Message with msgId %s has been ack-ed. deliveryTag: %d, multiple: %b%n", msgId, deliveryTag, false); 74 | } 75 | }; 76 | channel.addConfirmListener(cleanOutstandingConfirms, (deliveryTag, multiple) -> { 77 | String msgId = outstandingConfirms.get(deliveryTag); 78 | System.err.format("Message with msgId %s has been nack-ed. deliveryTag: %d, multiple: %b%n", msgId, deliveryTag, multiple); 79 | // send msg failed, re-publish 80 | }); 81 | 82 | channel.addReturnListener(returnMessage -> System.out.println("return msgId=" + returnMessage.getProperties().getMessageId())); 83 | } 84 | 85 | private void declare() throws IOException { 86 | channel.exchangeDeclare(EXCHANGE_NAME, "direct", true); 87 | channel.queueDeclare(QUEUE_NAME, true, false, false, null); 88 | channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY); 89 | } 90 | 91 | private void doSend( 92 | String content) throws IOException, TimeoutException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { 93 | try { 94 | String msgId = UUID.randomUUID().toString(); 95 | AMQP.BasicProperties props = new AMQP.BasicProperties.Builder().messageId(msgId).build(); 96 | 97 | channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY, true, props, content.getBytes(StandardCharsets.UTF_8)); 98 | 99 | outstandingConfirms.put(channel.getNextPublishSeqNo(), msgId); 100 | } catch (AlreadyClosedException e) { 101 | //need reconnect if channel is closed. 102 | String message = e.getMessage(); 103 | 104 | System.out.println(message); 105 | 106 | if (channelClosedByServer(message)) { 107 | factory.closeCon(channel); 108 | channel = factory.createChannel(); 109 | this.initChannel(); 110 | doSend(content); 111 | } else { 112 | throw e; 113 | } 114 | } 115 | } 116 | 117 | private boolean channelClosedByServer(String errorMsg) { 118 | if (errorMsg != null 119 | && errorMsg.contains("channel.close") 120 | && errorMsg.contains("reply-code=541") 121 | && errorMsg.contains("reply-text=InternalError")) { 122 | return true; 123 | } else { 124 | return false; 125 | } 126 | } 127 | } 128 | 129 | -------------------------------------------------------------------------------- /amqp-node-demo/README.md: -------------------------------------------------------------------------------- 1 | # 阿里云 amqp node 客户端 Demo 2 | 3 | ## 安装 4 | 5 | > 如果没有安装 amqplib 请执行如下命令安装 6 | ```bash 7 | npm install amqplib --save 8 | ``` 9 | 10 | ## 使用方法 11 | 消息发送: 12 | ```js 13 | node send.js 14 | ``` 15 | 16 | 消息接收: 17 | ```js 18 | node consume.js 19 | ``` 20 | 21 | ## Api 使用 22 | [请参考 amqplib 文档](http://www.squaremobius.net/amqp.node/channel_api.html) 23 | 24 | [amqplib 项目地址](https://github.com/squaremo/amqp.node) -------------------------------------------------------------------------------- /amqp-node-demo/consume.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const amqp = require('amqplib'); 3 | 4 | const endpoint = 'endpoint'; 5 | const username = 'username'; 6 | const password = 'password'; 7 | const vhost = 'vhost'; 8 | const queue = 'queue'; 9 | 10 | const amqpUrl = `amqp://${username}:${password}@${endpoint}/${vhost}`; 11 | 12 | //disabling TLS validation 13 | process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; 14 | 15 | 16 | async function consume() { 17 | try { 18 | // Connect to RabbitMQ Server 19 | const connection = await amqp 20 | .connect(amqpUrl) 21 | .catch((err) => { 22 | console.log(`connect error: ${err}`); 23 | throw err; 24 | }); 25 | 26 | // Create a channel 27 | const channel = await connection.createChannel().catch((err) => { 28 | console.log(`channel create error: ${err}`); 29 | throw err; 30 | }); 31 | 32 | // Consume message 33 | channel.consume( 34 | queue, 35 | (msg) => { 36 | if (msg !== null) { 37 | console.log(" [x] Received:", msg.content.toString()); 38 | // Ack after the message has been processed 39 | channel.ack(msg); 40 | } 41 | }, 42 | { noAck: false } 43 | ); 44 | } catch (error) { 45 | console.error("Error:", error); 46 | } 47 | } 48 | 49 | consume(); -------------------------------------------------------------------------------- /amqp-node-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "amqp-node-demo", 3 | "version": "1.0.0", 4 | "description": "amqp-node-demo", 5 | "main": "consume.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /amqp-node-demo/send.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const amqp = require('amqplib'); 3 | 4 | const endpoint = 'endpoint'; 5 | const username = 'username'; 6 | const password = 'password'; 7 | const vhost = 'vhost'; 8 | const queue = 'queue'; 9 | 10 | // disabling TLS validation 11 | process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; 12 | 13 | const amqpUrl = `amqp://${username}:${password}@${endpoint}/${vhost}`; 14 | 15 | async function connectToAmqpAndSendMsg(amqpUrl, queue, msg) { 16 | try { 17 | const connection = await amqp.connect(amqpUrl); 18 | const channel = await connection.createChannel(); 19 | await channel.assertQueue(queue, { durable: true }); 20 | channel.publish('amq.direct','binding-test', Buffer.from(msg)); 21 | console.log(" [x] Sent %s", msg); 22 | 23 | setTimeout(async () => { 24 | await channel.close(); 25 | await connection.close(); 26 | }, 500); // Close the connection after a delay to ensure message delivery 27 | } catch (error) { 28 | throw new Error(`Error connecting to AMQP or sending message: ${error.message}`); 29 | } 30 | } 31 | 32 | async function send() { 33 | try { 34 | const msg = "Hello World!"; 35 | await connectToAmqpAndSendMsg(amqpUrl, queue, msg); 36 | } catch (error) { 37 | console.error(error.message); 38 | process.exit(1); 39 | } 40 | } 41 | 42 | send(); 43 | -------------------------------------------------------------------------------- /amqp-php-demo/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "php-amqplib/php-amqplib": ">=2.8.1", 4 | "ext-json": "*" 5 | }, 6 | "require-dev": { 7 | "phpunit/phpunit": ">=5.6.3" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /amqp-php-demo/config.php: -------------------------------------------------------------------------------- 1 | 22 | -------------------------------------------------------------------------------- /amqp-php-demo/demos/receive.php: -------------------------------------------------------------------------------- 1 | channel(); 14 | 15 | // $channel->queue_declare('queue', false, true, false, false); 16 | 17 | echo " [*] Waiting for messages. To exit press CTRL+C\n"; 18 | 19 | $callback = function ($msg) { 20 | echo ' [x] Received: ', $msg->body, "\n"; 21 | $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']); 22 | }; 23 | 24 | $channel->basic_consume($queueName, $consumeTag, false, true, false, false, $callback); 25 | 26 | while (count($channel->callbacks)) { 27 | $channel->wait(); 28 | } 29 | 30 | $channel->close(); 31 | $connection->close(); 32 | ?> 33 | -------------------------------------------------------------------------------- /amqp-php-demo/demos/receiveWithProp.php: -------------------------------------------------------------------------------- 1 | channel(); 14 | 15 | // $channel->queue_declare($queueName, false, true, false, false); 16 | 17 | echo " [*] Waiting for messages. To exit press CTRL+C\n"; 18 | 19 | $callback = function ($msg) { 20 | echo ' [x] Received ', $msg->body, "\n"; 21 | if ($msg->has('application_headers')) { 22 | $headers = $msg->get('application_headers'); 23 | echo ' [x] Received Headers [delay=>', $headers->getNativeData()['delay'], "]\n"; 24 | } 25 | $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']); 26 | }; 27 | 28 | $channel->basic_consume($queueName, $consumeTag, false, true, false, false, $callback); 29 | 30 | while (count($channel->callbacks)) { 31 | $channel->wait(); 32 | } 33 | 34 | $channel->close(); 35 | $connection->close(); 36 | ?> 37 | -------------------------------------------------------------------------------- /amqp-php-demo/demos/send.php: -------------------------------------------------------------------------------- 1 | channel(); 14 | 15 | // $channel->queue_declare($queueName, false, true, false, false); 16 | 17 | /* 18 | * rabbitmq client 向Server发起connection,新建channel大约需要进行15+个TCP报文的传输,会消耗大量网络资源和Server端的资源,甚至引起Server端SYN flooding 攻击保护。 19 | * 因此我们建议消息的发送和消费尽量采用长链接的模式。 20 | * 对于php,可以采用rabbitmq提供的AMQPProxy来实现的长链接-参考https://github.com/cloudamqp/amqproxy 21 | */ 22 | for ($i = 0; $i < 10; $i++) { 23 | $body = "Hello World! I am PHP AMQP[$i]."; 24 | $msg = new AMQPMessage($body); 25 | $channel->basic_publish($msg, $exchangeName, $routingKey); 26 | echo " [x] Sent 'Hello World! I am PHP AMQP[$i].'\n"; 27 | } 28 | 29 | $channel->close(); 30 | $connection->close(); 31 | ?> 32 | -------------------------------------------------------------------------------- /amqp-php-demo/demos/sendWithProp.php: -------------------------------------------------------------------------------- 1 | channel(); 15 | 16 | // $channel->queue_declare($queueName, false, true, false, false); 17 | 18 | /* 19 | * rabbitmq client 向Server发起connection,新建channel大约需要进行15+个TCP报文的传输,会消耗大量网络资源和Server端的资源,甚至引起Server端SYN flooding 攻击保护。 20 | * 因此我们建议消息的发送和消费尽量采用长链接的模式。 21 | * 对于php,可以采用rabbitmq提供的AMQPProxy来实现的长链接-参考https://github.com/cloudamqp/amqproxy 22 | */ 23 | for ($i = 0; $i < 10; $i++) { 24 | 25 | $msgBody = json_encode(["name" => "AMQP", "index" => $i]); 26 | 27 | $amqpTable = new AMQPTable(["delay" => "1000"]); 28 | 29 | //生成消息 30 | $msg = new AMQPMessage($msgBody, ['application_headers' => $amqpTable, 'content_type' => 'text/plain', 'delivery_mode' => 2]); 31 | 32 | $channel->basic_publish($msg, $exchangeName, $routingKey); 33 | echo " [x] Sent 'Hello World! I am PHP AMQP Message[$msgBody].'\n"; 34 | 35 | } 36 | $channel->close(); 37 | $connection->close(); 38 | ?> 39 | -------------------------------------------------------------------------------- /amqp-php-demo/index.php: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /amqp-python-celery-demo/README.md: -------------------------------------------------------------------------------- 1 | # celery-demo 2 | 3 | 首先在test_celery的父目录(本demo中也即amqp-python-celery-demo)执行 4 | ```Bash 5 | celery -A test_celery worker --loglevel=info 6 | ``` 7 | 再开一个console 8 | 然后在test_celery的父目录(本demo中也即amqp-python-celery-demo)执行 9 | ```Bash 10 | python -m test_celery.run_tasks 11 | ``` 12 | 13 | 就可以看到远程任务的执行 14 | -------------------------------------------------------------------------------- /amqp-python-celery-demo/test_celery/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AliwareMQ/amqp-demos/9d172c29a5d101fe7d1df21bffe1735ad5351c04/amqp-python-celery-demo/test_celery/__init__.py -------------------------------------------------------------------------------- /amqp-python-celery-demo/test_celery/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AliwareMQ/amqp-demos/9d172c29a5d101fe7d1df21bffe1735ad5351c04/amqp-python-celery-demo/test_celery/__init__.pyc -------------------------------------------------------------------------------- /amqp-python-celery-demo/test_celery/celery.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, unicode_literals 2 | 3 | from celery import Celery 4 | 5 | AMQP_ENDPOINT = 'rabbitmq-xxxx.mq.amqp.aliyuncs.com' 6 | AMQP_USER = 'AMQP_USER_CONSOLE' 7 | AMQP_PASSWORD = 'AMQP_PASSWORD_CONSOLE' 8 | AMQP_VHOST = 'AMQP_VHOST' 9 | AMQP_QUEUE = 'AMQP_QUEUE' 10 | AMQP_EXCHANGE = 'AMQP_EXCHANGE' 11 | AMQP_EXCHANGE_TYPE = 'direct' 12 | CELERY_BROKER_URL = 'amqp://{0}:{1}@{2}:5672/{3}'.format(AMQP_USER, AMQP_PASSWORD, AMQP_ENDPOINT, AMQP_VHOST) 13 | 14 | app = Celery('test_celery', backend='rpc://', include=['test_celery.tasks']) 15 | app.conf.update( 16 | broker_url=CELERY_BROKER_URL, 17 | broker_login_method='PLAIN', 18 | task_default_queue=AMQP_QUEUE, 19 | task_default_exchange_type=AMQP_EXCHANGE_TYPE, 20 | task_default_exchange=AMQP_EXCHANGE 21 | ) 22 | -------------------------------------------------------------------------------- /amqp-python-celery-demo/test_celery/celery.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AliwareMQ/amqp-demos/9d172c29a5d101fe7d1df21bffe1735ad5351c04/amqp-python-celery-demo/test_celery/celery.pyc -------------------------------------------------------------------------------- /amqp-python-celery-demo/test_celery/run_tasks.py: -------------------------------------------------------------------------------- 1 | from .tasks import longtime_add 2 | import time 3 | 4 | if __name__ == '__main__': 5 | result = longtime_add.delay(1,2) 6 | # at this time, our task is not finished, so it will return False 7 | print('Task finished? ', result.ready()) 8 | print('Task result: ', result.result) 9 | # sleep 30 seconds to ensure the task has been finished 10 | time.sleep(30) 11 | # now the task should be finished and ready method will return True 12 | print('Task finished? ', result.ready()) 13 | print('Task result: ', result.result) 14 | -------------------------------------------------------------------------------- /amqp-python-celery-demo/test_celery/tasks.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | from test_celery.celery import app 3 | import time 4 | 5 | 6 | @app.task 7 | def longtime_add(x, y): 8 | print('long time task begins') 9 | # sleep 2 seconds 10 | time.sleep(2) 11 | print('long time task finished') 12 | return x + y 13 | -------------------------------------------------------------------------------- /amqp-python-celery-demo/test_celery/tasks.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AliwareMQ/amqp-demos/9d172c29a5d101fe7d1df21bffe1735ad5351c04/amqp-python-celery-demo/test_celery/tasks.pyc -------------------------------------------------------------------------------- /amqp-python-demo/README.md: -------------------------------------------------------------------------------- 1 | pika 版本使用问题 2 | 3 | 已经完全兼容最新版本 4 | -------------------------------------------------------------------------------- /amqp-python-demo/blockingConnectionConsumeWithRecovery.py: -------------------------------------------------------------------------------- 1 | import pika 2 | import connection 3 | 4 | def on_message(channel, method_frame, header_frame, body): 5 | print(method_frame.delivery_tag) 6 | print(body) 7 | print() 8 | channel.basic_ack(delivery_tag=method_frame.delivery_tag) 9 | 10 | while(True): 11 | try: 12 | print("Connecting...") 13 | 14 | connection = pika.BlockingConnection(connection.get_connection_param()) 15 | channel = connection.channel() 16 | channel.basic_qos(prefetch_count=1) 17 | 18 | channel.queue_declare('recovery-example', durable = False, auto_delete = True) 19 | channel.basic_consume('recovery-example', on_message) 20 | print("connected and starting consume...") 21 | try: 22 | channel.start_consuming() 23 | except KeyboardInterrupt: 24 | channel.stop_consuming() 25 | connection.close() 26 | break 27 | except pika.exceptions.ConnectionClosedByBroker: 28 | # Uncomment this to make the example not attempt recovery 29 | # from server-initiated connection closure, including 30 | # when the node is stopped cleanly 31 | # 32 | # break 33 | continue 34 | # Do not recover on channel errors 35 | except pika.exceptions.AMQPChannelError as err: 36 | print("Caught a channel error: {}, stopping...".format(err)) 37 | break 38 | # Recover on all other connection errors 39 | except pika.exceptions.AMQPConnectionError: 40 | print("Connection was closed, retrying...") 41 | continue 42 | -------------------------------------------------------------------------------- /amqp-python-demo/connection.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -* 2 | import ssl 3 | 4 | import pika 5 | 6 | # 接入点 7 | host = "rabbitmq-xxxx.mq.amqp.aliyuncs.com" 8 | # 默认端口 9 | port = 5672 10 | # 资源隔离 11 | virtualHost = "xxx" 12 | # 阿里云的AMQP的静态用户名 13 | userName = "xxx" 14 | # 阿里云的AMQP的静态密码 15 | userPassword = "xxxx" 16 | 17 | 18 | def get_connection_param(): 19 | credentials = pika.PlainCredentials(userName, userPassword, erase_on_connect=True) 20 | if port == 5671: 21 | context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) 22 | context.check_hostname = False 23 | context.verify_mode = False 24 | return pika.ConnectionParameters(host, port, virtualHost, credentials, ssl_options=pika.SSLOptions(context)) 25 | else: 26 | return pika.ConnectionParameters(host, port, virtualHost, credentials) 27 | -------------------------------------------------------------------------------- /amqp-python-demo/connection.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AliwareMQ/amqp-demos/9d172c29a5d101fe7d1df21bffe1735ad5351c04/amqp-python-demo/connection.pyc -------------------------------------------------------------------------------- /amqp-python-demo/receive.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import logging 3 | import pika 4 | import connection 5 | 6 | LOG_FORMAT = ('%(levelname) -10s %(asctime)s %(name) -30s %(funcName) ' 7 | '-35s %(lineno) -5d: %(message)s') 8 | LOGGER = logging.getLogger(__name__) 9 | 10 | class ExampleConsumer(object): 11 | """This is an example consumer that will handle unexpected interactions 12 | with RabbitMQ such as channel and connection closures. 13 | 14 | If RabbitMQ closes the connection, it will reopen it. You should 15 | look at the output, as there are limited reasons why the connection may 16 | be closed, which usually are tied to permission related issues or 17 | socket timeouts. 18 | 19 | If the channel is closed, it will indicate a problem with one of the 20 | commands that were issued and that should surface in the output as well. 21 | 22 | """ 23 | EXCHANGE = 'xx-exchange' 24 | EXCHANGE_TYPE = 'direct' 25 | QUEUE = 'xx-queue' 26 | ROUTING_KEY = 'xx-key' 27 | DURABLE = True 28 | def __init__(self): 29 | """Create a new instance of the consumer class, passing in the AMQP 30 | URL used to connect to RabbitMQ. 31 | 32 | :param str amqp_url: The AMQP url to connect with 33 | 34 | """ 35 | self._connection = None 36 | self._channel = None 37 | self._closing = False 38 | self._consumer_tag = None 39 | self._stopping = False 40 | 41 | def connect(self): 42 | """This method connects to RabbitMQ, returning the connection handle. 43 | When the connection is established, the on_connection_open method 44 | will be invoked by pika. 45 | 46 | :rtype: pika.SelectConnection 47 | 48 | """ 49 | LOGGER.info('Connecting .....') 50 | return pika.SelectConnection(connection.get_connection_param(), 51 | on_open_callback=self.on_connection_open, 52 | on_open_error_callback=self.on_connection_open_error, 53 | on_close_callback=self.on_connection_closed) 54 | 55 | def on_connection_open(self, unused_connection): 56 | """This method is called by pika once the connection to RabbitMQ has 57 | been established. It passes the handle to the connection object in 58 | case we need it, but in this case, we'll just mark it unused. 59 | 60 | :type unused_connection: pika.SelectConnection 61 | 62 | """ 63 | LOGGER.info('Connection opened') 64 | self.open_channel() 65 | 66 | def on_connection_open_error(self, _unused_connection, err): 67 | """This method is called by pika if the connection to RabbitMQ 68 | can't be established. 69 | 70 | :type unused_connection: pika.SelectConnection 71 | :type err: Exception 72 | 73 | """ 74 | LOGGER.error('Connection open failed, reopening in 5 seconds: %s', err) 75 | self._connection.ioloop.call_later(5, self._connection.ioloop.stop) 76 | 77 | def on_connection_closed(self, _unused_connection, reason): 78 | """This method is invoked by pika when the connection to RabbitMQ is 79 | closed unexpectedly. Since it is unexpected, we will reconnect to 80 | RabbitMQ if it disconnects. 81 | :param pika.connection.Connection connection: The closed connection obj 82 | :param Exception reason: exception representing reason for loss of 83 | connection. 84 | """ 85 | self._channel = None 86 | if self._stopping: 87 | self._connection.ioloop.stop() 88 | else: 89 | LOGGER.warning('Connection closed, reopening in 5 seconds: %s', 90 | reason) 91 | self._connection.ioloop.call_later(5, self._connection.ioloop.stop) 92 | 93 | 94 | def reconnect(self): 95 | """Will be invoked by the IOLoop timer if the connection is 96 | closed. See the on_connection_closed method. 97 | 98 | """ 99 | # This is the old connection IOLoop instance, stop its ioloop 100 | self._connection.ioloop.stop() 101 | 102 | if not self._closing: 103 | 104 | # Create a new connection 105 | self._connection = self.connect() 106 | 107 | # There is now a new connection, needs a new ioloop to run 108 | self._connection.ioloop.start() 109 | 110 | def open_channel(self): 111 | """Open a new channel with RabbitMQ by issuing the Channel.Open RPC 112 | command. When RabbitMQ responds that the channel is open, the 113 | on_channel_open callback will be invoked by pika. 114 | 115 | """ 116 | LOGGER.info('Creating a new channel') 117 | self._connection.channel(on_open_callback=self.on_channel_open) 118 | 119 | def on_channel_open(self, channel): 120 | """This method is invoked by pika when the channel has been opened. 121 | The channel object is passed in so we can make use of it. 122 | 123 | Since the channel is now open, we'll declare the exchange to use. 124 | 125 | :param pika.channel.Channel channel: The channel object 126 | 127 | """ 128 | LOGGER.info('Channel opened') 129 | self._channel = channel 130 | self.add_on_channel_close_callback() 131 | self.setup_exchange(self.EXCHANGE) 132 | 133 | def add_on_channel_close_callback(self): 134 | """This method tells pika to call the on_channel_closed method if 135 | RabbitMQ unexpectedly closes the channel. 136 | 137 | """ 138 | LOGGER.info('Adding channel close callback') 139 | self._channel.add_on_close_callback(self.on_channel_closed) 140 | 141 | def on_channel_closed(self, channel, reason): 142 | """Invoked by pika when RabbitMQ unexpectedly closes the channel. 143 | Channels are usually closed if you attempt to do something that 144 | violates the protocol, such as re-declare an exchange or queue with 145 | different parameters. In this case, we'll close the connection 146 | to shutdown the object. 147 | :param pika.channel.Channel: The closed channel 148 | :param Exception reason: why the channel was closed 149 | """ 150 | LOGGER.warning('Channel %i was closed: %s', channel, reason) 151 | self.close_connection() 152 | 153 | def setup_exchange(self, exchange_name): 154 | """Setup the exchange on RabbitMQ by invoking the Exchange.Declare RPC 155 | command. When it is complete, the on_exchange_declareok method will 156 | be invoked by pika. 157 | 158 | :param str|unicode exchange_name: The name of the exchange to declare 159 | 160 | """ 161 | LOGGER.info('Declaring exchange %s', exchange_name) 162 | # self._channel.exchange_declare(self.on_exchange_declareok, 163 | # exchange_name, 164 | # self.EXCHANGE_TYPE) 165 | self._channel.exchange_declare(exchange_name, 166 | durable=self.DURABLE, 167 | exchange_type=self.EXCHANGE_TYPE, 168 | callback=self.on_exchange_declareok) 169 | 170 | def on_exchange_declareok(self, unused_frame): 171 | """Invoked by pika when RabbitMQ has finished the Exchange.Declare RPC 172 | command. 173 | 174 | :param pika.Frame.Method unused_frame: Exchange.DeclareOk response frame 175 | 176 | """ 177 | LOGGER.info('Exchange declared') 178 | self.setup_queue(self.QUEUE) 179 | 180 | def setup_queue(self, queue_name): 181 | """Setup the queue on RabbitMQ by invoking the Queue.Declare RPC 182 | command. When it is complete, the on_queue_declareok method will 183 | be invoked by pika. 184 | 185 | :param str|unicode queue_name: The name of the queue to declare. 186 | 187 | """ 188 | LOGGER.info('Declaring queue %s', queue_name) 189 | # self._channel.queue_declare(self.on_queue_declareok, queue_name) 190 | 191 | # self._channel.queue_declare(queue_name, callback=self.on_queue_declareok) 192 | 193 | self._channel.queue_declare(queue_name, durable=self.DURABLE, callback=self.on_queue_declareok) 194 | 195 | def on_queue_declareok(self, method_frame): 196 | """Method invoked by pika when the Queue.Declare RPC call made in 197 | setup_queue has completed. In this method we will bind the queue 198 | and exchange together with the routing key by issuing the Queue.Bind 199 | RPC command. When this command is complete, the on_bindok method will 200 | be invoked by pika. 201 | 202 | :param pika.frame.Method method_frame: The Queue.DeclareOk frame 203 | 204 | """ 205 | LOGGER.info('Binding %s to %s with %s', 206 | self.EXCHANGE, self.QUEUE, self.ROUTING_KEY) 207 | # self._channel.queue_bind(self.on_bindok, self.QUEUE, 208 | # self.EXCHANGE, self.ROUTING_KEY) 209 | 210 | self._channel.queue_bind(self.QUEUE, 211 | self.EXCHANGE, self.ROUTING_KEY, callback=self.on_bindok) 212 | 213 | def on_bindok(self, unused_frame): 214 | """Invoked by pika when the Queue.Bind method has completed. At this 215 | point we will start consuming messages by calling start_consuming 216 | which will invoke the needed RPC commands to start the process. 217 | 218 | :param pika.frame.Method unused_frame: The Queue.BindOk response frame 219 | 220 | """ 221 | LOGGER.info('Queue bound') 222 | self.start_consuming() 223 | 224 | def start_consuming(self): 225 | """This method sets up the consumer by first calling 226 | add_on_cancel_callback so that the object is notified if RabbitMQ 227 | cancels the consumer. It then issues the Basic.Consume RPC command 228 | which returns the consumer tag that is used to uniquely identify the 229 | consumer with RabbitMQ. We keep the value to use it when we want to 230 | cancel consuming. The on_message method is passed in as a callback pika 231 | will invoke when a message is fully received. 232 | 233 | """ 234 | LOGGER.info('Issuing consumer related RPC commands') 235 | self.add_on_cancel_callback() 236 | self._consumer_tag = self._channel.basic_consume(self.QUEUE, on_message_callback=self.on_message) 237 | 238 | 239 | def add_on_cancel_callback(self): 240 | """Add a callback that will be invoked if RabbitMQ cancels the consumer 241 | for some reason. If RabbitMQ does cancel the consumer, 242 | on_consumer_cancelled will be invoked by pika. 243 | 244 | """ 245 | LOGGER.info('Adding consumer cancellation callback') 246 | self._channel.add_on_cancel_callback(self.on_consumer_cancelled) 247 | 248 | def on_consumer_cancelled(self, method_frame): 249 | """Invoked by pika when RabbitMQ sends a Basic.Cancel for a consumer 250 | receiving messages. 251 | 252 | :param pika.frame.Method method_frame: The Basic.Cancel frame 253 | 254 | """ 255 | LOGGER.info('Consumer was cancelled remotely, shutting down: %r', 256 | method_frame) 257 | if self._channel: 258 | self._channel.close() 259 | 260 | def on_message(self, unused_channel, basic_deliver, properties, body): 261 | """Invoked by pika when a message is delivered from RabbitMQ. The 262 | channel is passed for your convenience. The basic_deliver object that 263 | is passed in carries the exchange, routing key, delivery tag and 264 | a redelivered flag for the message. The properties passed in is an 265 | instance of BasicProperties with the message properties and the body 266 | is the message that was sent. 267 | 268 | :param pika.channel.Channel unused_channel: The channel object 269 | :param pika.Spec.Basic.Deliver: basic_deliver method 270 | :param pika.Spec.BasicProperties: properties 271 | :param str|unicode body: The message body 272 | 273 | """ 274 | LOGGER.warning('Received message # %s from %s: %s', 275 | basic_deliver.delivery_tag, properties.app_id, body) 276 | self.acknowledge_message(basic_deliver.delivery_tag) 277 | 278 | def acknowledge_message(self, delivery_tag): 279 | """Acknowledge the message delivery from RabbitMQ by sending a 280 | Basic.Ack RPC method for the delivery tag. 281 | 282 | :param int delivery_tag: The delivery tag from the Basic.Deliver frame 283 | 284 | """ 285 | LOGGER.info('Acknowledging message %s', delivery_tag) 286 | self._channel.basic_ack(delivery_tag) 287 | 288 | def stop_consuming(self): 289 | """Tell RabbitMQ that you would like to stop consuming by sending the 290 | Basic.Cancel RPC command. 291 | 292 | """ 293 | if self._channel: 294 | LOGGER.info('Sending a Basic.Cancel RPC command to RabbitMQ') 295 | # self._channel.basic_cancel(self.on_cancelok, self._consumer_tag) 296 | self._channel.basic_cancel(self._consumer_tag, self.on_cancelok) 297 | 298 | def on_cancelok(self, unused_frame): 299 | """This method is invoked by pika when RabbitMQ acknowledges the 300 | cancellation of a consumer. At this point we will close the channel. 301 | This will invoke the on_channel_closed method once the channel has been 302 | closed, which will in-turn close the connection. 303 | 304 | :param pika.frame.Method unused_frame: The Basic.CancelOk frame 305 | 306 | """ 307 | LOGGER.info('RabbitMQ acknowledged the cancellation of the consumer') 308 | self.close_channel() 309 | 310 | def close_channel(self): 311 | """Call to close the channel with RabbitMQ cleanly by issuing the 312 | Channel.Close RPC command. 313 | 314 | """ 315 | LOGGER.info('Closing the channel') 316 | self._channel.close() 317 | 318 | def run(self): 319 | """Run the example consumer by connecting to RabbitMQ and then 320 | starting the IOLoop to block and allow the SelectConnection to operate. 321 | 322 | """ 323 | while not self._stopping: 324 | self._connection = self.connect() 325 | self._connection.ioloop.start() 326 | 327 | def stop(self): 328 | """Cleanly shutdown the connection to RabbitMQ by stopping the consumer 329 | with RabbitMQ. When RabbitMQ confirms the cancellation, on_cancelok 330 | will be invoked by pika, which will then closing the channel and 331 | connection. The IOLoop is started again because this method is invoked 332 | when CTRL-C is pressed raising a KeyboardInterrupt exception. This 333 | exception stops the IOLoop which needs to be running for pika to 334 | communicate with RabbitMQ. All of the commands issued prior to starting 335 | the IOLoop will be buffered but not processed. 336 | 337 | """ 338 | LOGGER.info('Stopping') 339 | self._closing = True 340 | self.stop_consuming() 341 | self._connection.ioloop.start() 342 | LOGGER.info('Stopped') 343 | 344 | def close_connection(self): 345 | """This method closes the connection to RabbitMQ.""" 346 | LOGGER.info('Closing connection') 347 | self._connection.close() 348 | 349 | 350 | def main(): 351 | logging.basicConfig(level=logging.WARN, format=LOG_FORMAT) 352 | example = ExampleConsumer() 353 | try: 354 | example.run() 355 | except KeyboardInterrupt: 356 | example.stop() 357 | 358 | if __name__ == '__main__': 359 | main() 360 | -------------------------------------------------------------------------------- /amqp-ruby-demo/receive.rb: -------------------------------------------------------------------------------- 1 | #require "rubygems" 2 | require "amqp" 3 | 4 | 5 | #consumer 6 | class Consumer 7 | def handle_message(metadata, payload) 8 | puts "Received a message: #{payload}, content_type = #{metadata.content_type}" 9 | end 10 | end 11 | 12 | 13 | #worker thread 14 | class Worker 15 | def initialize(channel, queue_name = AMQP::Protocol::EMPTY_STRING, consumer = Consumer.new) 16 | @queue_name = queue_name 17 | @channel = channel 18 | @channel.on_error(&method(:handle_channel_exception)) 19 | @consumer = consumer 20 | end 21 | 22 | def start 23 | @queue = @channel.queue(@queue_name, :durable => true ) 24 | @queue.subscribe(&@consumer.method(:handle_message)) 25 | end 26 | 27 | def handle_channel_exception(channel, channel_close) 28 | puts "Oop... a channel-level[#{channel}] exception: code = #{channel_close.reply_code}, message = #{channel_close.reply_text}" 29 | end 30 | end 31 | 32 | 33 | #从控制台获取以下信息 34 | userName = "userName" 35 | passWord = "password" 36 | 37 | host = "rabbitmq-xxxxx.mq.amqp.aliyuncs.com" 38 | port = 5672 39 | vhost = "your-vhost" 40 | queueName = "your-queue" 41 | 42 | #连接服务器的URI 43 | connectStr = "amqp://" + userName + ":" + passWord + "@" + host + ":" + port.to_s + "/" + vhost 44 | 45 | 46 | 47 | #main 48 | AMQP.start(connectStr) do |connection, open_ok| 49 | channel = AMQP::Channel.new(connection) 50 | worker = Worker.new(channel, queueName) 51 | worker.start 52 | 53 | EM.add_timer(20.0) { connection.close{ EM.stop } } 54 | 55 | end 56 | 57 | -------------------------------------------------------------------------------- /amqp-ruby-demo/send.rb: -------------------------------------------------------------------------------- 1 | require "amqp" 2 | 3 | #producer 4 | class Producer 5 | def initialize(channel, exchange) 6 | @channel = channel 7 | @exchange = exchange 8 | 9 | end 10 | 11 | def publish(message, options = {}) 12 | @exchange.publish(message, options) do 13 | puts "Message sent and confirmed." 14 | end 15 | end 16 | 17 | def handle_channel_exception(channel, channel_close) 18 | puts "Oops... a channel-level exception: code = #{channel_close.reply_code}, message = #{channel_close.reply_text}" 19 | end 20 | end 21 | 22 | #从控制台获取以下信息 23 | userName = "userName" 24 | passWord = "password" 25 | 26 | host = "rabbitmq-xxxxx.mq.amqp.aliyuncs.com" 27 | port = 5672 28 | vhost = "your-vhost" 29 | queueName = "your-queue" 30 | exchangeName = "your-exchange" 31 | routingKey = "your-routing-key" 32 | 33 | #连接服务器的URI 34 | connectStr = "amqp://" + userName + ":" + passWord + "@" + host + ":" + port.to_s + "/" + vhost 35 | 36 | #main 37 | AMQP.start(connectStr) do |connection, open_ok| 38 | channel = AMQP::Channel.new(connection) 39 | 40 | exchange = channel.direct(exchangeName, :durable => true) 41 | queue = channel.queue(queueName, :durable => true) 42 | queue.bind(exchange, :routing_key => routingKey) 43 | # 注意:我们建议使用长链接方式发送和消费消息 44 | # Rabbitmq client 向Server发起connection,新建channel大约需要进行15+个TCP报文的传输,会消耗大量网络资源和Server端的资源,甚至引起Server端SYN flooding 攻击保护。因此我们建议消息的发送和消费尽量采用长链接的模式。 45 | producer = Producer.new(channel, exchange) 46 | puts "publish..." 47 | 10.times do |i| 48 | message = "hello, world, I am AMQP#{i}" 49 | producer.publish(message, :routing_key => routingKey, :persistent => true) 50 | end 51 | 52 | EM.add_timer(5.0) { connection.close { EM.stop } } 53 | 54 | end 55 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.gitignore: -------------------------------------------------------------------------------- 1 | *dependency-reduced-pom.xml 2 | .classpath 3 | .project 4 | .settings/ 5 | target/ 6 | devenv 7 | *.log* 8 | *.iml 9 | *.pid 10 | .idea/ 11 | *.versionsBackup 12 | !NOTICE-BIN 13 | !LICENSE-BIN 14 | .DS_Store 15 | .vscode 16 | **/.factorypath -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 36 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__com_google_guava_guava_19_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__com_jayway_jsonpath_json_path_2_4_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__com_rabbitmq_amqp_client_5_4_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__javax_annotation_javax_annotation_api_1_3_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__junit_junit_4_12.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_9_7.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_9_7.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__net_minidev_accessors_smart_1_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__net_minidev_json_smart_2_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_11_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_11_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_assertj_assertj_core_3_11_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_hamcrest_hamcrest_library_1_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_mockito_mockito_core_2_23_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_objenesis_objenesis_2_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_ow2_asm_asm_5_0_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_skyscreamer_jsonassert_1_5_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_slf4j_jul_to_slf4j_1_7_25.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_amqp_spring_amqp_2_1_3_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_amqp_spring_rabbit_2_1_3_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_1_2_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_1_2_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_1_2_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_amqp_2_1_2_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_1_2_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_1_2_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_1_2_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_1_2_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_retry_spring_retry_1_2_3_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_spring_aop_5_1_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_spring_beans_5_1_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_spring_context_5_1_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_spring_core_5_1_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_spring_expression_5_1_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_spring_jcl_5_1_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_spring_messaging_5_1_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_spring_test_5_1_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_springframework_spring_tx_5_1_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_xmlunit_xmlunit_core_2_6_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/libraries/Maven__org_yaml_snakeyaml_1_23.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.didispace 7 | rabbitmq-hello 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | rabbitmq-hello 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.1.2.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-amqp 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-test 35 | 36 | 37 | com.alibaba.mq-amqp 38 | mq-amqp-client 39 | 1.0.5 40 | 41 | 42 | com.google.guava 43 | guava 44 | 19.0 45 | 46 | 47 | org.apache.commons 48 | commons-lang3 49 | 3.4 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-starter-web 54 | 55 | 56 | org.slf4j 57 | slf4j-api 58 | 59 | 60 | 61 | 62 | 63 | org.springframework.boot 64 | spring-boot-maven-plugin 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/readme: -------------------------------------------------------------------------------- 1 | 不看必挂 2 | 1.修改application.properties 3 | #接入点根据控制台获取接入点 4 | spring.rabbitmq.host=${endpoint} 5 | #端口 默认5672 6 | spring.rabbitmq.port=${port} 7 | #accessKey ram控制台获取用户子账户ak 8 | spring.rabbitmq.username=${ak} 9 | #secretKey ram控制台获取用户子账户ak 10 | spring.rabbitmq.password=${sk} 11 | #virtual-host 你要使用的virtaulhost 12 | spring.rabbitmq.virtual-host=${vhost} 13 | 14 | 2.修改 RabbitConfig 类的属性INSTANCE_ID 15 | 16 | //实例Id 从阿里云AMQP控制台获取 17 | private static final String INSTANCE_ID="XXX"; -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/src/main/java/com/alibaba/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.alibaba; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | public static void main(String[] args) { 9 | SpringApplication.run(DemoApplication.class, args); 10 | } 11 | } -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/src/main/java/com/alibaba/rabbit/RabbitConfig.java: -------------------------------------------------------------------------------- 1 | package com.alibaba.rabbit; 2 | 3 | import java.security.KeyManagementException; 4 | import java.security.NoSuchAlgorithmException; 5 | import org.springframework.amqp.core.*; 6 | import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; 7 | import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; 8 | import org.springframework.amqp.rabbit.connection.ConnectionFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.autoconfigure.amqp.RabbitProperties; 11 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | 18 | @Configuration 19 | public class RabbitConfig { 20 | 21 | @Autowired 22 | private RabbitProperties rabbitProperties; 23 | 24 | @Bean 25 | public ConnectionFactory getConnectionFactory() throws NoSuchAlgorithmException, KeyManagementException { 26 | // 初始化RabbitMQ连接配置 connectionFactory 27 | CachingConnectionFactory connectionFactory = new CachingConnectionFactory(); 28 | connectionFactory.setHost(rabbitProperties.getHost()); 29 | connectionFactory.setPort(rabbitProperties.getPort()); 30 | connectionFactory.setUsername(rabbitProperties.getUsername()); 31 | connectionFactory.setPassword(rabbitProperties.getPassword()); 32 | connectionFactory.setVirtualHost(rabbitProperties.getVirtualHost()); 33 | // 开启Connection自动重连功能 34 | connectionFactory.getRabbitConnectionFactory().setAutomaticRecoveryEnabled(true); 35 | /* 36 | * 使用云消息队列 RabbitMQ,推荐使用CacheMode.CONNECTION 模式(建多个connection,程序会缓存一定数量的connection,每个connection中缓存一定数量的channel)。 37 | * 云消息队列 RabbitMQ 是集群分布式架构,在CONNECTION模式下,创建多个connection 可以更好地和集群的多个MQ服务节点连接,更高效的发送和消费消息。。 38 | */ 39 | connectionFactory.setCacheMode(CachingConnectionFactory.CacheMode.CONNECTION); 40 | // CONNECTION模式下,缓存的connection数量 41 | connectionFactory.setConnectionCacheSize(10); 42 | // 缓存中保持的channel数量 43 | connectionFactory.setChannelCacheSize(64); 44 | 45 | connectionFactory.setPublisherConfirms(rabbitProperties.isPublisherConfirms()); 46 | connectionFactory.setPublisherReturns(rabbitProperties.isPublisherReturns()); 47 | 48 | // 开启数据传输加密 49 | // connectionFactory.getRabbitConnectionFactory().useSslProtocol(); 50 | // connectionFactory.setPort(5671); 51 | 52 | return connectionFactory; 53 | } 54 | 55 | @Bean 56 | @ConditionalOnClass 57 | public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(CachingConnectionFactory connectionFactory) { 58 | SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); 59 | factory.setConnectionFactory(connectionFactory); 60 | factory.setAcknowledgeMode(AcknowledgeMode.MANUAL); 61 | return factory; 62 | } 63 | 64 | /** 65 | * 申明队列 66 | * 67 | * @return 68 | */ 69 | @Bean 70 | public Queue queue() { 71 | Map arguments = new HashMap<>(4); 72 | 73 | return new Queue("queue-rabbit-springboot-advance", true, false, false, arguments); 74 | } 75 | 76 | @Bean 77 | public Exchange exchange() { 78 | Map arguments = new HashMap<>(4); 79 | 80 | return new DirectExchange("exchange-rabbit-springboot-advance", true, false, arguments); 81 | } 82 | 83 | /** 84 | * 申明绑定 85 | * 86 | * @return 87 | */ 88 | @Bean 89 | public Binding binding() { 90 | return BindingBuilder.bind(queue()).to(exchange()).with("product").noargs(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/src/main/java/com/alibaba/rabbit/RabbitConfirmCallback.java: -------------------------------------------------------------------------------- 1 | package com.alibaba.rabbit; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.amqp.rabbit.connection.CorrelationData; 6 | import org.springframework.amqp.rabbit.core.RabbitTemplate; 7 | 8 | /** 9 | * @author siyong.dxh@taobao.com 10 | * @Date 2019/4/23 8:22 PM 11 | */ 12 | public class RabbitConfirmCallback implements RabbitTemplate.ConfirmCallback { 13 | 14 | private static final Logger log= LoggerFactory.getLogger(RabbitConfirmCallback.class); 15 | 16 | @Override 17 | public void confirm(CorrelationData correlationData, boolean ack, String cause) { 18 | log.info("MessageConfirm correlationData: {}, ack: {}, cause: {}", correlationData, ack, cause); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/src/main/java/com/alibaba/rabbit/RabbitReturnCallback.java: -------------------------------------------------------------------------------- 1 | package com.alibaba.rabbit; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.amqp.core.Message; 6 | import org.springframework.amqp.rabbit.core.RabbitTemplate; 7 | 8 | /** 9 | * @author siyong.dxh@taobao.com 10 | * @Date 2019/4/23 8:22 PM 11 | */ 12 | public class RabbitReturnCallback implements RabbitTemplate.ReturnCallback { 13 | 14 | private static final Logger log= LoggerFactory.getLogger(RabbitReturnCallback.class); 15 | 16 | @Override 17 | public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) { 18 | log.info("message return message: {}, replyCode: {}, replyText: {}, exchange: {}, routingKey: {}", 19 | new String(message.getBody()), replyCode, replyText, exchange, routingKey); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/src/main/java/com/alibaba/rabbit/Receiver.java: -------------------------------------------------------------------------------- 1 | package com.alibaba.rabbit; 2 | 3 | import com.rabbitmq.client.Channel; 4 | import java.io.IOException; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.amqp.core.Message; 8 | import org.springframework.amqp.rabbit.annotation.RabbitListener; 9 | import org.springframework.amqp.support.AmqpHeaders; 10 | import org.springframework.messaging.handler.annotation.Header; 11 | import org.springframework.stereotype.Component; 12 | 13 | @Component 14 | public class Receiver { 15 | 16 | private static final Logger log = LoggerFactory.getLogger(Receiver.class); 17 | 18 | /** 19 | * 消息接收 自动确认ack 20 | * @param message 消息 21 | */ 22 | // @RabbitListener(queues = "queue-rabbit-springboot-advance") 23 | // public void process(Message message) { 24 | // log.info("receive message: {}", new String(message.getBody())); 25 | // // 进入业务消费逻辑 26 | // } 27 | 28 | /** 29 | * 消息接收 手动确认ack 30 | * @param message 消息 31 | * @param deliveryTag messageProperties中的DELIVERY_TAG属性 32 | * @param channel 接收消息的channel 33 | */ 34 | @RabbitListener(queues = "queue-rabbit-springboot-advance") 35 | public void processMsgWithRequiredManualAck(Message message, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, 36 | Channel channel) throws IOException { 37 | log.info("receive message: {}", new String(message.getBody())); 38 | // 进入业务消费逻辑 39 | 40 | channel.basicAck(deliveryTag, false); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/src/main/java/com/alibaba/rabbit/Sender.java: -------------------------------------------------------------------------------- 1 | package com.alibaba.rabbit; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.amqp.core.Message; 6 | import org.springframework.amqp.core.MessageProperties; 7 | import org.springframework.amqp.rabbit.connection.CorrelationData; 8 | import org.springframework.amqp.rabbit.core.RabbitTemplate; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Component; 11 | 12 | import java.util.UUID; 13 | 14 | @Component 15 | public class Sender { 16 | 17 | private static final Logger log = LoggerFactory.getLogger(Sender.class); 18 | 19 | @Autowired 20 | private RabbitTemplate rabbitTemplate; 21 | 22 | public void send() { 23 | String exchange = "exchange-rabbit-springboot-advance"; 24 | String routingKey = "product"; 25 | 26 | MessageProperties messageProperties = new MessageProperties(); 27 | String msgId = "routing-" + UUID.randomUUID().toString(); 28 | //此处设置的msgId才能被会转成rabbitmq client的messageId,发送给broker 29 | messageProperties.setMessageId(msgId); 30 | Message message = new Message("发送一条消息".getBytes(), messageProperties); 31 | 32 | rabbitTemplate.convertAndSend(exchange, routingKey, message, 33 | new CorrelationData(msgId)); 34 | 35 | log.info("发送一条消息,exchange:[{}],routingKey:[{}],message:[{}]", exchange, routingKey, message); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/src/main/java/com/alibaba/rabbit/SenderWithCallback.java: -------------------------------------------------------------------------------- 1 | package com.alibaba.rabbit; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.amqp.core.Message; 6 | import org.springframework.amqp.core.MessageProperties; 7 | import org.springframework.amqp.rabbit.connection.CorrelationData; 8 | import org.springframework.amqp.rabbit.core.RabbitTemplate; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Component; 11 | 12 | import javax.annotation.PostConstruct; 13 | import java.util.UUID; 14 | 15 | 16 | @Component 17 | public class SenderWithCallback { 18 | private static final Logger log = LoggerFactory.getLogger(SenderWithCallback.class); 19 | @Autowired 20 | private RabbitTemplate rabbitTemplate; 21 | 22 | @PostConstruct 23 | public void initRabbitTemplate() { 24 | // 设置生产者消息确认 25 | rabbitTemplate.setConfirmCallback(new RabbitConfirmCallback()); 26 | rabbitTemplate.setReturnCallback(new RabbitReturnCallback()); 27 | } 28 | 29 | public void send() { 30 | String exchange = "exchange-rabbit-springboot-advance"; 31 | String unRoutingKey = "unProduct"; 32 | 33 | //1.发送一条未被路由消息 34 | MessageProperties messageProperties = new MessageProperties(); 35 | String msgId = "unRouting-" + UUID.randomUUID().toString(); 36 | //此处设置的msgId才能被会转成rabbitmq client的messageId,发送给broker 37 | messageProperties.setMessageId(msgId); 38 | Message message = new Message("发送一条消息".getBytes(), messageProperties); 39 | 40 | rabbitTemplate.convertAndSend(exchange, unRoutingKey, message, new CorrelationData(msgId)); 41 | 42 | log.info("发送一条消息,exchange:[{}],routingKey:[{}],message:[{}]", exchange, unRoutingKey, message); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/src/main/java/com/alibaba/rabbit/TestSenderController.java: -------------------------------------------------------------------------------- 1 | package com.alibaba.rabbit; 2 | 3 | import org.jboss.logging.Param; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestParam; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | import javax.annotation.Resource; 9 | 10 | @RestController 11 | @RequestMapping(value = "/test", produces = "application/json;charset=UTF-8") 12 | public class TestSenderController { 13 | 14 | @Resource 15 | private SenderWithCallback sendWithCallback; 16 | 17 | @Resource 18 | private Sender sender; 19 | 20 | /** 21 | * 发送消息 22 | * @param withCallback 测试messageReturn功能开关 23 | * @return "success" 24 | */ 25 | @RequestMapping(value="/send") 26 | public String sendMessage(@RequestParam(name="withCallback",required = false) boolean withCallback){ 27 | if(withCallback) { 28 | sendWithCallback.send(); 29 | }else{ 30 | sender.send(); 31 | } 32 | 33 | return "success"; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=rabbitmq-demo 2 | 3 | # http服务器端口 4 | server.port=8080 5 | 6 | spring.rabbitmq.host=${YOUR_HOST} 7 | spring.rabbitmq.port=5672 8 | spring.rabbitmq.username=${YOUR_USERNAME} 9 | spring.rabbitmq.password=${YOUR_PASSWORD} 10 | spring.rabbitmq.virtual-host=${YOUR_VIRTUAL_HOST} 11 | spring.rabbitmq.template.mandatory=true 12 | spring.rabbitmq.publisher-confirms=true 13 | spring.rabbitmq.publisher-returns=true 14 | spring.rabbitmq.dynamic=false 15 | -------------------------------------------------------------------------------- /amqp-springboot-demo/SprintBootDemo/src/test/java/com/alibaba/DemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.alibaba; 2 | 3 | import com.alibaba.rabbit.Sender; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 9 | 10 | @RunWith(SpringJUnit4ClassRunner.class) 11 | @SpringBootTest 12 | public class DemoApplicationTests { 13 | @Autowired 14 | private Sender sender; 15 | 16 | @Test 17 | public void hello() throws Exception { 18 | while (true) { 19 | try { 20 | sender.send(); 21 | Thread.sleep(1000); 22 | } catch (Exception e) { 23 | ; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /amqp-springcloud-stream-demo/amqp-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.demo 8 | amqp-demo 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | org.springframework.boot 14 | spring-boot-starter-parent 15 | 2.1.5.RELEASE 16 | 17 | 18 | 19 | 20 | UTF-8 21 | UTF-8 22 | 1.8 23 | Greenwich.SR1 24 | 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | 31 | 32 | org.springframework.cloud 33 | spring-cloud-starter-stream-rabbit 34 | 35 | 36 | 37 | com.alibaba.mq-amqp 38 | mq-amqp-client 39 | 1.0.5 40 | 41 | 42 | 43 | org.apache.commons 44 | commons-lang3 45 | 3.4 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-starter-test 51 | test 52 | 53 | 54 | org.springframework.cloud 55 | spring-cloud-stream-test-support 56 | test 57 | 58 | 59 | 60 | 61 | 62 | 63 | org.springframework.cloud 64 | spring-cloud-dependencies 65 | ${spring-cloud.version} 66 | pom 67 | import 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | org.springframework.boot 76 | spring-boot-maven-plugin 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /amqp-springcloud-stream-demo/amqp-demo/readme: -------------------------------------------------------------------------------- 1 | 不看必挂 2 | 1.修改application.properties 3 | #接入点根据AMQP控制台获取接入点 4 | spring.rabbitmq.host=${endpoint} 5 | #端口 默认5672 6 | spring.rabbitmq.port=${port} 7 | #userName AMQP控制台获取 8 | spring.rabbitmq.username=${userName} 9 | #password AMQP控制台获取用 10 | spring.rabbitmq.password=${password} 11 | #virtual-host 你要使用的virtaulhost,AMQP控制台获取用 12 | spring.rabbitmq.virtual-host=${vhost} 13 | 14 | -------------------------------------------------------------------------------- /amqp-springcloud-stream-demo/amqp-demo/src/main/java/com/mynotes/spring/Application.java: -------------------------------------------------------------------------------- 1 | package com.mynotes.spring; 2 | 3 | import com.mynotes.spring.channel.AmqpGreetingChannel; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.stream.annotation.EnableBinding; 7 | 8 | @EnableBinding(AmqpGreetingChannel.class) 9 | @SpringBootApplication 10 | public class Application { 11 | 12 | public static void main(String[] args) { 13 | SpringApplication.run(Application.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /amqp-springcloud-stream-demo/amqp-demo/src/main/java/com/mynotes/spring/channel/AmqpGreetingChannel.java: -------------------------------------------------------------------------------- 1 | package com.mynotes.spring.channel; 2 | 3 | import org.springframework.cloud.stream.annotation.Input; 4 | import org.springframework.cloud.stream.annotation.Output; 5 | import org.springframework.messaging.MessageChannel; 6 | import org.springframework.messaging.SubscribableChannel; 7 | 8 | public interface AmqpGreetingChannel { 9 | 10 | String GREETING_IN = "greetingInChannel"; 11 | String GREETING_OUT = "greetingOutChannel"; 12 | 13 | @Output(AmqpGreetingChannel.GREETING_OUT) 14 | MessageChannel outGreeting(); 15 | 16 | @Input(AmqpGreetingChannel.GREETING_IN) 17 | SubscribableChannel inGreeting(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /amqp-springcloud-stream-demo/amqp-demo/src/main/java/com/mynotes/spring/config/RabbitConfig.java: -------------------------------------------------------------------------------- 1 | package com.mynotes.spring.config; 2 | 3 | 4 | import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; 5 | import org.springframework.amqp.rabbit.connection.ConnectionFactory; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.autoconfigure.amqp.RabbitProperties; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | 11 | @Configuration 12 | public class RabbitConfig { 13 | @Autowired 14 | private RabbitProperties rabbitProperties; 15 | 16 | @Bean 17 | public ConnectionFactory getConnectionFactory() { 18 | com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = 19 | new com.rabbitmq.client.ConnectionFactory(); 20 | rabbitConnectionFactory.setHost(rabbitProperties.getHost()); 21 | rabbitConnectionFactory.setPort(rabbitProperties.getPort()); 22 | rabbitConnectionFactory.setVirtualHost(rabbitProperties.getVirtualHost()); 23 | rabbitConnectionFactory.setUsername(rabbitProperties.getUsername()); 24 | rabbitConnectionFactory.setPassword(rabbitProperties.getPassword()); 25 | //rabbitConnectionFactory.setAutomaticRecoveryEnabled(true); 26 | rabbitConnectionFactory.setNetworkRecoveryInterval(5000); 27 | // 开启数据传输加密 28 | // rabbitConnectionFactory.getRabbitConnectionFactory().useSslProtocol(); 29 | // rabbitConnectionFactory.setPort(5671); 30 | ConnectionFactory connectionFactory = new CachingConnectionFactory(rabbitConnectionFactory); 31 | ((CachingConnectionFactory) connectionFactory).setPublisherConfirms(rabbitProperties.isPublisherConfirms()); 32 | ((CachingConnectionFactory) connectionFactory).setPublisherReturns(rabbitProperties.isPublisherReturns()); 33 | return connectionFactory; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /amqp-springcloud-stream-demo/amqp-demo/src/main/java/com/mynotes/spring/consumer/AckModelChecker.java: -------------------------------------------------------------------------------- 1 | package com.mynotes.spring.consumer; 2 | 3 | import com.mynotes.spring.channel.AmqpGreetingChannel; 4 | import com.rabbitmq.client.Channel; 5 | import org.springframework.amqp.support.AmqpHeaders; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.cloud.stream.annotation.EnableBinding; 8 | import org.springframework.cloud.stream.annotation.StreamListener; 9 | import org.springframework.core.env.Environment; 10 | import org.springframework.messaging.Message; 11 | import org.springframework.messaging.handler.annotation.Header; 12 | import org.springframework.stereotype.Component; 13 | 14 | @Component 15 | public class AckModelChecker { 16 | @Autowired 17 | private Environment env; 18 | String ACK_MODE_PROPERTY = "spring.cloud.stream.rabbit.bindings.greetingInChannel.consumer.acknowledge-mode"; 19 | 20 | public boolean isManualAckModel() { 21 | String ackMode = env.getProperty(ACK_MODE_PROPERTY); 22 | return "MANUAL".equalsIgnoreCase(ackMode); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /amqp-springcloud-stream-demo/amqp-demo/src/main/java/com/mynotes/spring/consumer/ConsumerReceiver.java: -------------------------------------------------------------------------------- 1 | package com.mynotes.spring.consumer; 2 | 3 | import com.mynotes.spring.channel.AmqpGreetingChannel; 4 | import com.mynotes.spring.service.AmqpConsumeService; 5 | import com.rabbitmq.client.Channel; 6 | import org.springframework.amqp.support.AmqpHeaders; 7 | import org.springframework.cloud.stream.annotation.StreamListener; 8 | import org.springframework.messaging.Message; 9 | import org.springframework.messaging.handler.annotation.Header; 10 | import org.springframework.stereotype.Component; 11 | 12 | import javax.annotation.Resource; 13 | 14 | @Component 15 | public class ConsumerReceiver { 16 | 17 | @Resource 18 | private AckModelChecker ackModelChecker; 19 | 20 | @Resource 21 | private AmqpConsumeService amqpConsumeService; 22 | 23 | @StreamListener(target = AmqpGreetingChannel.GREETING_IN) 24 | public void consume(Message msg, @Header(AmqpHeaders.CHANNEL) Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) { 25 | String msgBody = msg.getPayload(); 26 | System.out.println("[x]Received message from greeting channel:" + msg); 27 | boolean consumeSuccess = amqpConsumeService.processMessage(msgBody); 28 | if (ackModelChecker.isManualAckModel()) { 29 | try { 30 | if (consumeSuccess) { 31 | channel.basicAck(deliveryTag, false); 32 | System.out.println("[ x]Success consuming message from greeting channel:" + msg); 33 | } else { 34 | channel.basicNack(deliveryTag, false, true); 35 | System.out.println("[ x]Failed consuming message from greeting channel:" + msg); 36 | } 37 | } catch (Exception e) { 38 | e.printStackTrace(); 39 | } 40 | } else { 41 | System.out.println("[ x]Auto-Ack message to greeting channel:" + msg); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /amqp-springcloud-stream-demo/amqp-demo/src/main/java/com/mynotes/spring/producer/ProducerController.java: -------------------------------------------------------------------------------- 1 | package com.mynotes.spring.producer; 2 | 3 | import com.mynotes.spring.service.AmqpGreetingService; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.PathVariable; 6 | import org.springframework.web.bind.annotation.RequestParam; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import javax.annotation.Resource; 10 | 11 | @RestController 12 | public class ProducerController { 13 | 14 | @Resource 15 | private AmqpGreetingService producerAmqpService; 16 | 17 | @GetMapping("/test/{name}") 18 | public String publish(@PathVariable String name) { 19 | String greeting = producerAmqpService.greetAmqp(name); 20 | return "Message Sent: " + greeting; 21 | } 22 | @GetMapping("/greet") 23 | public String greet(@RequestParam String message) { 24 | String greeting = producerAmqpService.greetAmqp(message); 25 | return "Message Sent: " + greeting; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /amqp-springcloud-stream-demo/amqp-demo/src/main/java/com/mynotes/spring/service/AmqpConsumeService.java: -------------------------------------------------------------------------------- 1 | package com.mynotes.spring.service; 2 | 3 | public interface AmqpConsumeService { 4 | 5 | boolean processMessage(String body); 6 | } 7 | -------------------------------------------------------------------------------- /amqp-springcloud-stream-demo/amqp-demo/src/main/java/com/mynotes/spring/service/AmqpConsumeServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.mynotes.spring.service; 2 | 3 | import org.springframework.stereotype.Service; 4 | 5 | @Service 6 | public class AmqpConsumeServiceImpl implements AmqpConsumeService { 7 | @Override 8 | public boolean processMessage(String body) { 9 | System.out.println("[x]Processed message from greeting channel:" + body); 10 | return true; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /amqp-springcloud-stream-demo/amqp-demo/src/main/java/com/mynotes/spring/service/AmqpGreetingService.java: -------------------------------------------------------------------------------- 1 | package com.mynotes.spring.service; 2 | 3 | public interface AmqpGreetingService { 4 | 5 | String greetAmqp(String body); 6 | } 7 | -------------------------------------------------------------------------------- /amqp-springcloud-stream-demo/amqp-demo/src/main/java/com/mynotes/spring/service/AmqpGreetingServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.mynotes.spring.service; 2 | 3 | import com.mynotes.spring.channel.AmqpGreetingChannel; 4 | import org.springframework.messaging.Message; 5 | import org.springframework.messaging.support.MessageBuilder; 6 | import org.springframework.stereotype.Service; 7 | 8 | import javax.annotation.Resource; 9 | 10 | @Service 11 | public class AmqpGreetingServiceImpl implements AmqpGreetingService { 12 | 13 | @Resource 14 | private AmqpGreetingChannel channel; 15 | 16 | @Override 17 | public String greetAmqp(String body) { 18 | String greeting = "Hello, Spring Could Stream AMQP[" + body + "]!"; 19 | System.out.println("[x]Sending greeting: " + greeting); 20 | Message msg = MessageBuilder.withPayload(greeting) 21 | .setHeader("routingKey", "yunQi-routing-key") 22 | .build(); 23 | this.channel.outGreeting().send(msg); 24 | return "Message Sent: " + greeting; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /amqp-springcloud-stream-demo/amqp-demo/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | # ??AMQP???? 3 | spring.rabbitmq.host=rabbitmq-xxxx.mq.amqp.aliyuncs.com 4 | spring.rabbitmq.port=5672 5 | spring.rabbitmq.username=username 6 | spring.rabbitmq.password=password 7 | spring.rabbitmq.virtual-host=your-vhost 8 | #spring.rabbitmq.template.mandatory=true 9 | #spring.rabbitmq.publisher-confirms=true 10 | #spring.rabbitmq.publisher-returns=true 11 | 12 | # ??Stream Output?? 13 | spring.cloud.stream.bindings.greetingOutChannel.destination="your-exchange" 14 | spring.cloud.stream.bindings.greetingOutChannel.group=your-queue 15 | spring.cloud.stream.bindings.greetingOutChannel.content-type=application/json 16 | 17 | spring.cloud.stream.rabbit.bindings.greetingOutChannel.producer.binding-routing-key=your-routing-key 18 | spring.cloud.stream.rabbit.bindings.greetingOutChannel.producer.exchange-durable=true 19 | spring.cloud.stream.rabbit.bindings.greetingOutChannel.producer.bind-queue=true 20 | spring.cloud.stream.rabbit.bindings.greetingOutChannel.producer.exchangeType=direct 21 | spring.cloud.stream.rabbit.bindings.greetingOutChannel.producer.routing-key-expression=headers[routingKey] 22 | 23 | # ??Stream Input?? 24 | spring.cloud.stream.bindings.greetingInChannel.destination=your-exchange 25 | spring.cloud.stream.bindings.greetingInChannel.group=your-queue 26 | 27 | spring.cloud.stream.rabbit.bindings.greetingInChannel.consumer.binding-routing-key=your-routing-key 28 | spring.cloud.stream.rabbit.bindings.greetingInChannel.consumer.queue-name-group-only=true 29 | spring.cloud.stream.rabbit.bindings.greetingInChannel.consumer.exchange-type=direct 30 | spring.cloud.stream.rabbit.bindings.greetingInChannel.consumer.exchange-durable=true 31 | spring.cloud.stream.rabbit.bindings.greetingInChannel.consumer.acknowledge-mode=MANUAL 32 | 33 | # ??Stream ?????? 34 | server.port=8080 -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/config-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | rabbitmq-hello 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | config-client 13 | 14 | rabbit-hello 15 | Demo project for Spring Cloud 16 | 17 | 18 | org.springframework.cloud 19 | spring-cloud-starter-config 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-starter-netflix-eureka-client 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-test 35 | 36 | 37 | 38 | org.springframework.cloud 39 | spring-cloud-starter-bus-amqp 40 | 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-starter-actuator 45 | 46 | 47 | 48 | com.alibaba.mq-amqp 49 | mq-amqp-client 50 | 1.0.5 51 | 52 | 53 | com.google.guava 54 | guava 55 | 19.0 56 | 57 | 58 | org.apache.commons 59 | commons-lang3 60 | 3.4 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | org.springframework.boot 75 | spring-boot-maven-plugin 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/config-client/readme: -------------------------------------------------------------------------------- 1 | 不看必挂 2 | 1.修改application.properties 3 | #接入点根据AMQP控制台获取接入点 4 | spring.rabbitmq.host=${endpoint} 5 | #端口 默认5672 6 | spring.rabbitmq.port=${port} 7 | #UserName AMQP控制台获取 8 | spring.rabbitmq.username=${username} 9 | #password AMQP控制台获取用 10 | spring.rabbitmq.password=${passqord} 11 | #virtual-host 你要使用的virtaulhost,AMQP控制台获取 12 | spring.rabbitmq.virtual-host=${vhost} 13 | -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/config-client/src/main/java/com/alibaba/ConfigClientApplication.java: -------------------------------------------------------------------------------- 1 | package com.alibaba; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | import org.springframework.cloud.context.config.annotation.RefreshScope; 8 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | @SpringBootApplication 13 | @EnableEurekaClient 14 | @EnableDiscoveryClient 15 | @RestController 16 | @RefreshScope 17 | public class ConfigClientApplication { 18 | 19 | /** 20 | * post http://localhost:8881/actuator/bus-refresh 21 | * post http://localhost:8881/actuator/bus-refresh/config-client:8881 局部刷新 22 | */ 23 | 24 | public static void main(String[] args) { 25 | SpringApplication.run(ConfigClientApplication.class, args); 26 | } 27 | 28 | @Value("${foo}") 29 | String foo; 30 | 31 | @RequestMapping(value = "/hi") 32 | public String hi(){ 33 | return foo; 34 | } 35 | } -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/config-client/src/main/java/com/alibaba/rabbit/RabbitConfig.java: -------------------------------------------------------------------------------- 1 | package com.alibaba.rabbit; 2 | 3 | import org.springframework.amqp.core.*; 4 | import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; 5 | import org.springframework.amqp.rabbit.connection.ConnectionFactory; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.autoconfigure.amqp.RabbitProperties; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | @Configuration 15 | public class RabbitConfig { 16 | //Exchange,从阿里云AMQP控制台获取 17 | private static final String exchangeName = "your-exchange"; 18 | private static final String queueName = "your-queue"; 19 | private static final String routingKey = "your-routing-key"; 20 | private static final boolean durable = true; 21 | @Autowired 22 | private RabbitProperties rabbitProperties; 23 | 24 | 25 | @Bean 26 | public ConnectionFactory getConnectionFactory() { 27 | com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = 28 | new com.rabbitmq.client.ConnectionFactory(); 29 | rabbitConnectionFactory.setHost(rabbitProperties.getHost()); 30 | rabbitConnectionFactory.setPort(rabbitProperties.getPort()); 31 | rabbitConnectionFactory.setVirtualHost(rabbitProperties.getVirtualHost()); 32 | rabbitConnectionFactory.setUsername(rabbitProperties.getUsername()); 33 | rabbitConnectionFactory.setPassword(rabbitProperties.getPassword()); 34 | rabbitConnectionFactory.setAutomaticRecoveryEnabled(true); 35 | rabbitConnectionFactory.setNetworkRecoveryInterval(5000); 36 | // 开启数据传输加密 37 | // rabbitConnectionFactory.getRabbitConnectionFactory().useSslProtocol(); 38 | // rabbitConnectionFactory.setPort(5671); 39 | ConnectionFactory connectionFactory = new CachingConnectionFactory(rabbitConnectionFactory); 40 | ((CachingConnectionFactory) connectionFactory).setPublisherConfirms(rabbitProperties.isPublisherConfirms()); 41 | ((CachingConnectionFactory) connectionFactory).setPublisherReturns(rabbitProperties.isPublisherReturns()); 42 | return connectionFactory; 43 | } 44 | 45 | /** 46 | * 申明队列 47 | * 48 | * @return 49 | */ 50 | @Bean 51 | public Queue queue() { 52 | Map arguments = new HashMap<>(4); 53 | 54 | return new Queue(queueName, durable, false, false, arguments); 55 | } 56 | 57 | @Bean 58 | public Exchange exchange() { 59 | Map arguments = new HashMap<>(4); 60 | 61 | return new DirectExchange(exchangeName, durable, false, arguments); 62 | } 63 | 64 | /** 65 | * 申明绑定 66 | * 67 | * @return 68 | */ 69 | @Bean 70 | public Binding binding() { 71 | return BindingBuilder.bind(queue()).to(exchange()).with(routingKey).noargs(); 72 | } 73 | 74 | 75 | } 76 | -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/config-client/src/main/resources/bootstrap.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=config-client 2 | spring.cloud.config.label=master 3 | spring.cloud.config.profile=dev 4 | #spring.cloud.config.uri= http://localhost:8888/ 5 | 6 | eureka.client.serviceUrl.defaultZone=http://localhost:8889/eureka/ 7 | spring.cloud.config.discovery.enabled=true 8 | spring.cloud.config.discovery.serviceId=config-server 9 | server.port=8882 10 | 11 | #spring.rabbitmq.host=localhost 12 | #spring.rabbitmq.port=5672 13 | #spring.rabbitmq.username=guest 14 | #spring.rabbitmq.password=guest 15 | 16 | spring.rabbitmq.host=rabbitmq-xxxx.mq.amqp.aliyuncs.com 17 | spring.rabbitmq.port=5672 18 | spring.rabbitmq.username=***** 19 | spring.rabbitmq.password=********** 20 | spring.rabbitmq.virtual-host=your-vhost 21 | spring.rabbitmq.template.mandatory=true 22 | spring.rabbitmq.publisher-confirms=true 23 | spring.rabbitmq.publisher-returns=true 24 | 25 | spring.cloud.bus.enabled=true 26 | spring.cloud.bus.trace.enabled=true 27 | #SpringCloud 2.0.0版本以后暴露接口方式 28 | management.endpoints.web.exposure.include=bus-refresh -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/config-client/src/test/java/com/alibaba/ConfigClientApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.alibaba; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class ConfigClientApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/config-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | rabbitmq-hello 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | config-server 13 | 14 | config-server 15 | Demo project for Spring Cloud 16 | 17 | 18 | org.springframework.cloud 19 | spring-cloud-starter-netflix-eureka-client 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | org.springframework.cloud 27 | spring-cloud-config-server 28 | 29 | 30 | 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-maven-plugin 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/config-server/src/main/java/com/alibaba/ConfigServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.alibaba; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.config.server.EnableConfigServer; 7 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 8 | 9 | 10 | @SpringBootApplication 11 | @EnableConfigServer 12 | @EnableDiscoveryClient 13 | @EnableEurekaClient 14 | public class ConfigServerApplication { 15 | 16 | public static void main(String[] args) { 17 | SpringApplication.run(ConfigServerApplication.class, args); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/config-server/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=config-server 2 | server.port=8888 3 | #config服务端,从git拉取数据 4 | spring.cloud.config.server.git.uri=https://github.com/tianliuliu/SpringcloudConfig-1 5 | spring.cloud.config.server.git.searchPaths=respo 6 | spring.cloud.config.label=master 7 | spring.cloud.config.server.git.username=username 8 | spring.cloud.config.server.git.password=password 9 | #注册服务 10 | eureka.client.serviceUrl.defaultZone=http://localhost:8889/eureka/ -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/config-server/src/test/java/com/alibaba/ConfigServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.alibaba; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class ConfigServerApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/eureka-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | rabbitmq-hello 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | eureka-server 13 | 14 | Demo project for Spring Cloud 15 | 16 | 17 | 18 | 19 | org.springframework.cloud 20 | spring-cloud-starter-netflix-eureka-server 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-maven-plugin 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/eureka-server/src/main/java/com/alibaba/EurekaServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.alibaba; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | 7 | @EnableEurekaServer 8 | @SpringBootApplication 9 | public class EurekaServerApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(EurekaServerApplication.class, args); 13 | } 14 | } -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/eureka-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8889 3 | 4 | eureka: 5 | instance: 6 | hostname: localhost 7 | client: 8 | registerWithEureka: false 9 | fetchRegistry: false 10 | serviceUrl: 11 | defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/eureka-server/src/test/java/com/alibaba/EurekaServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.alibaba; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class EurekaServerApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.demo 8 | rabbitmq-hello 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | config-client 13 | config-server 14 | eureka-server 15 | 16 | 17 | rabbit-hello 18 | Demo project for Spring Cloud bus 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-parent 24 | 2.0.8.RELEASE 25 | 26 | 27 | 28 | 29 | 30 | UTF-8 31 | UTF-8 32 | 1.8 33 | Finchley.SR2 34 | 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-test 40 | test 41 | 42 | 43 | 44 | 45 | 46 | 47 | org.springframework.cloud 48 | spring-cloud-dependencies 49 | ${spring-cloud.version} 50 | pom 51 | import 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-maven-plugin 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /amqp-springcloudbus-demo/readme: -------------------------------------------------------------------------------- 1 | 不看必挂 2 | 首先启动rabbitMQ服务端 3 | 1.配置eureka-server注册中心服务端,修改该模块的配置文件application.yml,并启动 4 | 2.配置config-server配置中心服务端,修改该模块的配置文件application.properties 5 | 配置相关的配置参数库信息,并启动 6 | 3.修改config-client配置客户端的配置文件application.properties 7 | #接入点根据AMQP控制台获取接入点 8 | spring.rabbitmq.host=${endpoint} 9 | #端口 默认5672 10 | spring.rabbitmq.port=${port} 11 | #UserName AMQP控制台获取 12 | spring.rabbitmq.username=${username} 13 | #Password AMQP控制台获取 14 | spring.rabbitmq.password=${password} 15 | #virtual-host 你要使用的virtaulhost,AMQP控制台获取 16 | spring.rabbitmq.virtual-host=${vhost} 17 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 36 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_5_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_5_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_5_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__com_rabbitmq_amqp_client_3_6_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__com_rabbitmq_http_client_1_0_0_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__commons_codec_commons_codec_1_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__commons_logging_commons_logging_1_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_3_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_3_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__org_springframework_amqp_spring_amqp_1_6_1_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__org_springframework_amqp_spring_rabbit_1_6_1_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__org_springframework_retry_spring_retry_1_1_3_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__org_springframework_spring_aop_4_2_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__org_springframework_spring_beans_4_2_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__org_springframework_spring_context_4_2_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__org_springframework_spring_core_4_2_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__org_springframework_spring_expression_4_2_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__org_springframework_spring_messaging_4_2_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__org_springframework_spring_tx_4_2_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/libraries/Maven__org_springframework_spring_web_4_2_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /spring-rabbit-demo/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /spring-rabbit-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.alibaba.rabbit 8 | spring-rabbit-demo 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | 14 | org.springframework.amqp 15 | spring-rabbit 16 | 1.6.1.RELEASE 17 | 18 | 19 | 20 | com.alibaba.mq-amqp 21 | mq-amqp-client 22 | 1.0.5 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /spring-rabbit-demo/src/main/java/com/alibaba/rabbit/spring/MessageReceiver.java: -------------------------------------------------------------------------------- 1 | package com.alibaba.rabbit.spring; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | 6 | @Component 7 | public class MessageReceiver { 8 | public void listen(String message) { 9 | System.out.println(" [x] Received '" + message + "'"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spring-rabbit-demo/src/main/java/com/alibaba/rabbit/spring/SpringMain.java: -------------------------------------------------------------------------------- 1 | package com.alibaba.rabbit.spring; 2 | 3 | import org.springframework.amqp.rabbit.core.RabbitTemplate; 4 | import org.springframework.context.support.AbstractApplicationContext; 5 | import org.springframework.context.support.ClassPathXmlApplicationContext; 6 | 7 | 8 | public class SpringMain { 9 | 10 | public static void main(final String... args) throws Exception { 11 | 12 | AbstractApplicationContext ctx = 13 | new ClassPathXmlApplicationContext("spring-rabbitmq.xml"); 14 | RabbitTemplate template = ctx.getBean(RabbitTemplate.class); 15 | int i = 0; 16 | while (i < 10) { 17 | String message = "Hello World, I am AMQP [" + i + "]!"; 18 | template.convertAndSend(message); 19 | System.out.println(" [-] Send '" + message + "'"); 20 | Thread.sleep(2000); 21 | i++; 22 | } 23 | ctx.destroy(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /spring-rabbit-demo/src/main/resources/spring-rabbitmq.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | --------------------------------------------------------------------------------