前回の記事では、IdentityServer4 をベースに開発されているため、知識のポイントがあまりありませんが、今後の説明では Catalog Service について説明します。 . 皆さんもご理解いただければ幸いです。
まず、非常に標準的な webapi ディレクトリであるディレクトリ構造を見てみましょう:
まず、UseWebRoot (「Pics」) が追加された IdentityService に似た Program を見てみましょう。 pics ディレクトリを設定します。 webroot になりました。他はすべて同じです。
スタートアップの構築方法では、シークレット マネージャー ツールの使用についても説明しましたが、ここではアセンブリ タイプがもう 1 つあります。実際、シークレットには userSecretsId のみが必要です。
ConfigureServices には次のコードが表示されます:
services.AddMvc(options => { options.Filters.Add(typeof(HttpGlobalExceptionFilter)); }).AddControllersAsServices();
フィルターが追加されました。この HTtpGlobalExceptionFilter はプロジェクト内にあります。これは、CatalogDomainException タイプのエラーがスローされたときに、特定のエラー コードが返されることを意味していると考えられます。
AddControllersAsServices は、プロジェクト内のすべてのコントローラーをサービスに登録する拡張メソッドです。ソース コードを見てみましょう:
public static IMvcCoreBuilder AddControllersAsServices(this IMvcCoreBuilder builder) { var feature = new ControllerFeature(); builder.PartManager.PopulateFeature(feature);foreach (var controller in feature.Controllers.Select(c => c.AsType())) { builder.Services.TryAddTransient(controller, controller); } builder.Services.Replace(ServiceDescriptor.Transient<icontrolleractivator>());return builder; }</icontrolleractivator>
真ん中の foreach セクションは、プロジェクト内の依存関係注入を通じて各コントローラーに簡単にアクセスできるようにするためのものです。 。
下に進みます:
services.AddDbContext<catalogcontext>(options => { options.UseSqlServer(Configuration["ConnectionString"], sqlServerOptionsAction: sqlOptions => { sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name); //Configuring Connection Resiliency: sqlOptions.EnableRetryOnFailure(maxRetryCount: 5, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); });// Changing default behavior when client evaluation occurs to throw. // Default in EF Core would be to log a warning when client evaluation is performed.options.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning));//Check Client vs. Server evaluation: });</catalogcontext>
DBContext を構成するときに、Connection Resiliency (バウンス接続) メソッドが使用されることがわかります。移行を使用する場合、このメソッドは、前に説明した FluentNhibernate と似ています。 EnableRetryOnFailure は、移行中に失敗が発生した場合に、このアクションの失敗メカニズムを設定し、アプリとデータベースの分離によって発生する偶発的な接続エラーの影響を回避します。なぜこのような仕組みがあるのでしょうか?データベースが Azure SQL などのクラウド上にある場合、アプリとデータベースをデータセンターに配置したとしても、ネットワーク接続の問題が発生することは避けられないため、この問題を設定できるようになりました。障害が発生した場合は動作を再開するため、ネットワークに起因する偶発的な問題をある程度回避できます。コマンドの実行時に再試行を有効にするようにいくつかのポリシーを設定することもできます。デフォルトでは、EF は、ConfigureWarnings を通じてこの警告をスローするようにすることもできます。また、これを無視するように構成することもできます。
次に、次のコードが表示されます:
services.Configure<catalogsettings>(Configuration);</catalogsettings>
各 eShop プロジェクトで同様のステートメントが見つかり、プロジェクト関連の設定をサービスに登録し、それらを環境変数に渡します。 settings.json による構成に加えて、Docker run –e を通じて柔軟な構成を実行することもできます。
ここで、CatalogSetting には ExternalCatalogBaseUrl 属性が含まれています。docker の実行時に次のコマンドを入力できます:
docke run -e "ExternalCatalogBaseUrl=http://localhost:5011/" ....
この方法では、docker コマンドを通じて柔軟に設定することができ、-e Assign を通じて設定を行うこともできます。 ConnectionString などの .json の変数に値を追加するには、クリックして詳細を確認してください。
// Add framework services.services.AddSwaggerGen(); services.ConfigureSwaggerGen(options => { options.DescribeAllEnumsAsStrings(); options.SingleApiVersion(new Swashbuckle.Swagger.Model.Info() { Title = "eShopOnContainers - Catalog HTTP API", Version = "v1", Description = "The Catalog Microservice HTTP API. This is a Data-Driven/CRUD microservice sample", TermsOfService = "Terms Of Service" }); }); services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); });
上記の 2 つのコードは、それぞれ SwaggerGen と Cors (クロスドメイン) 戦略を使用して構成されており、API を Web モードに自動的に変換して表示することもできます。デバッグするのは非常に簡単です。 Cors の設定はここではうまく使用されていません。すべてのリクエストを許可します。そうでない場合は、クロスドメイン設定の意味がありません。
次に、EventBus に関連する一連のサービスの追加操作を確認しました。しばらく見てみると、これまでにログ アクションのみが実行されていることがわかりました。コードを見てみましょう。コードは価格に含まれることを意味します。変更があった場合、EventService を呼び出して操作を保存および記録します。 PublishThroughEventBusAsync メソッドは、このレコードの状態を公開済みに変更します。現時点では、なぜこのメソッドが使用されるのか、なぜ EventBus という名前が付けられたのかはわかりませんが、プロジェクトの問題でこの質問を提起したので、プロジェクトの開発者が私に答えてくれることを願っています。答え。 Basket.Api を確認しました。このプロジェクトにはサブスクリプションの動作があります。詳細については次の章で説明します。
OK、Configure メソッドをもう一度見てみましょう。次のコード部分を見てみましょう:
if (raiseProductPriceChangedEvent) // Save and publish integration event if price has changed{//Create Integration Event to be published through the Event Busvar priceChangedEvent = new ProductPriceChangedIntegrationEvent(catalogItem.Id, productToUpdate.Price, oldPrice);// Achieving atomicity between original Catalog database operation and the IntegrationEventLog thanks to a local transactionawait _catalogIntegrationEventService.SaveEventAndCatalogContextChangesAsync(priceChangedEvent);// Publish through the Event Bus and mark the saved event as publishedawait _catalogIntegrationEventService.PublishThroughEventBusAsync(priceChangedEvent); }
ここでは、new ではなく GetService を通じてインスタンス化されていることがわかります。これにより、コンテキストが依存する他のインスタンスも取り込まれるため、非常に便利で使いやすくなります。
WaitForSqlAvailability メソッドは、後でデータ移行を実行する必要があるため、データベースを使用可能にしようとします。
CatalogService には 2 つのコントローラーが含まれており、1 つは PicController、もう 1 つは CatalogController であり、PicController は ID に基づいて画像を取得するだけです。
如果你要运行Catalog.Api,你必须安装MSSQL和RabbitMQ,这次我把我的系统换成了Win10 Pro,并在电脑上使用Docker安装了MSSQL-Server-Linux和RabbitMQ。安装这2个非常简单,仅仅需要输入几条命令即可:
docker run --name mssql -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Pass@word' -p 5433:1433 -d microsoft/mssql-server-linux docker run -d --hostname my-rabbit --name rabbitmq -p 8080:15672 -p 5672:5672 rabbitmq:3-management
ok,我们使用docker创建了mssql和rabbitmq,这里注意一下,我把mssql的端口映射到了本机的5433上,还有rabbitmq的管理页面,我映射到了本机的8080端口,你可以通过http://localhost:8080 进行访问。
上一篇我们说过我们可以通过iisexpress/Kestrel或者docker的形式运行因为牵涉到配置,所以这两种方式的运行有些不同。
一、iisExpress或Kestrel方式下,因为刚刚我们把mssql和rabbitmq的端口都映射到了本机,所以我们只需要在setting.json中把数据库连接和rabbitmq的地址指向本机即可,如下:
{ "ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word", "ExternalCatalogBaseUrl": "http://localhost:5101", "EventBusConnection": "localhost", "Logging": {"IncludeScopes": false,"LogLevel": { "Default": "Debug", "System": "Information", "Microsoft": "Information"} } }
ok,Ctrl+F5,运行一下看看:
当看到上面这个页面,说明你的运行正常了,你还得测试下api是否运行正常,比如Pic,比如Items。
二、docker中运行,参照上一篇的方式,先publish再build カタログ サービス - Microsoft マイクロサービス アーキテクチャのサンプル コードの分析, 不过这里要注意一点,因为你之前的ConnectionString和EventBusConnection都是指向本机(127.0.0.1)的,所以这里必须改一下,改成主机的ip地址或者是对应容器的ip也可以,如果您不想更改的话,也可以通过docker -e进行设置,比如:
docker run -p 8899:80 --name catalog -e "EventBusConnection=172.17.0.2" -d catalog:01
我这里的172.17.0.2是我rabbitmq容器的ip地址,你可以通过docker inspect containerId 进行查看容器的ip。
如果一切配置都正确的话,你就可以通过浏览器http://localhost:8899 进行浏览了。
当然,除了正常浏览外,你还需测试下api是否正常。
在这个项目中有一些疑惑,希望大家能够给我答案。
Connection Resiliency,我看了很久,字面意思是弹性连接,但我觉得用弹性好像不太适合,一般来讲我们说的弹性都是指架构或者系统的伸缩性,我一开始也是从这个角度去了解,但看了很多文章,觉得它只是让我们在启动的时候,设置一些重试策略,在后面调用中可使用此策略,策略会根据你设置的重试次数、延迟时间等去自动重试,避免因为偶尔的错误造成的影响,所以觉得用弹回比较恰当。
EventBus,我感觉很奇怪,为什么一定要取这个名字呢?在Android中,很明确的,它是进行订阅发布,消息传递,可以解耦发布者和订阅者,但在Catalog.Api里,变成了记录操作,没有看到解耦,也没有看到订阅。在我的理解中,应该在Startup进行订阅操作,发布者CatalogController在进行update操作的时候,订阅者进行add log动作,但在这个实例中,我看到的是同步进行了这些操作,所以很不解。
Mssql-server-linux,当你用Docker安装了以后,你却不能使用visual studio 2017的sql server data tools进行查询(只能进行连接),为了查看效果,还需要安装Microsoft Sql Server Management Studio(必须17版本以后)进行查看数据。
这次的文章来的比较晚,一方面有点忙,另一方面就是上面提到的困惑,面对困惑我试着去解答,但有时候真的无法解答,所以提出来集思广益。
后面可能会比较慢,需要学习的东西真多,一边写一边学习成为这次系列的乐趣,现在每天坚持6公里快走,夜走能够是我保持头脑清晰,思考项目中的疑问,现在发觉生活越发有趣。
或许有很多人觉得只看了Startup就够了吗?其实真不够,我目前先把框架的源码过一遍,后面会分篇讲述,比如Connection Resiliency。
以上がカタログ サービス - Microsoft マイクロサービス アーキテクチャのサンプル コードの分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。