第一天
项目熟悉
hm-common:用来存放使用到的工具包
hm-service: 整个单体项目
大差不差,配置层,控制层,实体,mapper接口,业务逻辑,配置文件
微服务架构认识
个人理解微服务是一个架构思想,通过Spring Cloud框架去实现技术。简单来说就是一个单体项目随着业务的发展会不断扩增项目功能,这样会造成性能下降。微服务是将一个单体项目中的各个模块功能拆开,每一个模块相互独立分别部署,这样不会因为某个模块的压力影响到另一个模块的功能使用,提高整体项目的性能。
如何对项目的拆分?
以黑马商城为例:黑马商城有五个模块,登录,搜索商品,购物车,下单,支付。我们可以按照模块功能拆分,只要能保证每一个服务能够完整的完成一个模块功能就行。
拆分商品服务和购物车
根据controller层,我们找出商品服务有关的类:ItemController,然后根据controller ——> service ——> mapper ——> domain 这条链路找到所有有关商品的类或接口,抽离出来放到新建maven项目里:
同理,购物车服务也是如此。
服务之间如何调用?
我们可以想想前端是如何获取数据的,前端就是通过接口加上参数与后端连接获取数据。所以服务之间也是通过网络请求相互通信的。
这里用到 Spring 的 RestTemplate去实现,利用它我们可以实现后端程序发送网络请求。
我们先注册Bean:
这里推荐通过构造注入依赖:
然后通过 exchange 方法就可以发起请求了给购物车服务:
RestTemplate 模板: <T> ResponseEntity<T> exchange( String url, // 请求地址 HttpMethod method, // 请求方法(GET, POST等) HttpEntity<?> requestEntity, // 请求实体(包含请求头和请求体,GET时通常为null) ParameterizedTypeReference<T> responseType, // 响应类型(用于处理泛型) Map<String, ?> uriVariables // URL中的路径变量参数 )
购物车中能查到商品的最新价格了:
总之微服务之间远程调用称为RPC,RPC实现又基于Http协议。
Http方式,这种方式不关心服务提供者的具体技术实现,只要对外暴露Http接口即可。
Java发送http请求可以使用Spring提供的RestTemplate,使用的基本步骤如下:
注册RestTemplate到Spring容器
调用RestTemplate的API发送请求,常见方法有:
getForObject:发送Get请求并返回指定类型对象
PostForObject:发送Post请求并返回指定类型对象
put:发送PUT请求
delete:发送Delete请求
exchange:发送任意类型请求,返回ResponseEntity
服务注册和发现
通过远程调用我们实现的服务之间的通信,但是如果item-service服务部署了多个实例,cart-service如何知道这些实例的地址?或如何调用这些实例?
所以我们引入了nacos注册中心。
什么是注册中心?
我们要清楚一个概念,服务调用者和服务提供者。
服务调用者:调用其它服务的实例
服务提供者:给其它服务调用的实例
注册中心就是管理服务调用和提供,它内部管理了所有服务提供者的地址,服务调用者调用服务时会根据服务名在注册中心中筛选出地址,然后根据负载均衡算法就能远程调用。此外,每一个服务调用者会发送心跳给注册中心,注册中心以此来判断部署实例是否有宕机,然后在第一时间发送给服务调用者,这样服务调用者就知道自己获取到的地址是否能正常使用。
nacos注册服务
不论是服务调用者还是服务提供者都需要引入依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
配置nacos地址:
spring:
application:
name: item-service # 服务名称
cloud:
nacos: server-addr: 192.168.150.101:8848 # nacos地址
spring:
cloud:
nacos:
server-addr: 192.168.150.101:8848
完成依赖引入和配置后,启动服务,它们就会自动注册到 Nacos 注册中心。
发现调用服务
这里思路是:
- 通过实例名获取服务列表
- 通过负载均衡算法调用某一个服务(这里就随机调用了)
注入 discoveryClient依赖
动态拼接调用地址,更灵活,不用写死
后续
打算边学边更,等学完看能不能扩展项目,引入redis,RabbitMQ等中间件。