前置知识:将本地服务注册到nacos地址上:

1、服务调用:
现在我们需要使用service-order 服务调用sercice-business服务
使用@EnableDiscoveryClient注解, 开启服务调用
引入依赖
XML
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
需要被调用的服务启动类:
java
@EnableDiscoveryClient //开启服务调用
@SpringBootApplication
public class BusinessMainApplication{
public static void main(String[] args) {
SpringApplication.run(BusinessMainApplication.class,args);
}
}
编写需要进行调用的接口:
java
@GetMapping("/business/{id}")
public Business getById(@PathVariable("id") String id){
return businessService.getBusiness(id);
}
创建RestTemplate配置类,防止new 多个对象
java
@Configuration
public class OrderConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
在服务层进行调用另外一个服务
java
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
@Override
public Order getById(Long id) {
Order order = new Order();
order.setTotalAmount(new BigDecimal("1000"));
order.setNickName("尚硅谷");
order.setId(id);
order.setProductList(Lists.newArrayList());
return order;
}
@Override
public Order createOrder(Long userId, Long productId) {
//进行远程调用获取商品数据
Business businessById = getBusinessById(productId.toString());
Order order = new Order();
order.setId(1L);
order.setAddress("将军大道108号");
order.setTotalAmount(BigDecimal.valueOf(businessById.getPrice() * businessById.getCount()));
order.setNickName("尚硅谷");
order.setUserId(userId);
order.setProductList(Arrays.asList(businessById));
return order;
}
/**
* 手动选择需要的实例进行调用
* @param businessId
* @return
*/
public Business getBusinessById(String businessId){
List<ServiceInstance> instances = discoveryClient.getInstances("service-business");
//获取服务的第几个实例对象
ServiceInstance instance = instances.get(0);
//端口的URL
String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/business/" + businessId;
log.info("远程调用的URL:" + url);
//进行远程调用
Business forObject = restTemplate.getForObject(url, Business.class);
log.info("返回的数据:" + forObject.toString());
return forObject;
}
}
2、负载均衡:
如果被调用的服务有多个实例,现在我们为了减轻某个服务的压力,对服务进行轮询调用:
现在我们需要在调用方,使用loadBanlancer依赖
依赖引入:
XML
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
依赖导入:
java
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
@Override
public Order getById(Long id) {
Order order = new Order();
order.setTotalAmount(new BigDecimal("1000"));
order.setNickName("尚硅谷");
order.setId(id);
order.setProductList(Lists.newArrayList());
return order;
}
@Override
public Order createOrder(Long userId, Long productId) {
//进行远程调用获取商品数据
// Business businessById = getBusinessById(productId.toString());
// Business businessById = getBusinessByIdWithLoadBalancer(productId.toString());
Business businessById = getBusinessByIdWithAnnotation(productId.toString());
Order order = new Order();
order.setId(1L);
order.setAddress("将军大道108号");
order.setTotalAmount(BigDecimal.valueOf(businessById.getPrice() * businessById.getCount()));
order.setNickName("尚硅谷");
order.setUserId(userId);
order.setProductList(Arrays.asList(businessById));
return order;
}
/**
* 手动选择需要的实例进行调用
* @param businessId
* @return
*/
public Business getBusinessById(String businessId){
List<ServiceInstance> instances = discoveryClient.getInstances("service-business");
//获取服务的第几个实例对象
ServiceInstance instance = instances.get(0);
//端口的URL
String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/business/" + businessId;
log.info("远程调用的URL:" + url);
//进行远程调用
Business forObject = restTemplate.getForObject(url, Business.class);
log.info("返回的数据:" + forObject.toString());
return forObject;
}
/**
* 使用LoadBalancer进行负载均衡
* @param businessId
* @return
*/
public Business getBusinessByIdWithLoadBalancer(String businessId){
ServiceInstance choose = loadBalancerClient.choose("service-business");
//端口的URL
String url = "http://" + choose.getHost() + ":" + choose.getPort() + "/business/" + businessId;
log.info("IP:" + choose.getHost() + ":" + choose.getPort());
log.info("远程调用的URL:" + url);
//进行远程调用
Business forObject = restTemplate.getForObject(url, Business.class);
log.info("返回的数据:" + forObject.toString());
return forObject;
}
/**
* 使用注解@LoadBalancer进行负载均衡
* 需要在restTemplate上添加注解LoadBalancer
* @param businessId
* @return
*/
public Business getBusinessByIdWithAnnotation(String businessId){
String url = "http://service-business/business/" + businessId;
//进行远程调用
Business forObject = restTemplate.getForObject(url, Business.class);
log.info("返回的数据:" + forObject.toString());
return forObject;
}
}
其中,第三种,使用注解的方式进行负载均衡,需要将注解添加在restTemplate配置类上
java
@Configuration
public class OrderConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}