本文主要介绍SpringCloud中的三种服务调用方式:SpringDiscoveryClient支持Ribbon的RestTemplateFeign客户端搭建服务测试环境。测试中,服务发现层使用Netflix的Eureka构建。主要步骤如下:1、导入Eureka所需的依赖org.springframework.cloudspring-cloud-starter-eureka-serverorg.springframework.cloudspring-cloud-starter-eureka2.修改配置文件server:eureka:instance:hostname:eureka9001.com#eurekaserver的实例名instance-id:eureka9001client:register-with-eureka:false#false表示不注册registryfetch-registry:false##false表示你是注册中心,你的职责是维护服务实例,不需要获取服务service-url:defaulteZone:http://127.0.0.1:9001Client1:server:port:8002spring:application:name:licensingserviceeureka:instance:instance-id:licensing-service-8002prefer-ip-address:trueclient:register-with-eureka:truefetch-registry:trueservice-url:defaultZone:http://127.0.0.1:9001/eureka/,客户端2:服务器:port:8002spring:application:name:licensingserviceeureka:instance:instance-id:licensing-service-8002prefer-ip-address:trueclient:register-with-eureka:truefetch-registry:true服务url:defaultZone:http://127.0.0.1:9001/eureka/,一组微服务的不同实例采用相同的服务名,区分不同的实例ID,对应spring.application.name和eureka.instance.instance-id3。启动服务服务器:@SpringBootApplication@EnableEurekaServerpublicclassEurekaServerPort9001_App{publicstaticvoidmain(String[]args){SpringApplication.run(EurekaServerPort9001_App.class,args);}}客户端:@SpringBootApplication@RefreshScope@EnableEurekaClientpublicclassLicense0statApplication(StringpublicclassLicense0stat2_[]args){SpringApplication.run(LicenseApplication_8002.class,args);}}4。测试输入Eureka服务器地址,我的是127.0.0.1:9001,可以查看注册到注册中心的服务。如图:注:Eureka已经通过了3次心跳测试,服务才能成功注册到注册中心。默认间隔10s,服务第一次需要等待30s才能在Eureka中看到注册的服务。消费者构建1、DiscoverClient模式微服务中的服务既是消费者又是调用者,所以消费者配置和上面的服务配置大致相同,依赖和配置参考上面的服务端构建方式。添加EnableEurekaClient注解启动主类:@SpringBootApplication@EnableEurekaClient@EnableDiscoveryClientpublicclassConsumerApplication_7002{publicstaticvoidmain(String[]args){SpringApplication.run(ConsumerApplication_7002.class,args);{}}核心配置类:@Componentpublic@scoveryCsumerDiAutowiredprivateDiscoveryClientdiscoveryClient;publicServiceInstancegetServiceInstance(){ListserviceInstances=discoveryClient.getInstances("licensingservice");如果(serviceInstances.size()==0){返回null;}返回serviceInstances.get(0);}publicStringgetUrl(Stringurl){ServiceInstanceserviceInstance=this.getServiceInstance();如果(serviceInstance==null)thrownewRuntimeException("404,NOTFOUND");字符串urlR=String.format(url,serviceInstance.getUri().toString());返回网址R;}}通过DiscoveryClient从Eureka获取licensingservice服务的实例数组,返回第一个实例。TestController@RestController@RequestMapping("test")publicclassTestController{//注意必须是new的,否则会被ribbon拦截器拦截,改变URL行为privateRestTemplaterestTemplate=newRestTemplate();@AutowiredprivateConsumerDiscoveryClientconsumerDiscoveryClient;@RequestMapping("/getAllEmp")publicListgetAllLicense(){Stringurl=consumerDiscoveryClient.getUrl("%s/test/getAllEmp");返回restTemplate.getForObject(url,List.class);}}Test:debuginfofrom这张图中可以直观的看到licensing服务,里面有两个服务实例,可以查看实例信息。页面返回的信息查询成功,将信息存入数据库。2、Ribbon函数的SpringRestTemplate方法依赖同上。核心配置类://表示负载均衡算法@BeanpublicIRuleiRule(){returnnewRoundRobinRule();}@Bean@LoadBalanced//告诉Spring创建一个支持Ribbon负载均衡的RestTemplatepublicRestTemplaterestTemplate(){returnnewRestTemplate();}设置负载均衡方式为roundrobin。测试类:@RestController@RequestMapping("rest")publicclassConsumerRestController{@AutowiredprivateRestTemplaterestTemplate;privatefinalstaticStringSERVICE_URL_PREFIX="http://LICENSINGSERVICE";@RequestMapping("/getById")publicEmpgetById(Longid){MultiValueMapparamMap=newLinkedMultiValueMap();paramMap.add("id",id);returnrestTemplate.postForObject(SERVICE_URL_PREFIX+"/test/getById",paramMap,Emp.class);}}测试结果:第一次:第二次:第三次:因为采用round-robin负载均衡的方式调用不同的服务实例,没有区别,一定程度上改了名字。Ribbon方法与上面两种方法相比,是对第一种方法的封装,内置了不同的加载算法,支持自定义。比较好用,但是RestTemplate的request方法需要写两次,比较繁琐,容易出错。第三种方式,Feignclient,大大降低了开发难度,提高了速度。3.feign客户端方式引入依赖:org.springframework.cloudspring-cloud-starter-feign主要代码:@FeignClient(value="LICENSINGSERVICE",fallbackFactory=ServiceImp.class)publicinterfaceServiceInterface{@RequestMapping("/test/getById")EmpgetById(@RequestParam("id")Longid);@RequestMapping("/test/getLicenseById")许可证getLicenseById(@RequestParam("id")Longid);@RequestMapping("/test/getAllEmp")ListgetAllLicense();}@ComponentpublicclassServiceImpimplementsFallbackFactory{@OverridepublicServiceInterfacecreate(Throwablethrowable){returnnewServiceInterface(){@OverridepublicEmpgetById(Longid){Empemp=newEmp();emp.setName("我假装后备创建");返回emp;}@OverridepublicLicensegetLicenseById(Longid){returnnull;}@OverridepublicListgetAllLicense(){返回空值;}};}}接口方式开发,通过注解指定服务名称和备份方法,当服务表现不佳时,方便返回默认结果,而不是一个不友好的错误主启动类:@SpringBootApplication@EnableEurekaClient@EnableFeignClientspublicclassConsumer_feign_Application_7004{publicstaticvoidmain(String[]args){SpringApplication.run(Consumer_feign_Application_7004.class,args);}}测试类:@RestController@RequestMapping("rest")publicclassConsumerRestController{@AutowiredprivateServiceInterfaceserviceInterface;@AutowiredprivateRestTemplaterestTemplate;@RequestMapping("/getById")publicEmpgetById(Longid){returnserviceInterface.getById(id);}}测试结果:正常测试:关闭两个服务实例,模拟服务实例死亡:Feign不仅可以简化服务调用,还可以在调用的服务失败时提供友好的反馈。这三种调用方式,从低到高,从不同的层次实现了SpringCloud中微服务的相互调用。