Redian新闻
>
服务拆分和远程调用,学起来!

服务拆分和远程调用,学起来!

公众号新闻

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入芋道快速开发平台知识星球。下面是星球提供的部分资料: 

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号等等功能:

  • Boot 地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 地址:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn

来源:blog.csdn.net/qq_54217349
/article/details/127955490/


不管任何分布式的架构,它都离不开服务之间的拆分,细化,微服务也一样,下面,风哥来带大家一起了解一下微服务的服务拆分原则,并带大家通过一个小案例了解一下服务间拆分和远程调用吧😀。

1 服务拆分

1.1 服务拆分原则

开头,风哥不墨迹了,把几个微服务之间的拆分原则先告诉大家。

  • 不同微服务之间,尽量不要有相同的业务,确保低耦合性
  • 每个微服务都应该有一个属于自己的独立数据库
  • 各个微服务之间,可通过微服务对外暴露的业务接口进行访问

1.2 服务拆分示例

1.2.1 实例的demo的结构如下:

请忽略eureka,它是下个章节的内容,学习的时候,做这个案例,一不小心没停下来😉。

cloud-demo:父工程

  • order-service:订单微服务,负责订单相关业务(当然这里只是一个小demo,只搞了一个查询的功能)
  • user-service:用户微服务,负责用户相关业务(功能也略少哈)

那么,根据上边服务拆分原则,可以得到如下结论(ps:没看下面的小伙伴们可以先看下上边,机灵的小脑袋瓜里先思考一下有什么结论):

  • 用户服务和订单服务都必须对外暴露Restful接口,供其他微服务调用
  • 两个服务之间如果要调用另一个微服务的功能,只能通过Restful接口调用,不能直接访问其他微服务的数据库
  • 所以,用户微服务和订单微服务要有自己独立的数据库

1.2.2 数据库表结构

Eg: cloud-order表中含有cloud-user的id字段。

那个,导入工程啥的,在这我就不给具体流程了,大家学到了这里,相信都有这些基本能力了,接下来咱们直接根据这个演示服务拆分的小demo,来聊一下远程调用。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

2 远程调用

2.1 远程调用实例

在这里为了演示微服务间的远程调用,在这里就要设定需求场景了,先看原来demo的功能:

先看一下两个微服务间需要交互的功能接口,这里的小demo只有一个,那就是查询订单的接口

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;
    
    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        return order;
    }
}

接下来启动服务,咱们看一下控制台返回的数据

从上面,可以很清晰地看到user是空的,那么我们查询订单的时候想让它显示对应的user信息怎么办呢?

这个时候,订单查询模块的接口就需要远程调用user模块的查询接口得到相应的user信息了。

那么,不同模块之间的怎么调用其他模块的接口呢?

有了这些疑问,接下来,大家跟着风哥一起探索一下吧。

2.2 案例需求

在做一个功能时,我们的大体思路都是先确定需求,画好流程图,然后讨论,明确需求,再去实施,微服务同样也不例外。

接下来,咱们看一下各个模块相互间的功能需求图,咱们这个小demo及其简单,微服务间的接口间的相互调用只有order-service中的查询接口的方法内去调用user-service中的查询接口,来,看需求图。

看了需求图,相信大家对过程有了一个更清晰的了解,也明白接下来咱们需要做什么了,没错,我上句话已经说过了,order-service模块中的查询方法要向user-service模块发送一个http请求,调用http://localhost:8081/user/{userId}这个接口,获得相应的用户信息。

然而呢,比较细心的小伙伴们,相信已经发现了现在风哥好像还没有说通过调用用户模块查询接口获取用户数据返回的数据类型是什么?

有的人肯定会说,那肯定是User类型啊。这样说没错,但是说明咱们欠缺了思考,从另一个模块的接口获得数据,你这个模块里又没有相应的数据类型,你怎么将人家的数据封装成User类型呢?而这也恰恰是咱们需要学习远程调用中的一个关键部分。带着疑问出发学习更有劲,那么,跟着风哥来看一下具体的步骤吧。

大概步骤:

  • 注册一个RestTemplate的实例并注入到Spring容器中取
  • 在order-service中修改OrderService类中的queryOrderById方法,根据Order对象中的userid查询user数据
  • 在OrderService类中注入RestTemplate的实例对象,通过调用它的getForObject()方法将指定url的数据封装成指定类型的数据
  • 将封装的User对象加入到Order对象中去,返回Order对象

来,小伙伴们跟着风哥的步骤一起来做一下,let’s go.

步骤一 在order模块的启动类注册RestTemplate对象

为什么选择在order模块的启动类中呢,因为在这个过程中,order模块的相应方法是一个消费者行为,user模块充当的是一个服务者行为,而关于消费者和服务者理论,我会放在文末进行描述。

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.classargs);
    }

    /**
     * 为了实现负载均衡
     * 创建RestTemplate并注入Spring容器中
     * @return
     */

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

}

步骤二 调用相应接口获取并封装数据

在这里,我把细分的2-4步合并为了一步,因为实现起来,不要问:风哥,为啥呢?因为它俩密不可分呐,拆开来描述是为了让大家更清晰地去了解具体流程,而现在实现则要根据实际情况啊,宝贝儿们。

这里我为什么url前面用的是userservice,而不是其微服务模块对应的端口呢,这就涉及了Eureka的知识了,在这里没改是为了给大家先埋下个种子。

restTemplate.getForObject(url, User.class):通过url调用相应的接口获取数据并封装成User数据类型

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        //2.查询user
        //2.1.获取url地址
        String url = "http://userservice/user/"+order.getUserId();
        //2.2.根据url发起远程调用获取user
        User user = restTemplate.getForObject(url, User.class);
        //3.设置用户
        order.setUser(user);
        // 4.返回
        return order;
    }
}

最后返回所需要的order数据类型即可。

结果图

2.3 服务者和消费者

前面说好的哈,文末跟大家聊一聊服务者和消费者理论。

在服务调用关系中,都有两个不同的角色:

  • 服务者:即服务的提供方,说的现实一点,就是乙方啊😂
  • 消费者:调用服务的一方,也说现实一点,就是甲方啊😂

在咱们这个小案例demo中,服务者和消费者非常清晰。

但是,凡是没有绝对,就像相对静止状态一样,状态随时可能会变,可能下一个业务中user-service就成了消费方,而order就成了服务者了,所以,这要根据具体业务具体分析🐶。


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,长按”或“扫描”下方二维码噢

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

文章有帮助的话,在看,转发吧。

谢谢支持哟 (*^__^*)

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
夜航气象站|“洋葱式穿衣法”速速学起来,最近在哈尔滨挺管用!留美理工女的诗和远方凯悦计划收购精选酒店预定平台史密斯夫妇【买史密斯GC可得Hyatt积分和房晚】竞赛|剑桥点名的化学竞赛UKChO,学霸都在偷偷备考!23新增考点get起来!中转SpringCloud 远程调用为啥要采用HTTP,而不是RPC?白俄罗斯雷达公司的三大利器,包括电子战系统和远程搜索雷达联合国教科文组织:2023全球中小学人工智能课程调研报告面试官:Feign 第一次调用为什么会很慢?大部分人都答不上来!水乡AI Agent 如何实现?6张4090 魔改Llama2:一句指令拆分任务、调用函数英媒揭开凯特保持平坦小腹的秘密,宅家都能学起来啊康州美景两日游!还有蒸汽火车乘坐!花和远方,皆不可错过!活动日程调整!第五届中国AFOL节暨乐高Ⓡ玩家作品交流展逛展全攻略!GDB 调试器如何通过调用帧信息来确定函数调用关系 | Linux 中国面试官:Feign第一次调用为什么会很慢?100句高频旅游口语,超实用,学完与老外对答如流!【滋味】重阳节将至,软糯不粘牙的重阳糕学起来!游记:莫斯科的大街小巷(文字+视频)在临海小镇做全麻手术太实用了!20个做菜小技巧,退休厨师都说好!快学起来吧!假期过半、喜报又来!新学期在即,这个课真心推荐给孩子们安排起来!GPT-4调用插件40次都没成功,果断放弃,无效调用、拒绝回答时有发生王室御用室内设计师的13个小妙招,可以学起来!为应对“哥谭市治安”,墨尔本华女分享“土澳最安全穿搭”,“Local见了抖三抖!“还不赶紧学起来!靠考学改变命运的我,该如何与孩子的低分和解?| 人间一篇带你看懂居住证积分和落户政策靠考学改变命运的我,该如何与孩子的低分和解?谁才是黑眼圈和细纹的救星?这支小金管眼霜用成分和实力说话孩子坐姿、体态不好,需要担心脊柱侧弯吗?如何排查和远离?“生活的选择就像围城,在故乡和远方间穿梭”湾区斜杠青年 - 生活不止眼前的苟且,还有赛车和远方「云集 | 职挂云帆」“一带一路”重磅白皮书发布,16个双语关键词学起来!妖鬼2【深圳】线下沙龙 | 漫步投资、财富和远方
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。