第8章サービス・ディスカバリー
サービスの多数の顔、構成および管理を簡単にするために、我々は「サービス発見」の概念を理解する必要があります
クラウドネイティブな特性を想起
外部設定
URLとログイン資格情報は、環境変数に、プロファイルとC#のコードの外を移動します
これは、より明確に設定パラメータを実行するために必要なコードを可能にする、と責任は、動作環境にこれらの構成を提供するために、
バックエンドサービス
かかわらず、必要とされているプログラムのバイナリストレージ、データベース、別のサービス、キューサービス、または依存の他の種類があり、これらの施設は、疎結合、および環境変数の設定からしなければなりません
2つの方法でバックエンドサービスのためのリソースバンドル:静的バインディングと動的バインディング
静的DevOpsチームのエンジニアがツールを自動化や割り当てられ、いずれかの手段を結合、サービスとリソース間の結合プロセスは、アプリケーションの起動時に発生し、変更しないことを、結合度
綴じ処理リソースが動作中に発生することを意味結合ダイナミック時変化、具体的には、結合関係が固定されておらず、受信した複数のアプリケーションを要求することができ
また、アプリケーション開発者、追加の複雑さを避けるために、それはまた、疎結合サポートしています
Netflixのユーレカはじめに
GitHubのリンク:https://github.com/Netflix/eureka
集中化されたディレクトリ・サービス - サービス検出が実行されている達成するために、我々は、「レジストリサービス」機能を使用する必要があります
アマゾンで実行されているNetflixの主要なインフラのクラウドサービス
ネットフリックスは、フェイルオーバーと負荷分散機能を提供し、登録のためのユーレカに独自の製品管理サービスを開発しました
開発者の視点から見ると、マイクロインタラクションサービスとユーレカ・サーバは、起動時に登録されています
あなたが見つけると、他のバックエンドサービスを消費する必要がある場合は、ディレクトリサービスサーバーユーレカから見つけることができます
ハートビートを送信するために一定の時間間隔でユーレカサービスにもマイクロサービス
サービスは特定の時間にハートビートを送信しない場合は、サービスレジストリから削除されます
サービス登録と発見で、ユーレカは唯一の選択肢ではありません
純粋にサービス登録ツールから完全な製品登録、発見とフォールトトレランスに、他の会社名および製品がたくさんありますご利用いただけます
- etcd:分散キー値ストアの底層、HTTPアクセスを提供します
- 領事:フル機能のサービス・ディスカバリツールは、キーと値のストアの設定機能のサポートを提供します
- Marathon:Mesos 和 DC/OS 上一个相当成熟的容器编排系统
- ZooKeeper:源自 Hadoop 项目,是这一体系中最悠久的产品
如果想体验 Eureka,但不想从源代码编译,也不想把它完整地安装到服务器上,你可以直接使用 docker hub 镜像来运行它,命令行如下:
$ docker run -p 8080:8080 --name eureka \
-d netflixoss/eureka:1.3.1
发现和广播 ASP.NET Core 服务
现在分析一些与 Eureka 服务交互的示例代码
在下面的虚构示例中,将开发一套用于支持电子商务的服务
最终的服务将公开一个产品目录,这个目录提供标准的 API 端点,用于访问产品列表和详细信息
此外,有一个库存服务,负责提供物理库存的实时状态
当需要展示产品详细信息时,产品服务将需要调用库存服务获取数据,用于组装最终的完整数据
服务注册
我们示例项目的第一部分是库存服务,它需要在运行期间动态地被其他服务发现,以提供实时库存状态
GitHub链接:https://github.com/microservices-aspnetcore/ecommerce-inventory
使用 .NET Core 配置系统向 Steeltoe 类库提供一些配置信息
appsettings.json
{
"spring": {
"application": {
"name": "inventory"
}
},
"eureka": {
"client": {
"serviceUrl": "http://localhost:8080/eureka/",
"shouldRegisterWithEureka": true,
"shouldFetchRegistry": false,
"validate_certificates": false
},
"instance": {
"port": 5000
}
},
}
我们用惯常的方式装配好配置,确保加载了保存着服务发现客户端配置信息的 appsettings.json 文件
var builder = new ConfigurationBuilder()
.SetBasePath(System.IO.Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
Configuration = builder.Build();
在 Startup 类的 ConfigureService 方法里调用 Steeltoe 的 AddDiscoveryClient 扩展方法
services.AddDiscoveryClient(Configuration);
最后,只需要在 Configure 方法中添加对 UseDiscoveryClient 方法的调用
app.UseDiscoveryClient();
发现并消费服务
有一个可供发现的服务之后,我们把注意力转到要开发的下一个服务上:目录服务
这个服务提供产品的目录,并通过查询库存服务来补充产品的详细信息
这一服务与我们开发过的其他服务之间最重要的区别是,它会在运行期间动态地发现库存服务
GitHub链接:https://github.com/microservices-aspnetcore/ecommerce-catalog
用与配置库存服务时几乎一样的方式配置客户端
appsettings.json
{
"spring": {
"application": {
"name": "catalog"
}
},
"eureka":{
"client":{
"serviceUrl":"http://localhost:8080/eureka/",
"shouldRegisterWithEureka":false
}
}
}
区别在于目录服务不需要被注册(因为它不需要被其他服务发现),只有获取注册表才能发现库存服务
请看 HttpInventoryClient 类的代码,它负责消费库存服务
using StatlerWaldorfCorp.EcommerceCatalog.Models;
using Steeltoe.Discovery.Client;
using System.Threading.Tasks;
using System.Net.Http;
using Newtonsoft.Json;
namespace StatlerWaldorfCorp.EcommerceCatalog.InventoryClient
{
public class HttpInventoryClient : IInventoryClient
{
private DiscoveryHttpClientHandler handler;
private const string STOCKSERVICE_URL_BASE = "http://inventory/api/skustatus/";
public HttpInventoryClient(IDiscoveryClient client)
{
this.handler = new DiscoveryHttpClientHandler(client);
}
private HttpClient CreateHttpClient()
{
return new HttpClient(this.handler, false);
}
public async Task<StockStatus> GetStockStatusAsync(int sku)
{
StockStatus stockStatus = null;
using (HttpClient client = this.CreateHttpClient())
{
var result = await client.GetStringAsync(STOCKSERVICE_URL_BASE + sku.ToString());
stockStatus = JsonConvert.DeserializeObject<StockStatus>(result);
}
return stockStatus;
}
}
}
.NET Core 的 HttpClient 类的构造函数有一个重载,允许传入一个自定义的 HttpHandler 实例
由 Steeltoe 提供的 DiscoveryHttpClientHandler 负责把 URL 中的服务名称替换成在运行期间发现的 URL
执行如下步骤,可在电脑上同时运行库存服务、目录服务和 Eureka
首先,启动 Eureka 服务
$ docker run -p 8080:8080 -d --name eureka \
-d netflixoss/eureka:1.3.1
然后在 5001 端口运行库存服务
$ cd <inventory service>
$ dotnet run --service.urls=http://0.0.0.0:5001
要在 Docker 中运行服务,请使用下面的 docker run 命令:
$ docker run -p 5001:5001 -e PORT=5001 \
-e EURKEA__CLIENT__SERVICEURL=http://192.168.0.33:8080/eureka/ \
dotnetcoreservices/ecommerce-inventory
如果要在这里覆盖配置的值,请确保使用本机的地址
在 Docker 镜像中运行时,指向 localhost 就会有问题
最后,在 5002 端口启动目录服务
$ cd <目录服务>
$ dotnet run --service.urls=http://0.0.0.0:5002
现在,可以向产品目录服务 API 发送一些请求,获取产品的列表和详情
GET http://localhost:5002/api/products
GET http://localhost:5002/api/products/{id}
获取产品详情信息,期间将调用库存服务,它的 URL 是通过 Eureka 动态发现的
DNS 以及由平台支持的服务发现
在我看来,服务发现、注册,以及失败检测都应该是非功能需求
也就是说,应用代码的任何部分都不应该紧耦合特定服务发现的实现
显然,还是要优先考虑现实状况,务实地做出决策,而且最终决定还要由你自己来做
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
如有任何疑问,请与我联系 ([email protected]) 。