【結果很簡單,過程很艱辛】記阿里雲Ons消息隊列服務.NET接口填坑過程


    Maybe 這個問題很簡單,因為解決方法是非常簡單,但填坑過程會把人逼瘋,在阿里雲ONS工作人員、同事和朋友的協助下,經過一天的調試和瞎搗鼓,終於解決了這個坑,把問題記下來,也許更多人在碰到類似問題的時候,會開放思路。當然不得不說,Ons的.NET接口還很不完善,甚至沒有獨立在Windos 2008/2012服務器測試過,希望官方加把力。

1、阿里雲ONS介紹

   ONS(Open Notification Service)即開放消息服務,是基於阿里開源消息中間件MetaQ(RocketMQ)打造的一款雲消息產品,歷經多次天貓雙十一海量消息考驗,在阿里巴巴內部有1000+個應用在使用,產品成熟穩定可靠, 是構建大型分布式系統的核心組件之一。它能為分布式應用系統提供異步解耦、削峰填谷能力,同時也具有海量消息堆積,高吞吐,可靠重試等互聯網應用所需特性。從2014年10月至今開始對外公測,目前ONS提供了北京,青島,杭州三大Region的高可用集群(產品穩定性及可用性完全按照阿里巴巴內部標准來實施,無單點,99.99%的高可用性),公測期間完全免費。

    目前支持Java,C++,.NET, PHP四種語言,Linux平台下支持C++,JAVA和PHP三種語言, Windows平台支持C++和.NET兩種語言。

2、系統環境、問題和解決過程

    總的來說,雖然官方的Demo很簡單,說明文檔也不詳細,連參數也沒解釋清楚,和Java的接口差距很大,但是自己選擇的路,含着淚也要走完,既然項目已經選擇了.NET,那就上吧。經過同事劉哥的前期嘗試,我拿過來之后,做為消息消費者,開發是非常順利的,只是在測試機測試的時候,碰到數據問題,經過努力,自己將真實數據模擬一下,也能解決。一切都很順其自然,當所有測試完成,准備去正式環境測試的時候,問題接踵而至。。。。

    開發環境:Win10 + .NET 4.0 + VS2013 ,目標平台:x86 

    測試環境:虛擬機-Windows Server 2008 R2 + .NET 4.0 + x64

    測試程序本地是完全沒有問題,所以興高采烈拿去服務器,馬上就出現下面的問題:

    說明:ManagedONS.dll就是Ons的.NET接口,這個錯誤以前也遇到過,猜測可能是自己疏忽目標平台編譯錯誤,因為是在64bit環境下使用32bit程序。

結果總么修改還是不行,由於我部署的Windows服務程序,怕有錯誤,馬上拖了一個控制台去測試,還是同樣的問題。。。。搜索了很多,也總結了一下:

 Why:開發機也是64,沒問題,為什么服務器不行,肯定是環境問題,環境差距在哪里?貌似也就是多了一個VS,然后我把本機的控制面板打開,看看那些是和開發環境相關的,如下圖所示:

    由於Ons的.NET接口是C++編寫的,后來才知道是C++/CLI編寫的,所以首先就懷疑Visual C++2012 Redistribution這個東西,馬上去下載了一個相同版本的東西,安裝下來,還是不行,杯具的是,后來才注意的,(我安裝的版本是11.0.5XXX,實際上安裝11.0.6XX也是不行的,原因不明,看下面分解)>。

    各種折騰,問題依舊,我馬上找了幾個分析程序集依賴的工具,看看到底和哪些dll相關,找出來Copy進去就好了,想法是好的,但使用了好幾個工具,如exescope,Dependency Walker等等,查找一遍后,確認該有的文件,服務器都有。。。。無果。。。 各種折騰都不行后,我只能向Ons官方旺旺群求助,他們的響應速度還可以,馬上有一個技術人員和我聯系,尋找問題和解決方法。首先阿里的技術人員對照說明文檔讓我核實了一些步驟,都沒有問題,然后讓我修改項目屬性,分析所有dll的最低支持系統版本等等,最后讓我把項目配置都該為X86+Release,結果這次出現的是這個問題:

  是找不到指定模塊。。。。毫無疑問,還是環境問題,經過我和同事劉哥的確認,Win10開發機,以及Win7的開發機都是可以運行的,最后我們迫不得已,正好劉哥電腦有一個Win 2012的虛擬機也是同樣的問題,為了驗證我們的想法,直接在虛擬機上安裝了一個VS2013,真的是淚流滿面。。。VS2013安裝到一半,馬上就OK了,我們馬上打開控制面板,看看多了哪些東西,和最上面還是一樣的,多了Visual C++2012 Redistribution,馬上我們把這個東西對應的版本重新安裝了一半到開發機,版本號是:11.0.6,興高采烈,結果還是失望,難道是傳說中的日了狗了。。。

  Win2012虛擬機安裝VS2013的確是可以運行,卸載后就又歇菜了。無奈,懷着沉重的心情,我們去吃了晚飯,回來后向新生命群的C++/CLI大神 石頭求助,把Ons的相關文件發過去后,他反編譯了一下,馬上給我發過來一個 更高版本的 運行時版本:12.0.3,就是下面這個鬼,

    我很納悶,因為前面試了幾個版本都不行,也不知道這個行不行,但是還是充滿希望的安裝上去,果然,一切OK。。。。。心情舒暢了,只能由衷的感謝。最后將解決方法發給了阿里的技術人員,希望他們寫更完善的文檔,不然開放測試服務,只會讓更多的人充當小白鼠。。。

3、資源與工具

  至今不懂為什么開發機的版本安裝上去不行,但高一個版本就可以。時間緊迫,解決問題就好了吧。為了解決這個問題,看到一篇文章,非常不錯,推薦給大家,雖然沒從其中找到問題,但也學了不少東西,今天可算是把system32的文件翻了底朝天:

dll文件32位64位檢測工具以及Windows文件夾SysWow64的坑

http://www.cnblogs.com/hbccdf/p/dllchecktoolandsyswow64.html

其中有一個檢測Win32和64位dll文件的代碼,為了檢測自己的dll,特別把該博客的代碼摳下來,做了一個winform工具,一起都留下來吧。核心代碼如下: 

private void button1_Click(object sender, EventArgs e)
{
	string path = System.Environment.CurrentDirectory;
	DirectoryInfo directory = new DirectoryInfo(path);
	FileInfo[] fileInfoArray = directory.GetFiles();
	StringBuilder sb = new StringBuilder ();
	foreach (var item in fileInfoArray)
	{
		String str = String.Format("{0}:  {1}",item.Name,IsPE32(item.FullName)? "32bit":"64bit");
		sb.AppendLine(str);
	}
	textBox1.Text = sb.ToString();
}

public static bool IsPE32(string path)
{
	FileStream stream = File.OpenRead(path);
	//移動到e_lfanew的位置處
	stream.Seek(0x40 - 4, SeekOrigin.Begin);
	byte[] buf = new byte[4];
	stream.Read(buf, 0, buf.Length);
	//根據e_lfanew的值計算出Machine的位置
	int pos = BitConverter.ToInt32(buf, 0) + 4;
	stream.Seek(pos, SeekOrigin.Begin);
	buf = new byte[2];
	stream.Read(buf, 0, buf.Length);
	//得到Machine的值,0x14C為32位,0x8664為64位
	Int16 machine = BitConverter.ToInt16(buf, 0);
	if (machine == 0x14C)
	{
		return true;
	}
	else
	{
		return false;
	}
}

 界面如下,比較簡陋,比較急着用,沒有加工,大家自己看着辦,使用方法是把程序拷貝到你要檢測的程序集目錄,如下圖:

小工具源碼在這里:FileDetect.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM