Microsoft StreamInsight 構建物聯網

來源:互聯網
上載者:User

原文:http://msdn.microsoft.com/zh-cn/magazine/hh852591.aspx 

最近關於“物聯網”(IoT) 的爭論有很多,而且理由都很充分。 Ericsson 的 CEO Hans Vestberg 預測到 2020 年將有 500 億台裝置串連到 Web(bit.ly/yciS7r [PDF 下載])。 目前約有 15 億台 PC 以及不足 10 億台電話串連到 Web — 500 億相當於全球每個人約 7 台裝置,這可以協助您直觀理解這一數字! 市場研究機構 IDC 則預測到 2015 年將有超過 160 億台裝置串連到 Internet(參見圖 1)。 不可否認,也存在一些較保守的預測,但通過每個人提供的數字,我們看到 Internet 的角色正在發生巨大轉變 — 從為人們提供資訊和娛樂內容到為支援裝置的新興應用程式提供串連服務。


圖 1 IDC 預測會出現“嵌入式 Internet”

這些龐大數字看似可信的理由是強大的驅動因素(商機和必然性)正在推動此類解決方案的快速增加。 《經濟學家》(economist.com/node/17388368) 最近的一期雜誌指出,“…經濟大潮的向前滾動不僅僅是為了符合技術公司和雄心勃勃的政治家的利益。 這種發展趨勢已獲得了動力,因為真的需要此類系統。”圖 2 按應用領域顯示了此類解決方案的增長態勢。 例如,在歐洲強制實施智能能源系統是一個必然結果。 如果我們還不能管理能源消耗,則無法構建所需的能源產生功能。 在商機方面,簡單的、無所不在的自動售貨機就是一個很好的樣本。 在串連該裝置之後,可以根據需要而不是某項並非最理想的計劃來指派服務人員。 如果本地需求增加或商品接近到期日,甚至還可以動態更改價格。 可以報告停電情況以便督促立即更換易腐商品。 換句話說,串連實現了更高效的全新業務模型。


圖 2 按行業劃分的應用增長態勢

通過引用串連裝置的數量來描述此轉變肯定很形象,但它也會讓人產生一些誤解 — 此種轉變並不表明幾十萬傳統嵌入式程式員將充分就業。 這些裝置僅是將其他裝置整合到 Internet 的所有方面(包括分析、雲、Web 應用程式、PC 和移動介面等)的複雜解決方案的終結點。

因此,看待此問題的方法是當前構建基於 Web 的應用程式的每個人將需要整合裝置並協助開發新業務和新業務模型。 換句話說,即使您不是嵌入式開發人員,也不在構建嵌入式裝置的商店中工作,這也是一個值得您評估的非常誘人的商機。 您當前具備的 Microsoft 技能將使您能夠在 IoT 方面取得成功。

對裝置資料進行分析

“資料已成為新的貨幣”,Windows Embedded 團隊的總經理 Kevin Dallas 在最近的採訪中說道 (bit.ly/wb1Td8)。 與當前 Internet 應用程式相比,IoT 涉及資訊產生、管理和訪問。 讓我們比較一下當今典型 Internet 應用與 IoT 應用的資料特徵。 您或許和其他幾百萬人均使用多家金融機構共用的流行機制聯機支付帳單。 您每月登入多次,查看一些頁面並提交付款資訊。 所有這些資料都是使用當您開始與系統互動時所啟動並執行查詢從傳統資料庫中提取的。 您下載的頁面量可能很大,但互動非常少,即使它們產生的有價值的資訊(付款資訊、個人資訊更新等)需要長時間儲存也是如此。

將此應用與能源管理系統進行對比,該系統中可能有 5000 萬座大樓(商業樓和住宅樓)正在提供輸入。 輸入由內部的多個本地終結點(例如,房子)使用發布到後端的單個彙總檢視產生。 該資料包括返回給大樓的成為定價和記帳基礎的即時使用資訊和強制性控制。 此系統將與價值相對較低的資料進行非常頻繁的互動,這些資料在您計算系統的目前狀態和該終結點的趨勢資料時不一定有意義。 不過,該系統需要能夠立即對可能威脅其啟動並執行情況(例如需求劇增引髮網格超載和停電)做出響應。 在這種情況下,廣播資訊可以立即減少能源消耗。 此類系統需要連續分析傳入資料並比較發展趨勢,以識別指示較高停電風險的模式。

圖 3 示範 IoT 應用的典型體繫結構。 堆棧底部顯示了各種資產或裝置,它們根據不同應用領域配備了不同種類的感應器。 這些感應器通常產生應用領域快速處理和分析所需的連續資料來源。 根據裝置的功能,裝置本身或許能夠在本地執行一些處理。 這稱為本地分析,並且 .NET Micro Framework 之類的工具可協助您在裝置傳遞資料之前執行該本地處理。 IoT 應用使用 網際網路通訊協定 (IP)傳遞裝置資料,以便可以對資料進行全域分析。 而全域分析的結果(例如電網的整體健全狀態)是管理運營的終端使用者或業務決策者關注的內容。 分析還可以驅動根據傳入資料中呈現的情況自動採取操作的封閉系統。 如果資產可接收來自全域分析的反饋(例如,影響行為更改或改進操作),則這些方法將非常有用。 需要連續計算推動這些過程的全域分析並儘快提供結果。 另外,分析頻繁參考隨感應器資料一起提供的時間和時間戳記。 因此,僅將此類資料放入資料庫中並對其運行定期查詢不是適當的方法。 幸運的是,Microsoft StreamInsight 支援不同的方法。


圖 3 物聯網應用的典型體繫結構

Microsoft StreamInsight

Microsoft StreamInsight 旨在對連續到達的資料提供及時反應,而不將資料寫入磁碟中以進行分析和查詢。 許多 IoT 應用領域需要在從源擷取資料後幾乎即時地分析傳入資料。 考慮我們提到的智能電網應用,它需要對劇增的電力需求快速做出反應以重新平衡電網的運營能力。 許多 IoT 應用具有相同的需求: 需要連續分析的資料處理和令人信服的延遲。 分析必須連續,因為資料來源不斷地產生新資料。 許多方案需要識別只能通過分析傳入資料而呈現的情況並對其快速做出反應,因此它們需要低延遲分析和幾乎立即提供的結果。 這些要求使在執行分析之前將資料存放區在關聯式資料庫中變得不切實際。

我們將這些應用稱為事件驅動應用,而 IoT 正是此類功能發揮作用的一個方案。 StreamInsight 是一個用於構建這些高度可伸縮、低延期事件驅動應用的強大平台。 它是自 2008 R2 版本發布以後的 Microsoft SQL Server 的一部分。 在事件驅動處理和基於豐富表達時間的分析方面,StreamInsight 為 SQL Server 提供了補充。 使用 StreamInsight,將以產生資料的速度,而不是處理傳統資料庫報告的速度提供商業見解。

可供人們立即使用或使應用程式能夠自動對事件做出反應的分析結果可協助企業更及時且更好地瞭解其相關運營情況,甚至可以自動執行部分運營工作。 它們也可以對感應器或裝置資料中出現的重要情況、商機或趨勢更快地做出反應。

要編寫 StreamInsight 應用程式,開發人員可使用 Microsoft .NET Framework、LINQ 和 Microsoft Visual Studio 等熟悉的工具。 圖 4 描述了 StreamInsight 應用程式的開發人員和運行時體驗並介紹了一些關鍵概念。


圖 4 StreamInsight 應用程式開發和運行時

簡單的 IoT 應用

讓我們更深入地瞭解可能的 IoT 應用方案;然後我們將構建它。 在我們的端到端樣本中,我們將關注一個簡單方案,該方案使用動作感應器監視旋轉裝置,例如渦輪或風車。 這很重要,因為震動過大會導致出現緊急情況,在這種情況下,裝置可能出現故障,並且如不立即停止,則會出現嚴重損壞。 為可靠地檢測此情況,每台裝置均配備多個跟蹤運動的感應器。 單個感應器中的運動激增可能僅指示該感應器的資料讀數不可靠,但多個感應器中同時出現異常劇烈的運動則表明出現緊急情況。 例如對於大型渦輪,您可能希望引發警報,甚至自動關閉裝置。 除了持續檢查此類情況外,我們還希望為操作員提供一個儀表板,它提供了裝置狀態的近即時視圖。

若要構建此方案,我們需要滿足以下要求和解決以下技術難題:

  • 裝置需要捕獲哪些資料?
  • 我們使用哪些感應器來測量資料?
  • 裝置如何將其感應器讀數傳送到 Internet?
  • 我們如何將裝置資料收集到一個位置以進行分析?
  • 我們如何可以連續分析傳入資料並對緊急情況快速做出反應?
  • 我們如何跨多台裝置及時關聯感應器讀數,以便可以檢查全域情況?

讓我們看一下滿足這些要求並實現端到端方案的方式。

IoT 應用: 實現要點

下面是實現上一節中所述的 IoT 應用的一些關鍵步驟。 我們將首先討論裝置,再轉到輸出的可視化,然後轉到填充儀表板的跨裝置分析。

裝置。為構建感應器裝置,我們首先從 Netduino Plus 著手,它是運行 .NET Micro Framework、具有 128K SRAM 的受歡迎的小型開發板。 我們添加了名為 WiFly GSX Breakout 的常見愛好者 Wi-Fi 無線電,並在自訂 PCB 板上安裝了實際感應器,包括三軸加速計。 我們對裝置進行編程,以將感應器讀數的每秒更新發送給 Web 服務,該服務充當從所有裝置收集資料並進行處理的中心。

我們對 Web 服務使用 RESTful 串連 — 它只是包含逗號分隔名稱-值對的 HTTP POST。 當然,您可以從支援 HTTP 的任何種類的裝置執行此操作。 我們選擇使用 .NET Micro Framework,以便整個應用程式(包括裝置、Web 服務、StreamInsight 適配器、Silverlight 儀表板等)全部可以使用單個編程模型 (.NET) 和工具鏈 (Visual Studio) 進行編寫。 很明顯,如果您具有 .NET 技能,則無需招聘新員工或將您的 IoT 項目的一部分外包給外部嵌入式商店;您具有完全執行它的技能。 例如,設定加速計時只需幾行代碼即可訪問 AnalogInput 類並調用 Read 方法:


  
  1.           this.analogInputX = new AnalogInput(pinX);
  2. this.analogInputY = new AnalogInput(pinY);
  3. this.analogInputZ = new AnalogInput(pinZ);
  4. ...
  5.           rawZ = analogInputZ.Read();
  6. rawY = analogInputY.Read();
  7. rawX = analogInputX.Read();
  8.        

在讀取感應器輸入並設定 HTTP 訊息內容格式後,發送資料所需的一切都包括在圖 5 中。

圖 5 提交感應器資料


  
  1.           protected void submitSensorData(string uri, string payload)
  2. {
  3.   // Message format
  4.   StringBuilder sb = new StringBuilder(256);
  5.   sb.Append(
  6.     "POST /Website/Services/DataService.aspx?method=SaveDeviceData HTTP/1.1\n");
  7.   sb.Append("User-Agent: NetduinoPlus\n");
  8.   sb.Append("Host: 192.168.1.101\n");
  9.   sb.Append("Connection: Keep-Alive\n");
  10.   sb.Append("Content-Length: ");
  11.   sb.Append(payload.Length.ToString());
  12.   sb.Append("\n");
  13.   sb.Append(payload);
  14.   sb.Append("\n");
  15.   try
  16.   {
  17.     HttpResponse response = webServer.SendRequest(uri, 80, request);
  18.   }
  19.   catch
  20.   {
  21.     ...
  22.           }
  23. }
  24.        

在伺服器端,我們實現方法 SaveDeviceData,裝置要將其訊息發布給該方法。 我們拆分訊息字串並分析 MAC 位址、時間戳記和負載資料,例如來自加速計的運動讀數。 我們使用所有這些資訊來填充傳遞給 StreamInsight 以進行後續分析的 DeviceData 對象(請參見圖 6)。

圖 6 填充 DeviceData 對象


  
  1.           private int SaveDeviceData()
  2. {
  3. ...
  4.           List<string> data = record.Split(',').ToList();
  5.   DeviceData deviceData = new DeviceData();
  6.   deviceData.MAC = NormalizeMAC(data[0].Trim());
  7.   deviceData.DateTime = DateTime.UtcNow;
  8. ...
  9.           deviceData.Motion = Convert.ToDecimal(data[2].Substring(data[2].IndexOf(":") + 1));
  10. ...
  11.           // Communicate each new device data record to StreamInsight          
  12.   DeviceDataStreaming streaming = (DeviceDataStreaming)
  13.     HttpContext.Current.Application[Global.StreamingIdentifier];
  14.     streaming.TrackDeviceData(deviceData);
  15. ...
  16.           }
  17.        

儀表板。現在我們要構建允許裝置操作員查看裝置上感應器的目前狀態的儀表板。 為便於示範,我們將僅關注一台裝置。 圖 7 顯示了一個此類儀表板的樣本。 讓我們從左側開始,查看感應器資料的不同視圖。


圖 7 用於裝置監視的儀表板

移動平均數視圖: 左下角的資料格顯示裝置的感應器讀數,其中包括光線、溫度和運動值以及裝置識別碼 和時間戳記。 正如您可以從時間戳記中看到的,這些值每秒更新一次。 但儀表板不顯示原始感應器值,而是顯示 10 秒內感應器資料的移動平均數。 這意味著會使用最近 10 秒內資料的平均數每秒更新一次值。 使用移動平均數是一種常見的簡單技術,可防止出現使用低成本感應器時偶爾出現的異常值和不良資料。

趨勢線視圖: 在右下角,儀表板顯示感應器的趨勢線。 趨勢線視圖的走勢由左側資料格中顯示的移動平均數決定。

警示檢視: 右上方的視圖顯示警報的資料格。 如果檢測到臨界情況,則會引發顯示時間和其他資訊(例如嚴重性和狀態)的警報。

分析。現在讓我們瞭解幕後操作並討論處理傳入感應器資料並計算儀表板可視化的結果的分析。 我們使用 StreamInsight 執行分析。 以下類表示裝置資料,其中包括 MAC 位址、時間戳記和感應器值:


  
  1.           public class DeviceData
  2. {
  3.   public string MAC { get; set; }
  4.   public DateTime DateTime { get; set; }
  5.   public decimal?
  6.           Light { get; set; }
  7.   public decimal?
  8.           Temperature { get; set; }
  9.   public decimal?
  10.           Motion { get; set; }
  11. }
  12.        

此類定義單個事件的形狀,但我們想要開始討論許多事件。 為此,我們為 StreamInsight 定義了 Observable 資料來源。 這僅是實現 System.IObservable 介面的資料來源:


  
  1.           public class DeviceDataObservable : IObservable<DeviceData>
  2.   {
  3.     ...
  4.           }
  5.        

在定義 .NET Framework 序列(例如 Enumerable 或類似的 Observable)後,即可開始編寫對這些集合的 StreamInsight 查詢。 讓我們快速瞭解一下其中某些關鍵查詢。 第一個查詢擷取 Observable 作為輸入並產生 StreamInsight 時間點事件流,以使用裝置資料中的“DateTime”欄位作為 StreamInsight 事件的時間戳記。 在下一個 LINQ 語句中,我們擷取此流作為輸入,並按 MAC 位址對資料進行分組。 對於每個組,我們然後應用視窗大小為 10 秒的跳動視窗(基於時間的一部分事件),並讓視窗每秒重新計算一次。 在每個視窗中,我們計算溫度、光線和運動的平均數。 這為我們提供了每秒重新計算一次的每台裝置的移動平均數。 圖 8 顯示了用於返回 StreamInsight 事件流形式的結果的函數實現此過程的代碼。

圖 8 擷取移動平均數


  
  1.           public static CepStream<AverageSensorValues> GroupedAverages(
  2.               Application application,
  3.               DeviceDataObservable source)
  4.   {
  5.     var q1 = from e1 in source.ToPointStream(application,
  6.       e => PointEvent.CreateInsert(
  7.         new DateTimeOffset(
  8.           e.DateTime.ToUniversalTime()),e),
  9.       AdvanceTimeSettings.StrictlyIncreasingStartTime,
  10.       "Device Data Input Stream")
  11.              select e1;
  12.     var q2 = from e2 in q1
  13.              group e2 by e2.MAC into groups
  14.              from w in groups.HoppingWindow(
  15.                TimeSpan.FromSeconds(10),
  16.                TimeSpan.FromSeconds(1))
  17.              select new AverageSensorValues
  18.              {
  19.                DeviceId = groups.Key,
  20.                Timestamp = null,
  21.                AvgTemperature = w.Avg(t => t.Temperature),
  22.                AvgLight = w.Avg(t => t.Light),
  23.                AvgMotion = w.Avg(t => t.Motion)
  24.              };
  25.     return q2;
  26.   }
  27.        

這是考慮實現警報查詢的最佳位置。 請記住,當有多個動作感應器的讀數同時高於運動閾值時,將觸發警報。 只需對剛計算的分組平均數使用幾個 StreamInsight LINQ 語句便可處理此問題。 通過將警示閾值的更改表示為名為 AlarmThresholdSignal 的事件流,第一個查詢 q3 應用了一個極佳的技巧。 此查詢將閾值與來自前一個查詢的平均數流聯結,然後僅篩選高於閾值的事件:


  
  1.           var q3 = from sensor in GroupedAverages(application, source)
  2.          from refdata in AlarmThresholdSignal(application, alarmsthresholds)
  3.          where (sensor.AvgMotion !=
  4.            null && (double) sensor.AvgMotion > refdata.Threshold)
  5.          select new
  6.          {
  7.            AlarmDevice = sensor.DeviceId,
  8.            AlarmInfo = "This is a test alarm for a single device",
  9.          };
  10.        

下一個查詢使用 StreamInsight 快照集視窗來識別事件狀態更改的時間點。 如果從前一個篩選查詢產生了一個新事件,則這是新快照,並且該快照操作產生一個新視窗,其中包含與觸發快照集視窗的事件一致或重疊的所有事件。 下面的代碼對建立快照集視窗時高於警示閾值的事件進行計數:


  
  1.           var alarmcount = from win in q3.SnapshotWindow()
  2.                  select new
  3.                  {
  4.                    AlarmCount = win.Count()
  5.                  };
  6.        

最後一步檢查計數是否顯示有多台裝置將發出警報指示:


  
  1.           var filteralarms = from f in alarmcount
  2.                    where f.AlarmCount >= 2
  3.                    select new AlarmEvent
  4.                    {
  5.                      AlarmTime = null,
  6.                      AlarmInfo = "Now we have an alarm across multiple devices",
  7.                      AlarmKind = 0,
  8.                      AlarmSeverity = 10,
  9.                      AlarmStatus = 1
  10.                    };
  11.        

現在,我們只需將包含平均感應器值和警報的輸出資料流從 StreamInsight 傳送到 UI。

使輸出資料流傳送到 UI

使用在伺服器端產生結果流的 StreamInsight,我們需要一種方法來將這些流傳送給使用者。 使用者可能不在伺服器處理序中運行,並可能使用輕型 Web 應用程式來可視化結果。 如果您使用 Silverlight,則雙工協議很方便,因為它支援從伺服器到用戶端的連續的基於推送的傳送。 HTML5 Web 通訊端也是令人信服的替代方法。 無論如何,您都希望輕鬆地在伺服器端添加新分析並能夠輕鬆地將它們與 UI 串連,而無需拆分 UI 和承載 StreamInsight 的進程之間的用戶端-伺服器介面。 如果 UI 和伺服器之間的負載適中,則您可以將伺服器端的結果序列化為 XML 並在用戶端對其進行還原序列化。 這樣,您只需關注線路上和您的用戶端-伺服器介面中的 XML,以及指示要還原序列化的類型的附加 Cookie。 下面是幾段關鍵代碼。

第一個程式碼片段是 Windows Communication Foundation 協定,它用於傳送 XML 序列化字串形式的事件數目據以及指示類型的 GUID:


  
  1.           [ServiceContract]
  2. public interface IDuplexClient
  3. {
  4.   [OperationContract(IsOneWay = true)]
  5.   void Receive(string eventData, Guid guid);
  6. }
  7.        

現在,我們可以使用資料合約為結果事件結構添加批註以使其可序列化,如圖 9 所示。

圖 9 為事件結構添加批註


  
  1.           [DataContract]
  2. public class AverageSensorValues : BaseEvent
  3. {
  4.   [DataMember]
  5.   public new static Guid TypeGuid =
  6.     Guid.Parse("{F67ECF8B-489F-418F-A01A-43B606C623AC}");
  7.   public override Guid GetTypeGuid() { return TypeGuid; }
  8.   [DataMember]
  9.   public string DeviceId { get; set; }
  10.   [DataMember]
  11.   public DateTime?
  12.           Timestamp { get; set; }
  13.   [DataMember]
  14.   public decimal?
  15.           AvgLight { get; set; }
  16.   [DataMember]
  17.   public decimal?
  18.           AvgTemperature { get; set; }
  19.   [DataMember]
  20.   public decimal?
  21.           AvgMotion { get; set; }
  22. }
  23.        

現在,我們可以輕鬆地序列化伺服器端的結果事件並將其傳送到用戶端,如圖 10 所示。

圖 10 從伺服器發送結果事件


  
  1.           static public void CallClient<T>(T eventData) where T : BaseEvent
  2.   {
  3.     if (null != client)
  4.     {
  5.       var xmlSerializer = new XmlSerializer(typeof(T));
  6.       var stringBuilder = new StringBuilder();
  7.       var stringWriter = new StringWriter(stringBuilder);
  8.       xmlSerializer.Serialize(stringWriter, eventData);
  9.       client.Receive(stringBuilder.ToString(), eventData.GetTypeGuid());
  10.     }
  11.   }
  12.        

在用戶端上,我們還原序列化雙工服務的回調方法中的事件,然後根據接收到的事件的類型將其分支到不同的方法中,如圖 11 所示。

圖 11 在用戶端上接收和還原序列化事件


  
  1.           void proxy_ReceiveReceived(object sender, ReceiveReceivedEventArgs e)
  2. {
  3.   if (e.Error == null)
  4.   {
  5.     if (AverageSensorValues.TypeGuid == e.guid)
  6.     {
  7.       ProcessAverageSensorValues(Deserialize<AverageSensorValues>(e.eventData));
  8.     }
  9.     else if (AlarmEvent.TypeGuid == e.guid)
  10.     {
  11.       ProcessAlarms(Deserialize<AlarmEvent>(e.eventData));
  12.     }
  13.     else
  14.     {
  15.       ProcessUnknown();
  16.     }
  17.   }
  18. }
  19.        

使用這些查詢並傳送到相應的 Web 應用程式,您現在可以選取幾台裝置並搖動它們,直到一些裝置讀數高於警示閾值。 然後,UI 將產生這些紅色警報之一,如圖 12 所示。


圖 12 包含警報的裝置儀表板

因為新資料會不斷進入幾乎即時的儀表板,所以 ObservableCollections 對更新 UI 極其有用。 如果您使資料格和趨勢線基於這些 Observable 集合,則無需擔心代碼中的更新部分。 這些集合將在後台為您自動執行此操作。

前景

在此實現中,裝置與常規 Web 服務通訊,該服務可以運行在串連到 Internet 的普通 PC 上。 但云計算是一個迷人的替代方法;您不一定需要為自己的 Web 服務器擁有硬體並運行軟體。 雲中的服務可以充當為您的應用程式收集所有裝置資料的中心。 這還使您能夠在裝置數量增加或部署針對裝置資料的其他分析時,非常輕鬆且靈活地擴充您的處理能力。 Microsoft 計劃將 StreamInsight 功能作為 Windows Azure 中的一項服務(StreamInsight 項目代碼名稱“Austin”)提供。 通過提供預定義的通訊終結點和協議,Austin 將使您能夠輕鬆地將裝置串連到 Microsoft 雲中豐富的分析處理功能。 如果您將 IoT 應用程式部署到 Windows Azure 中,則將自動獲得靈活擴充和預付方案等雲好處,以便管理裝置串連和對裝置資料執行豐富的分析。

另一個重大轉變涉及最近進行的 W3C 標準化工作。 IoT 應用程式的最重要計劃是 HTML5 和 Web 通訊端。 HTML5 為豐富的 Web 應用程式(例如我們實現的儀表板)提供平台。 而 WebSocket 又簡化了瀏覽器和 Web 服務器之間基於 TCP 的全雙工系統通訊,尤其是針對連續處理感應器資料時所要求的結果傳送的推送模型。

串連的裝置開創了一個令人興奮的新應用領域,並且 Microsoft 現在提供用於構建這些 IoT 應用程式的工具。 我們在這裡介紹了如何在裝置層級通過熟悉的介面利用您的 .NET Framework 技能,以及如何通過 Web 服務為 StreamInsight 的強大分析功能提供資料。 立即開始使用串連裝置構建您的 IoT 應用程式!

Torsten Grabs 是 Microsoft SQL Server 部門的首席專案經理。 他具有 10 餘年 Microsoft SQL Server 產品的使用經驗,並獲得瑞士蘇黎世的瑞士聯邦理工學院的電腦科學博士學位。

Colin Miller 在 PC 軟體領域工作了 25 年(其中有 15 年效力於 Microsoft),研究方向涉及資料庫、案頭發布、消費類產品、Word、Internet Explorer、Passport (LiveID) 及線上服務。 他是 .NET Micro Framework 的產品部經理。

衷心感謝以下技術專家對本文的審閱: Rafael Fernandez MoctezumaLorenzo Tessiore

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.