微服务笔记-拆分
微服务相比单体架构,提高了web应用的可用性,一部分服务挂了不会直接导致系统不可用。在微服务里会有服务集群部署的概念,通过这种方式可以将一个大型系统拆分部署到多个服务器上,对访问量高和重要的核心业务分配高性能服务器和配置更强的防御,不那么重要的业务分配普通的服务器,服务器资源的分配将更加合理。
当然,拆分后会产生一些新的问题,服务间互相访问需要远程调用,以及如何保证请求转发的时候仍然携带用户信息,服务注册与发现等,都会在微服务的学习中解决。
普通的MySQL服务能承受的访问量是比较低的,通常只有几百请求每秒,过多的请求会让单体项目的其他业务接口访问响应变慢,从几十毫秒下降到几百毫秒甚至无法访问。
这次学习使用的是黑马程序员公开在B站的微服务课程,对黑马商城进行拆分。
环境准备
一个前端html部署在nginx,一个Docker容器部署的MySQL数据库,以及完整的黑马商城后端Java代码。
注意:容器间相互访问需要创建Docker网络
# 创建网络
docker network create hm-net
# 创建MySQL容器
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=root \
-v /root/mysql/data:/var/lib/mysql \
-v /root/mysql/conf:/etc/mysql/conf.d \
-v /root/mysql/init:/docker-entrypoint-initdb.d \
--network hm-net\
mysql
SpringCloud
推荐使用:Spring Cloud 2021.0.x以及Spring Boot 2.7.x版本,因为现在仍然有大量的企业项目使用jdk17以下的版本,新版本依赖jdk17,所以统一版本的使用。
黑马微服务UML
UML是早期程序设计的时候程序员都要画的图,只不过由于可扩展性以及项目越来越复杂几乎已经没人画了,在大学的时候潘sir布置作业画这玩意真的折磨人,不过UML留存到现在这种时序流程的结构还是很清晰的,微信支付也是这样的图,还算继续发挥作用。
服务拆分原则
高内聚、低耦合
黑马商城后端业务可以拆成购物车模块,商品模块,支付模块,交易模块,用户模块,除此以外,还需要新建一个网关模块和远程调用api模块。
具体步骤是:创建空模块,拷贝实体类、mapper、service和controller,添加yml配置文件,添加服务名,数据库连接信息,引入pom依赖,然后编辑启动配置启动服务。原来的hm-service模块就可以删掉了。
细节:部分调用业务代码需要根据远程服务调用接口修改,启动类上需要增加包扫描路径,并且报红的模块名都要删掉再重新导入。
部分服务间存在调用关系,查看购物车需要在购物车服务调用商品服务,如这张图所示。
服务注册与发现
假如商品微服务被调用较多,为了应对更高的并发,我们进行了多实例部署,如图:
此时,每个item-service
的实例其IP或端口不同,问题来了:
item-service这么多实例,cart-service如何知道每一个实例的地址?
http请求要写url地址,
cart-service
服务到底该调用哪个实例呢?如果在运行过程中,某一个
item-service
实例宕机,cart-service
依然在调用该怎么办?如果并发太高,
item-service
临时多部署了N台实例,cart-service
如何知道新实例的地址?
为了解决上述问题,就必须引入注册中心的概念了,在微服务远程调用的过程中,包括两个角色:
服务提供者:提供接口供其它微服务访问,比如
item-service
服务消费者:调用其它微服务提供的接口,比如
cart-service
在大型微服务项目中,服务提供者的数量会非常多,为了管理这些服务就引入了注册中心的概念。注册中心、服务提供者、服务消费者三者间关系如下:
Nacos:Alibaba公司出品,目前被集成在SpringCloudAlibaba中,一般用于Java应用
Nacos安装
步骤:创建数据库,创建nacos容器,配置env
docker run -d \
--name nacos \
--env-file ./nacos/custom.env \ # env路径要正确
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--network hm-net \
--restart=always \
nacos/nacos-server:v2.1.0-slim
启动完成后,访问下面地址:http://IP:8848/nacos/,就可以进入nacos管理系统了,账号:密码,nacos:nacos
注意:如果使用云服务器,必须开放使用到的端口的云服务器安全组和Linux防火墙。
在pom文件引入nacos依赖,在yml文件添加服务地址,重启就可以将服务注册到nacos注册中心了。
<!--nacos 服务注册发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
OpenFeign
让远程调用像本地方法调用一样简单,这就是openfeign的作用。
添加依赖
在cart-service
服务的pom.xml中引入OpenFeign
的依赖和loadBalancer
依赖:
<!--openFeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--负载均衡器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
启用OpenFeign
接下来,我们在cart-service
的CartApplication
启动类上添加注解,启动OpenFeign功能:
@EnableOpenFeignClient
连接池
Feign底层发起http请求,依赖于其它的框架。其底层支持的http客户端实现包括:
HttpURLConnection:默认实现,不支持连接池
Apache HttpClient :支持连接池
OKHttp:支持连接池
因此我们通常会使用带有连接池的客户端来代替默认的HttpURLConnection。比如,我们使用OK Http.
添加依赖
在cart-service
的pom.xml
中添加如下依赖:
<!--OK http 的依赖 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
开启连接池
在cart-service
的application.yaml
配置文件中开启Feign的连接池功能:
feign:
okhttp:
enabled: true
重启服务,连接池就生效了。