精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

基于Quqrtz.NET 做的任務調度管理工具

開發 項目管理 后端
國慶前,需求讓我看了一下任務調度的數據表設計。和之前一樣,有100多個字段,p1 ~ p100, 我說這是干嘛啊!按這寫,寫死去了!然后在網上搜了一下開源的任務調度,第一個中意的就是 Quartz.NET,10.1 出來和老領導聚會,老領導說了另外一個東西:Zookeeper, 剛搜了一下,也有.NET的版本。

先入為主,Zookeeper 我就不深入了,整個10.1 在家基本除了看電影就是看 Quartz 了。

Quartz.net 提供了 Remoting 方式,Remoting 我08年的時候,寫過個小程序,讓一臺服務器通知另外一臺服務器去執行一些任務,簡單的應用,除了這些,在沒有深入過了。

看一下結構:

Jobs 下是任務

Listener 沒有寫好,不顯擺了。

QM.Server 是 Quartz 的調度服務

QM.Shell 是一個管理工具

我試想把管理工具放到本地來,即服務在服務器上,管理工具在本地,這樣就方便管理,但是除非本地能找到調度服務所用的所有的DLL,否則就會因為無法加載類型XXX而無法進行下去。

有了這個問題,那么只好管理工具和調度服務放一起了。

即然要把管理工具和服務放一起,那就不必把DLL COPY的到處都是,但是需要做一些特殊處理

下面是生成的目錄結構:

XXXXXX 管理工具目錄,

XXXXXX\Service 調度服務程序集存放在這里

XXXXXX\Service\Jobs 任務程序集存放在這里

要讓管理和調度服務都能找得到 任務程序集,需要改一下 app.config

管理工具的 app.config

 
....

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="Service/Jobs" />
...
 

調度服務的 app.config

...
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="Jobs"/>
...

這樣一來,把新寫好的任務程序集放到 XXXXX\Service\Jobs 下,管理工具和調度服務都可以找得到了。

QM.Server 用到的東西:

Quartz.Net 2.2.4.400

log4net 1.2.10

Common.Logging

Common.Logging.log4net 由于 log4net 選用的是 1.2.10 ,所以這個只能用 2.0 

Topshelf

列出來這些是因為我用 NuGet 搜索安裝的 Common.Logging.log4net ,程序一運行就退出。手動指定為 2.0 的 Common.Logging.log4net 才沒有問題。

調度服務我用的是 SqlCe 4.0 來存任務信息,所以需要安裝 SqlCe 4.0 的驅動, 可以從這里下載:

http://www.microsoft.com/en-us/download/details.aspx?id=17876

如果想指定其它數據庫,可以修改  quartz.config

quartz.jobStore.type = Quartz.Impl.AdoJobStore.JobStoreTX, Quartz 
quartz.jobStore.driverDelegateType = Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz 
quartz.jobStore.dataSource = ds 
quartz.dataSource.ds.connectionString = Data Source=QUARTZ.sdf;Persist Security Info=False; 
quartz.dataSource.ds.provider = SqlServerCe-400

因為管理工具是基于 Quartz REMOTING 的,所以要在 quartz.coonfig 中指定以下配置:

quartz.scheduler.exporter.type = Quartz.Simpl.RemotingSchedulerExporter, Quartz
quartz.scheduler.exporter.port = 5555
quartz.scheduler.exporter.bindName = TestScheduler
quartz.scheduler.exporter.channelType = tcp
quartz.scheduler.exporter.channelName = httpQuartz

這里我指定的端口號是 5555, bindName 是 TestScheduler, 這兩個東西要用在管理工具上。

Listener , Listener 不能通過 Remoting 來管理,因為 Not Support. 我嘗試做一個通UDP來廣播 Listener ,不知道哪里沒有寫好,就是收不到數據。沒有做好,我就不多廢話了。

管理工具用到的東西:

Quartz

Caliburn.Micro 

看到 Caliburn 就知道這個管理工具是用 WPF 寫的了!沒什么講的,上圖看看:

連接界面,主機即調度服務所在的IP

端口和 Scheduler 是上面所講的配置中的 port 和 bindName

觸發器/任務列表,可以用來停止/啟動/編輯/刪除指定的任務。

日歷編輯界面,目前只實現了 HolidayCalendar 的編輯,Holiday 是用來指定任務在哪些日期不執行的。

這個功能 Cron 表達式無法做到,其它的基本都可以由 Cron 來做,所以目前只實現了 HolidayCalendar 的編輯。

這個是日歷列表界面,右邊會跟據不同的日歷類型顯示日歷詳細,只是目前只實現了 HolidayCalendar, 所以右邊只有這一個界面。

任務編輯界面,觸發器類型編輯器目前只實現了 Simple 和 Cron 類型的。

概覽。

源碼下載:

http://files.cnblogs.com/xling/QuartzJobManager.7z

要運行示例,需要運行 QM.Shell\bin\Debug\Service\QM.Server.exe 然后在運行 QM.Shell.exe 。

Quartz.NET 的API還是挺簡單的,還有許多細小功能沒有添加上。

另外還有一個分布式的,還沒有看相關資料,沒有處理。

#p#

界面具體變化如下:

任務參數可視化

如上圖所示, 在管理任務的界面上就可以知道這個任務需哪些參數/類型 及 參數的說明.

實現方式, 在 Job 上添加 特性 :  ParameterTypeAttribute

 
 1 namespace JobA {
 2     [ParameterType(typeof(Parameter))]
 3     public class Job : IJob {
 4 
 5         public static ILog Log = LogManager.GetLogger(typeof(Job));
 6         public void Execute(IJobExecutionContext context) {
 7             var dataMap = context.JobDetail.JobDataMap;
 8             //if (dataMap.ContainsKey("int")) {
 9             //    var pInt = dataMap.GetIntValue("int");
10             //    Console.WriteLine("1 JobA Parameter {0}", pInt);
11             //} else {
12             //    Log.Error("缺少參數 int, 未執行");
13             //    throw new JobExecutionException("缺少參數");
14             //}
15 
16             var p = dataMap.Parse<Parameter>();
17             Console.WriteLine("{0}\t{1}\t{2}\t{3}", p.PDateTime, p.PDecimal, p.PInt, p.PNullableInt);
18 
19 
20             Thread.Sleep(TimeSpan.FromMinutes(3));
21         }
22     }
23 }
 

取參數直接調用 dataMap.Parse<Parameter>() 就行了.

Parse 方法在: QM.Common. DatamapParser 中定義.

相比原始的從 DataMap 中用 key / value 方法取參數, 這種處理方式的好處不言而喻.

但是也有缺點, DataMap 支持任何可序列化的類型,

而用這種方法只支持

string, decimal, long, int, single, double, DateTime, DateTimeOffset, TimeSpan , bool, char 這些類型. (沒有做更深一步的處理, 有興趣的,可以嘗試自己去實現.)

每個任務獨立的應用程序域

試想一下插件式開發, 如果你做的插件需要N個第三方DLL, 而這些DLL并沒有引用到主項目上, 怎么辦呢? 一堆的 FileLoadException, FileNotFoundException 等錯誤, 想想都頭疼.

如果你開發的插件想擁有自己的配置文件, 又該怎么辦呢? 自己實現一個配置文件讀取解析? ini ? xml ? 頭疼吧.

針對上面的問題, 在這里的最佳解決辦法是 : 獨立的應用程序域.

這個要從 IScheduler.JobFactory 說起.

在QM.Server.QMServer 的構造方法中, 指定 Schedule.JobFactory 為 IsolatedJobFactory

IsolatedJobFactory 的定義:

 
 1     public class IsolatedJobFactory : IJobFactory {
 2 
 3         public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) {
 4             return NewJob(bundle.JobDetail.JobType);
 5         }
 6 
 7         private IJob NewJob(Type jobType) {
 8             return new IsolatedJob(jobType);
 9         }
10 
11         public void ReturnJob(IJob job) {
12             IDisposable disposable = job as IDisposable;
13             if (disposable != null) {
14                 disposable.Dispose();
15             }
16         }
17     }
 

從 NewJob 方法上可以看出, 實例出來的 Job 并不是最終要執行的 Job, 而是 IsolatedJob 的實例, 它類似中間人的身份.

IsolatedJob 實現了 IInterruptableJob 接口, 為中斷執行中的任務埋下伏筆.

在 IsolatedJob 的構造方法中, 通過 IsolateDomainLoader 新建一個應用程序域:

IsolatedDomainLoader 的構造函數:

 
 1 public IsolateDomainLoader(string path, string configFileName = "") {
 2     AppDomainSetup setup = new AppDomainSetup();
 3     setup.ApplicationName = "IsolateDomainLoader";
 4     setup.ApplicationBase = path;
 5     setup.DynamicBase = path;
 6     setup.PrivateBinPath = path;
 7     setup.CachePath = setup.ApplicationBase;
 8     setup.ShadowCopyFiles = "true";
 9     setup.ShadowCopyDirectories = setup.ApplicationBase;
10     if (!string.IsNullOrWhiteSpace(configFileName)) {
11         setup.ConfigurationFile = configFileName;
12         setup.ConfigurationFile = Path.Combine(path, configFileName);
13     }
14     this.Domain = AppDomain.CreateDomain("ApplicationLoaderDomain", null, setup);
15 }
 

參數 path 即最終要執行的 job 所在的 dll 的路徑.

configFileName 即獨立的配置文件名稱.

這樣一來, 一個 job 一個文件夾, 文件夾內放置這個 job 相關的DLL和配置文件, 和主程序完全隔離開來.

上面說 IsolatedJob 是個中間人, 這里解釋一下:

1, IsolatedJobFactory 的 NewJob 方法返回的是 IsolatedJob 的實例, 而不是最終要執行的 Job.

2, 在 IsolatedJob 中, 會通過獨立的應用程序域 實例一個最終要執行的 Job 的遠程對象(通過 RemoteObject).

3, 當中間人的 Execute 方法被調用時, 會調用遠程 Job 對象的 Execute 方法.

4, Interrupt 方法同理.

遠程對象續約

因為獨立的應用程序域用到了遠程對象: MarshalByRefObject, 因此涉及到了遠程對象的租約過期及續租的問題.

遠程對象的租約默認為 5 分鐘, 可以重寫 InitializeLifetimeService 方法來修改租約的有效期. 但是一個 Job 不確定要執行多長時間, 修改租約有效期不是很合適, 所以這里是通過續約的方式來處理租約過期的問題.

本人對租約了解不多, 不多嘴.感興趣的話,可參見源碼:

QM.RemoteLoader.RemoteObjectSponsor 類

和 QM.RemoteLoader.IsolateDomainLoader類的 GetObject 方法.

立即中斷正在執行的任務

這個命題是有條件的, 即: 任務必須實現: IInterruptableJob 接口.

一般一個任務要執行很長時間, 如果不給個中斷的接口, 那就只能關閉服務或等任務執行完畢了.

實現了這個接口,在配合 CancellationToken.ThrowIfCancellationRequested 方法就可以中斷當前執行的任務了(別告訴我,你的任務是單線程的).

卸載域

任務執行完成后, 會將關聯的 IsolatedJob對象釋放, 在 IsolatedJob 的 Dispose 方法中,會把IsolateDomainLoader 對象釋放,IsolateDomainLoader 釋放的時候, 會把關聯的子應用程序域卸載.
所以, 如果如果你的任務是多線程的, 請在線程遠行完之前, 進行阻塞.

自定義Job的基類

 目前, 如果自定義的 Job 的基類在第三方DLL中, 而且第三方DLL未引用到QM.Server 項目中, 并且不在 QM.Server\Jobs 目錄下, 會報:

未能加載文件或程序集 XXX 或它的某一個依賴項。系統找不到指定的文件。

 

解決辦法有兩種:

1, 將缺少的DLL放到Jobs 目錄下.

2, 將缺少的DLL添加引用到 QM.Server 中.

注意, 該限制只針對 Job 的基類. 除基類使用外的第三方DLL不需要這樣做, 在JOB上引用就是了.

放上一段不用的, 可終止的 任務示例代碼 給你做參考

  1. [ParameterType(typeof(FetcherParameter))]  
  2.     public class ScheduleFetcherJob : IInterruptableJob, IDisposable {  
  3.  
  4.  
  5.         private CancellationTokenSource CTS = new CancellationTokenSource();  
  6.  
  7.         private long JobID = DateTime.Now.Ticks;  
  8.         public void Execute(IJobExecutionContext context) {  
  9.  
  10.             var par = context.JobDetail.JobDataMap.Parse<FetcherParameter>();  
  11.             this.CTS.Token.Register(() => {  
  12.                 Console.WriteLine("正在嘗試終止當前任務");  
  13.             });  
  14.             this.Execute(par);  
  15.         }  
  16.  
  17.         private string GetUrl(string org, string dest) {  
  18.             return string.Format("http://www.soushipping.com/shipping/{0}/{1}/{2}",  
  19.                 org, dest,  
  20.                 DateTime.Now.ToString("yyyy-MM-dd"));  
  21.         }  
  22.  
  23.         private void Execute(FetcherParameter par) {  
  24.             IFetcher<string> cityFetcher = new OrginCityFetcher();  
  25.             var orgCities = cityFetcher.GetDatasByUrl(cityFetcher.InitUrl);  
  26.             cityFetcher = new DestCityFetcher();  
  27.             var destCities = cityFetcher.GetDatasByUrl(cityFetcher.InitUrl);  
  28.  
  29.             Console.WriteLine("找到 {0} 條始發地, {1} 條目的地", orgCities.Count(), destCities.Count());  
  30.  
  31.             var limitScd = new LimitedConcurrencyLevelTaskScheduler(par.MaxThread);  
  32.  
  33.             var factory = new TaskFactory(limitScd);  
  34.  
  35.             List<Task> tasks = new List<Task>();  
  36.             foreach (var oc in orgCities.ToList()) {  
  37.                 foreach (var dc in destCities.ToList()) {  
  38.                     //注意下面這句的參數 t, 如果帶這個參數,  IsCanceled 永遠都為 false  
  39.                     //var task = Task.Factory.StartNew((t) => {  
  40.                     var task = factory.StartNew(() => {  
  41.                         this.CTS.Token.ThrowIfCancellationRequested();  
  42.  
  43.  
  44.                         var url = this.GetUrl(oc, dc);  
  45.  
  46.                         var fetcher = new ScheduleFetcher(url);  
  47.                         fetcher.PageFetchCompleted += fetcher_PageFetchCompleted;  
  48.                         fetcher.DownloadCompleted += fetcher_DownloadCompleted;  
  49.                         fetcher.Fetch();  
  50.                         fetcher = null;  
  51.                     }, this.CTS.Token)  
  52.                     .ContinueWith(t => {  
  53.                         //var completed = tasks.Where(tt => tt.Status == TaskStatus.RanToCompletion).Count();  
  54.                         //Console.WriteLine("{0}\t已完成:{1}", DateTime.Now.ToString("yyyy/MM/dd"), completed);  
  55.                         var arr = tasks.GroupBy(tt => tt.Status).Select(g => string.Format("{0}:{1}", g.Key, g.Count()));  
  56.                         Console.WriteLine("{0}\t{1}", DateTime.Now.ToString("MM/dd HH:mm:ss"), string.Join("  ", arr));  
  57.                         t.Dispose();  
  58.                     });//  
  59.                     //, TaskContinuationOptions.OnlyOnRanToCompletion)  
  60.                     //.ContinueWith(t => {  
  61.                     //    //Console.WriteLine("正在取消");  
  62.                     //    t.Dispose();  
  63.                     //}, TaskContinuationOptions.OnlyOnCanceled).ContinueWith(t => {  
  64.                     //    Console.WriteLine("發生錯誤");  
  65.                     //    t.Dispose();  
  66.                     //}, TaskContinuationOptions.OnlyOnFaulted);  
  67.  
  68.                     tasks.Add(task);  
  69.                 }  
  70.             }  
  71.  
  72.             try {  
  73.                 Task.WaitAll(tasks.ToArray());  
  74.             } catch (AggregateException ex) {  
  75.                 ex.Handle(er => er is TaskCanceledException);  
  76.             }  
  77.             Console.WriteLine("任務完成");  
  78.         }  
  79.  
  80.         #region  
  81.         //private void Execute2(FetcherParameter par) {  
  82.         //    IFetcher<string> cityFetcher = new OrginCityFetcher();  
  83.         //    var orgCities = cityFetcher.GetDatasByUrl(cityFetcher.InitUrl);  
  84.         //    cityFetcher = new DestCityFetcher();  
  85.         //    var destCities = cityFetcher.GetDatasByUrl(cityFetcher.InitUrl);  
  86.  
  87.         //    Console.WriteLine("找到 {0} 條始發地, {1} 條目的地", orgCities.Count(), destCities.Count());  
  88.  
  89.         //    var urls = orgCities.SelectMany(o => destCities.Select(d => this.GetUrl(o, d)));  
  90.  
  91.         //    var opts = new ParallelOptions() {  
  92.         //        MaxDegreeOfParallelism = par.MaxThread  
  93.         //    };  
  94.  
  95.         //    var total = urls.Count();  
  96.         //    object lockObj = new object();  
  97.  
  98.         //    //int sum = 0;  
  99.         //    Parallel.ForEach(urls, opts,  
  100.         //        (url) => {  
  101.         //            var fetcher = new ScheduleFetcher(url);  
  102.         //            fetcher.PageFetchCompleted += fetcher_PageFetchCompleted;  
  103.         //            fetcher.DownloadCompleted += fetcher_DownloadCompleted;  
  104.         //            fetcher.Fetch();  
  105.         //            fetcher = null;  
  106.  
  107.         //            lock (lockObj) {  
  108.         //                total--;  
  109.         //                Console.WriteLine(total);  
  110.         //            }  
  111.         //        }  
  112.         //        );  
  113.  
  114.         //}  
  115.         #endregion  
  116.  
  117.         private void fetcher_DownloadCompleted(object sender, DownloadArgs e) {  
  118.             if (e.ExceptionStatus.HasValue) {  
  119.                 Console.WriteLine("{0}\t請求地址: {1} 時,發生異常 {2}, 請檢查網絡環境.", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), e.Url, e.ExceptionStatus);  
  120.             }  
  121.         }  
  122.  
  123.  
  124.         private List<DIRTY_SCHEDULE> Datas = new List<DIRTY_SCHEDULE>();  
  125.         private object lockObj = new object();  
  126.  
  127.         void fetcher_PageFetchCompleted(object sender, FetchArgs<DIRTY_SCHEDULE> e) {  
  128.             var datas = e.Datas.Distinct(d => d.UNQTAG);  
  129.  
  130.             lock (lockObj) {  
  131.                 this.Datas.AddRange(datas);  
  132.                 if (this.Datas.Count > 100) {  
  133.                     var tmp = new DIRTY_SCHEDULE[this.Datas.Count];  
  134.                     this.Datas.CopyTo(tmp);  
  135.                     this.Datas = new List<DIRTY_SCHEDULE>();  
  136.                     //不是放入線程池, 而是立即執行的線程  
  137.                     var tr = new Thread(new ParameterizedThreadStart(this.SaveDatas));  
  138.                     tr.Start(tmp);  
  139.                 }  
  140.             }  
  141.         }  
  142.  
  143.         private void SaveDatas(object state) {  
  144.             IEnumerable<DIRTY_SCHEDULE> datas = (IEnumerable<DIRTY_SCHEDULE>)state;  
  145.             var biz = new Biz.DirtyScheduleBiz();  
  146.             biz.SaveDirtySchedule(datas, this.JobID);  
  147.         }  
  148.  
  149.         public void Interrupt() {  
  150.             this.CTS.Cancel();  
  151.         }  
  152.  
  153.         ~ScheduleFetcherJob() {  
  154.             Dispose(false);  
  155.         }  
  156.  
  157.         public void Dispose() {  
  158.             this.Dispose(true);  
  159.             GC.SuppressFinalize(this);  
  160.         }  
  161.  
  162.         protected virtual void Dispose(bool disposing) {  
  163.             if (disposing) {  
  164.                 if (this.CTS != null)  
  165.                     this.CTS.Dispose();  
  166.  
  167.                 Console.WriteLine("Job Disposed");  
  168.             }  
  169.         }  
  170.     } 

最后, 源碼下載

https://github.com/gruan01/QM

 

謝謝圍觀, 新年快樂!

----------------------------

題外: 大年初二, 我手一抖, 把斷斷續續寫了快一年的東西給誤刪了!誤刪了啊!

用 360 的數據恢復功能, 沒錯, 是 360, 找出的文件, 我哭了, 數據庫(SQLCE) 恢復出來的文件損壞, 用SQLCE的修復工具修復, 是個空庫! 也就是說, 恢復出來的文件就是個屁!跟本就沒有恢復出來!

EXCEL 文件也一樣, 打不開!

更糟糕的是, 我沒有驗證, 恢復之后就直接蓋到原來的位置上了!

淚奔啊, 大過年的, 我就忙著干這個去了!

責任編輯:林師授 來源: xling的博客
相關推薦

2009-08-03 16:30:46

ITIL運維管理廣通信達科技

2018-07-17 09:00:00

初創企業任務管理工具nTask

2011-08-12 10:38:09

MongoDB

2019-08-30 08:00:00

WebminWebLinux

2023-03-07 14:21:57

2010-05-25 18:36:54

MySQL管理工具

2011-04-13 16:21:22

SQL Server管理

2009-04-24 21:13:45

服務器虛擬化Vmware

2012-12-06 11:31:40

虛擬化

2020-10-30 11:18:47

網絡技術工具

2020-09-30 14:05:22

網絡管理

2012-04-09 09:43:49

云計算云管理

2010-11-08 09:27:21

SQL Server管

2011-06-23 14:34:38

MySQL

2013-07-17 09:54:17

2013-07-15 15:00:26

項目管理工具

2022-08-03 08:02:46

PDM工具Python

2022-05-06 12:04:24

Ansible管理工具

2014-03-28 11:15:42

phpmyadminMySQL管理

2021-03-04 12:55:01

systemd進程管理工具Linux
點贊
收藏

51CTO技術棧公眾號

日韩精品视频网址| 国产精品入口福利| 超碰97在线资源站| 欧美成人ⅴideosxxxxx| 国产欧美日韩激情| 成人字幕网zmw| 国产精品18p| 日韩成人综合| 欧美精品一区在线观看| 无码人妻丰满熟妇区五十路百度| 77777影视视频在线观看| 国产精品一级片| 欧美在线中文字幕| 久草视频手机在线| 综合亚洲自拍| 欧美一级高清大全免费观看| 日韩中文字幕三区| 国产在线高清视频| 久久久精品综合| 91久色国产| 丰满人妻一区二区三区四区| 激情欧美一区| zzijzzij亚洲日本成熟少妇| 男女一区二区三区| 亚洲日本中文| 色8久久人人97超碰香蕉987| 国产青草视频在线观看| www视频在线观看免费| 成人av在线资源网| 国产综合久久久久| 在线免费观看国产精品| 国产精品分类| 久久精品国产欧美亚洲人人爽 | 久久99精品久久久久久国产越南| 国语自产在线不卡| 玖玖爱免费视频| 日韩中字在线| 国产一区二区久久精品| 久久久久成人精品无码中文字幕| 国产精品777777在线播放| 91福利在线观看| 青青草成人免费在线视频| 巨大荫蒂视频欧美另类大| 国产日产欧美一区| 欧美区高清在线| 欧美一级淫片aaaaaa| 国产精品自在在线| 91牛牛免费视频| 亚洲一区二区三区在线视频| 成人黄色在线视频| 日日狠狠久久偷偷综合色| 亚洲欧美一区二区三区孕妇| 婷婷亚洲婷婷综合色香五月| 欧美日韩激情视频一区二区三区| 国产成人精品www牛牛影视| 成人网址在线观看| 一级黄色大毛片| 日韩av不卡在线观看| 日本久久久a级免费| 久久一区二区三区视频| 国产精品美女久久久浪潮软件| 久久久在线观看| 黄网站免费在线| 亚洲精品美女| 2023亚洲男人天堂| 亚洲黄色免费观看| 久久亚洲视频| 国产精品久久久久久久久久尿 | 中文字幕色网站| 国产免费av国片精品草莓男男| 制服丝袜激情欧洲亚洲| 激情久久综合网| 欧美激情精品| 337p日本欧洲亚洲大胆色噜噜| 成人免费看片载| 欧美影院天天5g天天爽| 亚洲精品视频在线观看视频| 这里只有久久精品| 色婷婷色综合| 久久综合九色九九| 精品人妻在线播放| 亚洲一区欧美二区| 国产精品狼人色视频一区| 亚洲一卡二卡在线观看| 国产很黄免费观看久久| 国内一区二区三区在线视频| 精品成人一区二区三区免费视频| 欧美经典一区二区| 在线观看17c| 日韩av影片| 欧美日韩国产区一| 69xxx免费视频| 最新亚洲精品| 久久久国产精品视频| 国产一级在线视频| 三级影片在线观看欧美日韩一区二区| 国产精品海角社区在线观看| 国产精品午夜福利| 99久久综合狠狠综合久久| 日产精品高清视频免费| 中文在线观看免费| 日韩欧美在线播放| 免费高清视频在线观看| 欧美一级二级三级视频| 亚洲天堂免费在线| 黄色一级视频免费观看| 首页亚洲欧美制服丝腿| 91欧美精品午夜性色福利在线 | 巨大黑人极品videos精品| 日韩美女视频一区二区在线观看| 国产黄片一区二区三区| 一区二区三区四区日韩| 日本高清视频精品| 亚洲第一成人av| 国产欧美日韩视频在线观看| 国产成人艳妇aa视频在线| 中文字幕日本一区二区| 亚洲第一在线视频| 卡通动漫亚洲综合| 三级成人在线视频| 国产在线精品一区| 自拍亚洲图区| 欧美日韩一区三区四区| 国产乱了高清露脸对白| 欧美日韩免费观看一区=区三区| 国产精品激情av电影在线观看| 天堂中文资源在线观看| 亚洲欧美一区二区三区极速播放| 99热成人精品热久久66| avtt综合网| 久久久成人精品视频| 中文字幕欧美人妻精品一区蜜臀| 91丨九色丨国产丨porny| 九九久久九九久久| 亚洲国产91视频| 尤物tv国产一区| 亚洲另类在线观看| www.亚洲在线| 97超碰国产精品| 国产美女亚洲精品7777| 久久视频国产精品免费视频在线| 艳妇乳肉豪妇荡乳av无码福利| 久久综合国产精品| 国产免费观看高清视频| 丁香综合av| 欧美多人爱爱视频网站| aaaa一级片| 亚洲伦在线观看| 在线播放黄色av| 国产精品99久久久久久动医院| 国产激情视频一区| 国产三级电影在线观看| 色婷婷激情久久| 国产aⅴ激情无码久久久无码| 一本色道久久综合亚洲精品不卡| 国产精品乱子乱xxxx| 国产精品69xx| 亚洲国产日韩精品在线| 国产网友自拍视频| 99久久伊人精品| 久激情内射婷内射蜜桃| 青青草原在线亚洲| 欧日韩在线观看| 国产在线观看黄| 欧美优质美女网站| 人与动物性xxxx| 国产一区二区免费看| 中国一级黄色录像| 9国产精品午夜| 91成人在线播放| 大胆av不用播放器在线播放| 欧美系列一区二区| www欧美com| 成人性生交大片免费看视频在线| 欧美日韩精品在线一区二区| 欧美女优在线视频| 成人在线一区二区| 韩国成人免费视频| 亚洲人永久免费| 国产又大又黑又粗| 亚洲国产毛片aaaaa无费看| www.日本高清| 奇米色777欧美一区二区| 中文字幕超清在线免费观看| av成人综合| 国产精品99久久久久久人| 欧美成人二区| 亚洲黄页网在线观看| 蜜臀尤物一区二区三区直播| 国产精品久久看| 国产乱淫av麻豆国产免费| 999亚洲国产精| 亚洲午夜精品久久久久久浪潮| 欧美黄视频在线观看| 欧美中文在线字幕| 成人短视频在线| 国产丝袜一区视频在线观看| 伊人影院中文字幕| 婷婷丁香久久五月婷婷| 国产黄色片在线| 成人免费精品视频| 鲁一鲁一鲁一鲁一av| 欧美日韩爆操| 视频在线观看成人| 国产精品成人自拍| 国产日韩在线视频| 中文字幕色婷婷在线视频| 深夜成人在线观看| 丝袜视频国产在线播放| 在线成人av影院| 欧美国产成人精品一区二区三区| ...av二区三区久久精品| 99久久人妻无码中文字幕系列| 捆绑调教一区二区三区| 国产成人无码精品久久久性色| 偷拍欧美精品| 色女孩综合网| 老司机在线精品视频| 成人a在线观看| 欧美一区久久久| 97在线视频国产| av在线官网| 北条麻妃一区二区三区中文字幕| 青青草免费在线视频| 日韩欧美在线1卡| 一卡二卡三卡在线| 色综合一区二区三区| 不卡的免费av| 亚洲美女淫视频| frxxee中国xxx麻豆hd| 国产欧美日韩不卡免费| 欧美丰满少妇人妻精品| 成人免费高清视频在线观看| 一区二区久久精品| 久久精品久久综合| 婷婷丁香激情网| 久久九九电影| 无码aⅴ精品一区二区三区浪潮| 精品成人久久| 免费在线黄网站| 国模吧视频一区| 欧美xxxx吸乳| 中文无码久久精品| 中文字幕日韩一区二区三区不卡| 欧洲视频一区| 亚洲欧美日韩国产成人综合一二三区| 视频一区在线观看| 欧美xxxx黑人又粗又长精品| 色婷婷狠狠五月综合天色拍| 精品伦精品一区二区三区视频| 盗摄牛牛av影视一区二区| 成人自拍网站| 国产精东传媒成人av电影| 高清国产一区| 国产精品香蕉| 久久国产精品-国产精品| 色综合久久中文| 欧美精彩一区二区三区| 奇米色欧美一区二区三区| 欧美精品欧美精品系列c| 色综合中文网| 亚洲欧美成人一区| 2023国产精品久久久精品双| 国产又粗又大又爽的视频| 欧美日本一区| 鲁一鲁一鲁一鲁一色| 久久综合五月| 日韩av在线中文| 国产乱理伦片在线观看夜一区| 亚洲 自拍 另类 欧美 丝袜| 成人精品国产福利| 粉嫩av蜜桃av蜜臀av| 国产农村妇女精品| 亚洲伦理一区二区三区| 一区二区在线观看免费| 国语对白一区二区| 日本韩国欧美三级| 国产一区二区视频免费观看| 日韩精品一区二区三区在线播放| 亚洲 美腿 欧美 偷拍| 国产亚洲欧美日韩精品| 黄色网址在线免费观看| 国语自产精品视频在线看一大j8| 日韩电影免费观看高清完整版| 国产欧美日韩专区发布| av成人综合| 亚洲精品一区二区毛豆| 亚洲一级二级| 日日躁夜夜躁aaaabbbb| 国产很黄免费观看久久| 97伦伦午夜电影理伦片| 亚洲人亚洲人成电影网站色| 天天操中文字幕| 欧美顶级少妇做爰| 久青草国产在线| 欧美噜噜久久久xxx| 欧美成人黑人| 高清国产在线一区| 外国成人免费视频| 女人扒开屁股爽桶30分钟| 国精品**一区二区三区在线蜜桃| 国产精品无码网站| 亚洲精品福利视频网站| 97人妻一区二区精品视频| 日韩免费视频一区二区| 91福利在线视频| 欧美一级淫片播放口| 国产精品免费精品自在线观看| 欧美激情第六页| 黄色精品一区| 国产一级免费大片| 久久久国际精品| 国产性xxxx高清| 制服丝袜亚洲网站| av网站在线免费观看| 91国内揄拍国内精品对白| 亚洲精品tv| 先锋影音一区二区三区| 亚洲永久字幕| 成人午夜精品无码区| 一区2区3区在线看| 国产一区二区在线不卡| 亚洲欧美日韩一区在线| 免费在线国产视频| 91精品国产综合久久久久久蜜臀 | 麻豆精品一区二区综合av| 国产大学生视频| 亚洲精品一二三| 中文字幕有码视频| 亚洲性日韩精品一区二区| 888av在线视频| 人人澡人人澡人人看欧美| 国产精品玖玖玖在线资源| 国产又粗又硬又长| 久久69国产一区二区蜜臀| 成人午夜福利一区二区| 洋洋成人永久网站入口| 国产免费叼嘿网站免费| 在线视频精品一| 成人va天堂| 欧美精品与人动性物交免费看| 国产精品chinese| 亚洲精品乱码久久久久久动漫| 国产人久久人人人人爽| 国产午夜无码视频在线观看| 日韩精品视频在线播放| 性欧美18~19sex高清播放| 精品国产乱码久久久久| 欧美午夜电影在线观看| 丰满少妇xbxb毛片日本| 亚洲精品成a人| 亚洲精品国产精品国| 欧美久久精品一级黑人c片| 日韩经典一区| 亚洲综合网中心| 韩国成人在线视频| 精品国产视频一区二区三区| 日韩欧美综合在线| 日本性爱视频在线观看| 国产日韩欧美一区二区三区四区| 中文乱码免费一区二区三区下载| 少妇愉情理伦片bd| 亚洲va国产天堂va久久en| 欧美一区二区三区成人片在线| 亚州国产精品久久久| 欧美三级自拍| 污污的网站18| 中文字幕一区在线| 国产日韩欧美一区二区东京热| 欧美激情亚洲另类| 精品三级av在线导航| 人妻丰满熟妇av无码区app| 91美女精品福利| 中文字幕精品一区二| 色777狠狠综合秋免鲁丝| 自拍偷自拍亚洲精品被多人伦好爽 | 久久久久久久久久99| 精品成人在线观看| 日韩不卡免费高清视频| 欧洲精品亚洲精品| 极品销魂美女一区二区三区| 欧美做爰爽爽爽爽爽爽| 精品国内片67194| 日本成人伦理电影| 中文字幕成人一区| 国产ts人妖一区二区| 国产午夜性春猛交ⅹxxx| 日韩精品在线视频| 96sao精品免费视频观看| 99国产精品白浆在线观看免费| 91麻豆福利精品推荐| 一区二区三区在线免费观看视频| 色综合久久天天综线观看| 欧美综合自拍| 999热精品视频| 婷婷成人激情在线网| 久久经典视频| 成人永久免费| 日本vs亚洲vs韩国一区三区| 久久久精品一区二区涩爱|