前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >cloud Alibaba电商项目系列:架构演进,了解领域驱动设计,项目公共模块编写

cloud Alibaba电商项目系列:架构演进,了解领域驱动设计,项目公共模块编写

作者头像
冷环渊
发布2021-12-03 08:10:03
3370
发布2021-12-03 08:10:03
举报
文章被收录于专栏:冷环渊的全栈工程师历程

cloud Alibaba项目

架构演进

单体架构

  • 统一在一个程序中 共享数据库和缓存,部署上线简单
  • 缺点明显,代码耦合严重 牵一发而动全身
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fwZLERaA-1638451334847)(springcloudalibaba项目.assets/image-20211202193212331.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fwZLERaA-1638451334847)(springcloudalibaba项目.assets/image-20211202193212331.png)]

垂直架构

  • 优点:服务,部署独立,水平扩展容易
  • 缺点:搭建复杂,服务之间关系错综复杂,维护困难
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-galTYCx0-1638451334848)(springcloudalibaba项目.assets/image-20211202193336709.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-galTYCx0-1638451334848)(springcloudalibaba项目.assets/image-20211202193336709.png)]

SOA架构

  • 开始有了分块的功能划分,但是还是通过一个总线,去调用各个服务节点
  • 优点:提供了底层服务的统一路由,方便调用
  • 缺点 : 实现难度较高,不同架构之间也有耦合
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rNaKHa12-1638451334849)(springcloudalibaba项目.assets/image-20211202193441209.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rNaKHa12-1638451334849)(springcloudalibaba项目.assets/image-20211202193441209.png)]

微服务架构

  • 相比SOA,微服务的入口开始有了变化,不再是直接访问程序,而是通过网关来分派转发
  • 通过过滤的请求会被转发到对应的微服务,每一个服务独立部,运行在不同的机器上,用rest或者http通信
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rTgyZed2-1638451334849)(springcloudalibaba项目.assets/image-20211202193659569.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rTgyZed2-1638451334849)(springcloudalibaba项目.assets/image-20211202193659569.png)]

认识领域驱动设计

优点,有入口鉴权,功能分布细化,性能卓越 缺点, 项目复杂难度,信息暴露,复杂链路等各种问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KWsO4uXm-1638451334849)(springcloudalibaba项目.assets/image-20211202194505723.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KWsO4uXm-1638451334849)(springcloudalibaba项目.assets/image-20211202194505723.png)]

对于领域驱动设计的理解

在这里插入图片描述
在这里插入图片描述

理解领域概念,学习领域知识,对领域建模

  • 分析领域模型,推演实体,值对象,领域服务
  • 找出聚合边界,降低服务耦合
  • 为耦合配备储存仓库,数据持久化
  • 实践DDD,并且不断的推到重构
经典分层架构

解读

  • User Interface 用户接口层 接收用户指令,展示信息
  • Appllcation 应用程序层 Controller 对外提供服务接口,对内调用领域层
  • Domain 领域层,相当于是实体对象,领域模型 对应 数据库中的表
  • infrastructure 基础设施层,为其他层提供基础通用的基础能力,通信能力和持久化机制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ug0oZxDl-1638451334850)(springcloudalibaba项目.assets/image-20211202194817297.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ug0oZxDl-1638451334850)(springcloudalibaba项目.assets/image-20211202194817297.png)]

传统开发: ​ 会在开始之前就设计好数据库的表,去实现需求,后面想要修改就会影响到功能甚至是整体结构 领域驱动设计: ​ 初期关心的是业务,持久化只是为了业务设计后期的考虑

电商工程业务解读,微服务模块拆分

Tips 学习领域知识最好的方法就是参考和借鉴

简单理解图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DwHV2Zoy-1638451334850)(springcloudalibaba项目.assets/image-20211202195710378.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DwHV2Zoy-1638451334850)(springcloudalibaba项目.assets/image-20211202195710378.png)]

微服务模块拆分

工程入口以及用户鉴权微服务

网关是微服务架构的唯一入口

这里是电商的门面

涉及到

  • 权限鉴定
  • 服务调用
  • 限流等
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MSBKYkG5-1638451334851)(springcloudalibaba项目.assets/image-20211202201004146.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MSBKYkG5-1638451334851)(springcloudalibaba项目.assets/image-20211202201004146.png)]
主要功能服务模块

账户,商品,订单,物流

  • 合理的微服务划分
  • 尽可能让每一个服务减少依赖和与其他服务的交集,最好是没有交集
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DuwddTEg-1638451334851)(springcloudalibaba项目.assets/image-20211202201445468.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DuwddTEg-1638451334851)(springcloudalibaba项目.assets/image-20211202201445468.png)]

E-commerce开发

实现公共模块

步骤

创建项目 -->导入依赖–>编写配置

父工程创建e-commerce-springcloud 导入需要的对应依赖

代码语言:javascript
复制
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>

    <groupId>com.hyc.ecommercegroupId>
    <artifactId>e-commerce-springcloudartifactId>
    <version>1.0-SNAPSHOTversion>

    <modules>
        <module>e-commerce-commonmodule>
        <module>e-commerce-mvc-configmodule>
    modules>

    <packaging>pompackaging>

    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.3.1.RELEASEversion>
    parent>

    <properties>
        
        <spring-cloud.version>Hoxton.SR8spring-cloud.version>
        
        <spring-cloud-alibaba.version>2.2.4.RELEASEspring-cloud-alibaba.version>
    properties>

    <dependencies>
        
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>1.16.18version>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        <dependency>
            <groupId>org.apache.commonsgroupId>
            <artifactId>commons-lang3artifactId>
            <version>3.11version>
        dependency>
        <dependency>
            <groupId>org.apache.commonsgroupId>
            <artifactId>commons-collections4artifactId>
            <version>4.4version>
        dependency>
        <dependency>
            <groupId>cn.hutoolgroupId>
            <artifactId>hutool-allartifactId>
            <version>5.6.0version>
        dependency>
        
        <dependency>
            <groupId>io.jsonwebtokengroupId>
            <artifactId>jjwt-apiartifactId>
            <version>0.10.5version>
        dependency>
        <dependency>
            <groupId>io.jsonwebtokengroupId>
            <artifactId>jjwt-implartifactId>
            <version>0.10.5version>
            <scope>runtimescope>
        dependency>
        <dependency>
            <groupId>io.jsonwebtokengroupId>
            <artifactId>jjwt-jacksonartifactId>
            <version>0.10.5version>
            <scope>runtimescope>
        dependency>
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>fastjsonartifactId>
            <version>1.2.47version>
        dependency>
    dependencies>

    
    <dependencyManagement>
        <dependencies>
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>${spring-cloud.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>

            
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-alibaba-dependenciesartifactId>
                <version>${spring-cloud-alibaba.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
        dependencies>
    dependencyManagement>

    
    <repositories>
        <repository>
            <id>spring-milestonesid>
            <name>Spring Milestonesname>
            <url>https://repo.spring.io/milestoneurl>
            <snapshots>
                <enabled>falseenabled>
            snapshots>
        repository>
    repositories>

project>
公共子模块 公共库 commons

e-commerce-common 模块

依赖如下

代码语言:javascript
复制
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>e-commerce-springcloudartifactId>
        <groupId>com.hyc.ecommercegroupId>
        <version>1.0-SNAPSHOTversion>
    parent>
    <modelVersion>4.0.0modelVersion>

    <artifactId>e-commerce-commonartifactId>

    
    <name>e-commerce-commonname>
    <description>通用模块description>
project>

这么模块之后会放入很多的数据模型,来给功能服务模块使用,这里先创建并且统一响应,之后会有对应的数据模型加入其中

创建响应格式

代码语言:javascript
复制
/**
 * @author : 冷环渊
 * @date : 2021/12/2
 * @context: 通用响应定义
 * {
 * "code":1
 * "message":hyc
 * "data":{}
 * }
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonResponse<T> implements Serializable {
    //相应码
    private Integer code;
    //返回消息 信息描述
    private String message;

    public CommonResponse(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    //泛型内容数据
    private T Data;
}
公共子模块 web统一返回与全局异常处理 e-commerce-mvc-config

e-commerce-mvc-config这个模块主要是为了隔离功能,有的服务模块比如网关,不能有web依赖的启动,这样他导入commons就可以了,起到很好的服务对应功能隔离

依赖如下

代码语言:javascript
复制
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>e-commerce-springcloudartifactId>
        <groupId>com.hyc.ecommercegroupId>
        <version>1.0-SNAPSHOTversion>
    parent>
    <modelVersion>4.0.0modelVersion>

    <artifactId>e-commerce-mvc-configartifactId>
    
    <name>e-commerce-mvc-configname>
    <description>通用配置模块description>

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>com.hyc.ecommercegroupId>
            <artifactId>e-commerce-commonartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>
    dependencies>

project>

编写注解 IgnoreResponseAdvice

IgnoreResponseAdvice 忽略统一响应注解定义,就是不需要用我们定义的CommonsResponese的类使用这个注解就可以不使用

代码语言:javascript
复制
/**
 * @author : 冷环渊
 * @date : 2021/12/2
 * @context:忽略统一响应注解定义
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreResponseAdvice {

}
实现统一响应和统一忽略响应注解
代码语言:javascript
复制
/**
 * @author : 冷环渊
 * @date : 2021/12/2
 * @context: 实现统一响应和统一忽略响应注解
 * @params :  null
 * @return :  * @return : null
 */
@RestControllerAdvice(value = "com.hyc.ecommerce")
//实现响应体建议接口
public class CommonResponseDataAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter methodParameter,
                            Class<? extends HttpMessageConverter<?>> aClass) {
        //判断类上面有没有这个注解 IgnoreResponseAdvice
        if (methodParameter.getDeclaringClass().isAnnotationPresent(IgnoreResponseAdvice.class)) {
            return false;
        }
        //判断方法上有没有这个注解 IgnoreResponseAdvice
        if (methodParameter.getMethod().isAnnotationPresent(IgnoreResponseAdvice.class)) {
            return false;
        }
        //都没有的话 就代表要使用公共返回格式
        return true;
    }

    //处理 如果是需要使用的话怎么用
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter,
                                  MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass,
                                  ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {
        //定义最终的返回对象
        CommonResponse<Object> response = new CommonResponse<>(0, "");
        //如果等于null就代表没有 直接返回
        if (o == null) {
            return response;
            //等于公共返回类型的 就把o转换成 公共返回 CommonResponse<>
        } else if (o instanceof CommonResponse) {
            response = (CommonResponse<Object>) o;
            //如果都不是的话 那就是响应内容 设置响应data 为这个object
        } else {
            response.setData(o);
        }
        return response;
    }
}
全局异常处理

GlobalExceptionAdvice 处理全局异常,只要出现了请求出现了异常给一个统一的返回结果

代码语言:javascript
复制
/**
 * @author : 冷环渊
 * @date : 2021/12/2
 * @context:全局异常处理
 * @params :  null
 * @return :  * @return : null
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionAdvice {
    //这个注解的意思就是异常处理起,参数是你想要捕捉的异常
    @ExceptionHandler(value = Exception.class)
    public CommonResponse<String> handlerCommerceException(HttpServerRequest req, Exception ex) {
        //初始化一个公共响应对象
        CommonResponse<String> response = new CommonResponse<>(
                -1, "business error"
        );
        //加入报错信息 到信息头
        response.setData(ex.getMessage());
        //控制后台打印报错日志 返回公共响应体 给调用方一个提示
        log.error("commerce service has error:[{}]", ex.getMessage(), ex);
        return response;
    }

}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/12/02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • cloud Alibaba项目
    • 架构演进
      • 单体架构
      • 垂直架构
      • SOA架构
      • 微服务架构
    • 认识领域驱动设计
      • 对于领域驱动设计的理解
      • 电商工程业务解读,微服务模块拆分
      • 微服务模块拆分
    • E-commerce开发
      • 实现公共模块
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档