上篇文章实际上只讲了服务治理中的服务注册,服务与服务之间如何调用呢?传统的方式,服务A调用服务B,那么服务A访问的是服务B的负载均衡地址,经过负载均衡来指向到服务B的真实地址,上篇文章已经说了这种方式的缺点。那么下面讲如何在spring cloud+dotnet core的应用下进行服务调用。html
假设一种场景,有一个订单服务,有一个产品服务,其中产品服务是由两个服务节点组成一个集群。需求是订单服务访问产品服务的一个API接口。根据上一章文章的内容建立3个应用程序ServiceOne(端口8010),ServiceTwo(端口8011),ServiceThree(8012)。其中ServiceOne设置应用程序名称为order。ServiceTwo和ServiceThree的应用程序名称为product,作成集群。java
ServiceOne.appsettings.jsongit
{ "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Warning" } }, "spring": { "application": { "name": "order" } }, "eureka": { "client": { "serviceUrl": "http://localhost:5000/eureka/" }, "instance": { "port": 8010 } } }
ServiceOne.Controllers.ValuesController.CSgithub
private readonly DiscoveryHttpClientHandler _handler; private const string ProductUrl = "http://product/api/values"; public ValuesController(IDiscoveryClient client, ILoggerFactory logFactory) { _handler = new DiscoveryHttpClientHandler(client); } [HttpGet("product")] public async Task<string> GoProductAsync() { var client = new HttpClient(_handler, false); return await client.GetStringAsync(ProductUrl); }
ServiceTwo.appsettings.jsonspring
{ "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Warning" } }, "spring": { "application": { "name": "product" } }, "eureka": { "client": { "serviceUrl": "http://localhost:5000/eureka/" }, "instance": { "port": 8011 } } }
ServiceTwo.appsettings.jsondocker
{ "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Warning" } }, "spring": { "application": { "name": "product" } }, "eureka": { "client": { "serviceUrl": "http://localhost:5000/eureka/" }, "instance": { "port": 8012 } } }
为了展示访问的差别,设置不一样的返回值。
ServiceTwo.Controllers.ValuesController.csjson
[HttpGet] public string Get() { return "ServiceTwo"; }
ServiceThree.Controllers.ValuesController.csapi
[HttpGet] public string Get() { return "ServiceThree"; }
同时启动这3个项目,先看看服务中心http://localhost:5000/
这个3个应用程序都已经注册到了服务中心。ServiceOne被注册到ORDER,ServiceTwo和ServiceThree注册到了PRODUCT。
分别访问
http://localhost:8011/api/values 返回ServiceTwo
http://localhost:8012/api/values 返回ServiceThree
证实这两个服务是没有问题的。
再访问http://localhost:8010/api/values/product,
如图所示,分别返回了“ServiceTwo”和“ServiceThree”,多刷新几回,发现结果是来回变更的,这说明服务中心帮咱们实现了负载均衡。架构
咱们再作一个测试,断开ServiceTwo这个应该程序。咱们继续访问http://localhost:8010/api/values/product,发现一次错误,一次正常返回ServiceThree。30秒之后(可配置)再访问正常返回ServiceThree,同时发现服务中心已经踢掉了端口为8011的应用程序(ServiceTwo)。app
经过上面3个实例咱们模拟了分布式的调用场景,其中Order访问Product集群的时候,并无指定具体的地址,而是指定了服务名称(product),服务中心自动分配了地址,并实现了负载均衡。联系实际应用场景,配合docker,咱们能够快速的对某个服务进行添加,再也不须要维护服务节点。同时某个服务节点挂掉之后,服务中心也会踢出这个服务节点(会有短暂的不可用)。结合CAP理论来讲,服务中心知足了AP。
这篇文章讲解了服务之间的调用,咱们实际的应用场景,还有各类客户端(IOS,Andriod,Web...)来访问,而服务通常是内网不对外暴露的,因此客户端访问服务的时候就须要有一个专门对外暴露的入口,那么就引入了下篇文章的API网关。
全部代码均上传github。代码按照章节的顺序上传,例如第一章demo1,第二章demo2以此类推。
求推荐,大家的支持是我写做最大的动力,个人QQ群:328438252,交流微服务。
java部分
.net部分