章節
第一章:https://www.cnblogs.com/kimiliucn/p/17662052.html
第二章:https://www.cnblogs.com/kimiliucn/p/17667200.html
作者:西瓜程式猿
主頁傳送門:xx
上一章節主要介紹了RocketMQ基本介紹和前期準備,以及如何建立生產者。那這一章節主要介紹一下消費端的實現、如何釋出消費端,以及遇到的坑怎麼去解決。
(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 才有用。
(1)在使用Visual Studio(VS)開發.NET的應用程式和類庫時,預設的目標平臺為「Any CPU」。但是.NET SDK僅支援Windows 64-bit作業系統,所以需要自行設定。先右擊【RocketMQ.Consumer】專案,然後點選【屬性】。
(2)點選左側選項的【生成】,然後將目標平臺改為【x64】。
(3)將資源包【ONSClient4CPP】資料夾裡面所有的檔案,複製到【bin/Debug】目錄下。
資源包:
專案:
(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);
(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
}
(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;
}
}
在【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();
我們如果要建立一個具體消費者去消費某一條訊息,需要先建立一個類,然後實現【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服務了。
(1)點選我們的服務【RocketMQConsumerService.cs】,然後右擊點選【新增安裝程式】。
(2)然後可以看到下面多出來了一個檔案,就是安裝程式。
(3)然後可以修改基本資訊,服務元件中的【服務名稱】【服務描述】等等。我們右擊【serviceInstall1】點選屬性,然後進行修改。
(4)然後點選【serviceProcessInstall1】右擊屬性,進行修改。
當我們直接按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
1、安裝服務:InstallUtil 專案啟動執行檔案全路徑
2、啟動服務:net start 服務名
3、停止服務:net stop 服務名
4、解除安裝服務:InstallUtil /u 專案啟動執行檔案全路徑
(1)首先可以先看一下紀錄檔,看一下這個消費者服務是否啟動成功了。
(2)然後再紀錄檔裡面記錄下消費的消費,在根據訊息Key或者訊息ID在阿里雲後臺查詢一下這一條訊息的【訊息軌跡】,如果提示消費成功就說明確實已經進行消費了。
最後,還有可能會出現訊息生產失敗、訊息消費失敗等場景,大佬們可以根據實際情況進行設計和跳轉哈。
異常詳情:
「ons.ONSClient4CPPPINVOKE」的型別初始值設定項引發異常。
解決方案:
第一步:在使用Visual Studio(VS)開發.NET的應用程式和類庫時,預設的目標平臺為「Any CPU」。但是.NET SDK僅支援Windows 64-bit作業系統,所以需要自行設定。先右擊【RocketMQ.Producer】專案,然後點選【屬性】,點選左側選項的【生成】,然後將目標平臺改為【x64】。
第二步:將資源包【ONSClient4CPP】資料夾裡面所有的檔案,複製到【bin】目錄下。
異常詳情:
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