• 微服务之间相互调用的三种最常见方式(含源码)


    相信大家平时开发的时候没少碰见,在微服务架构中需要调用很多服务才能完成一项功能。这时候,如何互相调用就变成微服务架构中的一个关键问题。在这里我介绍三个常用的方法

    一、RestTemplate方式

    @Bean
        public RestTemplate getRestTemplate(){
            return new RestTemplate();
        }
    
    • 1
    • 2
    • 3
    • 4

    服务的消费者(order)调用服务的提供者(Goods)

    @Autowired
        private RestTemplate restTemplate;
    
        @GetMapping("/createOrder/{gid}/{number}")
        public Order order(@PathVariable("gid") Integer id,@PathVariable("number") Integer number){
            log.info("用户开始下单,调用商品系统,查询{}号商品信息",id);
            Goods goods = restTemplate.getForObject("http://localhost:9002/goods/getGoods/" + id, Goods.class);
            log.info("商品信息查询完毕:"+ JSON.toJSONString(goods));
    
            log.info("开始下单:");
            Order order = new Order();
            order.setUid(1);
            order.setUname("测试用户");
            order.setGid(goods.getId());
            order.setGname(goods.getGoodsName());
            order.setNumber(number);
    
            orderService.createOrder(order);
            log.info("下单成功");
            return order;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    通过上面的方式我们解决了微服务之间的相互调用,但是存在硬编码的问题,如果服务提供者的地址发生变化,就需要手工修改代码;如果有多个服务提供者,无法实现服务的负载均衡;如果服务增多,人工调用会变得更加的复杂。

    这个时候就会需要服务治理,服务治理是微服务架构最核心的问题,用于实现各个微服务的自动化注册与发现。在这里选择Nacos。

    二、引入Nacos注册中心

    1.在服务的提供者与消费者的pom文件中引入依赖

    
            
                com.alibaba.cloud
                spring-cloud-starter-alibaba-nacos-discovery
            
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.在application.yml中添加配置

    spring:
      cloud:
        nacos:
          discovery:
            server-addr: 192.168.206.151:8848
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.在对应的微服务上添加

    @EnableDiscoveryClient
    
    • 1

    4.代码

       @Autowired
        private RestTemplate restTemplate;
       @Autowired
        private DiscoveryClient discoveryClient;
    
        @GetMapping("/createOrder2/{gid}/{number}")
        public Order order2(@PathVariable("gid") Integer id,@PathVariable("number") Integer number){
            log.info("用户开始下单,调用商品系统,查询{}号商品信息",id);
            //从nacos中获取服务地址
            ServiceInstance service = discoveryClient.getInstances("goods-service").get(0);
            String url = service.getHost() + ":" + service.getPort();
            //通过restTemplate调用
            Goods goods = restTemplate.getForObject("http://"+url+"/goods/getGoods/" + id, Goods.class);
            log.info("商品信息查询完毕:"+ JSON.toJSONString(goods));
    
            log.info("开始下单:");
            Order order = new Order();
            order.setUid(1);
            order.setUname("测试用户");
            order.setGid(goods.getId());
            order.setGname(goods.getGoodsName());
            order.setNumber(number);
    
            orderService.createOrder(order);
            log.info("下单成功");
            return order;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    注:DiscoveryClient是专门负责服务注册和发现的,我们可以通过它获取到注册到注册中心的所有服务

    三、Fegin实现服务调用

    Feign是Spring Cloud提供的一个声明式的伪Http客户端, 它使得调用远程服务就像调用本地服务一样简单, 只需要创建一个接口并添加一个注解即可。

    Nacos很好的兼容了Feign, Feign默认集成了 Ribbon, 所以在Nacos下使用Fegin默认就实现了负载均衡的效果。

    在服务消费者上进行以下操作:

    1.添加依赖

    
    
        org.springframework.cloud
        spring-cloud-starter-openfeign
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.在启动类上添加注解

    @EnableFeignClients
    
    • 1

    3.新建client包,并创建接口(把服务提供者controller对应的方法名复制过来,注意路径要完整。

    @FeignClient("goods-service")
    public interface GoodsService {
    
        @RequestMapping("/goods/getGoods/{id}")
        public Goods goods(@PathVariable("id") Integer id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.代码

    @Autowired
        private GoodsService goodsService;
    
        @GetMapping("/createOrder3/{gid}/{number}")
        public Order order3(@PathVariable("gid") Integer id,@PathVariable("number") Integer number){
            log.info("用户开始下单,调用商品系统,查询{}号商品信息",id);
    
            //通过feign调用商品微服务
            Goods goods = goodsService.goods(id);
            log.info("商品信息查询完毕:"+ JSON.toJSONString(goods));
    
            log.info("开始下单:");
            Order order = new Order();
            order.setUid(1);
            order.setUname("测试用户");
            order.setGid(goods.getId());
            order.setGname(goods.getGoodsName());
            order.setNumber(number);
    
            orderService.createOrder(order);
            log.info("下单成功");
            return order;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    好了,先介绍到这里,想要以上demo的可以加微信领取,另外还有一份《Java最新2022版面试题及解答-阿里内部资料(266页)》可以免费送给大家。

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    ModbusCRC16校验 示例代码
    Redis源码之SDS简单动态字符串
    Android TextWatcher 避免死循环
    [maven] scopes & 管理 & profile & 测试覆盖率
    技术分享 | app自动化测试(Android)–触屏操作自动化
    mongodb常用命令(3)
    共话云原生数据库的未来
    SpringBoot源码深度解析(三):SpringBoot启动流程原理详解
    9.数值统计
    SpringCloudAlibaba-Nacos集群
  • 原文地址:https://blog.csdn.net/m0_67393619/article/details/126081197