SpringCloud(5)Eureka与Ribbon -服务提供者与服务消费者--服务消费者consumer方式一
消费服务的三种方式:
通过DisconveryClient来调用,(我们这里用的这种)
通过LoadBalancerClient来调用
通过@LoadBalanced来
一:首先创建一个module
创建一个名字叫service-consumer的module(方式和prover一样)
二:pom文件和我们的prover一样,这里的yml修改
我们这里不将自己注册到服务列表中,只能拉取服务列表,从服务列表中远程调用服务
server: port: 9090 # 端口 spring: application: name: service-consumer # 应用名称 # 配置 Eureka Server 注册中心 eureka: client: register-with-eureka: false # 是否将自己注册到注册中心,默认为 true registry-fetch-interval-seconds: 10 # 表示 Eureka Client 间隔多久去服务器拉取注册信息,默认为30 秒 service-url: # 设置服务注册中心地址 defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
三:创建包,与俩个实体类

四:创建Service与impl
springboot与springcloud默认是没有RestTemplate的,我们需要在启动类中加上其Bean

package com.xxxx.service.impl;
/**
* 订单服务
*/
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
RestTemplate restTemplate;
// 元数据对象(它是去我们注册中心获取服务列表,获取多个服务
// ,然后我们需要从多个服务中通过名称来找到我们这个具体的服务
@Autowired
private DiscoveryClient discoveryClient;
@Override
public order selectOrderById(Integer id) {
return new order(id,"order-001","中国",319940D,selectProductListBydiscoveryClient());
}
private List<product> selectProductListBydiscoveryClient(){
StringBuffer sb=null;
//获取服务列表
List<String> serviceIds=discoveryClient.getServices();
if (CollectionUtils.isEmpty(serviceIds))
return null;
//根据服务名称获取服务
List<ServiceInstance> serviceInstances=discoveryClient.getInstances("service-provider");
if (CollectionUtils.isEmpty(serviceInstances))
return null;
ServiceInstance si=serviceInstances.get(0);
sb=new StringBuffer();
sb.append("http://"+si.getHost()+":"+si.getPort()+"/product/list");
//ResponseEntity : 封装了返回数据
ResponseEntity<List<product>> response=restTemplate.exchange(
sb.toString(),
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<product>>(){}
);
return response.getBody();
}
}
这里说一下远程调用的restTemplate中的方法:
二.RestTemplate使用 RestTemplate提供了六种常用的HTTP方法实现远程服务调用,RestTemplate的方法名遵循一定的命名规范,第一部分表示用哪种HTTP方法调用(get,post),第二部分表示返回类型。 getForObject – 发送GET请求,将HTTP response转换成一个指定的object对象 postForEntity – 发送POST请求,将给定的对象封装到HTTP请求体,返回类型是一个HttpEntity对象 每个HTTP方法对应的RestTemplate方法都有3种。其中2种的url参数为字符串,URI参数变量分别是Object数组和Map,第3种使用URI类型作为参数 exchange 和execute 方法比上面列出的其它方法(如getForObject、postForEntity等)使用范围更广,允许调用者指定HTTP请求的方法(GET、POST、PUT等),并且可以支持像HTTP PATCH(部分更新)。 这次主要讲的是exchange 方法的使用。 exchange(String url, HttpMethod method,@Nullable HttpEntity<?> requestEntity, Class responseType, Map 参数说明: url:请求路径 method:请求的方法(GET、POST、PUT等) requestEntity:HttpEntity对象,封装了请求头和请求体 responseType:返回数据类型 uriVariables:支持PathVariable类型的数据。 创建一个RestTemplate连接
五:Contorller层

六:启动Eureka8761与Eureka8763与,生产者prover ,启动consumer

通过consumer来远程调用我们的prover服务:

二:通过LoadBalancerClient来调用(运用负载均衡器)
修改一下我们的consumerServiceImpl中的类就可以了
package com.xxxx.service.impl;
/**
* 订单服务
*/
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
RestTemplate restTemplate;
// 元数据对象(它是去我们注册中心获取服务列表,获取多个服务
// ,然后我们需要从多个服务中通过名称来找到我们这个具体的服务
@Autowired
private DiscoveryClient discoveryClient;
//负载均衡器 Ribbon 负载均衡器
@Autowired
private LoadBalancerClient loadBalancerClient;
@Override
public order selectOrderById(Integer id) {
return new order(id,"order-001","中国",319940D,selectProductListBydiscoveryClient1());
}
private List<product> selectProductListBydiscoveryClient(){
StringBuffer sb=null;
//获取服务列表
List<String> serviceIds=discoveryClient.getServices();
if (CollectionUtils.isEmpty(serviceIds))
return null;
//根据服务名称获取服务
List<ServiceInstance> serviceInstances=discoveryClient.getInstances("SERVICE-PRODUCT");
if (CollectionUtils.isEmpty(serviceInstances))
return null;
ServiceInstance si=serviceInstances.get(0);
sb=new StringBuffer();
sb.append("http://"+si.getHost()+":"+si.getPort()+"/product/list");
//ResponseEntity : 封装了返回数据
ResponseEntity<List<product>> response=restTemplate.exchange(
sb.toString(),
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<product>>(){}
);
return response.getBody();
}
private List<product> selectProductListBydiscoveryClient1(){
StringBuffer sb=null;
//获取服务列表 这里没有了获取服务列表
//根据服务名称获取服务
ServiceInstance si=loadBalancerClient.choose("SERVICE-PRODUCT");
if (si==null)
return null;
sb=new StringBuffer();
sb.append("http://"+si.getHost()+":"+si.getPort()+"/product/list");
//ResponseEntity : 封装了返回数据
ResponseEntity<List<product>> response=restTemplate.exchange(
sb.toString(),
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<product>>(){}
);
return response.getBody();
}
}

三:通过@LoadBalanced来实现
启动类注入RestTemplate时添加@LoadBalanced负载均衡注解,表示这个RestTemplate在请求时拥有客户端负载均衡的能力
package com.xxxx;
//@EnableEurekaClient
//@EnableEurekaClient 注解,目前版本如果配置了Client注册中心,默认会开启该注解
@SpringBootApplication
public class ServiceConsumerApplication
{
@Bean
@LoadBalanced //负载均衡注解
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main( String[] args )
{
SpringApplication.run(ServiceConsumerApplication.class,args);
}
}
package com.xxxx.service.impl;
import java.util.List;
/**
* 订单服务
*/
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
RestTemplate restTemplate;
// 元数据对象(它是去我们注册中心获取服务列表,获取多个服务
// ,然后我们需要从多个服务中通过名称来找到我们这个具体的服务
@Autowired
private DiscoveryClient discoveryClient;
//负载均衡器 Ribbon 负载均衡器
@Autowired
private LoadBalancerClient loadBalancerClient;
@Override
public order selectOrderById(Integer id) {
return new order(id,"order-001","中国",319940D,selectProductListBydiscoveryClient3());
}
private List<product> selectProductListBydiscoveryClient3(){
//ResponseEntity : 封装了返回数据
ResponseEntity<List<product>> response=restTemplate.exchange(
"http://service-product/product/list", //这里只需要写微服务的应用名称就可以service-product
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<product>>(){});
return response.getBody();
}
}

浙公网安备 33010602011771号