02-微服务的拆分规则和基于RestTemplate的远程调用

微服务的拆分与远程调用

创建父工程

任何分布式架构都离不开服务的拆分, 微服务也是一样 , 微服务的拆分遵守三个原则

  • 微服务需要根据业务模块拆分,不同微服务不要重复开发相同业务
  • 每个微服务都有自己独立的数据库, 不要直接访问其他微服务的数据库
  • 微服务可以将自己的业务暴露为接口供其他微服务调用

创建父工程cloud-demo用来管理项目所需要的依赖的版本

  • order-service订单微服务模块(工程): 负责订单相关业务,如根据订单Id查询订单
  • user-service用户微服务模块(工程): 负责用户相关业务,如根据用户Id查询用户

在这里插入图片描述

<groupId>cn.itcast.demo</groupId>
<artifactId>cloud-demo</artifactId>
<version>1.0</version>
<!--管理子模块-->
<modules><module>user-service</module><module>order-service</module>
</modules>
<packaging>pom</packaging><!--当前SpringBoot项目继承的父工程-->
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.9.RELEASE</version><relativePath/>
</parent><!--依赖版本号属性-->
<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><spring-cloud.version>Hoxton.SR10</spring-cloud.version><mysql.version>5.1.47</mysql.version><mybatis.version>2.1.1</mybatis.version>
</properties><!--引用定义的依赖版本属性值,对依赖的版本进行管理,并不会在项目中引入依赖-->
<dependencyManagement><dependencies><!-- springCloud --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><!-- mysql驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.version}</version></dependency></dependencies>
</dependencyManagement>
<dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
</dependencies>

创建订单微服务模块(工程)

第一步: 执行cloud-order.sql文件创建订单数据库,cloud-ordertb_order表中含有用户数据库的tb_user表的Id字段

在这里插入图片描述

@Data
public class Order {private Long id;private Long price;private String name;private Integer num;private Long userId;private User user;
}

第二步: 配置order-service工程的pom.xml文件

<parent><artifactId>cloud-demo</artifactId><groupId>cn.itcast.demo</groupId><version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>order-service</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency>
</dependencies>
<build><finalName>app</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>

第三步: 配置order-service工程的application.yml文件

server:port: 8080
spring:datasource:url: jdbc:mysql://localhost:3306/cloud_order?useSSL=falseusername: rootpassword: 123driver-class-name: com.mysql.jdbc.Driver
mybatis:type-aliases-package: cn.itcast.user.pojoconfiguration:map-underscore-to-camel-case: true
logging:level:cn.itcast: debugpattern:dateformat: MM-dd HH:mm:ss:SSS

第四步: 创建Mapper接口和自定义Service类,这里就不再创建业务类的实现类了

@Mapper
public interface OrderMapper {@Select("select * from tb_order where id = #{id}")Order findById(Long id);
}
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate UserClient userClient;public Order queryOrderById(Long orderId) {// 查询订单Order order = orderMapper.findById(orderId);// 返回查询到的订单对象,user属性为nullreturn order;}
}

第五步: 在order-service工程中创建controller/OrderController,编写接口根据订单Id从订单数据库中查询订单信息

@RestController
@RequestMapping("order")
public class OrderController {@Autowiredprivate OrderService orderService;@GetMapping("{orderId}")public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {// 根据id查询订单并返回return orderService.queryOrderById(orderId);}
}

第五步: 打开浏览器访问http://localhost:8080/order/101可以查询到订单数据的但此时user属性的值是null

{"id": 101,"price": 699900,"name": "Apple 苹果 iPhone 12 ","num": 1,"userId": 1,"user": null
}

创建用户微服务模块(工程)

第一步: 执行cloud-user.sql文件创建用户数据库,创建tb_user表及其对应的实体类

在这里插入图片描述

@Data
public class User {private Long id;private String username;private String address;
}

第二步: 配置user-service工程的pom.xml文件

<parent><artifactId>cloud-demo</artifactId><groupId>cn.itcast.demo</groupId><version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion><artifactId>user-service</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency>
</dependencies>
<build><finalName>app</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>

第三步: 配置user-service工程的application.yml文件

server:port: 8081
spring:datasource:url: jdbc:mysql://localhost:3306/cloud_user?useSSL=falseusername: rootpassword: 123driver-class-name: com.mysql.jdbc.Driver
mybatis:type-aliases-package: cn.itcast.user.pojoconfiguration:map-underscore-to-camel-case: true
logging:level:cn.itcast: debugpattern:dateformat: MM-dd HH:mm:ss:SSS

第四步: 配置Mapper接口和Service类,这里就不再创建业务类的实现类了

@Mapper
public interface UserMapper {    @Select("select * from tb_user where id = #{id}")User findById(@Param("id") Long id);
}
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public User queryById(Long id) {return userMapper.findById(id);}
}

第五步: 在user-service工程中创建controller/UserController,编写接口根据用户Id从用户数据库中查询用户信息

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;/*** 路径: /user/110* @param id 用户id* @return 用户*/@GetMapping("/{id}")public User queryById(@PathVariable("id") Long id) {return userService.queryById(id);}
}

第六步: 打开浏览器访问http://localhost:8081/user/1查询到的数据如下

{"id": 1,"username": "柳岩","address": "湖南省衡阳市"
}

远程调用(RestTemplate)

需求: 访问订单模块根据订单Id查询订单,根据查询的订单对象中包含的userId访问用户模块查询出用户信息,然后封装到订单对象的user属性中返回

在这里插入图片描述

RestTemplate是Spring提供的发起http请求的工具类

方法名功能
Object getForObject(url, Xxx.class)发起一个get请求并指定返回的类型(服务器默认返回Json类型的数据)
Object postForObject(url, Xxx.class)发起一个post请求并指定返回的类型(服务器默认返回Json类型的数据)

第一步: 在order-service服务的代码逻辑中向user-service服务发起一个http请求,访问http://localhost:8081/user/{userId}查询用户信息

在这里插入图片描述

第二步: 在order-service服务中的OrderApplication启动类中(本质是个配置类)注册RestTemplate实例到Spring容器当中

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}

第三步: 修改订单服务的OrderService类中的queryOrderById方法,根据Order对象中包含的userId发http请求访问用户服务查询用户信息,然后一并返回

@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;public Order queryOrderById(Long orderId) {// 1.查询订单Order order = orderMapper.findById(orderId);// 2.使用RestTemplate指定url地址发起http请求查询User,指定接收的类型(服务器默认返回Json类型的数据)String url = "http://localhost:8081/user/" + order.getUserId();User user = restTemplate.getForObject(url, User.class);// 3.存入orderorder.setUser(user);// 4.返回return order;}
}

第四步: 访问订单服务查询订单的接口http://localhost:8080/order/101,此时订单对象中包含对应用户的信息

{"id": 101,"price": 699900,"name": "Apple 苹果 iPhone 12 ","num": 1,"userId": 1,"user": {"id": 1,"username": "柳岩","address": "湖南省衡阳市"}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/157137.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【网络安全】-网络安全的分类详解

文章目录 介绍1. 网络层安全&#xff08;Network Layer Security&#xff09;理论实操使用VPN保护隐私 2. 应用层安全&#xff08;Application Layer Security&#xff09;理论实操使用密码管理器 3. 端点安全&#xff08;Endpoint Security&#xff09;理论实操定期更新防病毒…

武汉凯迪正大—盐雾试验机

产品概述 武汉凯迪正大KDYD-YW盐雾试验箱乃针对各种材质表面处理&#xff0c;包含涂料、电镀、有机及无机皮膜&#xff0c;阳极处理&#xff0c;防锈油等防腐处理后测试其耐腐蚀性&#xff0c;从而确立产品的质量。 产品特点 1、结构紧凑&#xff0c;体积小、携带方便&#…

艺术作品3D虚拟云展厅能让客户远程身临其境地欣赏美

艺术品由于货物昂贵、易碎且保存难度大&#xff0c;因此在艺术品售卖中极易受时空限制&#xff0c;艺术品三维云展平台在线制作是基于web端将艺术品的图文、模型及视频等资料进行上传搭配&#xff0c;构建一个线上艺术品3D虚拟展厅&#xff0c;为艺术家和观众提供了全新的展示和…

Chrome和chromedriver版本不匹配导致的UI自动化测试无法运行的问题

今天&#xff0c;遇到一个小问题&#xff0c;本来跑的好好UI自动化测试脚本突然不好使了&#xff0c;期初怀疑是页面元素有调整导致脚本出现异常无法正常执行&#xff0c;经排查后发现近期页面没有任何调整。 这下头大了&#xff0c;啥也没改&#xff0c;怎么好好的脚本不能跑…

Vue3鼠标拖拽生成区域块并选中元素

Vue3鼠标拖拽生成区域块并选中元素&#xff0c;选中的元素则背景高亮(或者其它逻辑)。 <script setup> import { ref } from vue// 区域ref const regionRef ref(null)// 内容ref const itemRefs ref(null)// 是否开启绘画区域 const enable ref(false)// 鼠标开始位置…

LVS+keepalived——高可用集群

lvskeepalived&#xff1a;高可用集群 keepalived为lvs应运而生的高可用服务。lvs的调度器无法做高可用&#xff0c;于是keepalived这个软件。实现的是调度器的高可用。但是&#xff1a;keepalived不是专门为lvs集群服务的&#xff0c;也可以做其他代理服务器的高可用。 lvs的…

基于SSM的进销存管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Vue typescript项目配置eslint+prettier

1.安装依赖 安装 eslint yarn add eslint --dev安装 eslint-plugin-vue yarn add eslint-plugin-vue --dev主要用于检查 Vue 文件语法 安装 prettier 及相关插件 yarn add prettier eslint-config-prettier eslint-plugin-prettier --dev安装 typescript 解析器、规则补充 …

Spring-IOC-@Import的用法

1、Car.java package com.atguigu.ioc; import lombok.Data; Data public class Car {private String cname; }2、 MySpringConfiguration2.java package com.atguigu.ioc; import org.springframework.context.annotation.Bean; import org.springframework.context.annotatio…

树莓派的的串口通信协议

首先&#xff0c;回顾一下串口的核心知识点&#xff0c;也是面试重点&#xff1a; 串口通信通常使用在多机通讯中串口通信是全双工的决定串口通信的成功与否的是 数据格式 和 波特率数据格式&#xff1a;1. 数据位 2.停止位 3. 奇偶校验位 树莓派恢复串口 回忆前几节树莓派刷机…

Vue3 配置全局 scss 变量

variables.scss $color: #0c8ce9;vite.config.ts // 全局css变量css: {preprocessorOptions: {scss: {additionalData: import "/styles/variables.scss";,},},},.vue 文件使用

AI大发展:人机交互、智能生活全解析

目录 ​编辑 人工智能对我们的生活影响有多大 人工智能的应用领域 一、机器学习与深度学习 二、计算机视觉 三、自然语言处理 四、机器人技术 五、智能推荐系统 六、智能城市和智能家居 ​编辑 自己对人工智能的应用 自己的人工智能看法&#xff1a;以ChatGPT为例 …

一种全新且灵活的 Prompt 对齐优化技术

并非所有人都熟知如何与 LLM 进行高效交流。 一种方案是&#xff0c;人向模型对齐。 于是有了 「Prompt工程师」这一岗位&#xff0c;专门撰写适配 LLM 的 Prompt&#xff0c;从而让模型能够更好地生成内容。 而另一种更为有效的方案则是&#xff0c;让模型向人对齐。 这也是…

分布式任务调度-XXL-job

目录 源码仓库地址 前置环境 docker容器环境配置 连接linux数据库&#xff0c;并创建任务调度所用到的数据库xxl-job。 用到的表sql 打开映射网址 后端配置使用任务调度 依赖 yml配置 使用架构 config配置 job使用 快速入门使用 任务调度执行器 任务调度执行管理​编…

ck 配置 clickhouse-jdbc-bridge

背景 ck可以用过clickhouse-jdbc-bridge技术来直接访问各数据库 安装配置 需要准备的文件 clickhouse-jdbc-bridge https://github.com/ClickHouse/clickhouse-jdbc-bridge 理论上需要下载源码然后用mavne打包&#xff0c;但提供了打包好的&#xff0c;可以推测用的是mave…

USART的标准库编程

使用USART与计算机通信 电脑上只有usb端口 没有TX 和RX需要一个USB转TTL电平模块来实现通信 芯片C8T6中只有三个UASRT 选其中一个UASRT来通信即可 那么如何定位那个USART的TX 和RX引脚呢&#xff1f; 方式1 查找最小系统板引脚分布图 查找USART1的引脚 RTS CTS是硬件流控 CK…

C练习题_15

一、单项选择题(本大题共20小题&#xff0c;每小题2分&#xff0c;共40分。在每小题给出的四个备选项中&#xff0c;选出一个正确的答案,并将所选项前的字母填写在答题纸的相应位置上。) 在下列说法中&#xff0c;&#xff08;&#xff09;是正确的。 A.C程序从第一个函数开始…

Cache学习(1):常见的程序运行模型多级Cache存储结构

0 背景&#xff1a;常见的程序运行模型&#xff08;为什么要Cache&#xff09; 主存&#xff1a;Main Memory&#xff0c;硬件实现为RAM&#xff0c;产品形态&#xff1a;DDR&#xff08;例如&#xff1a; DDR3、DDR4等&#xff09;磁盘设备&#xff1a;Flash Memory&#xff…

IDEA如何将本地项目推送到GitHub上?

大家好&#xff0c;我是G探险者。 IntelliJ IDEA 是一个强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它支持多种编程语言和工具。它也内置了对Git和GitHub的支持&#xff0c;让开发者可以轻松地将本地项目推送到GitHub上。以下是一个操作手册&#xff0c;描述了…

Ubuntu下载离线安装包

旧版Ubuntu下载地址 https://old-releases.ubuntu.com/releases/ 下载离线包 sudo apt-get --download-only -odir::cache/ncayu install net-tools下载snmp离线安装包 sudo apt-get --download-only -odir::cache/root/snmp install snmp snmpd snmp-mibs-downloadersudo a…