日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

使用“即时消息服务框架”(iMSF)实现分布式事务的三阶段提交协议(电商创建订单的示例)...

發(fā)布時(shí)間:2025/3/15 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用“即时消息服务框架”(iMSF)实现分布式事务的三阶段提交协议(电商创建订单的示例)... 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1,示例解決方案介紹

在上一篇 《消息服務(wù)框架(MSF)應(yīng)用實(shí)例之分布式事務(wù)三階段提交協(xié)議的實(shí)現(xiàn)》中,我們分析了分布式事務(wù)的三階段提交協(xié)議的原理,現(xiàn)在我們來(lái)看看如何使用消息服務(wù)框架(MSF)來(lái)具體實(shí)現(xiàn)并且看用它來(lái)實(shí)現(xiàn)的一些優(yōu)勢(shì)。

首先,從Github克隆項(xiàng)目源碼,地址:https://github.com/bluedoctor/MSF-DistTransExample

解決方案如下圖:

我們看到解決方案有4個(gè)項(xiàng)目:

  • DistTransClient:分布式事務(wù)示例的客戶(hù)端,它調(diào)用“訂單服務(wù)”,創(chuàng)建一個(gè)訂單,服務(wù)會(huì)返回創(chuàng)建結(jié)果是成功還是失敗;
  • DistTransDto:包含商品,訂單和訂單詳情的實(shí)體類(lèi)型接口以及相關(guān)的接口實(shí)現(xiàn);
  • DistTransServices:包含訂單服務(wù),商品服務(wù)和分布式事務(wù)控制器服務(wù);
  • TistTransApp:本測(cè)試的宿主程序項(xiàng)目,主要用于安裝消息服務(wù)框架的服務(wù)宿主程序,以及啟動(dòng)訂單,商品和分布式事務(wù)控制器的服務(wù)進(jìn)程。
  • ?2,創(chuàng)建訂單的業(yè)務(wù)簡(jiǎn)介

    2.1,基本概念

    下面先介紹本示例要解決的業(yè)務(wù),并通過(guò)這個(gè)業(yè)務(wù)來(lái)分析分布式事務(wù)的執(zhí)行過(guò)程。

    在本示例中,使用的是電商系統(tǒng)最常見(jiàn)的業(yè)務(wù)場(chǎng)景:下單業(yè)務(wù),它的業(yè)務(wù)流程也概括起來(lái)比較簡(jiǎn)單:

    創(chuàng)建訂單:

  • 生成訂單基本信息;
  • 生成訂單項(xiàng)目明細(xì)(已購(gòu)商品清單):
  • 檢查庫(kù)存是否足夠
  • 扣減庫(kù)存
  • ?當(dāng)然,在具體的電商業(yè)務(wù)系統(tǒng)中,下單業(yè)務(wù)比較復(fù)雜,特別是對(duì)庫(kù)存的扣減方式,但大體的業(yè)務(wù)流程就是這樣的,我們今天的重點(diǎn)是研究這個(gè)下單過(guò)程在分布式環(huán)境下如何實(shí)現(xiàn)。

    2.2,微服務(wù)架構(gòu)

    假設(shè)我們的電商平臺(tái)使用微服務(wù)架構(gòu)的,包含了用戶(hù)服務(wù),商品服務(wù),訂單服務(wù)和支付服務(wù),這4個(gè)服務(wù)在下單業(yè)務(wù)中的功能分別如下:

    • 用戶(hù)服務(wù):檢查當(dāng)前用戶(hù)是否有效,查詢(xún)用戶(hù)的相關(guān)信息,比如用戶(hù)姓名,聯(lián)系電話(huà)等;
    • 訂單服務(wù):生成訂單,包括結(jié)合用戶(hù)服務(wù)的用戶(hù)信息,生成訂單基本信息;結(jié)合商品服務(wù),生成訂單項(xiàng)目明細(xì);
    • 商品服務(wù):向訂單服務(wù)返回商品的相關(guān)信息,并返回庫(kù)存是否可用,如果可用就扣減庫(kù)存;
    • 支付服務(wù):由第三方提供,但參與創(chuàng)建訂單的流程,用戶(hù)下單后需要用戶(hù)去第三方支付系統(tǒng)完成支付,然后支付服務(wù)回調(diào)訂單服務(wù),完成有效訂單確認(rèn)。

    ?下面是這4個(gè)服務(wù)在創(chuàng)建訂單的業(yè)務(wù)流程圖:

    上圖中,支付服務(wù)是第三方提供的服務(wù),需要用戶(hù)在創(chuàng)建訂單后跳轉(zhuǎn)調(diào)用,所以本質(zhì)上不是訂單服務(wù)直接調(diào)用,訂單服務(wù)需要提供一個(gè)支付完成的回調(diào)通知接口,完成有效訂單的確認(rèn)。 而用戶(hù)服務(wù)作為服務(wù)調(diào)用的發(fā)起方,它會(huì)傳遞必要的信息給訂單服務(wù),因此,對(duì)于“創(chuàng)建訂單”這個(gè)具體的業(yè)務(wù)功能,它涉及的需要同時(shí)進(jìn)行操作的只有創(chuàng)建訂單和扣減庫(kù)存這兩個(gè)子業(yè)務(wù),并且要求這2個(gè)子業(yè)務(wù)操作具有原子性,即要么同時(shí)成功,要么同時(shí)失敗撤銷(xiāo),所以這兩個(gè)操作組成一個(gè)事務(wù)操作,在我們當(dāng)前的場(chǎng)景中,它是一個(gè)分布式事務(wù)。

    2.3,分布式事務(wù)中的微服務(wù)容器

    在本例中,我們使用消息服務(wù)框架(MSF)來(lái)實(shí)現(xiàn)分布式事務(wù),為了更加真實(shí)的模擬微服務(wù)架構(gòu),我們將創(chuàng)建訂單相關(guān)的服務(wù)劃分為3個(gè)獨(dú)立的進(jìn)程,這些進(jìn)程就是MSF.Host服務(wù)容器,這里分為3個(gè)服務(wù)容器:

    • 協(xié)調(diào)器服務(wù)容器:運(yùn)行分布式事務(wù)協(xié)調(diào)器服務(wù);
    • 訂單服務(wù)容器:運(yùn)行訂單服務(wù)和分布式事務(wù)控制器組件;
    • 商品服務(wù)容器:運(yùn)行商品服務(wù)和分布式事務(wù)控制器組件。

    下面是這3個(gè)服務(wù)容器的進(jìn)程調(diào)用關(guān)系圖:

    ?

    ?

    3,創(chuàng)建訂單的分布式事務(wù)流程

    下面來(lái)看創(chuàng)建訂單的分布式事務(wù)處理過(guò)程,為簡(jiǎn)單起見(jiàn),只討論正常的流程,其中異常的流程,請(qǐng)參考原文對(duì)于3階段提供分布式事務(wù)的具體原理。

    1,客戶(hù)端調(diào)用訂單服務(wù)的創(chuàng)建訂單方法;(上圖步驟1)

    2,訂單服務(wù)實(shí)例化,接受一個(gè)訂單號(hào),用戶(hù)號(hào),要購(gòu)買(mǎi)的商品清單3個(gè)參數(shù)來(lái)創(chuàng)建訂單;(上圖步驟1)

    3,創(chuàng)建訂單的方法向分布式事務(wù)控制器進(jìn)行本地事務(wù)注冊(cè),傳入創(chuàng)建訂單的事務(wù)方法(委托);(上圖步驟2)

    4,創(chuàng)建訂單的事務(wù)方法遠(yuǎn)程調(diào)用商品服務(wù),更新商品庫(kù)存;(上圖步驟3)

    5,商品服務(wù)的更新商品庫(kù)存方法向分布式事務(wù)控制器進(jìn)行本地事務(wù)注冊(cè),傳入具體更新庫(kù)存的事務(wù)方法(委托);(上圖步驟4)

    6,商品服務(wù)執(zhí)行完成更新庫(kù)存的方法,向訂單服務(wù)返回必要的信息,準(zhǔn)備好提交事務(wù);(上圖步驟5)

    7,訂單服務(wù)收到商品服務(wù)的返回信息,構(gòu)建好訂單和訂單明細(xì),準(zhǔn)備好提交事務(wù);(上圖步驟6)

    8,分布式事務(wù)控制器檢測(cè)到注冊(cè)的各事務(wù)資源服務(wù)器(商品服務(wù)和訂單服務(wù))都已經(jīng)準(zhǔn)備好提交事務(wù),向它們發(fā)出提交指令;

    9,商品服務(wù)和訂單服務(wù)收到提交指令,提交本地事務(wù),事務(wù)資源服務(wù)方法執(zhí)行完成;(上圖步驟7,8)

    10,分布式事務(wù)控制器收到事務(wù)資源服務(wù)器的反饋,登記本次分布式事務(wù)執(zhí)行完成;

    11,訂單服務(wù)標(biāo)記創(chuàng)建訂單成功,向客戶(hù)端返回信息。

    4,分布式事務(wù)服務(wù)和組件

    4.1,分布式事務(wù)控制器

    分布式事務(wù)控制器是提供給事務(wù)資源服務(wù)使用的組件,在本示例中是類(lèi) DTController,它提供了如下重要方法:

    • 檢查并開(kāi)啟一個(gè)分布式事務(wù)控制器對(duì)象
    • 移除一個(gè)事務(wù)控制器
    • 累計(jì)事務(wù)資源服務(wù)器
    • 獲取分布式事務(wù)的狀態(tài)
    • 3階段分布式事務(wù)請(qǐng)求函數(shù)
    • 提交事務(wù)的方法
    • 回滾事務(wù)的方法

    其中“3階段分布式事務(wù)請(qǐng)求函數(shù)”,是事務(wù)控制器對(duì)象重要的函數(shù),它負(fù)責(zé)對(duì)“3階段分布式事務(wù)”的各個(gè)階段進(jìn)行流程控制,其中每一階段,都要和“分布式事務(wù)協(xié)調(diào)服務(wù)”進(jìn)行通信,接受它的指令,完成本地事務(wù)資源的控制,比如是提交還是回滾事務(wù)資源。下面我們看看它主要的代碼:

    ?在上面的函數(shù)中,MSF的客戶(hù)端服務(wù)訪問(wèn)代理類(lèi) Proxy 對(duì)象它請(qǐng)求的是“分布式事務(wù)協(xié)調(diào)服務(wù)”,即名字為“DTCService”的遠(yuǎn)程服務(wù);Proxy的RequestService 方法的最后一個(gè)參數(shù),表示服務(wù)調(diào)用過(guò)程中,服務(wù)端回調(diào)的客戶(hù)端函數(shù),在這個(gè)回調(diào)函數(shù)中,提供了3階段分布式事務(wù)協(xié)議中的各種指令的響應(yīng)處理,包括:

    • CanCommit--詢(xún)問(wèn)本地事務(wù)是否可以提交;
    • PreCommit--預(yù)提交指令;
    • Abort--撤銷(xiāo)事務(wù)的指令;
    • DoCommit--提交事務(wù)的指令。

    Proxy對(duì)象的RequestService 方法它是一個(gè)異步方法,所以調(diào)用它之后代碼會(huì)立即向下執(zhí)行,因此我們用?TaskCompletionSource 對(duì)象將異步方法的結(jié)果獲取過(guò)程作為一個(gè)任務(wù)來(lái)處理,這樣便可以阻塞異步方法的執(zhí)行并等待執(zhí)行完的結(jié)果,如果這個(gè)過(guò)程中發(fā)生了錯(cuò)誤,就立即回滾事務(wù),即下面的代碼:

    try{tcs.Task.Wait();return tcs.Task.Result;}catch (Exception ex){PrintLog("MSF DTC({0}) Task Error:{1}", transIdentity,ex.Message);TryRollback(dbHelper);}

    在當(dāng)前方法 DistTrans3PCRequest 的第二個(gè)和第三個(gè)參數(shù)中,都使用了 AdoHelper類(lèi)型的參數(shù),它是SOD框架基礎(chǔ)的 數(shù)據(jù)訪問(wèn)幫助類(lèi),它的“事務(wù)計(jì)數(shù)器” (TransactionCount屬性)有助于正確的開(kāi)啟事務(wù),化解嵌套的事務(wù),避免用戶(hù)的?transFunction 方法內(nèi)部開(kāi)啟和提交事務(wù),將事務(wù)的最終提交動(dòng)作交給當(dāng)前分布式事務(wù)控制器。

    ?

    4.2,分布式事務(wù)協(xié)調(diào)服務(wù)

    ?分布式事務(wù)控制器在執(zhí)行本地事務(wù)方法的前后,需要有一個(gè)分布式事務(wù)協(xié)調(diào)服務(wù)來(lái)協(xié)調(diào)它的執(zhí)行過(guò)程,這個(gè)協(xié)調(diào)過(guò)程包括以下功能:

    • (提供給控制器)調(diào)用指定標(biāo)識(shí)的分布式事務(wù),直到事務(wù)執(zhí)行完成;
    • 管理系統(tǒng)的分布式事務(wù)階段,向控制器推送(回調(diào))系統(tǒng)的分布式事務(wù)狀態(tài);
    • 分布式事務(wù)協(xié)調(diào)服務(wù)需要運(yùn)行在獨(dú)立服務(wù)進(jìn)程中,所以它可以協(xié)調(diào)多個(gè)分布式事務(wù)控制器的工作。

    下面是本服務(wù)的具體代碼實(shí)現(xiàn),比較簡(jiǎn)單:

    /// <summary>/// 分布式事務(wù)協(xié)調(diào)器服務(wù),基于3PC過(guò)程。/// </summary>public class DTCService:ServiceBase{private int TransactionResourceCount;private DistTrans3PCState CurrentDTCState;//private static System.Collections.Concurrent.ConcurrentBag<DistTransInfo> DTResourceList = new System.Collections.Concurrent.ConcurrentBag<DistTransInfo>();/// <summary>/// 參加指定標(biāo)識(shí)的分布式事務(wù),直到事務(wù)執(zhí)行完成。一個(gè)分布式事務(wù)包含若干本地事務(wù)/// </summary>/// <param name="identity">標(biāo)識(shí)一個(gè)分布式事務(wù)</param>/// <returns></returns>public bool AttendTransaction(string identity){DistTransInfo info = new DistTransInfo();info.ClientIdentity = base.CurrentContext.Request.ClientIdentity;info.CurrentDTCState = DistTrans3PCState.CanCommit;info.LastStateTime = DateTime.Now;info.TransIdentity = identity;//DTResourceList.Add(info);DateTime dtcStart = DateTime.Now;//獲取一個(gè)當(dāng)前事務(wù)標(biāo)識(shí)的協(xié)調(diào)器線程DTController controller = DTController.CheckStartController(identity);CurrentDTCState = DistTrans3PCState.CanCommit;while (CurrentDTCState != DistTrans3PCState.Completed){//獲取資源服務(wù)器的事務(wù)狀態(tài),資源服務(wù)器可能自身或者因?yàn)榫W(wǎng)絡(luò)情況出錯(cuò)if (!SendDTCState(info, controller, identity))break;}SendDTCState(info, controller, identity);DTController.RemoveController(identity);Console.WriteLine("DTC Current Use time:{0}(s)",DateTime.Now.Subtract(dtcStart).TotalSeconds);return true;}private bool SendDTCState(DistTransInfo info, DTController controller, string identity){string clientIdentity = string.Format("[{0}:{1}-{2}]", base.CurrentContext.Request.ClientIP, base.CurrentContext.Request.ClientPort, base.CurrentContext.Request.ClientIdentity);try{Console.WriteLine("DTC Service Callback {0} Message:{1}", clientIdentity, CurrentDTCState);info.CurrentDTCState = base.CurrentContext.CallBackFunction<DistTrans3PCState, DistTrans3PCState>(CurrentDTCState);info.LastStateTime = DateTime.Now;CurrentDTCState = controller.GetDTCState(info.CurrentDTCState);return true;}catch (Exception ex){Console.WriteLine("DTC Service Callback {0} Error:{1}", clientIdentity, ex.Message);return false;}}public override bool ProcessRequest(IServiceContext context){return base.ProcessRequest(context);}}

    ?在本服務(wù)中,通過(guò)?base.CurrentContext.CallBackFunction 方法回調(diào)分布式控制器,將當(dāng)前階段系統(tǒng)的分布式狀態(tài)告訴控制器。

    5,創(chuàng)建訂單相關(guān)服務(wù)

    5.1,訂單服務(wù)

    訂單服務(wù)方法首先它要實(shí)例化一個(gè)分布式事務(wù)控制器對(duì)象,在控制器對(duì)象里面完成創(chuàng)建訂單的事務(wù)操作,它會(huì)首先調(diào)用商品服務(wù)去更新相應(yīng)的商品庫(kù)存數(shù)并取得相關(guān)的商品信息,然后接著構(gòu)造訂單和訂單明細(xì),具體代碼如下:

    /// <summary>/// 生成訂單的服務(wù)方法/// </summary>/// <param name="orderId">訂單號(hào)</param>/// <param name="userId">用戶(hù)號(hào)</param>/// <param name="buyItems">購(gòu)買(mǎi)的商品簡(jiǎn)要清單</param>/// <returns>訂單是否創(chuàng)建成功</returns>public bool CreateOrder(int orderId,int userId,IEnumerable<BuyProductDto> buyItems){//在分布式事務(wù)的發(fā)起端,需要先定義分布式事務(wù)標(biāo)識(shí):string DT_Identity = System.Guid.NewGuid().ToString();productProxy.RegisterData = DT_Identity;//使用3階段提交的分布式事務(wù),保存訂單到數(shù)據(jù)庫(kù)OrderDbContext context = new OrderDbContext();DTController controller = new DTController(DT_Identity);return controller.DistTrans3PCRequest<bool>(DTS_Proxy, context.CurrentDataBase,db =>{//先請(qǐng)求商品服務(wù),扣減庫(kù)存,并獲取商品的倉(cāng)庫(kù)信息ServiceRequest request = new ServiceRequest();request.ServiceName = "ProductService";request.MethodName = "UpdateProductOnhand";request.Parameters = new object[] { DT_Identity, buyItems };List<SellProductDto> sellProducts = productProxy.RequestServiceAsync<List<SellProductDto>>(request).Result;#region 構(gòu)造訂單明細(xì)和訂單對(duì)象// productProxy.Connect();List<OrderItemEntity> orderItems = new List<OrderItemEntity>();OrderEntity order = new OrderEntity(){ID = orderId,OwnerID = userId,OrderTime = DateTime.Now,OrderName = "Prudoct:"};foreach (BuyProductDto item in buyItems){//注意:在商品數(shù)據(jù)庫(kù)上,前面更新商品,但還沒(méi)有提交事務(wù),下面這個(gè)查詢(xún)直接使用的話(huà)會(huì)導(dǎo)致查詢(xún)等待,因?yàn)镾QLSERVER的事務(wù)隔離級(jí)別是這樣的//所以 GetProductInfo 的實(shí)現(xiàn)需要注意。//ProductDto product = this.GetProductInfo(item.ProductId).Result;ProductDto product = this.GetProductInfoSync(item.ProductId);OrderItemEntity temp = new OrderItemEntity(){OrderID = orderId,ProductID = product.ID,BuyNumber = item.BuyNumber,OnePrice = product.Price,ProductName = product.ProductName};temp.StoreHouse = (from i in sellProducts where i.ProductId == temp.ProductID select i.StoreHouse).FirstOrDefault();orderItems.Add(temp);order.OrderName += "," + temp.ProductName;order.AmountPrice += temp.OnePrice * temp.BuyNumber;}////關(guān)閉商品服務(wù)訂閱者連接 productProxy.Close();#endregion//保存訂單數(shù)據(jù)到數(shù)據(jù)庫(kù)context.Add<OrderEntity>(order);context.AddList<OrderItemEntity>(orderItems);return true;});}

    注意在上面的方法中,我們創(chuàng)建訂單的代碼并沒(méi)有直接提交或者回滾事務(wù),而是通過(guò)控制器的 DistTrans3PCRequest 方法傳入了一個(gè)AdoHelper對(duì)象,由控制器來(lái)決定提交或者回滾事務(wù)。 其它相關(guān)代碼請(qǐng)看Github上的源碼。

    5.2,商品服務(wù)

    商品服務(wù)比較簡(jiǎn)單,這里只列出訂單服務(wù)需要直接調(diào)用的 UpdateProductOnhand方法,具體代碼如下:

    public class ProductService:ServiceBase {//其它代碼略/// <summary>/// 更新商品庫(kù)存,并返回商品售賣(mài)簡(jiǎn)要信息/// </summary>/// <param name="transIdentity">分布式事務(wù)標(biāo)識(shí)</param>/// <param name="buyItems">購(gòu)買(mǎi)的商品精簡(jiǎn)信息</param>/// <returns></returns>public List<SellProductDto> UpdateProductOnhand(string transIdentity, IEnumerable<BuyProductDto> buyItems){ProductDbContext context = new ProductDbContext();DTController controller = new DTController(transIdentity);return controller.DistTrans3PCRequest<List<SellProductDto>>(DTS_Proxy,context.CurrentDataBase,c =>{return InnerUpdateProductOnhand(context,buyItems);});} }

    可以看到,商品服務(wù)的更新商品庫(kù)存數(shù)的方法內(nèi)部也實(shí)例化了一個(gè)分布式事務(wù)控制器對(duì)象,然后在它里面執(zhí)行具體的本地事務(wù)操作。其它具體代碼略。

    需要注意的是,訂單服務(wù)在事務(wù)執(zhí)行過(guò)程中,多次調(diào)用了商品服務(wù)的其它方法,這些方法會(huì)操作數(shù)據(jù)庫(kù),如果這些商品服務(wù)操作的表正好是更新商品庫(kù)存的方法使用的表,此時(shí)如果兩個(gè)方法操作的數(shù)據(jù)庫(kù)連接不是同一個(gè)事務(wù)的連接,那么會(huì)導(dǎo)致死鎖。所以商品服務(wù)需要設(shè)置會(huì)話(huà)狀態(tài)來(lái)正確存儲(chǔ)和訪問(wèn)連接對(duì)象,如下代碼:

    public class ProductService:ServiceBase {//其它代碼略private List<SellProductDto> InnerUpdateProductOnhand(ProductDbContext context, IEnumerable<BuyProductDto> buyItems){List<SellProductDto> result = new List<SellProductDto>();foreach (BuyProductDto item in buyItems){ProductEntity entity = new ProductEntity(){ID = item.ProductId,Onhand= item.BuyNumber};OQL q = OQL.From(entity).UpdateSelf('-', entity.Onhand).Where(cmp => cmp.EqualValue(entity.ID) & cmp.Comparer(entity.Onhand, ">=", item.BuyNumber)).END;int count = context.ProductQuery.ExecuteOql(q);SellProductDto sell = new SellProductDto();sell.BuyNumber = item.BuyNumber;sell.ProductId = item.ProductId;//修改庫(kù)存成功,才能得到發(fā)貨地if (count > 0)sell.StoreHouse = this.GetStoreHouse(item.ProductId);result.Add(sell);}base.CurrentContext.Session.Set<ProductDbContext>("DbContext", context);Console.WriteLine("----------1,-Session ID:{0}----------", base.CurrentContext.Session.SessionID);return result;}public override bool ProcessRequest(IServiceContext context){context.SessionRequired = true;//客戶(hù)端(訂單服務(wù))將使用事務(wù)標(biāo)識(shí)作為連接的 RegisterData,因此采用這種會(huì)話(huà)模式context.SessionModel = SessionModel.RegisterData;return base.ProcessRequest(context);} }

    ?

    5.3,客戶(hù)端下單

    前面我們討論了分布式事務(wù)控制器,分布式事務(wù)協(xié)調(diào)服務(wù),訂單服務(wù)和商品服務(wù)的具體實(shí)現(xiàn),現(xiàn)在,我們終于可以看看客戶(hù)端如何調(diào)用訂單服務(wù)來(lái)創(chuàng)建一個(gè)訂單了,請(qǐng)看代碼:

    private static void TestCreateOrder(Proxy client){List<BuyProductDto> buyProducts = new List<BuyProductDto>();buyProducts.Add(new BuyProductDto() { ProductId=1, BuyNumber=3});buyProducts.Add(new BuyProductDto() { ProductId =2, BuyNumber = 1 });int orderId = 2000;int userId = 100;ServiceRequest request = new ServiceRequest();request.ServiceName = "OrderService";request.MethodName = "CreateOrder";request.Parameters = new object[] { orderId,userId, buyProducts };bool result=client.RequestServiceAsync<bool>(request).Result;if(result)Console.WriteLine("創(chuàng)建訂單成功,訂單號(hào):{0}",orderId);elseConsole.WriteLine("創(chuàng)建訂單失敗,訂單號(hào):{0}", orderId);}

    上面的方法構(gòu)造了一個(gè)準(zhǔn)備購(gòu)買(mǎi)的商品清單,這就是電商“購(gòu)物車(chē)”的簡(jiǎn)化版本,另外為了簡(jiǎn)便起見(jiàn),我們直接設(shè)定了一個(gè)訂單號(hào)和用戶(hù)號(hào),用這種方式來(lái)調(diào)用創(chuàng)建訂單的功能。

    由于我們的訂單號(hào)固定的,所以我們的測(cè)試程序第一次會(huì)創(chuàng)建成功訂單,而第二次就會(huì)失敗,正好可以用它來(lái)觀察系統(tǒng)的執(zhí)行情況。

    6,創(chuàng)建訂單的分布式事務(wù)測(cè)試

    6.1,測(cè)試環(huán)境簡(jiǎn)介:

    為了簡(jiǎn)化測(cè)試環(huán)境,所有服務(wù)實(shí)例都運(yùn)行在一臺(tái)PC機(jī)器上,包括數(shù)據(jù)。測(cè)試機(jī)器的性能如下:

    • CPU:Inter i7-4790 4.00GHz;
    • 內(nèi)存:16GB,可用內(nèi)存:8.7GB
    • 測(cè)試開(kāi)發(fā)環(huán)境:VS2017 社區(qū)版
    • 數(shù)據(jù)庫(kù):SqlServer 2008 R2

    打開(kāi)VS開(kāi)發(fā)環(huán)境,按F5以調(diào)試模式編譯運(yùn)行,設(shè)置多啟動(dòng)項(xiàng)目:

    • DistTransClient
    • TistTransApp

    測(cè)試項(xiàng)目 TistTransApp下面的配置文件 PdfNetEF.MessageServiceHost.exe.config ?? 配置內(nèi)容如下:

    <?xml version="1.0" encoding="utf-8"?> <configuration><appSettings><add key="IOCConfigFile" value=".\IOCConfig.xml" /><add key="ServerIP" value="127.0.0.1" /><add key="ServerPort" value="12345" /><add key="ProductUri" value="net.tcp://127.0.0.1:12306"/><add key="OrderUri" value="net.tcp://127.0.0.1:12308"/><!--MSF_DTS_Uri 分布式事務(wù)控制器服務(wù)連接地址--><add key="MSF_DTS_Uri" value="net.tcp://127.0.0.1:12345"/><!-- 全局緩存配置GlobalCacheProvider="CacheServer" 將使用分布式的緩存服務(wù)器,這時(shí)候需要配置 CacheConfigFile,其它值將使用本地的緩存CacheConfigFile :緩存服務(wù)器的地址的配置文件,也就是本 ServiceHost 運(yùn)行的另外一些實(shí)例--><add key="GlobalCacheProvider" value="" /><add key="CacheConfigFile" value="CacheServerCfg.xml" /><!-- 全局緩存配置結(jié)束 --><!--PDF.NET SQL 日志記錄配置(for 4.0)開(kāi)始記錄執(zhí)行的SQL語(yǔ)句,關(guān)閉此功能請(qǐng)將SaveCommandLog 設(shè)置為False,或者設(shè)置DataLogFile 為空;如果DataLogFile 的路徑中包括~符號(hào),表示SQL日志路徑為當(dāng)前Web應(yīng)用程序的根目錄;如果DataLogFile 不為空且為有效的路徑,當(dāng)系統(tǒng)執(zhí)行SQL出現(xiàn)了錯(cuò)誤,即使SaveCommandLog 設(shè)置為False,會(huì)且僅僅記錄出錯(cuò)的這些SQL語(yǔ)句;如果DataLogFile 不為空且為有效的路徑,且SaveCommandLog 設(shè)置為T(mén)rue,則會(huì)記錄所有的SQL查詢(xún)。在正式生產(chǎn)環(huán)境中,如果不需要調(diào)試系統(tǒng),請(qǐng)將SaveCommandLog 設(shè)置為False 。--><add key="SaveCommandLog" value="False" /><add key="DataLogFile" value=".\SqlLog.txt" /><!--LogExecutedTime 需要記錄的時(shí)間,如果該值等于0會(huì)記錄所有查詢(xún),否則只記錄大于該時(shí)間的查詢(xún)。單位毫秒。--><add key="LogExecutedTime" value="0" /><!--PDF.NET SQL 日志記錄配置 結(jié)束--><add key="ClientSettingsProvider.ServiceUri" value="" /></appSettings><connectionStrings><!--SOD for SQL Server ,框架會(huì)自動(dòng)創(chuàng)建需要的庫(kù) --><add name="OrdersDb" connectionString="Data Source=.;Initial Catalog=OrdersDb;Integrated Security=True" providerName="SqlServer"/><add name="ProductsDb" connectionString="Data Source=.;Initial Catalog=ProductsDb;Integrated Security=True" providerName="SqlServer"/><!-- SOD for SQL Server LocalDB 注意:請(qǐng)將下面的連接字符串,修改為你VS 里面打開(kāi)的數(shù)據(jù)庫(kù)文件的連接字符串 <add name="OrdersDb" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=~\DataBase\OrdersDB_data.mdf;Integrated Security=True;Connect Timeout=30" providerName="SqlServer"/><add name="ProductsDb" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=~\DataBase\ProductsDB_data.mdf;Integrated Security=True;Connect Timeout=30" providerName="SqlServer"/>--><!-- MSSQLLocalDB 連接示例<add name="OrdersDb" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=E:\Git\MSF-DistTransExample\Host\DataBase\OrdersDB_data.mdf;Integrated Security=True;Connect Timeout=30" providerName="SqlServer"/><add name="ProductsDb" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=E:\Git\MSF-DistTransExample\Host\DataBase\ProductsDB_data.mdf;Integrated Security=True;Connect Timeout=30" providerName="SqlServer"/>--><!-- SOD for Access 2007 ,2013,2016<add name="OrdersDb" connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=~\DataBase\OrdersDb.accdb;Persist Security Info=False;" providerName="Access"/><add name="ProductsDb" connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=~\DataBase\Products.accdb;Persist Security Info=False;" providerName="Access"/>--><!-- SOD for Access 2000,2003<add name="OrdersDb" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=~\DataBase\OrdersDb.mdb;Persist Security Info=False;" providerName="Access"/><add name="ProductsDb" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=~\DataBase\Products.mdb;Persist Security Info=False;" providerName="Access"/>--><!-- SOD for SQLite <add name="OrdersDb" connectionString="Data Source=DataBase\OrdersDb.db;" providerName="PWMIS.DataProvider.Data.SQLite,PWMIS.SQLiteClient"/><add name="ProductsDb" connectionString="Data Source=DataBase\Products.db;" providerName="PWMIS.DataProvider.Data.SQLite,PWMIS.SQLiteClient"/>--></connectionStrings><startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" /></startup><system.web><membership defaultProvider="ClientAuthenticationMembershipProvider"><providers><add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" /></providers></membership><roleManager defaultProvider="ClientRoleProvider" enabled="true"><providers><add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" /></providers></roleManager></system.web> </configuration> View Code

    配置文件中配置了多種數(shù)據(jù)庫(kù)連接方式,根據(jù)你的情況具體選擇。當(dāng)前是SqlServer.

    然后,按照下圖輸入相關(guān)的信息:

    由于我現(xiàn)在的測(cè)試環(huán)境是SQLSERVER數(shù)據(jù)庫(kù),所以不需要初始化數(shù)據(jù)庫(kù)。選擇啟動(dòng)事務(wù)協(xié)調(diào)器,測(cè)試程序會(huì)幫我們啟動(dòng) 協(xié)調(diào)器服務(wù)宿主進(jìn)程,商品服務(wù)宿主進(jìn)程和訂單服務(wù)宿主進(jìn)程。之后,我們?cè)诳蛻?hù)端控制臺(tái)輸入 12308,這是訂單服務(wù)的端口號(hào),接著客戶(hù)端就會(huì)調(diào)用訂單服務(wù)準(zhǔn)備創(chuàng)建訂單。

    6.2,測(cè)試結(jié)果

    下面是各種情況下的測(cè)試結(jié)果,分為訂單創(chuàng)建成功和創(chuàng)建失敗兩種情況。注意我們?cè)诜治稣嬲臏y(cè)試數(shù)據(jù)之前,要先跑一次服務(wù)進(jìn)行預(yù)熱,也就是先進(jìn)行一次測(cè)試,取第二次以后的測(cè)試結(jié)果。

    6.2.1,訂單創(chuàng)建成功:

    分布式協(xié)調(diào)服務(wù):

    ?

    [2018-01-31 17:13:45.807]訂閱消息-- From: 127.0.0.1:53276 [2018-01-31 17:13:45.807]正在處理服務(wù)請(qǐng)求--From: 127.0.0.1:53276,Identity:WMI2114256838 >>[PMID:1]Service://DTCService/AttendTransaction/System.String=1b975548-afac-4e7a-be6d-5821bce38ce7 DTC Service Callback [127.0.0.1:53276-WMI2114256838] Message:CanCommit [2018-01-31 17:13:45.853]訂閱消息-- From: 127.0.0.1:53278 [2018-01-31 17:13:45.854]正在處理服務(wù)請(qǐng)求--From: 127.0.0.1:53278,Identity:WMI2114256838 >>[PMID:1]Service://DTCService/AttendTransaction/System.String=1b975548-afac-4e7a-be6d-5821bce38ce7 DTC Service Callback [127.0.0.1:53278-WMI2114256838] Message:CanCommit DTC Service Callback [127.0.0.1:53276-WMI2114256838] Message:PreCommit DTC Service Callback [127.0.0.1:53278-WMI2114256838] Message:PreCommit DTC Service Callback [127.0.0.1:53278-WMI2114256838] Message:DoCommit DTC Service Callback [127.0.0.1:53278-WMI2114256838] Message:Completed DTC Current Use time:0.042516(s) [2018-01-31 17:13:45.897]請(qǐng)求處理完畢(43.0236ms)--To: 127.0.0.1:53278,Identity:WMI2114256838 >>[PMID:1]消息長(zhǎng)度:4字節(jié) ------- result:True Reponse Message OK. DTC Service Callback [127.0.0.1:53276-WMI2114256838] Message:DoCommit [2018-01-31 17:13:45.898]取消訂閱-- From: 127.0.0.1:53278 DTC Service Callback [127.0.0.1:53276-WMI2114256838] Message:Completed DTC Current Use time:0.1009371(s) [2018-01-31 17:13:45.909]請(qǐng)求處理完畢(101.9327ms)--To: 127.0.0.1:53276,Identity:WMI2114256838 >>[PMID:1]消息長(zhǎng)度:4字節(jié) ------- result:True Reponse Message OK. [2018-01-31 17:13:45.912]取消訂閱-- From: 127.0.0.1:53276

    ?

    訂單服務(wù):

    [2018-01-31 17:13:45.798]訂閱消息-- From: 127.0.0.1:53275 [2018-01-31 17:13:45.801]正在處理服務(wù)請(qǐng)求--From: 127.0.0.1:53275,Identity:WMI2114256838 >>[PMID:1]Service://OrderService/CreateOrder/System.Int32=2000&System.Int32=100&System.Collections.Generic.List`1[[DistTransDto.BuyProductDto, DistTransDto, Version%Eqv;1.0.0.0, Culture%Eqv;neutral, PublicKeyToken%Eqv;null]]=[{"ProductId":1,"BuyNumber":3},{"ProductI MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) Resource at 17:13:45.809 receive DTC Controller state:CanCommit [2018-01-31 17:13:45.879]請(qǐng)求處理完畢(77.9367ms)--To: 127.0.0.1:53275,Identity:WMI2114256838 >>[PMID:1]消息長(zhǎng)度:4字節(jié) ------- result:True MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) Resource at 17:13:45.879 receive DTC Controller state:PreCommit MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) 1PC,Child moniter task has started at time:17:13:45.879 Reponse Message OK. [2018-01-31 17:13:45.888]取消訂閱-- From: 127.0.0.1:53275 MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) 2PC,Child moniter task has started at time:17:13:45.888 MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) 1PC,Child moniter task find DistTrans3PCState has changed,Now is ACK_Yes_2PC,task break! MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) Resource at 17:13:45.898 receive DTC Controller state:DoCommit MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) Try Commit.. MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) Try Commit..OK MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) Resource at 17:13:45.903 receive DTC Controller state:Completed MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) 3PC Request Completed,use time:0.1019383 seconds. MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) 2PC,Child moniter task find DistTrans3PCState has changed,Now is Completed,task break! MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) Controller Process Reuslt:True,Receive time:17:13:45.913

    ?

    商品服務(wù):

    [2018-01-31 17:13:45.848]正在處理服務(wù)請(qǐng)求--From: 127.0.0.1:53277,Identity:WMI2114256838 >>[PMID:1]Service://ProductService/UpdateProductOnhand/System.String=1b975548-afac-4e7a-be6d-5821bce38ce7&System.Collections.Generic.List`1[[DistTransDto.BuyProductDto, DistTransDto, Version%Eqv;1.0.0.0, Culture%Eqv;neutral, PublicKeyToken%Eqv;null]]=[{"ProductId":1 MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) Resource at 17:13:45.855 receive DTC Controller state:CanCommit ----------1,-Session ID:1b975548-afac-4e7a-be6d-5821bce38ce7---------- MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) 1PC,Child moniter task has started at time:17:13:45.856 [2018-01-31 17:13:45.856]請(qǐng)求處理完畢(8.011ms)--To: 127.0.0.1:53277,Identity:WMI2114256838 >>[PMID:1]消息長(zhǎng)度:97字節(jié) ------- result:[{"StoreHouse":"廣州","ProductId":1,"BuyNumber":3},{"StoreHouse":"廣州","ProductId":2,"BuyNumber":1}] Reponse Message OK. [2018-01-31 17:13:45.857]取消訂閱-- From: 127.0.0.1:53277 [2018-01-31 17:13:45.858]訂閱消息-- From: 127.0.0.1:53277 [2018-01-31 17:13:45.867]正在處理服務(wù)請(qǐng)求--From: 127.0.0.1:53277,Identity:WMI2114256838 >>[RMID:0]Service://ProductService/GetProductInfo/System.Int32=1 ---------2,--Session ID:1b975548-afac-4e7a-be6d-5821bce38ce7---------- [2018-01-31 17:13:45.868]請(qǐng)求處理完畢(1.0005ms)--To: 127.0.0.1:53277,Identity:WMI2114256838 >>[RMID:0]消息長(zhǎng)度:53字節(jié) ------- result:{"ID":1,"Onhand":88,"Price":10.0,"ProductName":"商品0"} [2018-01-31 17:13:45.869]正在處理服務(wù)請(qǐng)求--From: 127.0.0.1:53277,Identity:WMI2114256838 >>[RMID:0]Service://ProductService/GetProductInfo/System.Int32=2 ---------2,--Session ID:1b975548-afac-4e7a-be6d-5821bce38ce7---------- [2018-01-31 17:13:45.869]請(qǐng)求處理完畢(0.5005ms)--To: 127.0.0.1:53277,Identity:WMI2114256838 >>[RMID:0]消息長(zhǎng)度:53字節(jié) ------- result:{"ID":2,"Onhand":96,"Price":11.0,"ProductName":"商品1"} [2018-01-31 17:13:45.870]取消訂閱-- From: 127.0.0.1:53277 MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) Resource at 17:13:45.888 receive DTC Controller state:PreCommit MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) 2PC,Child moniter task has started at time:17:13:45.889 MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) Resource at 17:13:45.890 receive DTC Controller state:DoCommit MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) Try Commit.. MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) Try Commit..OK MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) Resource at 17:13:45.895 receive DTC Controller state:Completed MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) 3PC Request Completed,use time:0.0470229 seconds. MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) 1PC,Child moniter task find DistTrans3PCState has changed,Now is Completed,task break! MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) Controller Process Reuslt:True,Receive time:17:13:45.900 MSF DTC(1b975548-afac-4e7a-be6d-5821bce38ce7) 2PC,Child moniter task find DistTrans3PCState has changed,Now is Completed,task break!

    ?

    性能總結(jié):

    ?訂單創(chuàng)建成功的情況下,分布式協(xié)調(diào)器服務(wù)總共耗時(shí) 0.042516(s),訂單服務(wù)耗時(shí)0.1019383秒,商品服務(wù)耗時(shí)0.0470229秒。

    總體上,執(zhí)行一個(gè)創(chuàng)建訂單的分布式事務(wù),耗時(shí)在50毫秒以?xún)?nèi)。

    6.2.2,訂單創(chuàng)建失敗:

    分布式協(xié)調(diào)服務(wù):

    [2018-01-31 17:04:11.669]訂閱消息-- From: 127.0.0.1:53201 [2018-01-31 17:04:11.670]正在處理服務(wù)請(qǐng)求--From: 127.0.0.1:53201,Identity:WMI2114256838 >>[PMID:1]Service://DTCService/AttendTransaction/System.String=76d175cc-5d40-4d05-adfb-94158b5c2215 DTC Service Callback [127.0.0.1:53201-WMI2114256838] Message:CanCommit [2018-01-31 17:04:11.679]訂閱消息-- From: 127.0.0.1:53203 [2018-01-31 17:04:11.680]正在處理服務(wù)請(qǐng)求--From: 127.0.0.1:53203,Identity:WMI2114256838 >>[PMID:1]Service://DTCService/AttendTransaction/System.String=76d175cc-5d40-4d05-adfb-94158b5c2215 DTC Service Callback [127.0.0.1:53203-WMI2114256838] Message:CanCommit DTC Service Callback [127.0.0.1:53201-WMI2114256838] Message:Abort DTC Service Callback [127.0.0.1:53201-WMI2114256838] Message:Completed DTC Service Callback [127.0.0.1:53203-WMI2114256838] Message:Abort DTC Current Use time:0.0434914(s) [2018-01-31 17:04:11.715]請(qǐng)求處理完畢(45.0015ms)--To: 127.0.0.1:53201,Identity:WMI2114256838 >>[PMID:1]消息長(zhǎng)度:4字節(jié) ------- result:True Reponse Message OK. DTC Service Callback [127.0.0.1:53203-WMI2114256838] Message:Completed [2018-01-31 17:04:11.717]取消訂閱-- From: 127.0.0.1:53201 DTC Current Use time:0.0400005(s) [2018-01-31 17:04:11.724]請(qǐng)求處理完畢(44.4941ms)--To: 127.0.0.1:53203,Identity:WMI2114256838 >>[PMID:1]消息長(zhǎng)度:4字節(jié) ------- result:True Reponse Message OK. [2018-01-31 17:04:11.731]取消訂閱-- From: 127.0.0.1:53203

    ?

    訂單服務(wù):

    [2018-01-31 17:04:11.662]訂閱消息-- From: 127.0.0.1:53200 [2018-01-31 17:04:11.665]正在處理服務(wù)請(qǐng)求--From: 127.0.0.1:53200,Identity:WMI2114256838 >>[PMID:1]Service://OrderService/CreateOrder/System.Int32=2000&System.Int32=100&System.Collections.Generic.List`1[[DistTransDto.BuyProductDto, DistTransDto, Version%Eqv;1.0.0.0, Culture%Eqv;neutral, PublicKeyToken%Eqv;null]]=[{"ProductId":1,"BuyNumber":3},{"ProductI MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) Resource at 17:04:11.672 receive DTC Controller state:CanCommit PDF.NET AdoHelper Query Error: DataBase ErrorMessage:;違反了 PRIMARY KEY 約束 'PK__Orders__2CE8FBFB7F60ED59'。不能在對(duì)象 'dbo.Orders' 中插入重復(fù)鍵。 語(yǔ)句已終止。 SQL:INSERT INTO [Orders]([OerderID],[OrderName],[AmountPrice],[OwnerID],[OrderTime]) VALUES (@P0,@P1,@P2,@P3,@P4) CommandType:Text Parameters: Parameter["@P0"] = "2000" //DbType=Int32 Parameter["@P1"] = "Prudoct:,商品0,商品1" //DbType=String Parameter["@P2"] = "41" //DbType=Single Parameter["@P3"] = "100" //DbType=Int32 Parameter["@P4"] = "2018-1-31 17:04:11" //DbType=DateTimeMSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) 1PC,Child moniter task has started at time:17:04:11.710 MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) Task Error:發(fā)生一個(gè)或多個(gè)錯(cuò)誤。 MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) Try Rollback.. MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) Resource at 17:04:11.711 receive DTC Controller state:Abort MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) Try Rollback..OK MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) Try Rollback.. [2018-01-31 17:04:11.712]請(qǐng)求處理完畢(46.5004ms)--To: 127.0.0.1:53200,Identity:WMI2114256838 >>[PMID:1]消息長(zhǎng)度:5字節(jié) ------- result:False Reponse Message OK. MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) Try Rollback..OK MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) Resource at 17:04:11.714 receive DTC Controller state:Completed MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) 3PC Request Completed,use time:0.0469998 seconds. [2018-01-31 17:04:11.716]取消訂閱-- From: 127.0.0.1:53200 MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) Controller Process Reuslt:True,Receive time:17:04:11.719 MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) 1PC,Child moniter task find DistTrans3PCState has changed,Now is Completed,task break!

    ?

    商品服務(wù):

    [2018-01-31 17:04:11.674]訂閱消息-- From: 127.0.0.1:53202 [2018-01-31 17:04:11.675]正在處理服務(wù)請(qǐng)求--From: 127.0.0.1:53202,Identity:WMI2114256838 >>[PMID:1]Service://ProductService/UpdateProductOnhand/System.String=76d175cc-5d40-4d05-adfb-94158b5c2215&System.Collections.Generic.List`1[[DistTransDto.BuyProductDto, DistTransDto, Version%Eqv;1.0.0.0, Culture%Eqv;neutral, PublicKeyToken%Eqv;null]]=[{"ProductId":1 MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) Resource at 17:04:11.681 receive DTC Controller state:CanCommit ----------1,-Session ID:76d175cc-5d40-4d05-adfb-94158b5c2215---------- MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) 1PC,Child moniter task has started at time:17:04:11.682 [2018-01-31 17:04:11.682]請(qǐng)求處理完畢(7.5003ms)--To: 127.0.0.1:53202,Identity:WMI2114256838 >>[PMID:1]消息長(zhǎng)度:97字節(jié) ------- result:[{"StoreHouse":"廣州","ProductId":1,"BuyNumber":3},{"StoreHouse":"廣州","ProductId":2,"BuyNumber":1}] Reponse Message OK. [2018-01-31 17:04:11.685]取消訂閱-- From: 127.0.0.1:53202 [2018-01-31 17:04:11.686]訂閱消息-- From: 127.0.0.1:53202 [2018-01-31 17:04:11.687]正在處理服務(wù)請(qǐng)求--From: 127.0.0.1:53202,Identity:WMI2114256838 >>[RMID:0]Service://ProductService/GetProductInfo/System.Int32=1 ---------2,--Session ID:76d175cc-5d40-4d05-adfb-94158b5c2215---------- [2018-01-31 17:04:11.688]請(qǐng)求處理完畢(1.5019ms)--To: 127.0.0.1:53202,Identity:WMI2114256838 >>[RMID:0]消息長(zhǎng)度:53字節(jié) ------- result:{"ID":1,"Onhand":88,"Price":10.0,"ProductName":"商品0"} [2018-01-31 17:04:11.690]正在處理服務(wù)請(qǐng)求--From: 127.0.0.1:53202,Identity:WMI2114256838 >>[RMID:0]Service://ProductService/GetProductInfo/System.Int32=2 ---------2,--Session ID:76d175cc-5d40-4d05-adfb-94158b5c2215---------- [2018-01-31 17:04:11.694]請(qǐng)求處理完畢(4ms)--To: 127.0.0.1:53202,Identity:WMI2114256838 >>[RMID:0]消息長(zhǎng)度:53字節(jié) ------- result:{"ID":2,"Onhand":96,"Price":11.0,"ProductName":"商品1"} [2018-01-31 17:04:11.694]取消訂閱-- From: 127.0.0.1:53202 MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) Resource at 17:04:11.714 receive DTC Controller state:Abort MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) Try Rollback.. MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) Try Rollback..OK MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) Resource at 17:04:11.717 receive DTC Controller state:Completed MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) 3PC Request Completed,use time:0.0410005 seconds. MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) 1PC,Child moniter task find DistTrans3PCState has changed,Now is Completed,task break! MSF DTC(76d175cc-5d40-4d05-adfb-94158b5c2215) Controller Process Reuslt:True,Receive time:17:04:11.731

    ?

    性能總結(jié):

    ?訂單創(chuàng)建成功的情況下,分布式協(xié)調(diào)器服務(wù)總共耗時(shí) 0.0434914(s),訂單服務(wù)耗時(shí)0.0469998秒,商品服務(wù)耗時(shí)0.0410005秒。

    總體上,執(zhí)行一個(gè)創(chuàng)建訂單的分布式事務(wù),耗時(shí)在50毫秒以?xún)?nèi)。

    6.2.3,總體性能總結(jié):

    ?從上面的測(cè)試結(jié)果看到,不論是訂單創(chuàng)建成功提交事務(wù),還是訂單創(chuàng)建失敗回滾事務(wù),總體上事務(wù)執(zhí)行時(shí)間都在50毫秒以?xún)?nèi),多次測(cè)試也沒(méi)用發(fā)現(xiàn)某個(gè)事務(wù)節(jié)點(diǎn)嚴(yán)重等待耗時(shí)的情況。

    7,并發(fā)下單性能測(cè)試

    上面測(cè)試單個(gè)分布式事務(wù)執(zhí)行在50毫秒以?xún)?nèi),那么并發(fā)執(zhí)行性能怎么樣呢?

    可以將客戶(hù)端的代碼稍加改造,如下:

    private static void TestCreateOrder(Proxy client){List<BuyProductDto> buyProducts = new List<BuyProductDto>();buyProducts.Add(new BuyProductDto() { ProductId=1, BuyNumber=3});buyProducts.Add(new BuyProductDto() { ProductId =2, BuyNumber = 1 });int orderId = 7000;int userId = 100;ServiceRequest request = new ServiceRequest();request.ServiceName = "OrderService";request.MethodName = "CreateOrder";request.Parameters = new object[] { orderId,userId, buyProducts };bool result=client.RequestServiceAsync<bool>(request).Result;if(result)Console.WriteLine("創(chuàng)建訂單成功,訂單號(hào):{0}",orderId);elseConsole.WriteLine("創(chuàng)建訂單失敗,訂單號(hào):{0}", orderId);Console.WriteLine("------開(kāi)始并發(fā)下單測(cè)試,按任意鍵繼續(xù)---------");Console.ReadLine();System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();sw.Start();int taskCount = 2;List<Task> tasks = new List<Task>();for (int i = 1; i <= taskCount; i++){Proxy client1 = new Proxy();client1.ServiceBaseUri = client.ServiceBaseUri;ServiceRequest request1 = new ServiceRequest();request1.ServiceName = "OrderService";request1.MethodName = "CreateOrder";request1.Parameters = new object[] { orderId+i, userId, buyProducts };var task = client1.RequestServiceAsync<bool>(request1);tasks.Add(task);Console.WriteLine("添加第 {0}個(gè)任務(wù).",i);}Console.WriteLine("{0} 個(gè)訂單請(qǐng)求任務(wù)創(chuàng)建完成,開(kāi)始等待所有任務(wù)執(zhí)行完成!",taskCount);Task.WaitAll(tasks.ToArray());Console.WriteLine("所有任務(wù)執(zhí)行完成!");sw.Stop();Console.WriteLine("總耗時(shí):{0}(s),TPS:{1}",sw.Elapsed.TotalSeconds,(double)taskCount /sw.Elapsed.TotalSeconds);}

    上面程序中,變量?taskCount 表示要并發(fā)下單的任務(wù)數(shù),TPS表示每秒處理的事務(wù)數(shù),是一個(gè)常用的性能指標(biāo)單位。

    先以2個(gè)并發(fā)下單任務(wù)數(shù)測(cè)試,結(jié)果如下:

    ------開(kāi)始并發(fā)下單測(cè)試,按任意鍵繼續(xù)---------添加第 1個(gè)任務(wù). 添加第 2個(gè)任務(wù). 2 個(gè)訂單請(qǐng)求任務(wù)創(chuàng)建完成,開(kāi)始等待所有任務(wù)執(zhí)行完成! 所有任務(wù)執(zhí)行完成! 總耗時(shí):0.0503977(s),TPS:39.6843506747332

    TPS接近40個(gè),還可以;

    再以3個(gè)并發(fā)任務(wù)數(shù)測(cè)試,結(jié)果如下:

    ------開(kāi)始并發(fā)下單測(cè)試,按任意鍵繼續(xù)---------添加第 1個(gè)任務(wù). 添加第 2個(gè)任務(wù). 添加第 3個(gè)任務(wù). 3 個(gè)訂單請(qǐng)求任務(wù)創(chuàng)建完成,開(kāi)始等待所有任務(wù)執(zhí)行完成! 所有任務(wù)執(zhí)行完成! 總耗時(shí):0.3463996(s),TPS:8.66051808373913

    3個(gè)并發(fā)后,性能下降很快,只有8個(gè)多TPS了。

    直接測(cè)試10個(gè)并發(fā),結(jié)果如下:

    ------開(kāi)始并發(fā)下單測(cè)試,按任意鍵繼續(xù)---------添加第 1個(gè)任務(wù). 添加第 2個(gè)任務(wù). 添加第 3個(gè)任務(wù). 添加第 4個(gè)任務(wù). 添加第 5個(gè)任務(wù). 添加第 6個(gè)任務(wù). 添加第 7個(gè)任務(wù). 添加第 8個(gè)任務(wù). 添加第 9個(gè)任務(wù). 添加第 10個(gè)任務(wù). 10 個(gè)訂單請(qǐng)求任務(wù)創(chuàng)建完成,開(kāi)始等待所有任務(wù)執(zhí)行完成! 所有任務(wù)執(zhí)行完成! 總耗時(shí):8.7288772(s),TPS:1.14562271537054

    到10個(gè)并發(fā)后,TPS下降的很厲害,只有1個(gè)多了。

    一直測(cè)試到50個(gè)并發(fā),TPS也只有1個(gè)多,初步結(jié)論在10個(gè)以上并發(fā)TPS只能有1個(gè)多,看來(lái)在高并發(fā)下,分布式事務(wù)的性能的確不理想。

    不過(guò),本次測(cè)試的電商下單業(yè)務(wù)邏輯稍微有點(diǎn)復(fù)雜,其中構(gòu)造訂單的過(guò)程中需要反復(fù)查詢(xún)幾次商品庫(kù)的信息,而且還有插入訂單明細(xì)的操作,在數(shù)據(jù)庫(kù)并發(fā)訪問(wèn)的時(shí)候很容易引起表鎖,這也是性能下降很明顯的原因。

    ?如果是銀行跨行轉(zhuǎn)賬這樣比較簡(jiǎn)單的例子,可能性能要高些,大家可以自己去做個(gè)測(cè)試。

    8,消息服務(wù)框架的分布式事務(wù)總結(jié)

    消息服務(wù)框架(MSF)成功的實(shí)現(xiàn)了基于3階段提交的分布式事務(wù)協(xié)議,并且事務(wù)執(zhí)行性能在分布式環(huán)境下是可以接受的。

    當(dāng)前實(shí)現(xiàn)過(guò)程中,利用消息服務(wù)框架的長(zhǎng)連接特性,它可以及時(shí)的發(fā)現(xiàn)網(wǎng)絡(luò)異常情況而不會(huì)出現(xiàn)出現(xiàn)“傻等”的問(wèn)題(等到超時(shí)),這可以保證分布式事務(wù)執(zhí)行的可靠性和效率。

    為什么長(zhǎng)連接能夠改善分布式事務(wù)的效率?

    你可以這樣理解,有A,B,C三個(gè)分布式服務(wù),它們需要完成一致性的操作,常規(guī)的做法是用復(fù)雜的分布式事務(wù)框架,但是,如果有一個(gè)M節(jié)點(diǎn),它將 A,B,C連接起來(lái)并且不中斷,調(diào)用它們的服務(wù)是不是像調(diào)用本地方法一個(gè)道理?這樣,只需要在M節(jié)點(diǎn)開(kāi)啟和提交事務(wù),就等于完成了分布式事務(wù)了。

    ?iMSF的分布式事務(wù)基于本地事務(wù)實(shí)現(xiàn)的,充分利用了iMSF的長(zhǎng)連接通信能力,使得分布式事務(wù)就像是本地事務(wù)一樣。

    分布式事務(wù)在高并發(fā)下性能表現(xiàn)不理想,我們?cè)趯?shí)際項(xiàng)目中需要注意這個(gè)問(wèn)題,但這不是iMSF的特例,而是分布式事務(wù)普遍的問(wèn)題。因此,要解決高性能問(wèn)題,不二之選是在系統(tǒng)設(shè)計(jì)的時(shí)候就考慮消息驅(qū)動(dòng)模式,使用Actor并發(fā)模型,iMSF框架支持Actor模型。

    ?

    總結(jié)

    以上是生活随笔為你收集整理的使用“即时消息服务框架”(iMSF)实现分布式事务的三阶段提交协议(电商创建订单的示例)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    久草免费福利在线观看 | 色综合国产 | 国产精品九九九九九 | 日韩成人精品一区二区三区 | 婷婷国产在线观看 | av资源网在线播放 | 在线导航福利 | 日韩大片在线播放 | 在线视频免费观看 | 在线播放 一区 | 免费观看性生交大片3 | 激情小说网站亚洲综合网 | 久久免费一级片 | 日韩电影在线视频 | 国产1区在线观看 | 91精品国产92久久久久 | 亚洲国产精品成人综合 | 国产色视频一区二区三区qq号 | 青青射 | 91精品国产91久久久久福利 | 99精品在线播放 | www.日韩免费| 国精产品满18岁在线 | 丁香视频 | av丁香花| 中文字幕电影在线 | 日本在线观看中文字幕 | 久久精品中文字幕少妇 | 日韩午夜电影 | 国产福利在线不卡 | 亚洲精品在线免费观看视频 | 婷婷丁香花五月天 | 在线a亚洲视频播放在线观看 | 色综合久久久久网 | 综合在线观看色 | 欧美性色综合网站 | av电影av在线 | 国产一区av在线 | 波多野结衣日韩 | 婷婷久久一区 | 午夜精品一二三区 | 亚洲h视频在线 | 日韩在线观看的 | 亚州精品天堂中文字幕 | 日韩资源在线播放 | 在线亚州 | 欧美性色黄 | 伊人干综合 | 超碰九九 | 97干com| 国产福利免费在线观看 | 午夜10000 | 日本精品久久久久影院 | 九九爱免费视频 | 91在线播放国产 | 精品伦理一区二区三区 | 国产精品24小时在线观看 | 91九色精品女同系列 | 中文字幕在线播放日韩 | 国产亚洲精品久久久久久久久久 | 午夜精品视频在线 | 国产乱码精品一区二区三区介绍 | 久久久久在线观看 | 午夜精品一区二区三区可下载 | 亚洲一区二区精品 | 亚洲欧美日韩在线看 | 二区三区在线视频 | 日韩中字在线观看 | 国产欧美精品一区二区三区四区 | 97免费在线观看 | 91精品国自产在线观看 | 色www永久免费 | 天天操天天操天天操 | 成人超碰在线 | 天天爽人人爽 | 中文字幕在线字幕中文 | 婷婷午夜激情 | 亚洲毛片视频 | 91国内在线| 日韩精品一区二区三区免费观看视频 | 亚洲va男人天堂 | 日本三级人妇 | 国产精品国产自产拍高清av | 激情自拍av | 永久免费在线 | 91看片在线播放 | 欧美成人高清 | 国产精品大片在线观看 | 91传媒在线观看 | 久久久精品小视频 | 狠狠色狠狠色 | 亚洲一区欧美精品 | 久久三级视频 | 狠狠色狠狠色综合日日小说 | 国产日韩欧美在线免费观看 | 精品免费视频123区 午夜久久成人 | 久久a视频 | 成人国产精品一区 | 国产午夜精品视频 | 天天躁日日躁狠狠躁av麻豆 | 狠狠色丁香婷婷综合视频 | 91黄色在线视频 | 人人草人人草 | 91爱爱免费观看 | 亚洲精品小视频 | 奇米网777 | 亚欧日韩成人h片 | 亚洲一级免费观看 | 麻豆视频在线免费看 | 欧美日韩精品在线观看视频 | 欧美一区二区三区在线看 | 久久精品久久久久久久 | 国产精品久久久久久超碰 | 国产在线精品一区二区不卡了 | 97精品视频在线播放 | 日本公妇在线观看高清 | 免费在线一区二区 | 亚洲精品国产欧美在线观看 | 免费网站v | 成人av av在线| 久草视频首页 | 国产高清专区 | av在线在线 | 九九免费精品视频 | 免费在线观看av网址 | 久久精品视频免费播放 | 国产精品欧美日韩在线观看 | 日韩精品一区二区在线观看视频 | 国产亚洲精品bv在线观看 | 天天激情站 | 伊人永久 | 亚洲精品国产精品国自产 | 9在线观看免费 | 00av视频 | 国产97色| 在线免费亚洲 | 麻豆国产精品va在线观看不卡 | 天天天天天天天操 | 日韩av视屏在线观看 | 国产成人精品一区二区三区在线观看 | 国产精品久久久久久久久久久久午 | a亚洲视频| 中文资源在线播放 | 91九色在线 | 99精品黄色片免费大全 | 综合黄色网 | 日韩一片| 国产资源在线视频 | 丁香午夜婷婷 | 天天干,天天操,天天射 | 国产精品一码二码三码在线 | 综合网天天射 | av一区二区三区在线 | 欧美成人日韩 | 亚洲激情综合 | 日本久久久久久科技有限公司 | 狠狠躁夜夜a产精品视频 | 久久久国产日韩 | av福利超碰网站 | 日韩av电影网站在线观看 | 特级西西www44高清大胆图片 | 激情伊人五月天 | 成人av日韩 | 黄色成人免费电影 | 久久精品1区 | 97成人免费 | 欧美久久久久久久久久久久 | 黄av免费在线观看 | 久草com| 日韩久久在线 | 久青草视频在线观看 | 91天天操| 日韩一级黄色av | 久久夜色网 | 免费久久片 | 日韩免费在线一区 | 亚洲精品18日本一区app | 91av影视 | www.五月婷婷 | 亚洲成成品网站 | 国产美女主播精品一区二区三区 | 免费在线观看91 | 国产精品久久久久一区 | 婷婷色av| 91爱爱免费观看 | 懂色av懂色av粉嫩av分享吧 | 亚洲 欧洲 国产 精品 | 丰满少妇高潮在线观看 | 精品成人a区在线观看 | 欧美日韩精品免费观看 | 狠狠色丁香婷婷综合久小说久 | 国内亚洲精品 | 91男人影院 | 国产精品一区二区三区免费视频 | 精品一二三四视频 | 久久高视频 | 激情五月在线视频 | 少妇bbbb| 国产精品2020 | 最新日韩视频在线观看 | 久久最新 | 国内视频在线观看 | 91精彩视频在线观看 | 视频在线观看入口黄最新永久免费国产 | 精品v亚洲v欧美v高清v | 狠狠网 | 久久综合影音 | 欧美淫aaa免费观看 日韩激情免费视频 | 国产高清在线不卡 | 欧美日韩在线播放 | 99久久精品免费视频 | 国产成人在线观看 | 久久久国产精品视频 | 免费一级特黄毛大片 | 国产精品毛片一区视频播不卡 | 欧美性色综合网站 | 69精品人人人人 | 日韩av一区在线观看 | 97精品视频在线 | 国产日韩欧美在线免费观看 | 久久五月网 | 美女免费视频网站 | 中文字幕国内精品 | 久久久久 | 免费看黄的 | 五月婷婷电影网 | 波多野结衣在线观看一区 | 开心激情五月婷婷 | 四虎最新域名 | 久久精彩视频 | 日韩精品久久久免费观看夜色 | 成人午夜av电影 | 九九色在线 | 国产精品电影在线 | 色婷婷99 | 国产免费高清视频 | 一区中文字幕在线观看 | 国产精品免费一区二区 | 国产v亚洲v| 狠狠色丁香婷婷综合久小说久 | 免费三级网 | 美女网站在线观看 | 亚洲日本色 | 国产一卡二卡在线 | a级国产乱理论片在线观看 特级毛片在线观看 | 国产乱对白刺激视频不卡 | 久久久久国产成人精品亚洲午夜 | 日本xxxx.com | 91精品国产91久久久久久三级 | 91精品视频免费观看 | 香蕉久草 | 97成人免费视频 | 999视频精品 | 天堂激情网 | 天天在线免费视频 | 中文在线 | 在线视频免费观看 | 黄色网在线免费观看 | 国产麻豆成人传媒免费观看 | 成人av网页 | 91香蕉视频黄 | 亚洲高清视频在线 | 久草爱| 91自拍视频在线 | 免费色网站 | 精品在线观 | 女人高潮一级片 | 亚洲天堂网在线播放 | 欧美精品中文在线免费观看 | 乱男乱女www7788| 干天天 | 久久美女精品 | 一区二区三区免费看 | 日本精品视频在线播放 | 国产中文在线播放 | 国产91全国探花系列在线播放 | 国内精品久久久久久久久久 | 成人aaa毛片 | 久久视| 天天干夜夜想 | 亚洲精品美女久久久 | 国产美女主播精品一区二区三区 | 中文字幕 国产视频 | 日本一区二区不卡高清 | 午夜精品久久久久久久99 | 国产无遮挡猛进猛出免费软件 | 国产乱对白刺激视频不卡 | 久久精品视频中文字幕 | 91免费的视频在线播放 | 免费视频色 | 日韩免费在线看 | 视频三区在线 | 亚洲视频456| 久久老司机精品视频 | 国产高清在线永久 | 黄色片免费看 | 欧美日韩伦理一区 | 亚洲国产片色 | 久久小视频 | 伊人五月综合 | 在线免费中文字幕 | 国产亚洲精品久久久久久移动网络 | 波多野结衣在线播放视频 | 毛片永久新网址首页 | 国产亚洲精品久久 | 欧美大码xxxx | 精精国产xxxx视频在线播放 | 日p视频在线观看 | 欧美99精品 | 亚洲视频999| 国产视频中文字幕在线观看 | 超碰在线观看av.com | 日韩欧美视频免费看 | 国产黄色片一级 | 久久在线免费观看 | 久久精彩免费视频 | 国产资源av | 狠狠干夜夜爽 | 亚洲综合色av| 欧美一级性 | 日本午夜免费福利视频 | 国产精品高 | 青青河边草免费观看完整版高清 | 超级碰碰免费视频 | 亚洲国产小视频在线观看 | 久久久国产精品人人片99精片欧美一 | 色婷婷狠狠五月综合天色拍 | www.人人草| 亚洲国产欧美在线人成大黄瓜 | 韩国一区二区三区视频 | 久久成人麻豆午夜电影 | 日韩av免费在线看 | 美女免费视频观看网站 | 婷婷在线免费 | 丝袜美腿在线视频 | 国产精品18videosex性欧美 | 精品毛片一区二区免费看 | 成人免费视频在线观看 | 天天操天天操天天 | 亚洲午夜久久久久久久久久久 | 久久99精品热在线观看 | 国产a免费 | 奇米影视777影音先锋 | 人人澡超碰碰97碰碰碰软件 | 蜜桃av综合网 | 这里只有精品视频在线 | 免费看在线看www777 | 丁香激情综合久久伊人久久 | 欧美激情综合五月色丁香小说 | 香蕉视频免费在线播放 | 久久免费a | 午夜视频播放 | 在线中文字幕网站 | 久久超级碰 | 97视频人人免费看 | www.超碰97.com | 四虎5151久久欧美毛片 | 手机av在线不卡 | 99热精品国产一区二区在线观看 | 国产精品毛片久久久久久久久久99999999 | 日韩欧美一区二区在线观看 | 成人影音av| 日日夜夜草 | 国产一区二区精品91 | 国产精品中文 | 国产麻豆精品久久一二三 | 天天爱天天射天天干天天 | www久久九 | 日韩毛片久久久 | 99精品久久久久久久 | 91九色蝌蚪视频在线 | 成人av影视观看 | 午夜性生活片 | 一区二区视频免费在线观看 | 日日夜精品 | 国产一区视频在线观看免费 | 亚洲精品免费看 | 国产福利在线免费观看 | 国产在线观看 | 东方av免费在线观看 | 免费看91的网站 | 国产原创av片 | 国产又黄又爽又猛视频日本 | 亚洲欧美经典 | 四虎影视8848dvd| 九九视频这里只有精品 | 成人免费在线视频 | 日本大片免费观看在线 | 国产一级一级国产 | 91手机在线看片 | av片一区二区 | a级片网站 | 成人午夜片av在线看 | 香蕉成人在线视频 | 九九热视频在线免费观看 | 五月婷婷丁香网 | 精品国产aⅴ一区二区三区 在线直播av | 欧美日韩免费观看一区=区三区 | 日韩在线免费视频 | 精品久久免费 | 狠色狠色综合久久 | 色狠狠婷婷 | 手机av电影在线 | 草免费视频 | 色小说av| 欧美久久久一区二区三区 | 亚洲精品国产区 | 在线精品视频在线观看高清 | 亚洲一区精品人人爽人人躁 | 欧美日韩在线观看视频 | 涩涩在线 | 亚洲精品免费播放 | 成人av片免费观看app下载 | 99在线高清视频在线播放 | 极品久久久久 | 黄色软件在线观看 | 久久精品2| 中文字幕av日韩 | 亚洲综合欧美精品电影 | 国产视频综合在线 | 精品在线小视频 | 国产精品嫩草影视久久久 | 4p变态网欧美系列 | 九九热在线免费观看 | 国产精品成人a免费观看 | 国产精品色在线 | 99免费在线视频观看 | 99九九免费视频 | 国产1区2区3区精品美女 | 成人作爱视频 | 国产日产精品一区二区三区四区的观看方式 | 国产精品久久久久久久久婷婷 | 999久久久久 | 久久久免费观看完整版 | 欧美日韩在线视频免费 | 欧洲不卡av | 成人影视片 | 黄色1级大片 | 成人免费看视频 | 性日韩欧美在线视频 | 国产一级大片免费看 | 91av免费看 | 成人午夜电影在线播放 | 日韩有码在线观看视频 | 国内久久久 | 免费视频成人 | 欧美91精品国产自产 | 国产精品一区二区视频 | 中文字幕在线观看一区 | 99久久久国产免费 | 黄色三级免费看 | 免费在线色视频 | 亚州视频在线 | 久久神马影院 | 波多野结衣在线观看一区 | 亚洲精品字幕在线观看 | 亚洲综合成人婷婷小说 | 69精品久久 | 欧美日韩国产欧美 | 91精品国产乱码久久 | 久久久久久久精 | 久久精品1区| 成人av资源 | 亚洲精品在线观看免费 | 又色又爽又激情的59视频 | 欧美另类交人妖 | 精品国产视频一区 | 激情xxxx| 欧美一区二区三区特黄 | 99色网站 | 成人av一区二区在线观看 | 激情欧美一区二区三区 | 91精品国产成人www | 久久国产精品影视 | 亚洲精品视频一二三 | 成人av免费 | 成人av片免费看 | 亚洲电影一区二区 | 国产精品免费观看网站 | 国产三级香港三韩国三级 | 在线电影av| 日韩亚洲在线视频 | 欧美成年人在线视频 | 特级毛片在线免费观看 | 国产伦理久久精品久久久久_ | 国产精品一区二区中文字幕 | 日韩一级成人av | 日韩视频一区二区三区在线播放免费观看 | 91精品对白一区国产伦 | 亚洲理论在线观看 | 在线看免费 | 亚洲视频一区二区三区在线观看 | 国产黄a三级三级 | 在线观看蜜桃视频 | 亚洲午夜久久久影院 | 91视频在线看 | av福利电影 | 西西444www高清大胆 | 婷婷久久精品 | 激情网五月天 | 久久经典国产视频 | 色爽网站| 国模视频一区二区三区 | 91看片淫黄大片一级在线观看 | 成人在线视频论坛 | 91九色视频在线观看 | 国产婷婷久久 | 91在线免费观看网站 | 日韩深夜在线观看 | 日韩a级免费视频 | 国产精品一区二区在线看 | 免费亚洲视频 | 国产亲近乱来精品 | 毛片二区 | 国产精品精品久久久久久 | 成年人在线 | 天天爽人人爽夜夜爽 | 亚洲桃花综合 | 99视| 97爱| 伊人干综合 | 在线观看免费高清视频大全追剧 | 中文字幕精品www乱入免费视频 | 在线中文字幕一区二区 | 欧美电影在线观看 | 久久精品中文字幕免费mv | 在线看片日韩 | 久草在线中文视频 | 91av99| 在线视频观看成人 | 99福利片| 五月天婷婷综合 | 五月婷婷伊人网 | 日本中文字幕网址 | 国产黄色精品在线 | 亚洲h在线播放在线观看h | 午夜久久久久久久久久久 | 日本天天色 | 亚洲午夜av电影 | 欧美91精品久久久久国产性生爱 | 91视频久久久久 | 在线看一区 | 国产偷在线 | 丁香激情综合国产 | 美女国内精品自产拍在线播放 | 久久视频在线看 | 中文字幕精 | 一区二区三区在线免费观看视频 | 亚洲综合成人专区片 | 啪啪资源| 黄色毛片网站在线观看 | 国产午夜精品一区二区三区 | 久久久久久久国产精品视频 | 日韩av三区| 中文字幕在线日 | av理论电影 | 中文字幕国产一区二区 | 成人h在线观看 | 国产精品久久久久久久久久久久 | av高清一区| 国际精品网| 91中文字幕在线视频 | 亚洲伊人av | 中文字幕电影网 | 国产精品久久电影网 | 最新av在线网址 | www.国产在线视频 | bbbb操bbbb| 亚洲精品网站在线 | 色瓜| 99 国产精品| 国模视频一区二区三区 | 精品久久久999 | 九九电影在线 | 香蕉成人在线视频 | 国产精品11 | 国产黄色精品网站 | 亚洲综合射| 日韩欧美电影 | 日韩免费小视频 | 久久99国产精品二区护士 | 黄色一级免费电影 | 九色免费视频 | 91看片成人 | 久久久天堂 | 99这里有精品 | 婷婷久操| 国产99久久久欧美黑人 | 日本在线观看中文字幕 | 免费日韩一区二区三区 | 91精品国产三级a在线观看 | av东方在线 | 日韩一区正在播放 | 免费在线观看日韩欧美 | 色婷婷久久 | 日本韩国中文字幕 | 欧美国产视频在线 | 午夜视频导航 | av片一区| 又黄又网站 | 91香蕉嫩草 | 人人爽人人搞 | 91麻豆文化传媒在线观看 | 免费av在线网站 | 日韩理论片 | av超碰在线 | 91色在线观看视频 | 日韩久久片| 91精品国产自产老师啪 | 欧美日韩后 | 欧美国产日韩一区二区 | 欧美日韩国产页 | 精品久久久久久国产偷窥 | 天天综合网天天 | 99视频播放| 一本—道久久a久久精品蜜桃 | 亚洲91在线| 中文在线免费观看 | 精品久久久久久久久久久院品网 | 免费网站在线观看人 | 国产伦理久久精品久久久久_ | 亚洲少妇久久 | 91九色在线视频 | 国产成人av网站 | 日韩精品一区二区三区电影 | 五月婷婷另类国产 | 四虎www com| 亚洲国产精品成人女人久久 | 国产精品成人av久久 | 日韩欧美国产精品 | 午夜美女网站 | 手机看国产毛片 | 一本一道久久a久久综合蜜桃 | 免费在线观看黄网站 | 国产黄大片在线观看 | 国产一区二区在线播放视频 | 国产精品免费视频一区二区 | 国产在线播放一区二区 | 中文字幕在线不卡国产视频 | 天天干天天看 | 国产精品黄色影片导航在线观看 | 丝袜美女在线 | 久久久高清免费视频 | 超碰个人在线 | 日韩精品视频在线观看免费 | 国产福利中文字幕 | 久草视频中文在线 | 国产一级久久 | 欧美va天堂va视频va在线 | 黄色在线成人 | 四虎www| 欧美极品xxxx | 一区二区电影网 | 在线三级av | 在线观看视频三级 | 日韩大片免费观看 | 特级黄色视频毛片 | 亚洲va天堂va欧美ⅴa在线 | 91视频免费播放 | 精品国产中文字幕 | 国产欧美精品一区二区三区 | 中文字幕在线播放一区二区 | 国产高清中文字幕 | 伊人天堂久久 | 91少妇精拍在线播放 | 精品国产伦一区二区三区观看方式 | 欧美激情第一页xxx 午夜性福利 | 99精品久久久| 国产成人精品亚洲 | 国产精品99视频 | 天天色天天上天天操 | 日日干夜夜草 | 中文字幕91 | 久久久久国产一区二区三区 | 国产黄在线免费观看 | 国产精品美女久久久久aⅴ 干干夜夜 | 九草视频在线观看 | 亚洲精品播放 | 波多野结衣一区三区 | 成年人免费看的视频 | 国产精品欧美久久久久久 | 国产美女在线观看 | 91激情视频在线观看 | 色网站免费在线看 | 久久免费久久 | 久久久久国产一区二区 | 去干成人网 | 中文字幕久久精品亚洲乱码 | 一区二区欧美激情 | 成年人免费在线观看网站 | 中文字幕超清在线免费 | 亚洲第二色 | 三级性生活视频 | 久99久在线 | 91看片在线播放 | 8x成人免费视频 | 欧美 亚洲 另类 激情 另类 | 伊人电影在线观看 | 欧美十八 | 国产一级二级在线播放 | 久久久久久久久久久久久国产精品 | 国产视频一区在线免费观看 | 激情五月网站 | 天堂网在线视频 | 在线成人国产 | 亚洲国产97在线精品一区 | 久久精品二区 | 丝袜制服综合网 | 日韩精品一区二区三区外面 | 亚洲精品一区二区三区新线路 | 天天操天天射天天插 | 久久精品99久久久久久 | 又黄又爽的免费高潮视频 | 国产麻豆视频网站 | 欧美日韩一级久久久久久免费看 | 在线免费91 | 色综合久久综合中文综合网 | 日韩av中文字幕在线免费观看 | 国产精品午夜在线 | 国产一卡二卡四卡国 | www.久久精品视频 | 天天插综合 | av在线短片 | 五月亚洲综合 | 黄色在线看网站 | 97狠狠操 | 热久久影视 | www.超碰 | 久久er99热精品一区二区三区 | 国产精彩视频一区 | 亚洲色图27p | 免费性网站 | 开心丁香婷婷深爱五月 | 精品一区二区久久久久久久网站 | 高潮久久久久久久久 | 国产一区私人高清影院 | 成人资源在线 | a视频在线 | 久久天天躁夜夜躁狠狠85麻豆 | 超碰国产97 | 免费国产ww | 成人在线观看你懂的 | 成人黄色在线视频 | 国产精品久久久一区二区三区网站 | 欧美精品一区二区在线观看 | 91探花在线 | 麻豆视频免费网站 | 玖玖爱免费视频 | 天天色天天射天天操 | 丁香五香天综合情 | 中文字幕在线播放视频 | 中文字幕在线观看视频网站 | 精品国产一区二区三区久久影院 | 亚州五月| 国产综合视频在线观看 | 麻豆国产视频下载 | 欧美一级片免费在线观看 | 日本三级吹潮在线 | 日日爱999| 五月天婷亚洲天综合网鲁鲁鲁 | 婷婷国产v亚洲v欧美久久 | 日韩久久网站 | 2021久久 | 精品一区二区免费在线观看 | 9在线观看免费高清完整版在线观看明 | 综合网av | 国产手机免费视频 | 精品美女在线视频 | 久久夜色网 | 日韩久久精品一区二区 | 亚洲一区免费在线 | 日韩精品 在线视频 | 18做爰免费视频网站 | 日韩精品一区在线观看 | 亚洲一区二区高潮无套美女 | 91久久精品一区二区三区 | 天天综合网~永久入口 | 久久九九国产视频 | 99视频精品 | 久久国产欧美日韩精品 | 久久天堂网站 | 国产精品va在线观看入 | 中文字幕在线视频第一页 | 99精品免费久久久久久久久日本 | 欧美视屏一区二区 | 国产在线不卡 | 免费一级特黄录像 | 97精品国产91久久久久久久 | a在线观看视频 | 欧美日韩在线观看一区二区三区 | 日韩一级精品 | 国产精品专区在线 | 日日干网址 | 国产精品久久久久久久久费观看 | 这里只有精品视频在线 | 欧美色图亚洲图片 | 欧美日韩一级视频 | 麻豆国产网站入口 | 国产在线观看h | 欧美成人在线网站 | 国产毛片久久 | 五月婷婷久久综合 | 少妇bbbb搡bbbb搡bbbb | 一级免费黄视频 | 国产流白浆高潮在线观看 | 成人av电影免费在线播放 | 欧美日本在线观看视频 | 欧美激情第一区 | 黄色av电影一级片 | 欧美韩日在线 | 国产高清在线免费观看 | 欧美 日韩 久久 | 国产小视频在线观看 | 亚洲少妇天堂 | 成年人黄色在线观看 | 欧美日韩在线第一页 | 久久久午夜精品理论片中文字幕 | 超碰在线人 | 欧美日韩网站 | 蜜桃传媒一区二区 | 一区二区三区在线影院 | 色婷婷国产在线 | 99视频在线精品国自产拍免费观看 | 91免费视频网站在线观看 | av一区二区三区在线 | 日韩www在线 | 天天操操操操操操 | 久久婷婷激情 | 伊人www22综合色 | 日韩精品中文字幕在线播放 | 人人超碰人人 | 在线观看国产中文字幕 | 国产经典三级 | 在线观看播放av | 丁香影院在线 | 四虎在线免费观看视频 | 婷婷丁香花 | 成人一区不卡 | 天天艹天天 | 91免费视频黄 | 日韩黄色影院 | 婷婷色中文 | 五月天中文字幕mv在线 | 亚洲午夜精品久久久久久久久久久久 | 欧美人zozo| 涩涩网站在线播放 | 国产精品 中文在线 | 国产精品一区二区在线免费观看 | 午夜精品久久久久久99热明星 | 综合天堂av久久久久久久 | 天天做天天爱夜夜爽 | 超碰激情在线 | 欧美aa一级片| 日韩欧美黄色网址 | va视频在线观看 | 国产精品毛片久久 | 日韩免费不卡视频 | 91精品视频免费观看 | 在线91网| 91久久久久久久一区二区 | 久久综合加勒比 | 免费久久精品视频 | 亚洲综合成人专区片 | 91污在线观看 | 国产一级特黄毛片在线毛片 | 欧美在线观看视频一区二区 | av亚洲产国偷v产偷v自拍小说 | 日韩资源在线 | 美女视频免费一区二区 | 欧美91片| 精品亚洲男同gayvideo网站 | 视频国产在线观看18 | 国产 日韩 欧美 自拍 | 天天操人人干 | 黄色av一区二区三区 | 中文字幕亚洲情99在线 | 国产一级二级av | 婷婷久月 | 在线视频 国产 日韩 | 久久av免费观看 | 久久精品79国产精品 | 欧美一级看片 | 午夜精品久久久久久久久久久久 | 国产精品精品久久久久久 | 国产成人精品女人久久久 | 精品999久久久 | 成人性生交大片免费观看网站 | 天天干天天拍天天操 | 日韩经典一区二区三区 | 亚洲精品在线一区二区三区 | 免费日韩视 | 久久午夜精品视频 | av网站大全免费 | 99久久久久久| 欧美在线观看视频免费 | 亚洲国产精久久久久久久 | 中文字幕乱偷在线 | 国产亚洲久一区二区 | 日韩高清 一区 | 一区二区三区在线视频111 | 综合久久婷婷 | 中文字幕精品一区 | 成人h在线播放 | 国产欧美精品一区aⅴ影院 99视频国产精品免费观看 | 国产成人香蕉 | 亚洲美女视频在线观看 | 久久视频二区 | 成人九九视频 | 成人h动漫精品一区二 | 性色av免费看 | 在线亚洲高清视频 | www在线观看视频 | 91豆花在线 | 97在线免费 | 久草在线在线精品观看 | 国产精品精品国产色婷婷 | 亚洲欧洲成人 | 美女视频免费精品 | 99久久综合国产精品二区 | 亚洲精品国产自产拍在线观看 | 四虎在线观看网址 | 91免费高清观看 | 国产视频日韩视频欧美视频 | 日韩在线视频一区 | 日批视频在线播放 | 欧美日韩久久一区 | 夜夜夜夜猛噜噜噜噜噜初音未来 | 一级性av | 婷婷在线免费视频 | www.五月婷婷 | 成人av资源 | 国产精品久久久久一区二区国产 | 五月天天色 | 超碰在线人人 | 一区二区男女 | 久久人人爽 | 深爱激情五月网 | 国产精品久久久久国产a级 激情综合中文娱乐网 | 91插插视频 | 韩国av免费在线观看 | 中文字幕一区二区三区视频 | 日韩色中色| 精品在线观看国产 | 久久一区二区三区超碰国产精品 | 2019中文最近的2019中文在线 | 中文字幕在线播放av | 中文字幕资源网在线观看 | 日日碰狠狠添天天爽超碰97久久 | 91精品视频观看 | 国产69熟| 99精品免费久久久久久久久 | 天天综合色网 | 天天干天天做天天操 | 久久r精品 | 在线观看免费视频你懂的 | 欧美黄色免费 | 久久高清免费观看 | 国产精品一区在线观看你懂的 | 天天摸日日摸人人看 | 五月激情婷婷丁香 | 九九九九免费视频 | 在线免费视频一区 | 日本黄色免费网站 | 久久久久综合精品福利啪啪 | 日韩欧美视频一区二区三区 | 日韩字幕 | 中文字幕在线观看免费观看 | 日韩91精品| 成人黄大片 | 在线免费视频你懂的 | 五月婷在线播放 | 色片网站在线观看 | 深爱激情av | 欧美日韩一区二区三区在线观看视频 | 99电影456麻豆 | 欧美精品乱码99久久影院 | 色综合久久久久久久久五月 | 欧美吞精 | av在线直接看| 国产精品久久久久久久久岛 | 日韩有码中文字幕在线 | 亚洲天堂精品视频在线观看 | 最新超碰在线 | 高清免费av在线 | 精品女同一区二区三区在线观看 | 麻豆国产视频 | 国产高清专区 | 精品在线一区二区三区 | 国产精品毛片完整版 | 亚洲资源在线观看 | 国产黄色在线 | 最新av网址在线 | 国产手机视频在线 | 国产精品久久久久久久久久久免费 | 一区二区中文字幕在线 | 久久综合欧美精品亚洲一区 | 三级免费黄 | 一区二区三区韩国免费中文网站 |