相信我们已经能够搭建起微服务架构的各个模块,并且已经成功运行起来。 现在我们已经有了服务注册中心和服务提供者,下面就来尝试构建一个服务消费者。服务消费者 这个服务消费者,主要完成两个目标:发现服务以及消费服务 其中,服务的发现任务是由Eureka客户端完成,而服务消费的任务是由Ribbon完成,Ribbon是一个基于HTTP和TCP的客户端负载均衡器,它可以在通过客户端中配置的ribbonServerList服务端列表去轮询访问以达到负载均衡的作用。当Ribbon与Eureka联合使用时,Ribbon的服务实例清单ribbonServerList会被DiscoveryEnabledNIWSServerList重写,扩展成从Eureka注册中心中获取服务端列表。同时它也会用NIWSServerPing来取代IPing,它将职责委托给Eureka来确定服务端是否已经启动。本质就是它在Eureka服务发现的基础上实现了一套对服务实例的选择策略,从而实现对服务的消费。编码实现1。准备工作 启动之前高可用的服务注册中心eurekaserver以及helloservice服务,为了试实验Ribbon的客户端负载均衡的功能,通过javajar命令行的方式来启动不同端口的helloservice 但是在打包之前,如果helloservice中有测试类,需要将测试类跳过,否则敲入命令mvn:install会报错,因此打包的时候要使用这个命令:mvninstallDmaven。test。skiptrue复制代码 然后在target目录下,敲入命令:javajarspringboot011。0SNAPSHOT。jarserver。port8081javajarspringboot011。0SNAPSHOT。jarserver。port8082复制代码 在启动成功之后,如下图所示,从Eureka信息面板可以看到名为HELLOSERVICE的服务中出现了两个实例单元,分别是通过命令启动的8081端口和8082端口的服务。 两个端口的服务2。新建Consumer 创建一个SpringBoot的基础工程来实现消费服务者,取名为ribbonconsumer,并在pom中引入如下的依赖,新增了springcloudstarterribbondependenciesdependencygroupIdorg。springframework。bootgroupIdspringbootstarterwebartifactIddependencydependencygroupIdorg。springframework。bootgroupIdspringbootstartertestartifactIdscopetestscopedependencydependencygroupIdorg。springframework。cloudgroupIdspringcloudstartereurekaserverartifactIddependencydependencygroupIdorg。springframework。cloudgroupIdspringcloudstarterribbonartifactIddependencydependencies复制代码 然后创建应用主类ConsumerApplication,通过EnableDiscoveryClient注解让该应用注册为Eureka客户端应用,以获得服务发现的能力。同时,在该主类中创建RestTemplate的SpringBean实例,并通过LoadBalanced注解开启客户端负载均衡。EnableDiscoveryClientSpringBootApplicationpublicclassConsumerApplication{BeanLoadBalancedRestTemplaterestTemplate(){returnnewRestTemplate();}publicstaticvoidmain(String〔〕args){SpringApplication。run(ConsumerApplication。class,args);}}复制代码 创建ConsumerController类并实现ribbonconsumer接口。在该接口中,通过在上面创建的RestTemplate来实现对HELLOSERVICE服务提供的hello接口进行调用。可以看到在这里访问的地址是服务名HELLOSERVICE,而不是一个具体的地址,在服务治理框架中,这是一个重要的特性。RestControllerpublicclassConsumerController{AutowiredRestTemplaterestTemplate;GetMapping(ribbonconsumer)publicStringhelloConsumer(){returnrestTemplate。getForEntity(http:HELLOSERVICEhello,String。class)。getBody();}}复制代码 在application。properties中配置Eureka服务注册中心的位置,需要与helloservice一样,不然是发现不了服务的。spring。application。nameribbonconsumerserver。port9000eureka。client。serviceUrl。defaultZonehttp:localhost:1111eureka复制代码3。启动服务 启动服务,然后在注册中心的面板中我们可以看到有两个服务。 消费者服务 然后在地址栏中输入http:localhost:9000ribbonconsumer发起get请求,成功返回了Helloworld,此时我们可以在ribbonconsumer应用的控制台中看到如下信息,Ribbon输出了当前客户端维护的HELLOSERVICE的服务列表情况。其中包含了各个实例的位置,Ribbon就是按照此信息进行轮询访问,以实现基于客户端的负载均衡。DynamicServerListLoadBalancerforclientHELLOSERVICEinitialized:DynamicServerListLoadBalancer:{NFLoadBalancer:nameHELLOSERVICE,currentlistofServers〔192。168。31。142:8081,192。168。31。142:8082〕,LoadbalancerstatsZonestats:{defaultzone〔Zone:defaultzone;Instancecount:2;Activeconnectionscount:0;Circuitbreakertrippedcount:0;Activeconnectionsperserver:0。0;〕},Serverstats:〔〔Server:192。168。31。142:8081;Zone:defaultZone;TotalRequests:0;Successiveconnectionfailure:0;Totalblackoutseconds:0;Lastconnectionmade:ThuJan0108:00:00CST1970;Firstconnectionmade:ThuJan0108:00:00CST1970;ActiveConnections:0;totalfailurecountinlast(1000)msecs:0;averageresptime:0。0;90percentileresptime:0。0;95percentileresptime:0。0;minresptime:0。0;maxresptime:0。0;stddevresptime:0。0〕,〔Server:192。168。31。142:8082;Zone:defaultZone;TotalRequests:0;Successiveconnectionfailure:0;Totalblackoutseconds:0;Lastconnectionmade:ThuJan0108:00:00CST1970;Firstconnectionmade:ThuJan0108:00:00CST1970;ActiveConnections:0;totalfailurecountinlast(1000)msecs:0;averageresptime:0。0;90percentileresptime:0。0;95percentileresptime:0。0;minresptime:0。0;maxresptime:0。0;stddevresptime:0。0〕〕}ServerList:org。springframework。cloud。netflix。ribbon。eureka。DomainExtractingServerList673b1fae复制代码 再尝试发送几次请求,并观察两个HELLOSERVICE的控制台,可以看到两个控制台会交替打印下面的日志,可以用来判断当前的ribbonconsumer对HELLOSERVICE的调用是否是负载均衡的。com。web。controller。HelloController:add,host:192。168。31。142,serviceid:helloservice