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();
	}
}

 

 

posted @ 2021-06-25 15:02  iLisa  阅读(118)  评论(0编辑  收藏  举报