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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

构建自己的简单微服务架构(开源)

發布時間:2023/11/29 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 构建自己的简单微服务架构(开源) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
構建自己的簡單微服務架構(開源) 原文:構建自己的簡單微服務架構(開源)

前言? ? ? ? ? ? ? ?

本篇僅作引導,內容較多,如果閱讀不方便,可以使用電腦打開我們的文檔官網進行閱讀。如下圖所示:

文檔官網地址:https://docs.xin-lai.com/


?

目錄

總體介紹

  • 微服務架構的好處
  • 微服務架構的不足(這個時候就需要用到服務發現)
  • 傳統模式?
  • Ocelot(網關)模式?
  • 集成IdentityService(認證)
  • 集成consul(服務發現)

基于Ocelot搭建一個簡單的微服務架構?

  • Ocelot?
  • 基本集成
  • 添加Ocelot?
  • 添加測試API項目
  • 配置項目的上游請求對象(ocelot.json)?
  • 啟動結果?
    • 聚合API文檔(SwaggerUI)
  • ConfigureServices?
  • Configure
  • appsettings.json?
  • 配置Swagger的上游請求對象(ocelot.json)?
  • 啟動結果?
    • IdentityServer 集成?
  • 添加授權服務項目?
  • 配置appsetting.json?
  • 添加IdentityServerConfig類?
  • 定義API資源?

    定義身份資源

    定義測試客服端?

    • 配置Startup?
  • ConfigureServices?
  • Configure?
  • 啟動結果?
  • 配置ApiGateway網關項目?
  • 調用Ocelot管理API?
  • API方法?
    • Consul(服務發現)
  • 本地部署?
  • 安裝?
  • 添加服務配置?
  • 添加檢查配置?
  • docker部署(騰訊云)?
  • 配置Ocelot 網關?
    • 集成消息隊列——CAP?
  • 簡介?
  • 環境準備?
  • .Net Core 集成 CAP?
  • Cap 發布?

    Cap 訂閱(接收)?

    最后——附上總體代碼?


    ?

    總體介紹

    隨著業務需求的快速發展變化,需求不斷增長,迫切需要一種更加快速高效的軟件交付方式。微服務可以彌補單體應用不足,是一種更加快速高效軟件架構風格。單體應用被分解成多個更小的服務,每個服務有自己的獨立模塊,單獨部署,然后共同組成一個應用程序。把范圍限定到單個獨立業務模塊功能。分布式部署在各臺服務器上。本篇我們將介紹如何使用.NET Core打造自己的微服務架構。

    注意:微服務架構不是萬能藥,本篇僅供參考和探討。對于大部分小項目來說,請不要為了微服務而微服務。畢竟技術不是萬能的,技術是為業務服務的。


    ?

    微服務架構的好處

    • 單個服務很容易開發、理解和維護。
    • 每個服務都可以有專門開發團隊來開發。
    • 每個微服務獨立的部署。
    • 每個服務獨立擴展。

    微服務架構的不足(這個時候就需要用到服務發現)

    • 微服務應用是分布式系統,由此會帶來固有的復雜性。
    • 服務地址目錄,服務健康度,部署困難,服務依賴問題,數據庫分區問題。

    傳統模式

    ?

    Ocelot(網關)模式

    ?

    ?

    集成IdentityService(認證)

    ?

    ?

    集成consul(服務發現)

    ?

    ?

    基于Ocelot搭建一個簡單的微服務架構

    Ocelot

    Ocelot 是一個僅適用于 .Net Core 的網關組件。Ocelot
    中間件使用非常簡單,難的點在于如何去配置。它的功能包括了:路由、請求聚合、服務發現、認證、鑒權、限流熔斷、并內置了負載均衡器等的集成,而這些功能都是通過配置實現。

    Ocelot的開源地址:https://github.com/ThreeMammals/Ocelot

    Ocelot官網地址:https://ocelot.readthedocs.io/en/latest/index.html

    ?

    基本集成

    ?

    ?

    添加Ocelot

    新建一個 .Net core 2.2 web 項目(ApiGateway),添加以下Nuget包:

    • Ocelot
    • Ocelot.Administration?Ocelot支持在運行時通過經過身份驗證的HTTP
      API更改配置。這可以通過兩種方式進行身份驗證:使用Ocelot的內部IdentityServer(僅用于驗證對管理API的請求)或將管理API身份驗證掛鉤到您自己的IdentityServer中。
    • Ocelot.Cache.CacheManager?CacheManager.Net擴展包
    • Ocelot.Provider.Polly?Polly.NET擴展包

    在項目根目錄添加ocelot.json,名字可以自取。

    ?

    ?

    前面說了,所有功能都是通過配置實現的,所以配置也相對復雜。配置有兩個部分。一組ReRoutes和一個GlobalConfiguration。ReRoutes是告訴Ocelot如何處理上游請求的對象。GlobalConfiguration顧名思義是全局配置,具體配置請查看官網。下面列舉簡單配置

    {"GlobalConfiguration": {//外部訪問路徑"BaseUrl": "http://localhost:13000",//限速配置"RateLimitOptions": {//白名單"ClientWhitelist": [],"EnableRateLimiting": true,//限制時間段,例如1s,5m,1h,1d"Period": "1s",//重試等待的時間間隔(秒)"PeriodTimespan": 1,//限制"Limit": 1,//自定義消息"QuotaExceededMessage": "單位時間內請求次數超過限制!","HttpStatusCode": 999},//熔斷配置"QoSOptions": {"ExceptionsAllowedBeforeBreaking": 3,"DurationOfBreak": 5,//超時值(毫秒)"TimeoutValue": 5000}},"ReRoutes": []}

    配置文件初始化好之后,需要在Program.cs
    文件中加載JSON配置,Ocelot支持根據環境變量使用配置文件。

    public class Program{public static void Main(string[] args){CreateWebHostBuilder(args).Build().Run();}public static IWebHostBuilder CreateWebHostBuilder(string[] args) => new WebHostBuilder().UseKestrel((context, opt) =>{opt.AddServerHeader = false;從配置文件讀取配置//opt.Configure(context.Configuration.GetSection("Kestrel"));}).UseContentRoot(Directory.GetCurrentDirectory()).ConfigureAppConfiguration((hostingContext, config) =>{var env = hostingContext.HostingEnvironment;//根據環境變量加載不同的JSON配置config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true).AddJsonFile("ocelot.json").AddEnvironmentVariables(); //從環境變量添加配置}).UseIISIntegration().ConfigureLogging((hostingContext, logging) =>{logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));//添加控制臺日志,Docker環境下請務必啟用logging.AddConsole();//添加調試日志logging.AddDebug();}).UseStartup<Startup>();}

    然后在Startup.cs
    文件ConfigureServices方法中注冊服務時使用AddOcelot(),Configure
    方法中使用app.UseOcelot().Wait();?這樣網關的配置就完成了。

    services.AddOcelot(Configuration)app.UseOcelot().Wait();

      

    添加測試API項目

    新建兩個 .Net core 2.2 web項目(vs 自建的那種就OK),并使用Swagger來做接口說明。

    ?

    Nuget 添加?Swashbuckle.AspNetCore
    Microsoft.Extensions.PlatformAbstractions?實現Swagger ui,代碼如下

    public void ConfigureServices(IServiceCollection services){services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);services.AddSwaggerGen(options =>{options.SwaggerDoc("SwaggerAPI1", new Info { Title = "API1", Version = "v1" });var basePath = PlatformServices.Default.Application.ApplicationBasePath;var xmlPath = Path.Combine(basePath, "Services.Test1.xml");options.IncludeXmlComments(xmlPath);});//服務注冊//services.Configure<ServiceRegistrationOptions>}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IHostingEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseSwagger(c => { c.RouteTemplate = "{documentName}/swagger.json"; });app.UseSwaggerUI(c =>{c.SwaggerEndpoint("/SwaggerAPI1/swagger.json", "API1");});app.UseMvc();}

    項目.csproj文件中設置XML文檔輸出路徑

    Services.Test1 和 Services.Test2
    一樣的配置,略過。編譯啟動,頁面如下,接口配置完成。

    ?

    配置項目的上游請求對象(ocelot.json

    "ReRoutes": [//API1項目配置{"UpstreamPathTemplate": "/gateway/1/{url}","UpstreamHttpMethod": [ "Get", "Post", "Delete", "Put" ],"DownstreamPathTemplate": "/api1/{url}","DownstreamScheme": "http","ServiceName": "API1","UseServiceDiscovery": true,"LoadBalancer": "RoundRobin","DownstreamHostAndPorts": [{"Host": "119.29.50.115","Port": 80},{"Host": "localhost","Port": 13001}],"QoSOptions": {"ExceptionsAllowedBeforeBreaking": 3,"DurationOfBreak": 10,"TimeoutValue": 5000}//"AuthenticationOptions": {// "AuthenticationProviderKey": "Bearer",// "AllowedScopes": [// ]//}},//API2項目配置{"UpstreamPathTemplate": "/gateway/2/{url}","UpstreamHttpMethod": [ "Get", "Post", "Delete", "Put" ],"DownstreamPathTemplate": "/api2/{url}","DownstreamScheme": "http","ServiceName": "API2","UseServiceDiscovery": true,"LoadBalancer": "RoundRobin","DownstreamHostAndPorts": [{"Host": "111.230.160.62","Port": 80},{"Host": "localhost","Port": 13002}],"QoSOptions": {"ExceptionsAllowedBeforeBreaking": 3,"DurationOfBreak": 10,"TimeoutValue": 5000}//"AuthenticationOptions": {// "AuthenticationProviderKey": "Bearer",// "AllowedScopes": [// ]//}},]

    ReRoutes API對象模板配置節點解釋如下:

    UpstreamPathTemplate

    上游路徑模板

    UpstreamHttpMethod

    上游HTTP請求方法

    DownstreamPathTemplate

    下游路徑模板

    DownstreamScheme

    下游協議Https/Http

    DownstreamHostAndPorts

    下游主機和端口號,允許配置多個

    UseServiceDiscovery

    是否使用服務發現(True/False)

    ServiceName

    服務名稱(結合服務發現使用)

    LoadBalancer

    指定一個負載均衡算法: RoundRobin:輪詢 LeastConnection:最少連接數 NoLoadBalancer:不適用負載均衡

    LoadBalancerOptions

    負載均衡器配置

    QoSOptions

    熔斷配置,在請求向下游服務時使用斷路

    AuthenticationOptions

    權限配置

    ?

    啟動結果

    啟動web
    項目,web頁面報錯,但無妨,使用PostMan請求網關接口訪問api1/TestOnes成功。

    ?

    聚合API文檔(SwaggerUI

    前面配置了網關接口上游,但是頁面Swagger沒有顯示,這節主要是整合SwaggerUI。

    首先需要配置ApiGateway項目的Swagger,在配置文件配置上面兩個接口的SwaggerNames,代碼中遍歷添加到網關項目的SwaggerUI中,代碼如下

    ConfigureServices

    services.AddSwaggerGen(options =>{options.SwaggerDoc(Configuration["Swagger:Name"], new Info { Title = Configuration["Swagger:Title"], Version = Configuration["Swagger:Version"] });});

      

    Configure

    public void Configure(IApplicationBuilder app, IHostingEnvironment env){var apis = Configuration["Apis:SwaggerNames"].Split(";").ToList();if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseMvc().UseSwagger().UseSwaggerUI(options =>{apis.ToList().ForEach(key =>{options.SwaggerEndpoint($"/{key}/swagger.json", key);});options.DocumentTitle = "網關";});app.UseOcelot().Wait();}

      

    appsettings.json

    "Swagger": {"Name": "ApiGateway","Title": "網關服務","Version": "v1"},"Apis": {"SwaggerNames": "SwaggerAPI1;SwaggerAPI2"}

    PS:SwaggerAPI1、SwaggerAPI2是前面兩個接口的SwaggerName,這里需要對應上。

    ?

    配置Swagger的上游請求對象(ocelot.json

    //swagger API1配置{"DownstreamPathTemplate": "/SwaggerAPI1/swagger.json","DownstreamScheme": "http","UpstreamPathTemplate": "/SwaggerAPI1/swagger.json","UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],"DownstreamHostAndPorts": [{"Host": "119.29.50.115","Port": 80},{"Host": "localhost","Port": 13001}]},//swagger API2配置{"DownstreamPathTemplate": "/SwaggerAPI2/swagger.json","DownstreamScheme": "http","UpstreamPathTemplate": "/SwaggerAPI2/swagger.json","UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],"DownstreamHostAndPorts": [{"Host": "111.230.160.62","Port": 80},{"Host": "localhost","Port": 13002}]}

      

    啟動結果

    使用SwaggerUI整合了API1和API2的接口文檔。

    ?

    ?

    IdentityServer 集成

    官網文檔地址:http://docs.identityserver.io/en/latest/index.html

    IdentityServer4是一個基于OpenID Connect和 OAuth 2.0的針對 ASP .NET Core 2.0的框架。

    IdentityServer是將規范兼容的OpenID Connect和OAuth 2.0終結點添加到任意ASP .NET
    Core應用程序的中間件。你構建包含登錄和注銷頁面的應用程序,IdentityServer中間件會向其添加必要的協議頭,以便客戶端應用程序可以使用這些標準協議與其對話。

    ?

    ?

    添加授權服務項目

    新建 .Net core 2.2 web項目,添加以下Nuget包:

    • IdentityServer4.AspNetIdentity
    • IdentityServer4.EntityFramework?使用數據存儲機制

    ?

    ?

    配置appsetting.json

    配置測試環境下的客服端信息和Identity API
    資源配置,具體配置需要按照自己的邏輯定義,這里只是為了結合我下面的IdentityServerConfig文件所定義,代碼如下,

    為了結合我下面的IdentityServerConfig文件所定義,代碼如下,

    "IdentityServer": {"ApiName": "default-api","ApiSecret": "secret","Clients": [{"ClientId": "client","AllowedGrantTypes": ["password"],"ClientSecrets": [{"Value": "def2edf7-5d42-4edc-a84a-30136c340e13"}],"AllowedScopes": ["default-api"]},{"ClientId": "demo","ClientName": "MVC Client Demo","AllowedGrantTypes": ["hybrid","client_credentials"],"RequireConsent": "true","ClientSecrets": [{"Value": "def2edf7-5d42-4edc-a84a-30136c340e13"}],"RedirectUris": ["http://openidclientdemo.com:8001/signin-oidc"],"PostLogoutRedirectUris": ["http://openidclientdemo.com:8001/signout-callback-oidc"],"AllowedScopes": ["openid","profile","default-api"],"AllowOfflineAccess": "true"}]}

      

    添加IdentityServerConfig

    IdentityServerConfig 類分為三個方法:

    定義API資源:

    public static IEnumerable<ApiResource> GetApiResources(){return new List<ApiResource>{new ApiResource("default-api", "Default (all) API"){Description = "AllFunctionalityYouHaveInTheApplication",ApiSecrets= {new Secret("secret") }}};}

      

    定義身份資源:

    public static IEnumerable<IdentityResource> GetIdentityResources(){return new List<IdentityResource>{new IdentityResources.OpenId(),new IdentityResources.Profile(),new IdentityResources.Email(),new IdentityResources.Phone(),new IdentityResources.Address()};}public static IEnumerable<IdentityResource> GetIdentityResources(){var customProfile = new IdentityResource(name: "custom.profile",displayName: "Custom profile",claimTypes: new[] { "name", "email", "status" });return new List<IdentityResource>{new IdentityResources.OpenId(),new IdentityResources.Profile(),customProfile};}

      

    IdentityResource?具體屬性

    Enabled

    指示此資源是否已啟用且可以請求。默認為true。

    Name

    標識資源的唯一名稱。這是客戶端將用于授權請求中的scope參數的值。

    DisplayName

    顯示名稱。

    Description

    描述。

    Required

    默認為false。(暫未深究理解)

    Emphasize

    默認為false。(暫未深究理解)

    ShowInDiscoveryDocument

    指定此范圍是否顯示在發現文檔中。默認為true。

    UserClaims

    應包含在身份令牌中的關聯用戶聲明類型的列表。

    定義測試客服端

    此處則是通過appsetting.json 文件獲取配置

    public static IEnumerable<Client> GetClients(IConfiguration configuration){var clients = new List<Client>();foreach (var child in configuration.GetSection("IdentityServer:Clients").GetChildren()){clients.Add(new Client{ClientId = child["ClientId"],ClientName = child["ClientName"],AllowedGrantTypes = child.GetSection("AllowedGrantTypes").GetChildren().Select(c => c.Value).ToArray(),RequireConsent = bool.Parse(child["RequireConsent"] ?? "false"),AllowOfflineAccess = bool.Parse(child["AllowOfflineAccess"] ?? "false"),ClientSecrets = child.GetSection("ClientSecrets").GetChildren().Select(secret => new Secret(secret["Value"].Sha256())).ToArray(),AllowedScopes = child.GetSection("AllowedScopes").GetChildren().Select(c => c.Value).ToArray(),RedirectUris = child.GetSection("RedirectUris").GetChildren().Select(c => c.Value).ToArray(),PostLogoutRedirectUris = child.GetSection("PostLogoutRedirectUris").GetChildren().Select(c => c.Value).ToArray(),});}return clients;}

      

    配置Startup

    ConfigureServices

    這里只是用作測試,所以沒有在數據庫中讀取配置,而是在內存中獲取。相應的數據庫讀取方法也有說明。

    public void ConfigureServices(IServiceCollection services){//var connectionString = Configuration.GetConnectionString("Default");//services.AddDbContext<MagicodesAdminContext>(options => options.UseSqlServer(connectionString));//services.AddIdentity<AbpUsers, AbpRoles>()// .AddEntityFrameworkStores<MagicodesAdminContext>()// .AddDefaultTokenProviders();services.AddIdentityServer().AddDeveloperSigningCredential().AddInMemoryPersistedGrants().AddInMemoryIdentityResources(IdentityServerConfig.GetIdentityResources()).AddInMemoryApiResources(IdentityServerConfig.GetApiResources()).AddInMemoryClients(IdentityServerConfig.GetClients(Configuration))//.AddAspNetIdentity<AbpUsers>()//從數據庫讀取配置等內容(clients, resources)//.AddConfigurationStore(options =>//{// options.ConfigureDbContext = b =>// b.UseSqlServer(connectionString);//})// this adds the operational data from DB (codes, tokens, consents)//.AddOperationalStore(options =>//{// options.ConfigureDbContext = b =>// b.UseSqlServer(connectionString);// options.PersistedGrants.Name = "AbpPersistedGrants";// //options.DeviceFlowCodes.Name =// // this enables automatic token cleanup. this is optional.// options.EnableTokenCleanup = true;//});//.AddAspNetIdentity()//.AddAbpPersistedGrants<AdminDbContext>()//.AddAbpIdentityServer<User>();;}

      

    Configure

    public void Configure(IApplicationBuilder app, IHostingEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseIdentityServer();}

      

    啟動結果

    就這樣可以啟動服務了,瀏覽器啟動會顯示如下頁面,因為沒有任何頁面啟動,所為顯示為404。

    ?

    但無妨,我們可以使用PostMan 訪問:

    http://localhost:13004/.well-known/openid-configuration

    ?

    ?

    你會看到官方所謂的發現文檔。客戶端和API將使用它來下載必要的配置數據。到此為止IdentityServer服務已經搭建成功!

    首次啟動時,IdentityServer將為您創建一個開發人員簽名密鑰,它是一個名為的文件。您不必將該文件檢入源代碼管理中,如果該文件不存在,將重新創建該文件。tempkey.rsa

    ?

    配置ApiGateway網關項目

    在前面Ocelot章節中,配置了ocelot.json,這里繼續修改ocelot.json文件,啟用權限認證

    {"UpstreamPathTemplate": "/gateway/1/{url}","UpstreamHttpMethod": [ "Get", "Post", "Delete", "Put" ],"DownstreamPathTemplate": "/api1/{url}","DownstreamScheme": "http","ServiceName": "API1","UseServiceDiscovery": true,"LoadBalancer": "RoundRobin","DownstreamHostAndPorts": [{"Host": "119.29.50.115","Port": 80},{"Host": "localhost","Port": 13001}],"QoSOptions": {"ExceptionsAllowedBeforeBreaking": 3,"DurationOfBreak": 10,"TimeoutValue": 5000}//啟用權限認證"AuthenticationOptions": {"AuthenticationProviderKey": "IdentityBearer","AllowedScopes": []}}

    然后還需要在ApiGateway項目中修改appsetting.json文件,添加IdentityService服務配置。

    "IdentityService": {"Uri": "http://localhost:13004",//認證服務IP"DefaultScheme": "IdentityBearer","UseHttps": false,"ApiName": "default-api","ApiSecret": "def2edf7-5d42-4edc-a84a-30136c340e13"}

    接下來就是配置 ApiGateway項目 Startup文件了。

    需要引入Nuget包:IdentityServer4.AccessTokenValidation

    public void ConfigureServices(IServiceCollection services){//Identity Server Bearer TokensAction<IdentityServerAuthenticationOptions> isaOpt = option =>{option.Authority = Configuration["IdentityService:Uri"];option.RequireHttpsMetadata = Convert.ToBoolean(Configuration["IdentityService:UseHttps"]);option.ApiName = Configuration["IdentityService:ApiName"];option.ApiSecret = Configuration["IdentityService:ApiSecret"];option.SupportedTokens = SupportedTokens.Both;};services.AddAuthentication().AddIdentityServerAuthentication(Configuration["IdentityService:DefaultScheme"], isaOpt);services.AddOcelot(Configuration)//啟用緩存.AddCacheManager(x => { x.WithDictionaryHandle(); }).AddPolly()services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); ;services.AddSwaggerGen(options =>{options.SwaggerDoc(Configuration["Swagger:Name"], new Info { Title = Configuration["Swagger:Title"], Version = Configuration["Swagger:Version"] });});}

    配置完成后啟用Service.Test1、Service.Test2、ApiGateway、IdentityService項目。使用SwaggerUI請求會提示401
    Unauthorized,這個時候IdentityService就起到作用了。

    ?

    使用PostMan去請求IdentityService獲取token

    ?

    使用token訪問接口,數據返回正常

    ?

    ?

    調用Ocelot管理API

    通過IdentityServer 身份驗證來調用Ocelot 管理接口。

    首先需要做的是引入相關的NuGet包:Install-Package Ocelot.Administration

    修改 ApiGateway項目 Startup文件

    添加代碼.AddAdministration(“/administration”, isaOpt);路徑名稱可自取。

    public void ConfigureServices(IServiceCollection services){//Identity Server Bearer TokensAction<IdentityServerAuthenticationOptions> isaOpt = option =>{option.Authority = Configuration["IdentityService:Uri"];option.RequireHttpsMetadata = Convert.ToBoolean(Configuration["IdentityService:UseHttps"]);option.ApiName = Configuration["IdentityService:ApiName"];option.ApiSecret = Configuration["IdentityService:ApiSecret"];option.SupportedTokens = SupportedTokens.Both;};services.AddAuthentication().AddIdentityServerAuthentication(Configuration["IdentityService:DefaultScheme"], isaOpt);services.AddOcelot(Configuration)//啟用緩存.AddCacheManager(x => { x.WithDictionaryHandle(); }).AddPolly().AddAdministration("/administration", isaOpt);services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); ;services.AddSwaggerGen(options =>{options.SwaggerDoc(Configuration["Swagger:Name"], new Info { Title = Configuration["Swagger:Title"], Version = Configuration["Swagger:Version"] });});}

     

    API方法

    POST {adminPath} / connect / token

    獲取token

    請求的主體是表單數據,如下所示

    client_id?設為管理員

    client_secret?設置為設置管理服務時使用的任何內容。

    scope?設為管理員

    grant_type?設置為client_credentials

    獲取{adminPath} /configuration

    獲得當前的Ocelot配置。

    POST {adminPath} / configuration

    這會覆蓋現有配置。

    請求的主體是JSON,它與我們用于在文件系統上設置Ocelot.json格式相同。

    如果要使用此API,則運行Ocelot的進程必須具有寫入ocelot.json或ocelot.{environment}
    .json所在磁盤的權限。這是因為Ocelot會在保存時覆蓋它們。

    刪除{adminPath} / outputcache / {region}

    清除所有緩存區域

    Consul(服務發現)

    官網地址:https://www.consul.io/

    Consul包含多個組件,但是作為一個整體,提供服務發現和服務配置的工具。

    主要特性:

    • 服務發現
      組件記錄了分布式系統中所有服務的信息,其它服務可以據此找到這些服務。
    • 健康檢查?Consul 客戶端可用提供任意數量的健康檢查。
    • Key/Value存儲?應用程序可用根據自己的需要使用 Consul 的層級的 Key/Value
      存儲。
    • 多數據中心
      Consul支持開箱即用的多數據中心。這意味著用戶不需要擔心需要建立額外的抽象層讓業務擴展到多個區域。

    這里框架主要介紹服務發現和健康檢查。

    本地部署

    下載相應版本consul
    軟件包,下載地址:https://www.consul.io/downloads.html,以下內容為windows講解。承接上面的網關項目,整合Consul。

    安裝

    ?

    ?

    解壓完成,只有一個consul.exe,別慌,確實就只有一個文件。

    管理員運行CMD ,CD 到consul 文件夾,直接運行?consul
    命令,出現如下頁面,則配置成功

    ?

    ?

    添加服務配置

    添加服務注冊配置文件,在consul.exe同級目錄下添加config
    (名字可自取)文件夾,在config
    文件夾中創建service.json(名字可自取)文件,用來注冊服務和服務檢查配置。如圖所示:

    ?

    ?

    配置service.json,代碼如下:

    {"services": [{"id": "API1",//唯一標識"name": "API1",//服務名稱"tags": [ "API1" ],//服務標簽"address": "172.0.0.1",//我隨便配的IP,注意配置服務的真實IP和port"port": 80},{"id": "API2","name": "API2","tags": [ "API2" ],"address": "172.0.0.1",//我隨便配的IP,注意配置服務的真實IP和port"port": 81}]}

    這樣服務注冊配置就OK了,接下來使用配置啟動Consul,下面是幾種形式啟動consul,詳細的命令參數可以移步到官方文檔查看。

    • 以開發模式啟動?consul agent -dev -config-dir=./config
    • 以服務方式啟動?consul agent -server -bootstrap-expect 2 -data-dir
      ./tmp/consul -node=n1 -bind=192.168.109.241 -ui-dir ./dist -dc=dc1
    • 以客戶端方式啟動?consul agent -data-dir ./tmp/consul -ui-dir ./dist
      -bind=192.168.109.204 -dc=dc1

    開發模式啟動如下,在輸出窗口中可以看到consul ui HTTP 啟動路徑為
    127.0.0.1:8500?,注冊了API 和 API2 兩個服務。

    瀏覽器訪問 127.0.0.1:8500 ,可以看到Consul UI頁面

    ?

    添加檢查配置

    需要查看服務的運行狀態是否健康,就需要配置檢查。具體檢查配置移步官方文檔。

    檢查定義有一下幾種:

    腳本檢查:

    {"check": {"id": "mem-util","name": "Memory utilization","args": ["/usr/local/bin/check_mem.py", "-limit", "256MB"],"interval": "10s","timeout": "1s"}}

      

    HTTP檢查:

    {"check": {"id": "api","name": "HTTP API on port 5000","http": "https://localhost:5000/health","tls_skip_verify": false,"method": "POST","header": {"x-foo":["bar", "baz"]},"interval": "10s","timeout": "1s"}}

     

    TCP檢查:

    {"check": {"id": "ssh","name": "SSH TCP on port 22","tcp": "localhost:22","interval": "10s","timeout": "1s"}}

      

    TTL檢查:

    {"check": {"id": "web-app","name": "Web App Status","notes": "Web app does a curl internally every 10 seconds","ttl": "30s"}}

      

    Docker檢查:

    {"check": {"id": "mem-util","name": "Memory utilization","docker_container_id": "f972c95ebf0e","shell": "/bin/bash","args": ["/usr/local/bin/check_mem.py"],"interval": "10s"}}

      

    gRPC檢查:

    {"check": {"id": "mem-util","name": "Service health status","grpc": "127.0.0.1:12345","grpc_use_tls": true,"interval": "10s"}}

      

    本地服務的別名檢查:

    {"check": {"id": "web-alias","alias_service": "web"}}

    我這邊簡單使用了TCP檢查, 繼續修改service.json文件,檢測 tcp為
    “172.0.0.1:80”的服務,修改為如下代碼:

    {"services": [{"id": "API1",//唯一標識"name": "API1",//服務名稱"tags": [ "API1" ],//服務標簽"address": "172.0.0.1",//我隨便配的IP,注意配置服務的真實IP和port"port": 80},{"id": "API2","name": "API2","tags": [ "API2" ],"address": "172.0.0.1",//我隨便配的IP,注意配置服務的真實IP和port"port": 81}],"check": [{"id": "APICheck","name": "APICheck","tcp": "119.29.50.115:80","interval": "10s","timeout": "1s"}]}

      

    check
    定義為service同級節點則是為所有服務使用同一個檢查規則,定義在services節點內則是具體為某一個服務定義檢查規則

    啟動如下圖,很明顯多了一個名叫APICheck 的代理。

    ?

    啟動頁面也有不同,checks 為2了,說明check
    配置成功了。點擊某個服務進去可以查看詳細信息

    ?

    ?

    ?

    docker部署(騰訊云)

    前面說的是本地部署,現在說一下基于騰訊云docker
    部署。首先拉去docker鏡像創建服務。

    Docker Hub(鏡像文件庫)?里包含Consul
    的鏡像文件,只需要在Docker創建服務使用鏡像就可以了。

    ?

    ?

    ?

    設置容器端口為8500,服務端口為80,通過Ingress進行路由轉發。

    訪問服務外網,結果如下,配置成功

    ?

    配置Ocelot 網關

    首先修改前面的網關項目ApiGateway Startup.cs 文件里的 ConfigureServices方法,添加
    .AddConsul()方法代碼如下:

    public void ConfigureServices(IServiceCollection services){//Identity Server Bearer TokensAction<IdentityServerAuthenticationOptions> isaOpt = option =>{option.Authority = Configuration["IdentityService:Uri"];option.RequireHttpsMetadata = Convert.ToBoolean(Configuration["IdentityService:UseHttps"]);option.ApiName = Configuration["IdentityService:ApiName"];option.ApiSecret = Configuration["IdentityService:ApiSecret"];option.SupportedTokens = SupportedTokens.Both;};services.AddAuthentication().AddIdentityServerAuthentication(Configuration["IdentityService:DefaultScheme"], isaOpt);services.AddOcelot(Configuration).AddConsul()//啟用緩存.AddCacheManager(x => { x.WithDictionaryHandle(); }).AddPolly().AddAdministration("/administration", isaOpt);services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); ;services.AddSwaggerGen(options =>{options.SwaggerDoc(Configuration["Swagger:Name"], new Info { Title = Configuration["Swagger:Title"], Version = Configuration["Swagger:Version"] });});}

    接下來配置ocelot.json 文件,在GlobalConfiguration
    節點下添加服務發現提供程序配置

    //服務發現提供程序"ServiceDiscoveryProvider": {"Host": "111.230.118.59","Port": 80,"Type": "PollConsul","PollingInterval": 1000}

    項目上游配置添加ServiceName?和?UseServiceDiscovery屬性,代碼如下:

    {"UpstreamPathTemplate": "/gateway/2/{url}","UpstreamHttpMethod": [ "Get", "Post", "Delete", "Put" ],"DownstreamPathTemplate": "/api2/{url}","DownstreamScheme": "http","ServiceName": "API2","UseServiceDiscovery": true,"LoadBalancer": "RoundRobin","DownstreamHostAndPorts": [{"Host": "111.230.160.62","Port": 80},{"Host": "localhost","Port": 13002}],"QoSOptions": {"ExceptionsAllowedBeforeBreaking": 3,"DurationOfBreak": 10,"TimeoutValue": 5000}"AuthenticationOptions": {"AuthenticationProviderKey": "IdentityBearer","AllowedScopes": []}}

    啟動OcelotGateway,API001,API002項目,通過http://localhost:13000/gateway/1/values,和http://localhost:13000/gateway/2/values訪問;因為Ocelot配置了Consul的服務治理,所以可以通過配置的服務名稱和GlobalConfiguratin的Consul
    http
    api接口查找到對應服務的地址,進行訪問,這些都是Ocelot幫我們做,這點很容易證明,可以修改Consul配置文件中服務的address為錯誤IP,就會發現通過13000端口訪問不成功。

    集成消息隊列——CAP

    簡介

    CAP 是一個基于 .NET Standard 的 C#
    庫,它是一種處理分布式事務的解決方案,同樣具有 EventBus
    的功能,它具有輕量級、易使用、高性能等特點。

    微服務系統的過程中,通常需要使用事件來對各個服務進行集成,在這過程中簡單的使用消息隊列并不能保證數據的最終一致性,
    CAP
    采用的是和當前數據庫集成的本地消息表的方案來解決在分布式系統互相調用的各個環節可能出現的異常,它能夠保證任何情況下事件消息都是不會丟失的。

    Github 地址:https://github.com/dotnetcore/CAP

    支持消息隊列:

    • Kafka
    • RabbitMQ
    • AzureServiceBus

    數據庫存儲:

    • Sql Server
    • MySql
    • PostgreSQL
    • MongoDB

    環境準備

    我們以RabbitMQ 與Sql Server來講解。

    首先我們需要安裝RabbitMQ 服務,很簡單,官方下載最新的安裝包。

    ?

    ?

    但是在安裝RabbitMQ
    時會提示安裝Erlang,Erlang是一種通用的面向并發的編程語言,Erlang來編寫分布式應用要簡單的多。RabbitMQ是用Erlang實現的一個高并發高可靠AMQP消息隊列服務器。

    官方下載對應的Erlang 安裝程序,建議RabbitMQ和Erlang都安裝最新版本

    ?

    安裝完成之后,會多了以下幾個程序,安裝包幫我生成了start、remove、stop等命令程序。我們拿來直接用就可以了,當然你也可以配置環境變量,使用命令啟動。先運行start
    程序運行起來。

    ?

    ?

    ?

    .Net Core 集成 CAP

    Nuget 包下載:

    • DotNetCore.CAP 核心包
    • DotNetCore.CAP.RabbitMQ CAP RabbitMQ
    • DotNetCore.CAP.SqlServer CAP Sql Server 擴展包

    繼續修改測試項目Service.Test1項目,使用CodeFirst生成數據庫:

    ?

    新建測試類Test

    public class Test{public int Id { get; set; }public string Name { get; set; }public string Title { get; set; }}

    添加AppDbContext?數據庫上下文 文件,代碼如下:

    public class AppDbContext:DbContext{public AppDbContext(DbContextOptions<AppDbContext> options)base(options){}public virtual DbSet<Test> Tests { get; set; }protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);}}

    配置數據庫連接字符串:

    "ConnectionStrings": {"Default": "Server=(localdb)\\MSSQLLocalDB; Database=Service_test1; Trusted_Connection=True;"}

    Program.cs?文件配置讀取appsettings.json文件。

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>WebHost.CreateDefaultBuilder(args).ConfigureAppConfiguration((hostingContext, config) =>{config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).AddEnvironmentVariables();}).UseStartup<Startup>();

    Startup.cs?文件ConfigureServices添加數據訪問配置

    services.AddDbContext<AppDbContext>(options =>options.UseSqlServer(Configuration.GetConnectionString("Default")));services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    到這里正常的CodeFirst
    項目配置已經完成了,直接運行數據遷移命令就可以創建數據庫了。

    但是我這里需要集成CAP,肯定這樣是不行的。需要進行CAP的配置,繼續在ConfigureServices
    添加如下代碼:

    services.AddDbContext<AppDbContext>(options =>options.UseSqlServer(Configuration.GetConnectionString("Default")));services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);Action<CapOptions> capOptions = option =>{option.UseEntityFramework<AppDbContext>();option.UseSqlServer(Configuration.GetConnectionString("Default"));option.UseRabbitMQ("localhost");//UseRabbitMQ 服務器地址配置,支持配置IP地址和密碼option.UseDashboard();//CAP2.X版本以后官方提供了Dashboard頁面訪問。if (Convert.ToBoolean(Configuration["Cap:UseConsul"])){option.UseDiscovery(discovery =>{discovery.DiscoveryServerHostName = Configuration["Cap:DiscoveryServerHostName"];discovery.DiscoveryServerPort = Convert.ToInt32(Configuration["Cap:DiscoveryServerPort"]);discovery.CurrentNodeHostName = Configuration["Cap:CurrentNodeHostName"];discovery.CurrentNodePort = Convert.ToInt32(Configuration["Cap:CurrentNodePort"]);discovery.NodeId = Convert.ToInt32(Configuration["Cap:NodeId"]);discovery.NodeName = Configuration["Cap:NodeName"];discovery.MatchPath = Configuration["Cap:MatchPath"];});}};services.AddCap(capOptions);

    RabbitMQ 也是支持配置options

    option.UseRabbitMQ(cfg =>{cfg.HostName = Configuration["MQ:Host"];cfg.VirtualHost = Configuration["MQ:VirtualHost"];cfg.Port = Convert.ToInt32(Configuration["MQ:Port"]);cfg.UserName = Configuration["MQ:UserName"];cfg.Password = Configuration["MQ:Password"];});

    CAP 內置集成了Consul
    服務注冊,注冊的同時默認攜帶了簡況檢查,但是只支持HTTP檢查,所以我們需要在接口中定義health
    路徑提供給檢查訪問。

    ?

    在appsetting.json 文件中添加相應的配置節點:

    "Cap": {"UseConsul": true,//是否開啟"CurrentNodeHostName": "localhost",//當前節點IP"CurrentNodePort": 13001,//當前節點Port"DiscoveryServerHostName": "127.0.0.1",//發現服務主機IP"DiscoveryServerPort": 8500,//發現服務主機Port"NodeId": 1,//節點標識"NodeName": "CAP_API1",//節點名稱"MatchPath": "/api1/TestOnes"//健康檢查根路勁 最終的路徑為api1/TestOnes/health}

    進行數據遷移創建數據庫,表結構如下:

    ?

    ?

    Cap 發布

    接下來就是去使用Cap 發布了,修改Controller代碼

    public class TestOnesController : ControllerBase{private readonly ICapPublisher _capBus;public TestOnesController(ICapPublisher capPublisher){_capBus = capPublisher;}[HttpGet]public ActionResult<IEnumerable<string>> Get(){_capBus.Publish("services.test1.show.time", DateTime.Now);return new string[] { "TestOnes_value1", "TestOnes_value2" };}//定義路由為health提供給服務檢查使用[HttpGet][Route("health")]public ActionResult<string> Health(){return "Health!!!!!";}}

    因為啟用的Consul ,所以要按照前面說過的consul 教程來啟動consul

    訪問http://127.0.0.1:8500,頁面如下

    接下來啟動項目,還是老樣子直接看到如下頁面。

    ?

    但是我們集成了CAP,所以可以訪問呢http://localhost:13001/cap?訪問cap
    Dashboard頁面查看詳細

    這里一般啟動的話發出的時不存在,也是因為前面有測試過,數據庫里存在了。我們調用api1/TestOnes方法
    發出消息。

    請求成功,在來看看數據庫。數據庫多了兩張表,以張是接收數據表,一張是發布數據表。

    ?

    再來看看里面的數據,也是就是發布的消息,因為之前請求過四次,我這邊就多了四條數據。

    cap Dashboard也能看到一些統計和數據列表

    再來看看consul 頁面,一個CAP_API1 的服務已經被注冊進來了

    如果前面?MatchPath
    路徑沒有配置對的話,就會出現下面的情況,導致無法通過健康檢查。

    ?

    Cap 訂閱(接收)

    使用API訂閱消息,為了方便,使用同一個項目的另一個接口實現訂閱

    [Route("api1/[controller]")][ApiController]public class ValuesController : ControllerBase{[HttpGet("Received")][CapSubscribe("services.test1.show.time")]//配置發布時填寫的Namepublic ActionResult<string> GetReceivedMessage(DateTime datetime){Console.WriteLine("訂閱:"+datetime);return "訂閱:" + datetime;}}

    這樣就OK了,但是如果你時在不同的項目,還是需要像前面一樣配置CAP。

    啟動項目請求一次CAP發布接口,查看http://localhost:13001/cap
    可以看到接收的里面有1條數據

    訂閱列表中也有了一條數據

    在來看數據庫也添加一條數據

    ?

    最后——附上總體代碼

    整個實踐代碼已托管到Github,具體如下所示:https://github.com/magicodes/Magicodes.Simple.Services



    posted on 2019-05-22 16:41 NET未來之路 閱讀(...) 評論(...) 編輯 收藏

    轉載于:https://www.cnblogs.com/lonelyxmas/p/10906839.html

    總結

    以上是生活随笔為你收集整理的构建自己的简单微服务架构(开源)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    国产美女网 | 中文字幕视频观看 | 欧美激情综合网 | 婷婷国产精品 | 亚洲一区网站 | 日本精品中文字幕在线观看 | www.黄色片网站 | av一级片 | 国产一区在线观看免费 | 国产一级片毛片 | 一区二区三区四区精品 | 婷婷久久久久 | 国产精品久久久久久久99 | 国产精品av在线 | 欧美激情综合五月色丁香 | 91视频链接| 国产一区二区三区在线 | 一级久久久 | 久久国产日韩 | 成年人视频在线观看免费 | 色吊丝在线永久观看最新版本 | av亚洲产国偷v产偷v自拍小说 | 亚洲,国产成人av | 亚洲在线高清 | 天天曰夜夜操 | 亚洲视频axxx | 日韩一区二区三区免费视频 | 岛国片在线| 99中文视频在线 | 国产成人精品电影久久久 | 久久婷亚洲五月一区天天躁 | 日韩午夜电影 | 国产亚洲永久域名 | 国内精品久久久久 | 欧美二区在线播放 | 久久国产美女视频 | 免费在线观看日韩视频 | 麻豆小视频在线观看 | 国产手机视频在线观看 | 国产第页 | 国产精品99久久久久的智能播放 | 午夜色婷婷 | 又黄又爽又色无遮挡免费 | 欧美性生活大片 | 亚洲精品合集 | 一本大道久久精品懂色aⅴ 五月婷社区 | 天天操狠狠操网站 | 久久精品国产免费看久久精品 | 久久国产精品电影 | av综合 日韩 | 亚洲国产午夜 | 久久人人97超碰精品888 | 久久国产成人午夜av影院宅 | 在线观看91av | 日韩成人中文字幕 | 国产亚洲欧美一区 | 亚洲欧美国产视频 | 97在线观看免费高清完整版在线观看 | 国产手机在线观看视频 | 91网站观看 | 日韩一区二区三区免费视频 | 欧美在线视频一区二区 | 久久综合久久八八 | 毛片随便看 | 免费高清在线观看电视网站 | 成人丝袜 | 久久毛片网 | 欧美日韩高清一区 | 日日夜日日干 | 国产美女视频免费 | 黄色片视频在线观看 | av不卡网站 | 在线观看中文字幕第一页 | 在线国产激情视频 | 免费在线观看日韩 | 黄污污网站 | 五月天视频网站 | 91你懂的| 综合天堂av久久久久久久 | 国产精品高清免费在线观看 | 日日摸日日碰 | 国产精品久久网 | 成人黄色小视频 | 亚洲一级黄色 | 亚洲一区二区三区毛片 | 久草在线视频网站 | 91看片淫黄大片一级在线观看 | 免费成人在线电影 | 国产中文字幕网 | 涩涩网站在线 | 中文字幕在线观看播放 | 免费黄色av电影 | 欧美国产亚洲精品久久久8v | 色视频网站在线观看一=区 a视频免费在线观看 | 日韩电影中文字幕在线 | 在线观看的av | 精品99久久久久久 | 国产一区二区在线免费观看 | 在线亚洲小视频 | 亚洲免费成人av电影 | 深夜免费福利网站 | 五月在线 | 精品国产成人av在线免 | 天天做天天射 | 久久亚洲免费 | 亚洲国产成人高清精品 | av黄色在线播放 | 99精品视频在线免费观看 | 久久97久久97精品免视看 | 最新色视频 | 国产精品美女久久久久久网站 | 2019精品手机国产品在线 | www看片网站 | 欧美一区二区三区在线视频观看 | 四虎在线免费观看视频 | 丝袜少妇在线 | 91看片在线观看 | 精品影院一区二区久久久 | 国内免费久久久久久久久久久 | 日韩欧美视频在线观看免费 | 国产精品第54页 | 日p视频| 日韩免费b | 久草在线视频首页 | 黄色av大片 | 精品一区三区 | 激情视频网页 | 婷婷综合导航 | 亚洲精选视频免费看 | 国内精品视频久久 | 97久久久免费福利网址 | 国产精品久久久久毛片大屁完整版 | 久久久久久久久久久电影 | 99精品国产高清在线观看 | 成人在线免费观看网站 | 国产一区观看 | 欧美aa在线 | 91久久人澡人人添人人爽欧美 | 国产精品久久99 | 播五月综合 | 色婷婷综合激情 | 99热精品在线 | av先锋影音少妇 | 天天色天天综合网 | 欧洲高潮三级做爰 | 国产精品视频全国免费观看 | 欧美大片mv免费 | 在线免费国产 | 99久久婷婷国产一区二区三区 | aaa免费毛片| 亚洲清纯国产 | 亚洲精品乱码久久久久久蜜桃欧美 | 91免费看黄色 | 久久久99精品免费观看 | av中文在线播放 | 色婷婷激情四射 | av久久在线| 成人免费毛片aaaaaa片 | 亚洲国产视频a | 国产色视频网站2 | 久久不卡视频 | 天天搞天天干天天色 | 国产精品毛片一区二区三区 | 国产精品av免费在线观看 | 日韩久久久 | 美女网站视频久久 | 国内视频在线观看 | 天天干夜夜操视频 | 亚洲dvd| 久久国产精品色av免费看 | 国产色拍拍拍拍在线精品 | 日韩黄色一区 | 91视视频在线直接观看在线看网页在线看 | 麻豆精品国产传媒 | 视频在线精品 | 国产精品久久久久久久久久久久久久 | 欧美成人久久 | 国产丝袜在线 | 黄色片免费电影 | 久久一区二区三区国产精品 | 亚洲欧美日韩国产一区二区 | 国产精品原创视频 | 成人在线黄色电影 | 91在线最新 | 中文字幕在线观看视频一区 | 精品国产精品国产偷麻豆 | 中文字幕免费看 | 国产精品久久久久久久久久久久冷 | 国产黄在线 | 中文字幕在线观看免费高清电影 | 久久成人免费电影 | 丁香久久综合 | 日韩激情久久 | 黄色在线看网站 | 亚洲精品久久久蜜臀下载官网 | 国产精品免费视频网站 | 国产精品观看 | 亚洲一级性 | 99久久国产免费,99久久国产免费大片 | 婷婷久久综合九色综合 | 美女黄色网在线播放 | av免费电影在线 | 毛片a级片 | 亚洲精品成人在线 | 国产资源免费在线观看 | 92国产精品久久久久首页 | 日本中出在线观看 | 天天躁天天躁天天躁婷 | 久久久久久免费网 | 国产精品久久久久久av | 国产99色 | www.日本色| 又长又大又黑又粗欧美 | 99午夜| 久色小说 | 亚洲激情在线观看 | 96久久 | 国产一级免费观看 | 国产日韩视频在线 | 久久欧美综合 | 国产精品嫩草55av | av免费观看高清 | 色婷婷精品大在线视频 | 免费看麻豆 | 91亚洲国产成人久久精品网站 | 91最新网址在线观看 | 99国产视频在线 | 日韩视频三区 | 国产在线播放一区二区三区 | 九九视频这里只有精品 | 久久婷婷精品 | 色偷偷av男人天堂 | 97在线观看免费高清 | 久久综合色婷婷 | 一区二区三区福利 | 欧美另类重口 | 国产剧情久久 | 亚洲人成人在线 | 中文字幕在线观看资源 | 黄色在线网站噜噜噜 | 91丨porny丨九色 | 色九九在线 | 亚洲三级影院 | 日韩精品欧美专区 | 婷婷九九 | 天天干天天插 | 国产精品永久免费 | www.亚洲视频.com | 97精品超碰一区二区三区 | 99久久精品免费看国产一区二区三区 | 亚洲精品午夜久久久久久久 | 亚洲精品在线免费播放 | 久久精品五月 | 一级理论片在线观看 | 欧美aa在线 | 天天激情天天干 | 日韩精品三区四区 | 天天干天天干天天色 | 亚洲综合丁香 | 国产视频亚洲精品 | 一区二区三区在线观看免费视频 | 精精国产xxxx视频在线播放 | av不卡中文 | 天干啦夜天干天干在线线 | 午夜丁香视频在线观看 | 亚洲国产精品女人久久久 | 手机av片 | 五月天综合婷婷 | 欧美成人免费在线 | 精品一区久久 | 国产福利在线免费观看 | 996久久国产精品线观看 | 天天舔天天搞 | 久久96国产精品久久99软件 | 久久久久久久久影视 | 国产精品乱码高清在线看 | 成人免费观看视频大全 | 免费网址在线播放 | 在线精品视频免费播放 | 日韩高清一区 | 中文字幕在线免费看线人 | 超碰精品在线观看 | 成人av网站在线观看 | 欧美成亚洲 | 日韩草比 | 亚洲精品免费视频 | 丁香午夜 | 欧美日韩免费一区二区三区 | 99电影456麻豆 | 久久久久久久久久久久影院 | 97超级碰碰碰碰久久久久 | 免费碰碰| 欧美 日韩 性 | 成人精品影视 | 日韩在线第一 | 日韩av电影网站在线观看 | 丁香五月网久久综合 | 狠狠躁夜夜a产精品视频 | 一区二区精品视频 | 亚洲成人网在线 | 一区二区三区免费在线观看视频 | 丁香狠狠 | 色片网站在线观看 | 免费在线一区二区 | 毛片在线播放网址 | 狠狠色丁香婷婷综合最新地址 | 福利视频导航网址 | 在线观看岛国av | 国精产品999国精产品视频 | 色之综合网 | 激情婷婷网 | 国产成人久久久77777 | 国产精品成人一区二区三区吃奶 | 久久成人在线视频 | 精品国产综合区久久久久久 | 亚洲专区在线视频 | 久久综合婷婷国产二区高清 | 亚洲成人免费在线观看 | 国产一区私人高清影院 | 人人澡人人舔 | 亚洲综合色视频在线观看 | 亚洲小视频在线 | 丁香激情综合久久伊人久久 | 婷婷色网站 | 欧美日韩精品在线 | 91探花在线视频 | 狠狠干狠狠色 | 玖玖爱免费视频 | 久久精品男人的天堂 | 久久中文字幕在线视频 | 亚洲欧美婷婷六月色综合 | 操碰av| 亚洲激情综合 | 中文字幕在线免费看 | 96精品高清视频在线观看软件特色 | 午夜国产在线观看 | 在线亚洲小视频 | 最新国产精品久久精品 | 97av精品| 天天操天天射天天爱 | 亚洲欧美综合精品久久成人 | 欧美激情视频一区 | 欧洲视频一区 | 精品日本视频 | 久久精品一二三 | 亚洲第一成网站 | 一区二区三区高清不卡 | 亚洲精品国产精品国自 | 精品国产一区二区三区四区在线观看 | 久久香蕉国产精品麻豆粉嫩av | 成人在线电影观看 | 在线观看国产www | 丁香综合网 | 国产精品不卡一区 | 国产精品va最新国产精品视频 | 久久视频在线观看 | 国产区在线 | 九九欧美视频 | 高清在线观看av | 99久久99久久精品 | 91视频 - v11av | 精品在线观看国产 | av综合站| 91激情视频在线播放 | 91av视频在线免费观看 | 超碰在线观看97 | 福利电影久久 | 91男人影院 | 一区二区精品久久 | 狠狠干中文字幕 | 亚洲国产视频网站 | 五月婷网 | 国产精品二区在线 | 久久久久久久久久久久电影 | 五月婷婷综 | 欧美一区在线看 | 亚洲欧洲一级 | 久久成人综合视频 | 国产99免费视频 | 天天射天天干天天 | 一区二区三区免费在线观看视频 | 午夜精品999| 91黄视频在线观看 | 韩国在线视频一区 | 欧美日韩aaaa | 毛片二区 | 婷婷五月在线视频 | 美女网站视频色 | 热久久免费国产视频 | 欧美精品一区二区免费 | 国产理论在线 | 午夜精品久久久久久久久久 | 日韩欧美精品在线 | wwwwwww黄 | 人人澡超碰碰 | 婷婷丁香七月 | 成人永久在线 | 亚洲高清不卡av | 2018亚洲男人天堂 | 久久亚洲精品国产亚洲老地址 | 免费进去里的视频 | 国产a国产 | 久久成人免费 | 国产不卡在线视频 | 天天干天天操av | 色天天中文 | 五月激情天 | 欧美日韩国产一区二区三区在线观看 | 99热.com | 国产91在| a在线免费观看视频 | 久久精品导航 | 国产一区二区在线视频观看 | 五月婷网站 | 麻豆视频免费版 | 欧美成人亚洲成人 | 一区三区视频在线观看 | 激情欧美一区二区三区 | 久久视频6 | 九九日韩| 亚洲丝袜一区二区 | www九九热 | 免费av网址在线观看 | 又黄又刺激 | 在线网址你懂得 | 日韩av综合网站 | 久久在线观看视频 | 看片网站黄色 | 欧美最爽乱淫视频播放 | 婷婷精品国产欧美精品亚洲人人爽 | 国产亚洲在 | 国产中文字幕在线视频 | 成人作爱视频 | 久草在线免费新视频 | 天天狠狠干 | 日本久久久久久久久久 | 国产精品视频资源 | 91在线看片 | 亚洲最大色 | 亚洲理论电影 | 最新日韩精品 | 免费观看成人av | 成人aⅴ视频 | 色瓜| 中文字幕av免费在线观看 | 一级片色播影院 | 免费久久久 | 草久久久久 | 91麻豆国产 | 中文字幕一区二区三区四区视频 | 天天干天天拍天天操天天拍 | 中文字幕在线有码 | 免费成人黄色av | 成年人免费看的视频 | 夜色.com| 亚洲 成人 欧美 | 亚洲国产999 | 日本成人中文字幕在线观看 | 国产成人在线网站 | 综合亚洲视频 | 91成人免费观看视频 | 亚洲 中文 欧美 日韩vr 在线 | 激情五月婷婷网 | a v在线观看 | 午夜精品久久久久99热app | 日本久久中文字幕 | 亚洲黄色小说网 | 久久久久北条麻妃免费看 | 色网站在线免费 | 国产一级片久久 | 欧美精品久久久久久久久久久 | 国产成人综合图片 | 国产精品一区久久久久 | 一区二区不卡高清 | 在线观看一区 | 激情五月激情综合网 | 久久欧美综合 | 97色se | 色综合久久久久综合体 | 日韩精品一区不卡 | 国产中文字幕久久 | 国产免费一区二区三区最新6 | 亚洲欧美日韩国产一区二区三区 | 欧美日韩一区二区久久 | 天天做天天爱夜夜爽 | 亚洲精品无 | 91精品在线视频观看 | 亚洲日本色| 91综合色| 久久婷婷国产 | 久久观看免费视频 | 色国产精品一区在线观看 | 日本美女xx | 日韩免费av片 | 在线观看网站av | 亚洲精品国偷拍自产在线观看蜜桃 | 久久久久国产成人精品亚洲午夜 | 精产嫩模国品一二三区 | 国产久草在线观看 | 国产精品一区二区在线免费观看 | 免费网站污 | 在线成人性视频 | 国产麻豆剧果冻传媒视频播放量 | 91在线亚洲| 99精品视频在线播放免费 | 91视频 - x99av | 精品国产aⅴ一区二区三区 在线直播av | 亚洲jizzjizz日本少妇 | 亚洲综合日韩在线 | av成人免费在线 | 美女福利视频在线 | 国产美女精品视频 | av高清影院 | 国产成人av综合色 | 美女免费视频一区 | 亚洲精品黄色在线观看 | 亚洲三区在线 | 中文在线亚洲 | 精品欧美一区二区精品久久 | 久久免费视频2 | 99精品国产99久久久久久97 | 中文字幕 二区 | 久久久久网站 | 久草在线这里只有精品 | 久久伊99综合婷婷久久伊 | 色综合久久88色综合天天免费 | 91超碰在线播放 | 国产精品成人久久久久 | 久久96国产精品久久99漫画 | 色天天综合久久久久综合片 | 亚洲精品综合在线观看 | 精品免费国产一区二区三区四区 | 国产精品久久久免费看 | 成人播放器 | 国产精品久久网 | 国产精品久久久亚洲 | 久久亚洲私人国产精品va | 久久午夜鲁丝片 | 国产偷v国产偷∨精品视频 在线草 | 99热高清| 免费观看的黄色 | 欧美日韩免费看 | 亚洲国产美女精品久久久久∴ | 国产精品久久久av久久久 | 成人a视频 | 色综合色综合色综合 | 欧美午夜精品久久久久久孕妇 | 一区二区日韩av | 99在线热播精品免费99热 | 亚洲国产小视频在线观看 | 高清国产一区 | 日韩一级电影在线 | av黄色在线观看 | 久久免费美女视频 | 日韩偷拍精品 | 国产一区国产精品 | a久久免费视频 | 成人一区电影 | 国产美女网站视频 | 日韩专区在线 | 一区二区三区四区精品视频 | 亚洲精品午夜一区人人爽 | 国产视频丨精品|在线观看 国产精品久久久久久久久久久久午夜 | 久久久久国产视频 | 一级黄色片在线播放 | 亚洲,国产成人av | 日韩激情视频在线 | 国产精品久久久久久久久久久不卡 | 精品国产91亚洲一区二区三区www | 香蕉视频在线观看免费 | 二区中文字幕 | 久草在线视频首页 | 久久婷婷视频 | 麻豆91网站| 国产成人av免费在线观看 | 欧美日韩免费视频 | 亚洲性xxxx | 亚洲黄色免费在线看 | 日韩欧美精品一区二区三区经典 | 最近免费中文字幕大全高清10 | a黄色| 久久久www成人免费精品 | 五月婷婷视频在线 | 在线视频福利 | 国产精美视频 | 天堂网一区二区三区 | 五月天六月婷婷 | 免费日韩精品 | 免费看一级特黄a大片 | 日日综合 | 欧美久久电影 | 在线观看你懂的网址 | 精品国产乱码久久久久久1区二区 | 精品99久久久久久 | 97电影在线观看 | 国产精品99久久久久 | www国产在线 | 日韩精品一区二区三区免费观看 | 欧美一级性生活 | 日韩在线观看你懂得 | 成年人黄色av | 日韩免费观看一区二区三区 | 在线免费观看黄色 | 国产剧情在线一区 | 国产专区视频 | 欧美精品国产精品 | 丝袜精品视频 | 涩五月婷婷 | 亚洲国产精品一区二区尤物区 | 综合激情 | 久久成人国产精品免费软件 | 久久国产成人午夜av影院宅 | 9在线观看免费高清完整版 玖玖爱免费视频 | 国产色女人 | 一级黄色片在线免费看 | 国产精品午夜久久 | 中国一级片视频 | 69久久久| www免费黄色 | 亚洲国产黄色 | www黄com | 97超级碰碰碰碰久久久久 | 国产精品久久三 | 欧美激情精品久久久 | 天天天色 | 精品国产一区二区三区久久 | 粉嫩av一区二区三区入口 | 精品国内自产拍在线观看视频 | 午夜12点| 91污污视频在线观看 | 国产视频中文字幕在线观看 | 免费观看xxxx9999片 | 91污在线观看 | 91色偷偷 | 精品久久久久一区二区国产 | 国产一级在线看 | 最近最新mv字幕免费观看 | 久久久久久久久久久免费av | 久久这里只有精品视频99 | 久久久久亚洲最大xxxx | 日本aaaa级毛片在线看 | 久久久久久久久精 | 欧美日韩二三区 | 日韩免费不卡av | 人人干人人艹 | 色在线高清 | 91免费观看视频网站 | 亚洲砖区区免费 | 91视频在线看 | 中文字幕av网站 | 久久成电影 | 亚洲国产成人精品久久 | 日日摸日日碰 | 久久精品一二三区白丝高潮 | 国产一级大片在线观看 | 99久久久国产免费 | 91麻豆精品国产午夜天堂 | 91尤物国产尤物福利在线播放 | 久久精品香蕉 | 91成人午夜 | 亚洲激情在线视频 | 国产日韩在线看 | 国产成人99久久亚洲综合精品 | 国产成人久 | 最近2019中文免费高清视频观看www99 | 字幕网av| 在线免费观看国产黄色 | 亚洲国产精品资源 | 欧美激情视频久久 | 久久久精品电影 | 色婷婷国产 | 九九热久久免费视频 | 精品国产亚洲一区二区麻豆 | 国产精品毛片久久久 | 久久精彩 | 久久好看| 在线观看视频日韩 | 99久久www| 国产999精品久久久久久绿帽 | 探花视频免费观看 | 免费99视频 | 国产高清av在线播放 | 免费看三级 | 一区二区三区高清不卡 | 免费国产在线观看 | 中文字幕电影高清在线观看 | 欧美一级黄色片 | 天天添夜夜操 | 天天干,天天干 | 亚洲人成人99网站 | 欧美大片在线观看一区 | 伊色综合久久之综合久久 | 91免费在线视频 | 久久久久久久久久网 | av高清一区二区三区 | 色综合天天狠狠 | 国产精品黄色 | 亚洲人成影院在线 | 欧美一区二区三区在线视频观看 | 国产一区在线播放 | 久久久国产一区二区三区 | 亚洲精品美女在线观看播放 | 欧美一级片免费观看 | 久久精品播放 | 91av在| 久久图 | 欧美日韩精品在线免费观看 | 99精品99 | 一区二区激情 | 日日日日 | 亚洲一区网 | 国产精品va在线观看入 | 国产视频久久久 | 密桃av在线| 91看片成人| 手机av在线网站 | av久久在线 | 久久精品视频播放 | 国产亚洲精品女人久久久久久 | 欧美孕妇视频 | 天天做天天爱天天爽综合网 | av+在线播放在线播放 | 麻豆手机在线 | 久久精品一级片 | 精品福利片 | 国产精品一区二区在线 | 在线观看视频日韩 | 五月天网站在线 | 一区二区视频在线观看免费 | 成人a级免费视频 | 国产精品video爽爽爽爽 | av福利第一导航 | 久久精品草| 视频在线一区 | 日韩不卡高清视频 | 深夜视频久久 | 欧美贵妇性狂欢 | 亚洲天天做 | 日日日日干 | 丁香高清视频在线看看 | 香蕉视频网站在线观看 | 国产在线观看高清视频 | 免费在线观看国产精品 | 国产精品久久久久9999吃药 | 人人玩人人添人人澡97 | 国产成人免费观看久久久 | 久久久久久麻豆 | 亚洲年轻女教师毛茸茸 | 欧美精品网站 | 99视频免费播放 | 天天艹| 在线观看涩涩 | 在线观看aaa| 玖玖视频 | 日韩午夜视频在线观看 | 久久免费视频网站 | 91看片网址 | 久久久精品一区二区三区 | 天天碰天天操 | 欧美黄色特级片 | 人人澡av| 免费看污片 | 国产成人久久av | 成人av免费网站 | 手机成人av | 国产麻豆精品久久 | 久久免费视频2 | 欧美日韩国产一区二区三区在线观看 | 久久国产精品免费看 | 在线观看一区视频 | 91九色性视频 | 一区二区电影在线观看 | 国产96av| av短片在线 | 日日精品| 免费观看成人 | 午夜美女福利 | 成人动漫精品一区二区 | 天天射天天艹 | 国产一级视频在线观看 | 免费观看完整版无人区 | 日韩欧美有码在线 | 午夜精品久久久 | 黄色免费在线视频 | 国产丝袜制服在线 | 国产香蕉97碰碰久久人人 | 日韩精品久久久久久久电影99爱 | 91免费日韩 | 亚洲综合欧美精品电影 | 久久九九免费 | 中文字幕日韩一区二区三区不卡 | 激情综合五月网 | 国产精品一区免费在线观看 | 久久精品1区 | 在线a人片免费观看视频 | 玖玖精品在线 | 国产日本亚洲高清 | 亚洲乱码精品久久久 | 亚洲国产精品成人女人久久 | 少妇bbbb搡bbbb搡bbbb| 成人av一区二区三区 | 九色精品在线 | 婷婷色站 | 超碰97人人爱 | 婷婷丁香av | 久草精品视频在线看网站免费 | 亚洲综合视频在线播放 | 狠狠色丁香久久婷婷综合_中 | 日日夜色 | 日韩精品一区二区三区在线播放 | 国产黄色a| 在线va视频 | 日韩在线三级 | 国产男女无遮挡猛进猛出在线观看 | 久久免费观看少妇a级毛片 久久久久成人免费 | 精品无人国产偷自产在线 | 免费v片 | 四季av综合网站 | 午夜精品99久久免费 | 精品视频123区在线观看 | 成人av.com | 九九亚洲视频 | 国产在线一区观看 | 国产午夜在线观看视频 | 色偷偷人人澡久久超碰69 | 91在线亚洲 | 国产色小视频 | 国产在线观看污片 | 欧美成人性战久久 | 国产精品专区在线 | 亚洲区视频在线观看 | 69国产在线观看 | 欧美日韩亚洲第一页 | 日日干天天爽 | 热久久影视 | 日韩在线免费看 | 在线精品一区二区 | 中文av字幕在线观看 | 国产福利中文字幕 | 国产成人精品综合 | 久久久久久久久综合 | 91资源在线观看 | 成人福利在线观看 | 久草网在线视频 | 日本三级国产 | 91香蕉视频好色先生 | av线上看 | 国产午夜精品理论片在线 | 国产精品99久久久久久久久久久久 | 国产免码va在线观看免费 | 日韩精品一区二区在线观看 | 日日麻批40分钟视频免费观看 | 超碰97在线人人 | 久久国产手机看片 | 99精品观看 | 天天综合导航 | 成人国产精品入口 | 日本mv大片欧洲mv大片 | 亚洲成人资源在线 | 特黄特色特刺激视频免费播放 | 亚洲视频久久久久 | 国产精品av免费观看 | 国产精品video爽爽爽爽 | 97福利社| 国产精品扒开做爽爽的视频 | 日韩精品在线播放 | www.天天操.com | 欧洲色综合 | 国产精品久久久久影院日本 | 在线黄色国产电影 | 91豆花在线观看 | 日韩激情片在线观看 | 久久99精品国产91久久来源 | 狠狠色丁香婷婷综合 | 天天做天天射 | 日韩高清精品免费观看 | 日韩h在线观看 | 一区二区三区免费在线观看视频 | 久久久精选 | 99人成在线观看视频 | 成人免费在线视频观看 | www.天天干| 日韩乱码中文字幕 | 久久久久久久看片 | www久| 天天操天天射天天爱 | 91视频久久久久 | 日韩在线观看你懂得 | 久久久久久久久爱 | 久久福利| 欧美精品午夜 | 久久免费视频8 | 色www精品视频在线观看 | 国产精品四虎 | 综合激情 | 狠狠色婷婷丁香六月 | 国产亚洲精品v | 五月亚洲 | 中文字幕一区二区三区乱码在线 | 五月婷婷免费 | 久久久久二区 | 在线中文字幕播放 | 久久久精品免费观看 | 成人一区二区三区在线观看 | 免费久久片 | 国产美女被啪进深处喷白浆视频 | 色av男人的天堂免费在线 | 97热久久免费频精品99 | 国产福利精品在线观看 | 成人av动漫在线 | 色999精品 | 亚洲欧洲中文日韩久久av乱码 | 99高清视频有精品视频 | 日韩成人免费在线电影 | 麻豆 free xxxx movies hd | 中文字幕日韩国产 | 最新日韩精品 | av中文字幕剧情 | 久久人人干| 天天射综合 | 国产福利在线免费观看 | 欧美日韩一区二区三区在线免费观看 | 欧美综合色在线图区 | 欧美日韩精品在线视频 | 亚洲黄色软件 | 免费视频18| 久草免费电影 | 亚洲污视频 | 91精品在线免费视频 | 久久久久久99精品 | 尤物一区二区三区 | 最近中文字幕高清字幕在线视频 | 久久午夜电影 | 成 人 黄 色 视频 免费观看 | 亚洲资源| 97在线视频免费看 | 99精品国产成人一区二区 | 日韩大片在线 | 免费色婷婷 | 91福利在线观看 | www.久草.com| 色狠狠综合天天综合综合 | 99久高清在线观看视频99精品热在线观看视频 | 激情影音先锋 | 在线播放日韩av | 日本中文字幕在线播放 | 色.www| 久久婷婷国产 | 欧美色插 | 美女黄频在线观看 | 国内精品久久久久影院男同志 | 九七视频在线 | 欧美日韩视频在线观看免费 | 中文字幕视频一区 | 三级黄色免费 | 欧美日韩视频在线观看免费 | 成年人视频在线免费 | 久久超碰免费 | 日本在线视频网址 | 国产精品精品国产 | 在线亚洲成人 | 激情综合啪 | 一区 二区 精品 | 欧美日本啪啪无遮挡网站 | 天天射色综合 | 国产精品免费在线观看视频 | 国内精品久久久久国产 | 久久久久久久久久免费视频 | 国产精品国产亚洲精品看不卡 | 在线视频你懂得 | 精品91在线| 黄色免费网战 | 在线免费高清 | 久久99视频精品 | 亚洲欧美日韩在线一区二区 | 一级黄视频 | 色小说av | 国产黄网在线 | 亚洲精品乱码久久久久久9色 | 日本动漫做毛片一区二区 | 色天天 | 婷婷网址| 免费a网| 午夜精品久久久 | 国产成人亚洲在线观看 | 国产精品一区久久久久 | 欧美精品小视频 | 超碰在线日本 | 最新精品视频在线 | 美女免费视频黄 | 成人av午夜 | www.99av| 视频91| 久久精品久久久久 | 婷色在线 | 久热色超碰 | 人人澡人人干 | av三级在线播放 |