三、微服务的拆分与编写

【微服务的概念,使用场景,建模,架构通览,拆分微服务并且一步步分析,编写一些基础的微服务功能】

微服务的拆分与编写

(一)、单体架构

什么是单体架构?

一个归档包(例如war格式或者Jar格式)包含了应用所有功能的应用程序,我们通常称之为单体应用。架构单体应用的方法论,我们称之为单体应用架构,这是一种比较传统的架构风格。

架构图

三、微服务的拆分与编写_第1张图片

 缺陷

1.复杂性高
整个项目包含的模块非常多,模块的边界模糊,依赖关系不清晰,代码质量参差不齐,整个项目非常复杂。每次修改代码都心惊胆战,甚至添加一个简单的功能,或者修改一个BUG都会造成隐含的缺陷。

2.技术债务逐渐上升
随着时间推移、需求变更和人员更迭,会逐渐形成应用程序的技术债务,并且越积越多。已使用的系统设计或代码难以修改,因为应用程序的其他模块可能会以意料之外的方式使用它。

3.部署速度逐渐变慢,频率低
随着代码的增加,构建和部署的时间也会增加。而在单体应用中,每次功能的变更或缺陷的修复都会导致我们需要重新部署整个应用。全量部署的方式耗时长、影响范围大、风险高,这使得单体应用项目上线部署的频率较低,从而又导致两次发布之间会有大量功能变更和缺陷修复,出错概率较高。

4.扩展能力受限,无法按需伸缩
单体应用只能作为一个整体进行扩展,无法结合业务模块的特点进行伸缩。

5.阻碍技术创新
单体应用往往使用统一的技术平台或方案解决所有问题,团队的每个成员都必须使用相同的开发语言和架构,想要引入新的框架或技术平台非常困难。

(二)、微服务架构

什么是微服务架构?

三、微服务的拆分与编写_第2张图片

特性

每个微服务可独立运行在自己的进程里;
一系列独立运行的微服务共同创建起整个系统;
每个服务为独立的业务开发,一个微服务只关注某个特定的功能,例如订单管理、用户管理等;
可以使用不同的语言和数据存储技术(契合项目情况和团队的实力);
微服务之间通过轻量级的通信机制进行通信,例如通过REST API进行调用;
全自动的部署机制。

全景架构图

三、微服务的拆分与编写_第3张图片

优点

单个服务更易于开发、维护
单个微服务启动较快
局部修改容易部署
技术栈不受限
按需伸缩

缺点

运维要求高
分布式固有的复杂性

使用环境

大型复杂的系统,例如电商系统
访问压力大的系统,例如秒杀系统
迭代快的系统

(三)、微服务拆分

方法论

三、微服务的拆分与编写_第4张图片

合理的粒度

良好的满足业务
幸福感:你的团队认为微服务不是太大,同时部署也非常地高效
增量迭代:每个微服务之间相对独立,每次迭代只会涉及到有限个微服务
持续进化:如果一个微服务使用Java开发的,现在选用Python,风险是可控的
微服务的拆分是一个动态过程

(四)、微信小程序项目

1、服务拆分

三、微服务的拆分与编写_第5张图片

 2、项目架构图

三、微服务的拆分与编写_第6张图片

3、数据库设计

数据建模

三、微服务的拆分与编写_第7张图片

建表

user-center.sql

CREATE DATABASE `user_center`;
USE `user_center`;
 
-- -----------------------------------------------------
-- Table `user`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `user` (
  `id` INT NOT NULL AUTO_INCREMENT COMMENT 'Id',
  `wx_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '微信id',
  `wx_nickname` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '微信昵称',
  `roles` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '角色',
  `avatar_url` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '头像地址',
  `create_time` DATETIME NOT NULL COMMENT '创建时间',
  `update_time` DATETIME NOT NULL COMMENT '修改时间',
  `bonus` INT NOT NULL DEFAULT 300 COMMENT '积分',
  PRIMARY KEY (`id`))
COMMENT = '分享';
 
 
-- -----------------------------------------------------
-- Table `bonus_event_log`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `bonus_event_log` (
  `id` INT NOT NULL AUTO_INCREMENT COMMENT 'Id',
  `user_id` INT NULL COMMENT 'user.id',
  `value` INT NULL COMMENT '积分操作值',
  `event` VARCHAR(20) NULL COMMENT '发生的事件',
  `create_time` DATETIME NULL COMMENT '创建时间',
  `description` VARCHAR(100) NULL COMMENT '描述',
  PRIMARY KEY (`id`),
  INDEX `fk_bonus_event_log_user1_idx` (`user_id` ASC) )
ENGINE = InnoDB
COMMENT = '积分变更记录表';

content-center.sql

CREATE DATABASE `content_center`;
USE `content_center`;
 
-- -----------------------------------------------------
-- Table `share`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `share` (
  `id` INT NOT NULL AUTO_INCREMENT COMMENT 'id',
  `user_id` INT NOT NULL DEFAULT 0 COMMENT '发布人id',
  `title` VARCHAR(80) NOT NULL DEFAULT '' COMMENT '标题',
  `create_time` DATETIME NOT NULL COMMENT '创建时间',
  `update_time` DATETIME NOT NULL COMMENT '修改时间',
  `is_original` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否原创 0:否 1:是',
  `author` VARCHAR(45) NOT NULL DEFAULT '' COMMENT '作者',
  `cover` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '封面',
  `summary` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '概要信息',
  `price` INT NOT NULL DEFAULT 0 COMMENT '价格(需要的积分)',
  `download_url` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '下载地址',
  `buy_count` INT NOT NULL DEFAULT 0 COMMENT '下载数 ',
  `show_flag` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否显示 0:否 1:是',
  `audit_status` VARCHAR(10) NOT NULL DEFAULT 0 COMMENT '审核状态 NOT_YET: 待审核 PASSED:审核通过 REJECTED:审核不通过',
  `reason` VARCHAR(200) NOT NULL DEFAULT '' COMMENT '审核不通过原因',
  PRIMARY KEY (`id`))
ENGINE = InnoDB
COMMENT = '分享表';
 
 
-- -----------------------------------------------------
-- Table `mid_user_share`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mid_user_share` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `share_id` INT NOT NULL COMMENT 'share.id',
  `user_id` INT NOT NULL COMMENT 'user.id',
  PRIMARY KEY (`id`),
  INDEX `fk_mid_user_share_share1_idx` (`share_id` ASC) ,
  INDEX `fk_mid_user_share_user1_idx` (`user_id` ASC) )
ENGINE = InnoDB
COMMENT = '用户-分享中间表【描述用户购买的分享】';
 
 
-- -----------------------------------------------------
-- Table `notice`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `notice` (
  `id` INT NOT NULL AUTO_INCREMENT COMMENT 'id',
  `content` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '内容',
  `show_flag` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否显示 0:否 1:是',
  `create_time` DATETIME NOT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`));

4、API文档

地址 https://t.itmuch.com/doc.html

5、如何创建一个小程序?

注册账号https://mp.weixin.qq.com/

填写相关信息

6、前端代码如何使用?

https://github.com/eacdy/itmuch-miniapp

7、创建项目

(1)技术选型

Spring Boot(快速开发)
Spring MVC(MVC框架)
MyBatis(持久层框架,操作数据库)+通用Mapper
Spring Cloud Alibaba(分布式)

 

(2)创建项目

地址 https://blog.csdn.net/weixin_41842236/article/details/104200900

 

(3)整合Lombok

地址 https://blog.csdn.net/weixin_41842236/article/details/104200900

 

(4)Intellij IDEA中Mybatis Mapper自动注入警告的6种解决方案

地址 https://www.imooc.com/article/287865

(5)创建用户微服务和内容微服务

三、微服务的拆分与编写_第8张图片

三、微服务的拆分与编写_第9张图片

user-center

项目部分结构图

三、微服务的拆分与编写_第10张图片

service层

三、微服务的拆分与编写_第11张图片

controller层

三、微服务的拆分与编写_第12张图片

content-center

三、微服务的拆分与编写_第13张图片

ShareDTO

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Table(name = "share")
public class ShareDTO {
    /**
     * id
     */
    private Integer id;

    /**
     * 发布人id
     */
    private Integer userId;

    /**
     * 标题
     */
    private String title;

    /**
     * 创建时间
     */
    private Date createTime;

    /**
     * 修改时间
     */
    private Date updateTime;

    /**
     * 是否原创 0:否 1:是
     */
    private Boolean isOriginal;

    /**
     * 作者
     */
    private String author;

    /**
     * 封面
     */
    private String cover;

    /**
     * 概要信息
     */
    private String summary;

    /**
     * 价格(需要的积分)
     */
    private Integer price;

    /**
     * 下载地址
     */
    private String downloadUrl;

    /**
     * 下载数 
     */
    private Integer buyCount;

    /**
     * 是否显示 0:否 1:是
     */
    private Boolean showFlag;

    /**
     * 审核状态 NOT_YET: 待审核 PASSED:审核通过 REJECTED:审核不通过
     */
    private String auditStatus;

    /**
     * 审核不通过原因
     */
    private String reason;

    /**
     * 发布人昵称
     */
    private String wxNickname;
}

UserDTO

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserDTO {
    /**
     * Id
     */
    private Integer id;

    /**
     * 微信id
     */
    private String wxId;

    /**
     * 微信昵称
     */
    private String wxNickname;

    /**
     * 角色
     */
    private String roles;

    /**
     * 头像地址
     */
    private String avatarUrl;

    /**
     * 创建时间
     */
    private Date createTime;

    /**
     * 修改时间
     */
    private Date updateTime;

    /**
     * 积分
     */
    private Integer bonus;
}

主启动类上添加

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

ShareService

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ShareService {
    private final ShareMapper shareMapper;
    private final RestTemplate restTemplate;

    public ShareDTO findById(Integer id){
        // 获取分享的详情
        Share share = this.shareMapper.selectByPrimaryKey(id);
        // 发布人id
        Integer userId = share.getUserId();
        // 怎么调用用户微服务的users/{userId}
        UserDTO userDTO = this.restTemplate.getForObject(
                "http://localhost:8080/users/{id}",
                UserDTO.class,
                userId
        );
        // 消息的装配
        ShareDTO shareDTO = new ShareDTO();
        BeanUtils.copyProperties(share,shareDTO);
        shareDTO.setWxNickname(userDTO.getWxNickname());
        return shareDTO;
    }

}

ShareController

@RestController
@RequestMapping("/shares")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ShareController {
    private final ShareService shareService;

    @GetMapping("/{id}")
    public ShareDTO findById(@PathVariable Integer id){
        return this.shareService.findById(id);
    }
}

测试

三、微服务的拆分与编写_第14张图片

你可能感兴趣的:(Spring,Cloud,Alibaba)