上一章節主要介紹了RocketMQ基本介紹和前期準備,以及如何創建生產者。那這一章節主要介紹一下消費端的實現、如何發佈消費端,以及遇到的坑怎麼去解決。 ...
章節
第一章:https://www.cnblogs.com/kimiliucn/p/17662052.html
第二章:https://www.cnblogs.com/kimiliucn/p/17667200.html
作者:西瓜程式猿
主頁傳送門:https://www.cnblogs.com/kimiliucn/
上一章節主要介紹了RocketMQ基本介紹和前期準備,以及如何創建生產者。那這一章節主要介紹一下消費端的實現、如何發佈消費端,以及遇到的坑怎麼去解決。
四、消費端實現
4.1-創建消費者
4.1.1-創建Windows服務項目
(1)右擊解決方案,然後依次點擊【添加】——>【新建項目】,然後選擇【 Windows 服務(.NET Framework) 】,點擊下一步。
註意:Windows服務只有在.NET Framework版本中才有了,在跨平臺中使用Worker Service。
(2)修改項目名稱,項目名稱[西瓜程式猿]寫的是【RocketMQ.Consumer】,然後框架選擇的是【.NET Farmework 4.8】,這個可以根據自己的需要填寫和選擇,然後點擊【創建】。
創建好的目錄如下:【Program.cs】是主程式的入口,【Service1.cs】是服務的入口,可以創建多個,然後在Prodrams.cs中配置就好了。
(3)【Service1】服務名稱可以重命名修改,此處我重命名為【RocketMQConsumerService】, Program.cs文件中也相對應的也要進行修改。
(4)然後我們就可以在【RocketMQConsumerService】中寫業務邏輯代碼了,有很多種方式可以定位到要寫的具體代碼文件,先列舉兩種常用的。
方法一:在【program.cs】文件中,找到這個類,按鍵盤上的F12可以直接進入查看文件。
方法二:直接右擊,然後點擊【查看代碼】。
業務代碼寫到這裡面:
到這一步消費者服務就創建好了,然後就寫具體的業務代碼就行了。註意:服務必須至少重寫 OnStart 和 OnStop 才有用。
4.1.2-項目依賴配置
(1)在使用Visual Studio(VS)開發.NET的應用程式和類庫時,預設的目標平臺為“Any CPU”。但是.NET SDK僅支持Windows 64-bit操作系統,所以需要自行設置。先右擊【RocketMQ.Consumer】項目,然後點擊【屬性】。
(2)點擊左側選項的【生成】,然後將目標平臺改為【x64】。
(3)將資源包【ONSClient4CPP】文件夾裡面所有的文件,複製到【bin/Debug】目錄下。
資源包:
項目:
4.1.3-配置日誌(log4net)
(1)為了方便測試,先介紹一下如何使用log4net做日誌記錄,當日誌啟動時和停止時我們記錄一下。我們在項目目錄下新建一個文件夾【LogConfig】,然後再創建一個文件為【log4net.config】。
(2)【log4net.config】內容如下。
<?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)並且右擊【log4net.config】文件,點擊【屬性】,然後將[複製到輸出目錄]設置為【始終複製】。
(4)然後安裝log4net。在項目目錄中右擊【引用】,然後點擊【管理NuGet程式包】
(5)然後點擊瀏覽,搜索【log4net】,右側點擊安裝。
(6)重要:然後配置【AssemblyInfo.cs 】文件,如果不配置,是輸出不了日誌的。
添加到底部即可:(如果你的【log4net.config】文件路徑和我的不一樣,記得修改成跟自己配置路徑一樣的)。
代碼:
[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension = "config", ConfigFile = "LogConfig/log4net.config", Watch = true)]
(7)在服務啟動方法【OnStart】中,配置啟動log4net。
代碼:
XmlConfigurator.Configure(new System.IO.FileInfo("LogConfig/log4net.config"));
(8)然後就可以使用log4net了,首先在Windows服務中獲得log4net的實例。
代碼:
private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
4.2-配置連接信息
(1)然後右擊【RocketMQ.Consumer】項目下,點擊【引用】,然後將【RocketMQ.Core】項目勾選上確定。
(2)然後將前期準備的基本信息放在配置文件中。在【App.config】文件進行配置。
代碼:
<!--設置為雲消息隊列 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_Consumer_Develop" />
(3)然後創建一個【Config】文件夾,寫一個獲得【ConfigSetting】配置文件的幫助類。
代碼:
/// <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
}
4.3-封裝核心代碼
(1)新建一個【ConsumerStartup】文件,這個類繼承自【MessageListener】類,然後實現consume方法,這個方法主要是消費者具體要執行的任務。
代碼:
/// <summary>
/// 消費端啟動
/// </summary>
public class ConsumerStartup : MessageListener
{
private readonly static ILog logger = LogManager.GetLogger(typeof(ConsumerStartup));
private readonly static ConsumerManager manager = new ConsumerManager();
private readonly string _consumerClientCode;
private readonly string _ons_groupId;
/// <summary>
/// 構造函數
/// </summary>
/// <param name="consumerClientCode">消費者客戶端Code</param>
/// <param name="ons_groupId">消費者消費的分組</param>
public ConsumerStartup(string consumerClientCode, string ons_groupId)
{
_consumerClientCode = consumerClientCode;
_ons_groupId = ons_groupId;
}
~ConsumerStartup()
{
}
/// <summary>
/// 消費者任務
/// </summary>
/// <param name="value"></param>
/// <param name="context"></param>
/// <returns></returns>
public override ons.Action consume(Message value, ConsumeContext context)
{
Console.WriteLine("【消費者任務】:消費者消息進來了...");
logger.Info($"【消費者任務】:消費者消息進來了...");
string topic = value.getTopic();
string business_id = value.getKey();
string message_id = value.getMsgID();
string msg_tag = value.getTag();
byte[] bytes = Encoding.Default.GetBytes(value.getBody());
string msg_body = Encoding.Default.GetString(bytes);
if (string.IsNullOrEmpty(msg_body))
{
return ons.Action.CommitMessage;
};
string log_body = $"本次消費的消息:【消費序列:{value.getQueueOffset()}】【消息key:{business_id}】【消息ID:{message_id}】【Tag:{msg_tag}】";
Console.WriteLine(log_body);
logger.Info(log_body);
logger.Info($"【消費內容】:{msg_body}");
int status = 1;
string error_msg = "";
long sys_msg_id = 0;
QueueOnsCommonModel consumerModel = null;
try
{
//調度到具體的消費者
consumerModel = JsonUtility.DeserializeJSON<QueueOnsCommonModel>(msg_body);
if (consumerModel != null)
{
logger.Info($"【消費者任務】:真正開始執行了(消息key:{consumerModel.MessageId})");
if (!long.TryParse(consumerModel.MessageId, out sys_msg_id))
{
logger.Info("sys_msg_id 轉換失敗!");
}
manager.ExecuteConsumer(consumerModel.Tag, consumerModel.EventType, consumerModel);
logger.Info($"【消費者任務】:執行完成了(消息key:{consumerModel.MessageId})");
}
else
{
status = 2;
error_msg = "【調度到具體的消費者】解析消息body內容為空,無法進行消費";
logger.Error($"【調度到具體的消費者】解析消息body內容為空,無法進行消費");
}
}
catch (Exception ex)
{
logger.Error($"【消費者任務】:發生異常了:{ex.Message}", ex);
status = 2;
error_msg = ex.Message;
}
return ons.Action.CommitMessage;
}
}
4.4-啟動消費者
在【RocketMQConsumerService.cs】文件OnStart方法中創建生產者,主要就是從配置文件中獲得配置信息,然後調用【QueueOnsProducer.CreatePushConsumer】方法創建消息隊列生產者,通過調用【QueueOnsProducer.SetPushConsumer】方法來設置生產者,最後通過調用【QueueOnsProducer.StartPushConsumer】方法來啟動生產者。
代碼:
//創建消費者
string ons_access_key = ConfigSetting.ons_access_key;
string ons_secret_key = ConfigSetting.ons_secret_key;
string ons_topic = ConfigSetting.ons_topic;
string ons_groupId = ConfigSetting.ons_groupId;
string ons_name_srv = ConfigSetting.ons_name_srv;
string ons_client_code = ConfigSetting.ons_client_code;
QueueOnsProducer.CreatePushConsumer(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.SetPushConsumer(new ConsumerStartup(ons_client_code, ons_groupId), "*");
//啟動消費者
QueueOnsProducer.StartPushConsumer();
4.5-接收消費消息
我們如果要創建一個具體消費者去消費某一條消息,需要先創建一個類,然後實現【IConsumerMsg】介面中的【Consume】方法。需要在這個方法上面標註兩個特性,也可以是一個(意味著滿足一個條件即可),一個是【ConsumerTag】Tag標簽,表示要消費哪個生產的Tag標簽,一個是【EventType】,表示要消費哪個生產的事件類型。如果有多個不同的消費者,就按照上面的方式創建多個即可。[西瓜程式猿]這邊創建一個名為【SampleConsumer】的類作為例子。
代碼:
/// <summary>
/// 消費者Sample
/// </summary>
[ConsumerTag(QueueTagConsts.XG_Blog_Sample_Tag)]
[EventType(QueueOnsEventType.RocketMQ_TEST)]
public class SampleConsumer : IConsumerMsg
{
private readonly static ILog logger = LogManager.GetLogger(typeof(SampleConsumer));
public void Consume(QueueOnsCommonModel model)
{
logger.Info($"【西瓜程式猿-消費者Sample】:測試消費者進來了");
if (model != null)
{
Console.WriteLine("tag:" + model.Tag);
Console.WriteLine("body" + model.Body);
}
Console.WriteLine("【西瓜程式猿-消費者Sample】消費成功了!");
}
}
五、發佈消費端
然後來介紹一下如何部署消費端。之前看評論區說使用NSSM部署安裝Window服務更方便,後面我也試了一下確實還挺好用,但是針對目前這個程式始終運行不起來(各位大佬如果有更好的方法和建議可以在評論區提出來哈),所以這次還是用之前的方法來介紹如何部署Windows服務了。
5.1-服務基本配置
(1)點擊我們的服務【RocketMQConsumerService.cs】,然後右擊點擊【添加安裝程式】。
(2)然後可以看到下麵多出來了一個文件,就是安裝程式。
(3)然後可以修改基本信息,服務組件中的【服務名稱】【服務描述】等等。我們右擊【serviceInstall1】點擊屬性,然後進行修改。
(4)然後點擊【serviceProcessInstall1】右擊屬性,進行修改。
5.2-服務運行與發佈
當我們直接按F5或者其他方式直接運行項目時,會提示:"無法從命令行或調試程式啟動服務。必須首先安裝 Windows服務(使用installutil.exe),然後用ServerExplorer、Windows服務管理工具或 NET START命令啟動它。"。不是這樣運行的,跟著下麵步驟來操作運行與發佈Windows服務吧。
前提註意:如果你設置的目標平臺是x64,打開的目錄會不一樣,不然導致服務運行不起來。可以右擊項目名,點擊【屬性】——>【生成】——>【目標平臺】查看。
如果不是x64版本,複製這個地址:
C:\Windows\Microsoft.NET\Framework\v4.0.30319
如果是x64版本,複製這個地址:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319
不然會報類似這種錯誤:在初始化安裝時發生異常: System.BadImageFormatException: 未能載入文件或程式集...
(1)然後我們把上面的地址(根據自己的環境選擇)添加到環境變數中。點擊【控制面板】——>【系統和安全】
(2)然後點擊【系統】
(3)點擊【高級系統設置】
(4)點擊【環境變數】
(5)在【系統變數】中找到Path,然後點擊【編輯】。
(6)然後點擊【新建】,然後把我們拷貝的目錄複製到這裡。然後點擊確認即可。
(7)測試是否配置成功,輸入這個命令查看一下【InstallUtil】,如果是下麵這樣的內容說明成功了。
(8)然後編輯解決方案和項目。
(9)以管理員身份運行cmd命令,然後安裝服務。
InstallUtil 項目啟動執行文件全路徑
西瓜程式猿的例子:
InstallUtil D:\項目演示臨時保存\MyDemoService\MyDemoService\bin\Debug\MyDemoService.exe
(10)出現這個說明安裝成功了。
(11)打開服務管理器,找到要啟動的服務,然後右擊啟動服務。
(12)如果要卸載服務,可以運行這個命令:
InstallUtil /u 項目啟動執行文件全路徑
西瓜程式猿的例子:
InstallUtil /u D:\項目演示臨時保存\MyDemoService\MyDemoService\bin\Debug\MyDemoService.exe
5.3-常見命令
1、安裝服務:InstallUtil 項目啟動執行文件全路徑
2、啟動服務:net start 服務名
3、停止服務:net stop 服務名
4、卸載服務:InstallUtil /u 項目啟動執行文件全路徑
5.4-測試消費消息
(1)首先可以先看一下日誌,看一下這個消費者服務是否啟動成功了。
(2)然後再日誌裡面記錄下消費的消費,在根據消息Key或者消息ID在阿裡雲後臺查詢一下這一條消息的【消息軌跡】,如果提示消費成功就說明確實已經進行消費了。
最後,還有可能會出現消息生產失敗、消息消費失敗等場景,大佬們可以根據實際情況進行設計和跳轉哈。
六、防踩坑指南
5.1:ons.ONSClient4CPPPINVOKE的類型初始值設定項引發異常
異常詳情:
“ons.ONSClient4CPPPINVOKE”的類型初始值設定項引發異常。
解決方案:
第一步:在使用Visual Studio(VS)開發.NET的應用程式和類庫時,預設的目標平臺為“Any CPU”。但是.NET SDK僅支持Windows 64-bit操作系統,所以需要自行設置。先右擊【RocketMQ.Producer】項目,然後點擊【屬性】,點擊左側選項的【生成】,然後將目標平臺改為【x64】。
第二步:將資源包【ONSClient4CPP】文件夾裡面所有的文件,複製到【bin】目錄下。
5.2:Topic Route does not exist
異常詳情:
Topic Route does not exist, Topic:XG_CXY_Test exception:msg: No route info of this topic, ,error:-1,in file <..\src\producer\DefaultMQProducer.cpp> line:581
See https://github.com/alibaba/ons/issues/7 for further details.”
異常截圖:
解決方案:
這個問題一般是沒有鏈接上RocketMQ,檢查一下配置文件中信息是否與RocketMQ信息一致。尤其是[ons_name_srv] RocketMQ 版控制台獲取的接入點信息,類似“rmq-cn-XXXX.rmq.aliyuncs.com:8080”切記不要加"http://或者https