Practical use of RocketMQ (Alibaba Cloud version) in .NET Framework [Chapter 1]

Table of contents

Development background

environment version

1. Basic introduction to RocketMQ

1.1-RocketMQ Introduction

1.2-RocketMQ Advantages

1.3-RocketMQ basic concepts

2. RocketMQ preliminary preparation

2.1-Download resource package and SDK

2.2-Query basic configuration information

2.3-Configure Topic and Group

2. RocketMQ core part packaging

2.1-Create a class library project

2.2-Encapsulation and transmission entity model

2.3-Encapsulation connection RocketMQ

3. Production-side implementation

3.1-Create a producer

3.1.1-Create MVC project

3.1.2-Project dependency configuration

3.1.3-Using log4net

3.1.4-Encapsulate and send messages

3.2-Configure connection information

3.3-Start the producer

3.3.1-MVC/WebAPI project

3.3.2-JOB (Console Application) Project

3.4-Send a message


chapter

第一章:https://blog.csdn.net/2301_79251107/article/details/132536594

第二章:https://blog.csdn.net/2301_79251107/article/details/132581955

Author: Xigua Programmer

Homepage Portal:Xigua Programmer_ASP.NET Core,ASP.NET,Database-CSDN Blog

Development background

When developing a certain requirement, the leader requested to use RocketMQ (Alibaba Cloud version) as the message queue. The version used is 5.x, and there is currently no entrance to purchase 4.x, so you can only buy the 5.x series. The company's projects still use the relatively old technology .NET Framework 4.8. The producers mainly include WebAPI/MVC/JOB (console application), and the consumers use Windows services to consume information through long links. During this period, I encountered many pitfalls due to various reasons, and then I consulted customer service and said that RocketMQ (Alibaba Cloud version) 5.0 does not support .NET Framework, but in the end it worked (only supports cluster mode, not subscription mode), so today [Xigua Programmer] will record how to use RocketMQ (Alibaba Cloud version), and give it as a reference to prevent pitfalls.

environment version

Alibaba Cloud RocketMQ version: 5.0 series

.NET version: .NET Framework 4.8

.NET version: production side (WebAPI/MVC/JOB), consumer side (Windows service)

If you don’t know how to choose, or don’t know how to buy Cloud Message Queue RocketMQ (Alibaba Cloud Edition)? You can contact me [Xigua Programmer]. If you need to buy at a special price, you can visit the following address:

Activity site:Government site

1. Basic introduction to RocketMQ

Official website address:RocketMQ · Official website | RocketMQ

RocketMQ Alibaba Cloud-Official Document:How to quickly get started with RocketMQ_Cloud Message Queue MQ-Alibaba Cloud Help Center

1.1-RocketMQ Introduction

RocketMQ (Apache RocketMQ) is an open source distributed messaging middleware system developed and maintained by the Alibaba Cloud Computing Platform team under the Alibaba Group. It was originally designed to meet Alibaba's internal large-scale distributed messaging needs and later became one of the Apache Foundation's top open source projects.

1.2-RocketMQ Advantages

It is widely used in many application scenarios, such as e-commerce, logistics and distribution, financial payment, big data processing, etc. It is used by many enterprises to build high-performance and reliable message queuing systems, enable asynchronous communication and decouple application components. RocketMQ provides a reliable, scalable and high-performance messaging solution with the following features:

  1. Asynchronous communication: RocketMQ supports two message communication modes: publish-subscribe and point-to-point to meet the needs of different scenarios.
  2. High reliability: Provides multiple storage options, including local file storage and remote shared storage, to ensure reliable transmission and persistence of messages.
  3. High throughput: supports horizontal expansion and can easily cope with large-scale message passing and high concurrency requirements.
  4. Strict orderliness: Supports messages to be processed in an orderly manner according to the sending order and consumption order, ensuring the orderliness of messages.
  5. Distributed architecture: It adopts distributed architecture and has good horizontal scalability and high availability.

1.3-RocketMQ basic concepts

This content is compiled based on Alibaba Cloud official documents:How to quickly get started with RocketMQ_Cloud Message Queue MQ-Alibaba Cloud Help Center

Topic:The top-level container for message transmission and storage in Cloud Message Queue RocketMQ version, used to identify messages of the same type of business logic. Topics are uniquely identified and distinguished through TopicName.

Message Type: A classification defined according to different message transmission characteristics in the RocketMQ version of Cloud Message Queue, used for type management and security verification. The message types supported by Cloud Message Queue RocketMQ include ordinary messages, sequential messages, transaction messages and scheduled/delayed messages.

Message Queue (MessageQueue): Queue is the actual container for message storage and transmission in Cloud Message Queue RocketMQ version, and is also the smallest storage unit of messages. All topics of Cloud Message Queue RocketMQ version are composed of multiple queues to achieve horizontal splitting of the number of queues and streaming storage inside the queues. Queues are uniquely identified and distinguished by QueueId.

Message (Message):Message is the smallest data transmission unit in Cloud Message Queue RocketMQ version. The producer packages the load and extended attributes of the business data into messages and sends them to the Cloud Message Queue RocketMQ version server. The server delivers the messages to the consumer for consumption according to relevant semantics.

Message View:Message View is a message read-only interface provided by RocketMQ version of Cloud Message Queue from a development perspective. Through the message view, you can read multiple attributes and payload information inside the message, but you cannot make any modifications to the message itself.

Message Tag (MessageTag): Message tag is a fine-grained message classification attribute provided by Cloud Message Queue RocketMQ version, which can subdivide message types under the topic level. Consumers implement fine-grained filtering by subscribing to specific tags.

Message location (MessageQueueOffset):Messages are stored in multiple queues of the specified topic in the order in which they arrive at the Cloud Message Queue RocketMQ server. Each message is in the queue. Each has a unique Long type coordinate, which is defined as the message location.

Consumption position (ConsumerOffset):After a message is consumed by a consumer, it will not be deleted from the queue immediately. The Cloud Message Queue RocketMQ version will be based on each consumer. The group records the position of the latest message consumed, that is, the consumption position.

Message Index (MessageKey):Message Index is a message-oriented index attribute provided by Cloud Message Queue RocketMQ version. The corresponding message content can be quickly found through the set message index.

Producer:The producer is the running entity used in the Cloud Message Queue RocketMQ system to build and transmit messages to the server. Producers are usually integrated into business systems, encapsulating business messages into Cloud Message Queue RocketMQ version messages as required and sending them to the server.

TransactionChecker:A listener used by producers in Cloud Message Queue RocketMQ version to perform local transaction checking and exception transaction recovery. The transaction checker should check and judge the status of transaction messages through the status of business-side data.

Transaction status (TransactionResolution):During the transaction message sending process in the RocketMQ version of the cloud message queue, the status identifier of the transaction submission, the server controls whether the transaction message should be submitted through the transaction status and Delivery. Transaction status includes transaction commit, transaction rollback and transaction pending.

ConsumerGroup:Consumer group is a load balancing group that carries multiple consumers with consistent consumption behavior in the Cloud Message Queue RocketMQ version system. Unlike consumers, consumer groups are not running entities, but a logical resource. In the RocketMQ version of Cloud Message Queue, multiple consumers are initialized within consumer groups to achieve horizontal expansion of consumption performance and high-availability disaster recovery.

Consumer:Consumer is the running entity used to receive and process messages in RocketMQ version of Cloud Message Queue. Consumers are usually integrated into business systems, obtain messages from the Cloud Message Queue RocketMQ server, and convert the messages into business-understandable information for business logic processing.

Consumption result (ConsumeResult): The processing result returned by the PushConsumer consumption listener in the RocketMQ version of Cloud Message Queue after the message is processed, used to identify whether the message was processed correctly. Consumption results include consumption success and consumption failure.

Subscription:The subscription relationship is the rules and status configuration for consumers to obtain and process messages in the RocketMQ version of the cloud message queue system. The subscription relationship is dynamically registered to the server system by consumer groups, and in subsequent message transmission, message matching and consumption progress maintenance are performed according to the filtering rules defined by the subscription relationship.

Message filtering:Consumers can filter messages by subscribing to specified message tags (Tag) to ensure that only filtered message collections are ultimately received. The calculation and matching of filtering rules are completed on the server side of Cloud Message Queue RocketMQ version.

Reset consumption position: Taking the timeline as the coordinate, within the time range of message persistence storage, reset the consumption progress of the consumer group on the subscribed topic, set After completion, the consumer will receive the messages sent by the producer to the Cloud Message Queue RocketMQ server after the set time point.

Message track:In the process of a message being sent from the producer to being received and processed by the consumer, a complete link formed by the time, location and other data of each relevant node information. Through the message trace, you can clearly locate the complete link from the producer to the cloud message queue RocketMQ server and delivery to the consumer, making it easy to locate and troubleshoot problems.

Message accumulation:The producer has sent the messages to the RocketMQ version of the cloud message queue server, but due to the limited consumption capacity of the consumer, it was not possible to send all the messages in a short time. The message is consumed correctly. At this time, the server of RocketMQ version of Cloud Message Queue stores unconsumed messages. This state is message accumulation.

Transaction message:Transaction message is an advanced message type provided by Cloud Message Queue RocketMQ version, which supports the ultimate consistency of message production and local transactions in distributed scenarios.

Timing/delayed message:Timing/delayed message is an advanced message type provided by Cloud Message Queue RocketMQ version. After the message is sent to the server, it will be sent at the specified time. before it can be consumed by consumers. By setting a certain timing time, the delayed scheduling triggering effect of distributed scenarios can be achieved.

Sequential message:Sequential message is an advanced message type provided by Cloud Message Queue RocketMQ version, which supports consumers to obtain messages in the order in which they are sent, thereby realizing business scenarios. sequential processing.

2. RocketMQ preliminary preparation

First, you need to download the relevant .NET-related SDK, and then find the [Instance User Name] [Instance Password] [Access Point Link Information] and other information in the Alibaba Cloud backend. Finally, you need to create [Group ID] and [Topic] for We call.

2.1-Download resource package and SDK

[Xigua Programmer] provides a resource package for the friends who are reading this article. The [ONSClient4CPP] folder contains the DLL files that the Alibaba Cloud version of RocketMQ depends on. The [RocketMQ_SDK] folder contains the .NET Framework using RocketMQ Alibaba. The SDK file used for the cloud version, the [vcredistx64] folder contains the Visual C++ 2015 runtime environment installation package, because the C++ DLL file depends on this, and this needs to be installed. Also includes other auxiliary tools and code.

Downloads are accessible (please contact me if it doesn't work).

下载地址(编码:stalua6n): ​​https://yongteng.lanzoub.com/ifvpL17wzdqf​

Password: c15e

File screenshot:

2.2-Query basic configuration information

(1) First click the link below to enter the message queue RocketMQ workbench. If you are not logged in, you must log in first. Then find the region list to be operated in [Resource Distribution] and click [Region Name].

Message queue RocketMQ (Alibaba Cloud version):Alibaba Cloud login - Welcome to Alibaba Cloud, a safe and stable cloud computing service platform

(2) Then you can see the instance list, find the instance you want to operate, and click [Details].

(3) Then find [Instance User Name] and [Instance Password] in [Run Information]. Note that they are not the instance ID/instance name.

(4) Then while still on the current page, scroll down to [TCP Protocol Access Point] to find the access point and network information. If you need to access the external network and open public network access by yourself, it seems that you need to pay extra. [Xigua Programmer] can only be accessed through [VPC Private Network], that is, it can only be accessed on the intranet. So I will introduce it as a VPC private network.

Then we have collected all the necessary information, which are [instance user name] [instance password] [TCP protocol access point connection].

2.3-Configure Topic and Group

So what is a Topic? The top-level container for message transmission and storage in Cloud Message Queue RocketMQ version is used to identify messages of the same type of business logic. Topics are uniquely identified and distinguished through TopicName. It can be understood that different topics are configured for different systems and different release environments. Then let’s talk about how to match Topic and GroupID.

(1) Find [Topic Management] in the left navigation bar, and then click [Create Topic]. The name and description are required, and the message type is selected according to your business scenario. [Xigua Programmer] requires messages to be sent and consumed in order, so select [Sequential Message].

(2) Then create the GroupID. A Group ID represents a Consumer instance group. All Consumer instances under the same consumer Group ID must ensure that the subscribed Topic is consistent, and the filtering rules (Tag) set when subscribing to the Topic must also be consistent. Otherwise your messages may be lost.

Then we have created all the necessary resources, namely [Topic name] [GroupID].

Topic name:

GroupID:

2. RocketMQ public part encapsulation

This generally encapsulates the public transmission entities used by the production end and the consumer end, message queue tag constant definitions, message queue event type definitions, etc.

2.1-Create a class library project

(1) Click [Create New Project], and then select [Class Library (.NET Framework)].

Table of contents:

 

2.2-Encapsulation and transmission entity model

Create a [QueueTagConsts] file to order message queue Tag constants, and a [QueueOnsEventType] file to define event types.

Table of contents:

QueueTagConsts:

 /// <summary>
    /// 消息队列Tag常量定义
    /// 命名规范:项目名_自定义业务名_Tag
    /// </summary>
    public class QueueTagConsts
    {
        /// <summary>
        /// 测试Sample
        /// </summary>
        public const string XG_Blog_Sample_Tag = "XG_Blog_Sample_Tag";
    }

QueueOnsEventType:

    /// <summary>
    /// 消息队列-事件类型
    /// </summary>
    public class QueueOnsEventType
    {
        /// <summary>
        /// RocketMQ测试
        /// </summary>
        public const string RocketMQ_TEST = "RocketMQ_TEST";
    }

3. Production-side implementation

3.1-Create a producer

3.1.1-Create MVC project

(1) Then create a producer, you can create WebAPI/MVC/JOB (console application), etc. Then [Xigua Programmer] uses the MVC project as an example to introduce and create a project named [RocketMQ.Producer] .

Run the test:

3.1.2-Project dependency configuration

The .NET version provided by Alibaba Cloud is a managed package based on the CPP version of the RocketMQ version of the cloud message queue. This ensures that .NET is completely independent of the Windows.NET public library. C++ multi-threaded concurrent processing is used internally to ensure the efficiency and stability of the .NET version.

(1) The underlying C++ DLL related files and the Visual C++ 2015 runtime environment installation package. If the Visual Studio 2015 runtime environment is not installed, you need to find the [vc_redist.x64.exe] file in the resource package to install it.

(2) When using Visual Studio (VS) to develop .NET applications and class libraries, the default target platform is "Any CPU". However, the .NET SDK only supports Windows 64-bit operating system, so you need to set it up yourself. First right-click the [RocketMQ.Producer] project, and then click [Properties].

(3) Click [Generate] on the left option, and then change the target platform to [x64].

(4) Copy all the files in the resource package [ONSClient4CPP] folder to the [bin] directory.

Resource pack:

project:

3.1.3-Using log4net

(1) Use lo4net to output logs. You can also use other log frameworks. Remember to make modifications where you use logs. Then [Xigua Programmer] uses log4net to introduce it. We create a file called [log4net.config] in the root directory of the project.

(2) The content of [log4net.config] is as follows.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
	<configSections>
		<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
	</configSections>

	<system.web>
		<compilation debug="true" targetFramework="4.5.2" />
		<httpRuntime targetFramework="4.5.2" />
	</system.web>
	<log4net>
		<!--错误日志:::记录错误日志-->
		<!--按日期分割日志文件 一天一个-->
		<!-- appender 定义日志输出方式   将日志以回滚文件的形式写到文件中。-->
		<appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender">
			<!--保存路径:下面路径项目启动的时候自动在C盘中创建log、logError文件-->
			<file value="log/error/error_" />
			<!-- 如果想在本项目中添加路径,那就直接去掉C:\\  只设置log\\LogError   项目启动中默认创建文件 -->
			<appendToFile value="true"/>
			<!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
			<rollingStyle value="Date"/>
			<!--这是按日期产生文件夹-->
			<datePattern value="yyyy-MM-dd'.log'"/>
			<!--是否只写到一个文件中-->
			<staticLogFileName value="false"/>
			<!--保留的log文件数量 超过此数量后 自动删除之前的   好像只有在 按Size分割时有效 设定值value="-1"为不限文件数-->
			<param name="MaxSizeRollBackups" value="100"/>
			<!--每个文件的大小。只在混合方式与文件大小方式下使用。超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志-->
			<maximumFileSize value="50MB" />
			<!-- layout 控制Appender的输出格式,也可以是xml  一个Appender只能是一个layout-->
			<layout type="log4net.Layout.PatternLayout">
				<!--每条日志末尾的文字说明-->
				<!--输出格式 模板-->
				<!-- <param name="ConversionPattern"  value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 记录类:%logger   
        操作者ID:%property{Operator} 操作类型:%property{Action}%n  当前机器名:%property%n当前机器名及登录用户:%username %n  
        记录位置:%location%n 消息描述:%property{Message}%n   异常:%exception%n 消息:%message%newline%n%n" />-->

				<!--样例:2008-03-26 13:42:32,111 [10] INFO  Log4NetDemo.MainClass [(null)] - info-->
				<!--<conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n错误描述:%message%newline %n"/>-->
				<conversionPattern value="%n==========
                                  %n【日志级别】%-5level
                                  %n【记录时间】%date
                                  %n【执行时间】[%r]毫秒
                                  %n【出错文件】%F
                                  %n【出错行号】%L
                                  %n【出错的类】%logger 属性[%property{NDC}]
                                  %n【错误描述】%message
                                  %n【错误详情】%newline"/>
			</layout>
			<filter type="log4net.Filter.LevelRangeFilter,log4net">
				<levelMin value="ERROR" />
				<levelMax value="FATAL" />
			</filter>
		</appender>

		<!--DEBUG:::记录DEBUG日志-->
		<!--按日期分割日志文件 一天一个-->
		<!-- appender 定义日志输出方式   将日志以回滚文件的形式写到文件中。-->
		<appender name="DebugAppender" type="log4net.Appender.RollingFileAppender">
			<!--保存路径:下面路径项目启动的时候自动在C盘中创建log、logError文件-->
			<file value="log/debug/debug_" />
			<!-- 如果想在本项目中添加路径,那就直接去掉C:\\  只设置log\\LogError   项目启动中默认创建文件 -->
			<appendToFile value="true"/>
			<!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
			<rollingStyle value="Date"/>
			<!--这是按日期产生文件夹-->
			<datePattern value="yyyy-MM-dd'.log'"/>
			<!--是否只写到一个文件中-->
			<staticLogFileName value="false"/>
			<!--保留的log文件数量 超过此数量后 自动删除之前的   好像只有在 按Size分割时有效 设定值value="-1"为不限文件数-->
			<param name="MaxSizeRollBackups" value="100"/>
			<!--每个文件的大小。只在混合方式与文件大小方式下使用。超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志-->
			<maximumFileSize value="50MB" />
			<!-- layout 控制Appender的输出格式,也可以是xml  一个Appender只能是一个layout-->
			<layout type="log4net.Layout.PatternLayout">
				<!--每条日志末尾的文字说明-->
				<!--输出格式 模板-->
				<!-- <param name="ConversionPattern"  value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 记录类:%logger   
        操作者ID:%property{Operator} 操作类型:%property{Action}%n  当前机器名:%property%n当前机器名及登录用户:%username %n  
        记录位置:%location%n 消息描述:%property{Message}%n   异常:%exception%n 消息:%message%newline%n%n" />-->

				<!--样例:2008-03-26 13:42:32,111 [10] INFO  Log4NetDemo.MainClass [(null)] - info-->
				<!--<conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n错误描述:%message%newline %n"/>-->
				<conversionPattern value="%n==========
                                  %n【日志级别】%-2level
                                  %n【记录时间】%date
                                  %n【执行时间】[%r]毫秒
                                  %n【debug文件】%F
                                  %n【debug行号】%L
                                  %n【debug类】%logger 属性[%property{NDC}]
                                  %n【debug描述】%message"/>
			</layout>
			<filter type="log4net.Filter.LevelRangeFilter,log4net">
				<levelMin value="DEBUG" />
				<levelMax value="WARN" />
			</filter>
		</appender>


		<!--INFO:::记录INFO日志-->
		<!--按日期分割日志文件 一天一个-->
		<!-- appender 定义日志输出方式   将日志以回滚文件的形式写到文件中。-->
		<appender name="INFOAppender" type="log4net.Appender.RollingFileAppender">
			<!--保存路径:下面路径项目启动的时候自动在C盘中创建log、logError文件-->
			<file value="log/info/info_" />
			<!-- 如果想在本项目中添加路径,那就直接去掉C:\\  只设置log\\LogError   项目启动中默认创建文件 -->
			<appendToFile value="true"/>
			<!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
			<rollingStyle value="Date"/>
			<!--这是按日期产生文件夹-->
			<datePattern value="yyyy-MM-dd'.log'"/>
			<!--是否只写到一个文件中-->
			<staticLogFileName value="false"/>
			<!--保留的log文件数量 超过此数量后 自动删除之前的   好像只有在 按Size分割时有效 设定值value="-1"为不限文件数-->
			<param name="MaxSizeRollBackups" value="100"/>
			<!--每个文件的大小。只在混合方式与文件大小方式下使用。超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志-->
			<maximumFileSize value="50MB" />
			<!-- layout 控制Appender的输出格式,也可以是xml  一个Appender只能是一个layout-->
			<layout type="log4net.Layout.PatternLayout">
				<!--每条日志末尾的文字说明-->
				<!--输出格式 模板-->
				<!-- <param name="ConversionPattern"  value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 记录类:%logger   
        操作者ID:%property{Operator} 操作类型:%property{Action}%n  当前机器名:%property%n当前机器名及登录用户:%username %n  
        记录位置:%location%n 消息描述:%property{Message}%n   异常:%exception%n 消息:%message%newline%n%n" />-->

				<!--样例:2008-03-26 13:42:32,111 [10] INFO  Log4NetDemo.MainClass [(null)] - info-->
				<!--<conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n错误描述:%message%newline %n"/>-->
				<conversionPattern value="%n==========
                                  %n【日志级别】%-2level
                                  %n【记录时间】%date
                                  %n【执行时间】[%r]毫秒
                                  %n【info文件】%F
                                  %n【info行号】%L
                                  %n【info类】%logger 属性[%property{NDC}]
                                  %n【info描述】%message"/>
			</layout>
			<filter type="log4net.Filter.LevelRangeFilter,log4net">
				<levelMin value="INFO" />
				<levelMax value="WARN" />
			</filter>
		</appender>

		<!--Set root logger level to DEBUG and its only appender to A1-->
		<root>
			<!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF-->
			<level value="ALL" />
			<appender-ref ref="DebugAppender" />
			<appender-ref ref="ErrorAppender" />
			<appender-ref ref="INFOAppender" />
		</root>
	</log4net>
</configuration>

(3) And right-click the [log4net.config] file, click [Properties], and then set [Copy to Output Directory] to [Always Copy].

(4) Then install log4net. Right-click [References] in the project directory, and then click [Manage NuGet Packages]

(5) Then click Browse, search for [log4net], and click Install on the right side.

(6) Then register log4net in the [Global.asax] file.

        protected void Application_Start()
        {
            XmlConfigurator.Configure(new System.IO.FileInfo(Server.MapPath("~/log4net.config")));
        }

3.1.4-Install Nuget package

(1) Right-click the [RocketMQ.Producer] producer project, click [Reference] -> [Manage NuGet Package].

(2) Search for the [Kimi.RocketMQ.NET] package, and then select the latest version to install.

3.1.5-Encapsulate and send messages

(1) Create a new [Services] folder in the current project as the service layer. You can also create Services as a separate class library, then introduce [RocketMQ.Core] to this project, and introduce [Services] to the [RocketMQ.Producer] project area. Then [Xigua Programmer] wrote it directly in the current project for convenience. Then create the [BaseProducerService] file in the [Services] folder to encapsulate the producer's message sending service.

Table of contents:

Code:

 /// <summary>
    /// 生产者服务
    /// </summary>
    public class BaseProducerService
    {
        private readonly ILog logger = log4net.LogManager.GetLogger(typeof(BaseProducerService));

        public void SendQueueOnsProducer(string body, string msg_tag, string mgs_eventType)
        {
            if (string.IsNullOrEmpty(body)) { throw new ArgumentNullException("body is null"); }
            if (string.IsNullOrEmpty(msg_tag)) { throw new ArgumentNullException("msg_tag is null"); }
            if (string.IsNullOrEmpty(mgs_eventType)) { throw new ArgumentNullException("mgs_eventType is null"); }

            string ons_topic = QueueOnsProducer.getOnsTopic;
            string ons_client_code = QueueOnsProducer.getOnsClientCode;

            //TODO:这里需要生成唯一ID
            string businessId = "MQ_1001";

            logger.Info($"【发送RocketMQ消息队列消息】准备开始执行了:(消息key:{businessId})(tag:{msg_tag})(event_type:{mgs_eventType})");
            logger.Info($"【发送RocketMQ消息队列消息】消息内容:{body}");

            // TODO:在这里可以持久化生产者消息
            logger.Info($"【发送RocketMQ消息队列消息】消息持久化成功!(消息主键id:{businessId})");

            Task.Run(() =>
            {
                try
                {
                    QueueOnsProducer.SendMessage(new QueueOnsCommonModel()
                    {
                        MessageId = businessId,
                        Tag = msg_tag,
                        EventType = mgs_eventType,
                        Body = body
                    }, msg_tag);
                    logger.Info($"【发送RocketMQ消息队列消息】消息发送成功!");
                }
                catch (Exception ex)
                {
                    logger.Error($"【发送RocketMQ消息队列消息】发生异常:{ex.Message}", ex);
                }
            });
        }
    }

3.2-Configure connection information

(1) Then right-click under the [RocketMQ.Producer] project, click [Reference], and then check the [RocketMQ.Core] project and confirm.

(2) Then put the basic information prepared in the early stage in the configuration file. Configure in the [Web.config] file.

Code:

    <!--消息队列:RocketMQ-->
    <!--设置为云消息队列 RocketMQ 版控制台实例详情页的实例用户名。-->
    <add key="ons_access_key" value="xxx" />
    <!--设置为云消息队列 RocketMQ 版控制台实例详情页的实例密码。-->
    <add key="ons_secret_key" value="xxx" />
    <!--您在云消息队列 RocketMQ 版控制台创建的Topic。-->
    <add key="ons_topic" value="XG_CXY_Test" />
    <!--设置为您在云消息队列 RocketMQ 版控制台创建的Group ID。-->
    <add key="ons_groupId" value="XG_CXY_Group_Test" />
    <!--设置为您从云消息队列 RocketMQ 版控制台获取的接入点信息,类似“rmq-cn-XXXX.rmq.aliyuncs.com:8080”-->
    <add key="ons_name_srv" value="xxx-xxx-xxx-xxx.rmq.aliyuncs.com:8080" />
    <!--消费者/生产者目标来源-->
    <add key="ons_client_code" value="XG_CXY_Producer_Develop" />

(3) Then create a [Config] folder and write a helper class to obtain the [ConfigGeter] configuration file.

Code:

    /// <summary>
    /// 配置文件
    /// </summary>
    public class ConfigGeter
    {
        private static T TryGetValueFromConfig<T>(Func<string, T> parseFunc, Func<T> defaultTValueFunc, [CallerMemberName] string key = "", string supressKey = "")
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(supressKey))
                {
                    key = supressKey;
                }

                var node = ConfigurationManager.AppSettings[key];
                return !string.IsNullOrEmpty(node) ? parseFunc(node) : defaultTValueFunc();
            }
            catch (Exception ex)
            {
                return default(T);
            }
        }

        #region 消息队列:RocketMQ
        /// <summary>
        /// 设置为云消息队列 RocketMQ 版控制台实例详情页的实例用户名。
        /// </summary>
        public static string ons_access_key
        {
            get
            {
                return TryGetValueFromConfig(_ => _, () => string.Empty);
            }
        }

        /// <summary>
        /// 设置为云消息队列 RocketMQ 版控制台实例详情页的实例密码。
        /// </summary>
        public static string ons_secret_key
        {
            get
            {
                return TryGetValueFromConfig(_ => _, () => string.Empty);
            }
        }

        /// <summary>
        ///  您在云消息队列 RocketMQ 版控制台创建的Topic。
        /// </summary>
        public static string ons_topic
        {
            get
            {
                return TryGetValueFromConfig(_ => _, () => string.Empty);
            }
        }

        /// <summary>
        /// 设置为您在云消息队列 RocketMQ 版控制台创建的Group ID。
        /// </summary>
        public static string ons_groupId
        {
            get
            {
                return TryGetValueFromConfig(_ => _, () => string.Empty);
            }
        }

        /// <summary>
        /// 设置为您从云消息队列 RocketMQ 版控制台获取的接入点信息,类似“rmq-cn-XXXX.rmq.aliyuncs.com:8080”。
        /// </summary>
        public static string ons_name_srv
        {
            get
            {
                return TryGetValueFromConfig(_ => _, () => string.Empty);
            }
        }

        /// <summary>
        /// 消息来源(生产者/消费端客户端编码)
        /// </summary>
        public static string ons_client_code
        {
            get
            {
                return TryGetValueFromConfig(_ => _, () => string.Empty);
            }
        }
        #endregion
    }

3.3-Start the producer

3.3.1-MVC/WebAPI project

Create a producer in the Application_Start method of the [Global.asax] file, mainly to obtain the configuration information from the configuration file, then call the [QueueOnsProducer.CreateProducer] method to create a message queue producer, and start the producer by calling the [QueueOnsProducer.StartProducer] method .

Code:

protected void Application_Start()
        {
            //创建生产者[西瓜程序猿]
            string ons_access_key = ConfigGeter.ons_access_key;
            string ons_secret_key = ConfigGeter.ons_secret_key;
            string ons_topic = ConfigGeter.ons_topic;
            string ons_groupId = ConfigGeter.ons_groupId;
            string ons_name_srv = ConfigGeter.ons_name_srv;
            string ons_client_code = ConfigGeter.ons_client_code;
            QueueOnsProducer.CreateProducer(new ONSPropertyConfigModel()
            {
                AccessKey = ons_access_key,
                SecretKey = ons_secret_key,
                Topics = ons_topic,
                GroupId = ons_groupId,
                NAMESRV_ADDR = ons_name_srv,
                OnsClientCode = ons_client_code,
            });
            //启动生产者
            QueueOnsProducer.StartProducer();
        }

3.3.2-JOB (Console Application) Project

Create a producer in the Main method of the [Program.cs] project startup file, mainly to obtain the configuration information from the configuration file, and then call the [QueueOnsProducer.CreateProducer] method to create a message queue producer, by calling the [QueueOnsProducer.StartProducer] method Start the producer.

3.4-Send a message

(1) First design the message transmission content (Body) entity. For example, if I need to do some asynchronous business processing based on name/account, then I will create a new class called [RocketMQSampleModel].

Table of contents:

Code:

    /// <summary>
    /// 发送RocketMQ测试消息实体
    /// </summary>
    public class RocketMQSampleModel
    {
        public string user_name { get; set; }
        public string user_account { get; set; }
    }

(2) Then start to create a specific service for sending RocketMQ messages. You can create it according to your own business. Then [Xigua Programmer] will create a service named [SampleProducerService] to send RocketMQ messages, and then inherit [BaseProducerService] kind.

Table of contents:

Code:

public class SampleProducerService : BaseProducerService
    {
        /// <summary>
        /// 发送RocketMQ测试消息
        /// </summary>
        /// <param name="model"></param>
        public void SendTestMessageHandle(RocketMQSampleModel model)
        {
            if (model == null) return;
            string msg_body = JsonUtility.SerializeJSON<RocketMQSampleModel>(model);
            if (msg_body != null)
            {
                SendQueueOnsProducer(msg_body, QueueTagConsts.XG_Blog_Sample_Tag, QueueOnsEventType.RocketMQ_TEST);
            }
        }
    }

(3) Then we call it in the Controller to send the message. [Xigua Programmer] Use it here in [Home/Index].

screenshot:

Code:

 //调用消息队列
            new SampleProducerService().SendTestMessageHandle(new RocketMQSampleModel()
            {
                user_name = "西瓜程序猿",
                user_account = "admin"
            });

(4) Then run it to see if the message can be successfully sent (it will be executed to Home/Index by default). [Xigua Programmer] This needs to be published to the server before it can be called, because it can only be accessed on the server intranet, so I will publish it here.

Note: After publishing to the server, you also need to copy all the [ONSClient4CPP] files in the resource package to the [bin] directory of the server site.

(5) After publishing, run it and you will see that it is successful.

Then we take a look at the log, which shows that the transmission was successful.

Finally, go to the Alibaba Cloud backend to check whether there is a record of this message. Query can be performed in two ways: message Key and message ID. You can see in the background that the sending was actually successful.

The blog has a limit on the number of pictures and texts, so this section will be written here for the time being. It will be continuously updated. The next chapter will include consumer implementation, anti-trap guide, etc.!

I am a Xigua programmer, thank you all for reading. It is not easy to write. If it is helpful to everyone, please use your little fortune to like and follow. Thank you very much! If you have any questions, please contact me to learn and discuss together~

Open source address:

Gitee:​​https://gitee.com/kimiliucn/Kimi.RocketMQ.NET​

GitHub:​​https://github.com/kimiliucn/Kimi.RocketMQ.NET​

Next chapter:https://blog.csdn.net/2301_79251107/article/details/132581955

Copyright statement: This article is an original article, and the copyright belongs to [Xigua Programmer]. Please indicate the source when reprinting. If you have any questions, please send a private message.

Original link:https://blog.csdn.net/2301_79251107/article/details/132536594

Guess you like

Origin blog.csdn.net/2301_79251107/article/details/132536594