java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > 微服务进行远程调用其他服务

微服务进行远程调用其他服务方式

作者:袅沫

文章主要介绍了如何将本地服务注册到Nacos地址上,并详细描述了服务调用和负载均衡的实现方法,包括使用`@EnableDiscoveryClient`注解开启服务调用、编写调用接口、创建RestTemplate配置类以及使用负载均衡依赖进行服务调用

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

1、服务调用

现在我们需要使用service-order服务调用sercice-business服务

使用@EnableDiscoveryClient注解, 开启服务调用

引入依赖

        <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>

需要被调用的服务启动类:

@EnableDiscoveryClient //开启服务调用
@SpringBootApplication
public class BusinessMainApplication{
    public static void main(String[] args) {
        SpringApplication.run(BusinessMainApplication.class,args);
    }
}

编写需要进行调用的接口:

    @GetMapping("/business/{id}")
    public Business getById(@PathVariable("id") String id){
        return  businessService.getBusiness(id);
    }

创建RestTemplate配置类,防止new 多个对象

@Configuration
public class OrderConfig {

    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

在服务层进行调用另外一个服务

@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依赖

依赖引入:

  <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>

依赖导入:

@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配置类上

@Configuration
public class OrderConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文