黑马商城微服务复习(2)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、单体架构缺点


提示:以下是本篇文章正文内容,下面案例可供参考

二、微服务

微服务架构,首先是服务化,就是将单体架构中的功能模块从单体应用中拆分出来,独立部署为多个服务。同时要满足下面的一些特点:

  • 单一职责:一个微服务负责一部分业务功能,并且其核心数据不依赖于其它模块。
  • 团队自治:每个微服务都有自己独立的开发、测试、发布、运维人员,团队人员规模不超过10人(2张披萨能喂饱)
  • 服务自治:每个微服务都独立打包部署,访问自己独立的数据库。并且要做好服务隔离,避免对其它服务产生影响
    例如,黑马商城项目,我们就可以把商品、用户、购物车、交易等模块拆分,交给不同的团队去开发,并独立部署:
    在这里插入图片描述
  • 团队协作成本高?
    • 由于服务拆分,每个服务代码量大大减少,参与开发的后台人员在1~3名,协作成本大大降低
  • 系统发布效率低?
    • 每个服务都是独立部署,当有某个服务有代码变更时,只需要打包部署该服务即可
  • 系统可用性差?
    • 每个服务独立部署,并且做好服务隔离,使用自己的服务器资源,不会影响到其它服务。

三、SpringCloud

1.特点

在这里插入图片描述

四、单体拆分

1 熟悉单体

在这里插入图片描述

在这里插入图片描述
购物车和商品不一致怎么处理

在这里插入图片描述

2. 拆分商品服务

一般微服务项目有两种不同的工程结构:

  • 完全解耦:每一个微服务都创建为一个独立的工程,甚至可以使用不同的开发语言来开发,项目完全解耦。
    • 优点:服务之间耦合度低
    • 缺点:每个项目都有自己的独立仓库,管理起来比较麻烦
  • Maven聚合:整个项目为一个Project,然后每个微服务是其中的一个Module
    • 优点:项目代码集中,管理和运维方便(授课也方便)
    • 缺点:服务之间耦合,编译时间较长

商品服务拆分:
1.在hmall中创建module:
2.选择maven模块,并设定JDK版本为11:
3.商品模块,我们起名为item-service:
4.引入依赖
5.编写启动类


```java
package com.hmall.item;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@MapperScan("com.hmall.item.mapper")
@SpringBootApplication
public class ItemApplication {
    public static void main(String[] args) {
        SpringApplication.run(ItemApplication.class, args);
    }
}

在这里插入图片描述
ymal文件修改

server:
  port: 8081
最重要:微服务名称修改
*spring:
  application:
    name: item-service*
  profiles:
    active: dev
 数据库:每个微服务独享一个数据库
  datasource:
    url: jdbc:mysql://${hm.db.host}:3306/hm-item?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: ${hm.db.pw}

  1. 接下来是配置文件,可以从hm-service中拷贝:
  2. 接下来,就可以启动测试了,在启动前我们要配置一下启动项,让默认激活的配置为local而不是dev:

2.拆分购物车

和商品拆分相似

3. 远程调用

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
先将RestTemplate注册为一个Bean:

package com.hmall.cart.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RemoteCallConfig {

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

接下来,我们修改cart-service中的com.hmall.cart.service.impl.CartServiceImpl的handleCartItems方法,发送http请求到item-service:
在这里插入图片描述

4. 注册中心

在这里插入图片描述

在这里插入图片描述

5.Nacos

5.1 服务注册

  1. 引入依赖
  2. 配置nacos 在item-service的application.yml中添加nacos地址配置:
spring:
  application:
    name: item-service # 服务名称
  cloud:
    nacos:
      server-addr: 192.168.150.101:8848 # nacos地址
  1. 启动服务实例

5.2 服务发现
4. 引入依赖
5. 配置Nacos地址
在cart-service的application.yml中添加nacos地址配置:

spring:
  cloud:
    nacos:
      server-addr: 192.168.150.101:8848
  1. 发现并调用服务
    接下来,服务调用者cart-service就可以去订阅item-service服务了。不过item-service有多个实例,而真正发起调用时只需要知道一个实例的地址。
    因此,服务调用者必须利用负载均衡的算法,从多个实例中挑选一个去访问。常见的负载均衡算法有:
  • 随机
  • 轮询
  • IP的hash
  • 最近最少访问

  • 这里我们可以选择最简单的随机负载均衡
    在这里插入图片描述

通过nacos注册中心,服务调用者在Service中注入discoveryClient,使用里面的方法指定调用服务的名称,负载均衡策略,得到最终的uri,在使用远程调用,获取最终的服务。
在这里插入图片描述
5.3 OpenFeign
在上一章,我们利用Nacos实现了服务的治理,利用RestTemplate实现了服务的远程调用。但是远程调用的代码太复杂了:在这里插入图片描述
而且这种调用方式,与原本的本地方法调用差异太大,编程时的体验也不统一,一会儿远程调用,一会儿本地调用。
因此,我们必须想办法改变远程调用的开发模式,让远程调用像本地方法调用一样简单。而这就要用到OpenFeign组件了。
其实远程调用的关键点就在于四个:

  • 请求方式
  • 请求路径
  • 请求参数
  • 返回值类型
  1. 引入依赖 在cart-service服务的pom.xml中引入OpenFeign的依赖和loadBalancer依赖:
  2. 启用OpenFeign
    接下来,我们在cart-service的CartApplication启动类上添加注解,启动OpenFeign功能:
    在这里插入图片描述
  3. .编写OpenFeign客户端
    4.在这里插入图片描述
  4. 直接使用Feign 进行远程调用
  5. 底层原理相似
    在这里插入图片描述
    默认使用的HttpURLCONNECTION,效率低,所以开启连接池
    在这里插入图片描述
    在这里插入图片描述
    在需要服务调用的单体模块中,新建了Feign客户端,OpenFeign客户端,设置了相关调用请求的名字,参数,然后在对应这个单体模块中直接远程调用方法。

6. 最佳实践

如果拆分了交易微服务(trade-service),它也需要远程调用item-service中的根据id批量查询商品功能。这个需求与cart-service中是一样的。
因此,我们就需要在trade-service中再次定义ItemClient接口,这不是重复编码吗? 有什么办法能加避免重复编码呢?
也就是有两个微服务都需要调用同一个微服务,按之前所说得先在这两个微服务里面都配置依赖,启动OpenFeign,在新建OpenFeign的文件(也就是ItemClient),然后在这两个微服务里分别调用。所以需要简化。简化思路:再开启一个模块,把重合部分都放里,这两个微服务都引入这个模块依赖,到时候直接用
在这里插入图片描述

7. 拆分用户微服务

  1. 创建项目
  2. 引入依赖
  3. 启动类
  4. 配置文件
  5. 代码 复制hm-service中所有与user、address、jwt有关的代码,最终项目结构如下:
  6. user-service也需要自己的独立的database,向MySQL中导入课前资料提供的SQL:
  7. 给user-service配置启动项,设置profile为local:

8. 拆分交易微服务

  1. 创建项目
  2. 依赖
  3. 启动类
  4. 配置文件
  5. 基础代码
  6. 抽取ItemClient接口
    - 根据id查询商品列表
  • 计算商品总价
  • 保存订单
    - 扣减库存
    - 清理购物车商品
    其中,查询商品、扣减库存都是与商品有关的业务,在item-service中有相关功能;清理购物车商品是购物车业务,在cart-service中有相关功能。
    因此交易服务要调用他们,必须通过OpenFeign远程调用。我们需要将上述功能抽取为FeignClient.

首先是扣减库存,在item-service中的对应业务接口如下:在这里插入图片描述
我们将这个接口抽取到hm-api模块的com.hmall.api.client.ItemClient中:
在这里插入图片描述
将接口参数的OrderDetailDTO抽取到hm-api模块的com.hmall.api.dto包下:
在这里插入图片描述
接下来是清理购物车商品,在cart-service中的对应业务接口如下:在这里插入图片描述
在这里插入图片描述
接下来,就可以改造OrderServiceImpl中的逻辑,将本地方法调用改造为基于FeignClient的调用。

8. 拆分支付微服务

  • 扣减用户余额
  • 标记支付单状态为已支付
  • 标记订单状态为已支付

其中,扣减用户余额是在user-service中有相关功能;标记订单状态则是在trade-service中有相关功能。因此交易服务要调用他们,必须通过OpenFeign远程调用。我们需要将上述功能抽取为FeignClient.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值