微服务01
导入微服务项目
步骤按照飞书文档记录的步骤操作
记录一下卡了我两天的小问题
按照步骤我一直无法登陆,遇到的问题是我无论启不启动后端,我的前端登录一直都是用户名密码错误,启动后端登录会报错Mybatispuls版本相关的内容,我也尝试改了版本号,都没有解决。然后查询得知可能是缓存依赖的问题(我有Maven clean),但发现启动的时候还是3.4.3版本(我使用JDK17,根据视频弹幕我需要改成3.4.2版本),我又每个文件夹下全部重新Maven clean 一次(对了,这次成功的时候我还点击了reload all Maven project,就是那个转圈的图标),这时候在启动就改为3.4.2版本了,后面就是报了个数据库连接相关的错误(这就说明我的版本问题解决了!),发现是我配置的虚拟机IP改变了,重新修改地址就好了,然后成功登录了!
认识微服务
单体架构:将业务中的所有功能集中在一个项目中开发,打成一个包部署。
微服务架构:是服务化思想指导下的一套最佳实践架构方案。服务化,就是把单体架构中的功能模块拆分为多个独立项目。
微服务拆分
拆分原则
创业型项目:先采用单体架构,快速开发,快速试错。随着规模扩大,逐渐拆分 – 先易后难
确定的大型项目:资金充足,目标明确,可以直接选择微服务架构,避免后续拆分的麻烦 – 先难后易
拆分目标
高内聚:每个服务的职责尽量单一,包含的业务相互关联度搞,完整度高
低耦合:每个微服务的功能要相对独立,尽量减少对其他维服务的依赖
拆分方式
纵向拆分:按照业务模块来拆分
横向拆分:抽取公共服务,提高复用性
黑马商城选择Maven聚合工程结构(每new出来一个module就是一个新的微服务)
商品模块
1.新建module,创建新启动类,拷贝配置文件(修改配置文件端口和服务名称)
2.每个微服务一个新的数据库,创建数据库,导入数据库表(数据库之间独立,服务器代价太大,此处直接用不同的数据库)
3.拷贝代码,要先拷贝domain包下相关内容,domain->mapper->service->controller
4.特别注意service实现代码中String sqlStatement = “com.hmall.item.mapper.ItemMapper.updateStock”;修改了,添加了item
5.启动类的激活文件不要忘记改为local
6.启动item-service,访问商品微服务的swagger接口文档:http://localhost:8081/doc.html
购物车模块类似
服务调用
远程调用
在购物车启动类将RestTemplate注册为Bean
public class CartApplication {
public static void main(String[] args) {
SpringApplication.run(CartApplication.class, args);
}
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
调用http请求代码:一直报错,后面找到原因是HttpMethod导入的包不对。
ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
"http://localhost:8081/items?ids={ids}",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<ItemDTO>>() {},
Map.of("ids",CollUtil.join(itemIds,","))
);
服务注册和发现
背景:手动发送Http请求的方式存在一些问题。假如商品微服务被调用较多,为了应对更高的并发,我们进行了多实例部署,每个item-service的实例其IP或端口不同,cart-service如何知道实例的地址,调用哪一个,服务挂掉了怎么办之类的问题,所以需要引入注册中心的概念。
虚拟机设置为静态IP:因为后面nacos也需要IP地址,此处插播记录下我设置静态IP过程
我本身的设置是自定义Nat模式,
找到文件"/etc/netplan/01-network-manager-all.yaml"修改为:
# Let NetworkManager manage all devices on this system
network:
version: 2
renderer: NetworkManager
#xiamain add
renderer: networkd
ethernets:
ens33:
dhcp4: no
addresses:
- 192.168.208.136/24 #自己想配的地址
gateway4: 192.168.208.2
nameservers:
addresses:
- 8.8.8.8
- 8.8.4.4
保存后执行sudo netplan apply
应用新的网络设置即可
基于docker部署nacos的注册中心,详见黑马在线文档
服务注册
item-service注册到Nacos,步骤如下:
- 引入依赖
- 配置Nacos地址
- 重启
服务发现
服务的消费者要去nacos订阅服务,这个过程就是服务发现,步骤如下:
- 引入依赖
- 配置Nacos地址
- 发现并调用服务
OpenFeign
Nacos实现了服务的治理,利用RestTemplate实现了服务的远程调用。但是远程调用的代码太复杂了,远程调用关键点就4个:
- 请求方式
- 请求路径
- 请求参数
- 返回值类型
OpenFeign就利用SpringMVC的相关注解来声明上述4个参数,然后基于动态代理帮我们生成远程调用的代码,而无需我们手动再编写,非常方便
具体步骤见文档
(第二天购物车服务和商品服务突然无法启动,重启下nacos服务,docker restart nacos)
OpenFeign连接池
- 引入依赖
- 开启连接池功能
- 验证
连接池用法不会改变,但是发起请求的性能会提高
最佳实践
当不同微服务都需要调用一个微服务的接口时候,如何减少代码重复呢?但是抽取!
- 思路1:抽取到微服务之外的公共module
- 思路2:每个微服务自己抽取一个module
方案1抽取更加简单,工程结构也比较清晰,但缺点是整个项目耦合度偏高。
方案2抽取相对麻烦,工程结构相对更复杂,但服务之间耦合度降低。
黑马商城采用方案一
- 在hmall下定义一个新的module,命名为hm-api
- 修改依赖
- 把ItemDTO和ItemClient都拷贝过来(cart-service下的可以删除了)
- 任何微服务要调用item-service中的接口,只需要引入hm-api模块依赖即可,无需自己编写Feign客户端了
- cart-service的pom.xml中引入hm-api模块;删除cart-service中原来的ItemDTO和ItemClient,重启项目,发现报错了;这里因为ItemClient现在定义到了com.hmall.api.client包下,而cart-service的启动类定义在com.hmall.cart包下,扫描不到ItemClient,所以报错了。
- 解决方法如下
日志配置直接看黑马文档
用户、交易和支付拆分见文档