SpringCloud微服务实战——搭建企业级开发框架(七):自定义通用响应消息及统一异常处理

简介: 平时开发过程中,无可避免我们需要处理各类异常,所以这里我们在公共模块中自定义统一异常,Spring Boot 提供 @RestControllerAdvice 注解统一异常处理,我们在GitEgg_Platform中新建gitegg-platform-boot子工程,此工程主要用于Spring Boot相关功能的自定义及扩展。1、修改gitegg-platform-boot的pom.xml,添加spring-boot-starter-web和swagger依赖,设置optional为true,让这个包在项目之间依赖不传递。

  平时开发过程中,无可避免我们需要处理各类异常,所以这里我们在公共模块中自定义统一异常,Spring Boot 提供 @RestControllerAdvice 注解统一异常处理,我们在GitEgg_Platform中新建gitegg-platform-boot子工程,此工程主要用于Spring Boot相关功能的自定义及扩展。


1、修改gitegg-platform-boot的pom.xml,添加spring-boot-starter-web和swagger依赖,设置optional为true,让这个包在项目之间依赖不传递。


<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.gitegg.platform</groupId>
            <artifactId>gitegg-platform-swagger</artifactId>
            <optional>true</optional>
        </dependency>


2、自定义通用响应消息类,Result和PageResult,一个是普通响应消息,一个是分页响应消息。


Result类:


package com.gitegg.platform.boot.common.base;
import com.gitegg.platform.boot.common.enums.ResultCodeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
/**
 * @ClassName: Result
 * @Description: 自定义通用响应类
 * @author GitEgg
 * @date 2020年09月19日 下午9:24:50
 */
@ApiModel(description = "通用响应类")
@Getter
@ToString
public class Result<T> {
    @ApiModelProperty(value = "是否成功", required = true)
    private boolean success;
    @ApiModelProperty(value ="响应代码", required = true)
    private int code;
    @ApiModelProperty(value ="提示信息", required = true)
    private String msg;
    @ApiModelProperty(value ="响应数据")
    private T data;
    /**
     * 
     * @param code
     * @param data
     * @param msg
     */
    private Result(int code, T data, String msg) {
        this.success = ResultCodeEnum.SUCCESS.code == code;
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
    /**
     * 
     * @param resultCodeEnum
     */
    private Result(ResultCodeEnum resultCodeEnum ) {
        this(resultCodeEnum.code, null, resultCodeEnum.msg);
    }
    /**
     * 
     * @param resultCodeEnum
     * @param msg
     */
    private Result(ResultCodeEnum resultCodeEnum , String msg) {
        this(resultCodeEnum, null, msg);
    }
    /**
     * 
     * @param resultCodeEnum
     * @param data
     */
    private Result(ResultCodeEnum resultCodeEnum , T data) {
        this(resultCodeEnum, data, resultCodeEnum.msg);
    }
    /**
     * 
     * @param resultCodeEnum
     * @param data
     * @param msg
     */
    private Result(ResultCodeEnum resultCodeEnum , T data, String msg) {
        this(resultCodeEnum.code, data, msg);
    }
    /**
     * 
     *
     * @param data 数据
     * @param <T>  T 响应数据
     * @
     */
    public static <T> Result<T> data(T data) {
        return data(data, ResultCodeEnum.SUCCESS.msg);
    }
    /**
     * 
     *
     * @param data 数据
     * @param msg  消息
     * @param <T>  T 响应数据
     * @
     */
    public static <T> Result<T> data(T data, String msg) {
        return data(ResultCodeEnum.SUCCESS.code, data, msg);
    }
    /**
     * 
     *
     * @param code 状态码
     * @param data 数据
     * @param msg  消息
     * @param <T>  T 响应数据
     * @
     */
    public static <T> Result<T> data(int code, T data, String msg) {
        return new Result<>(code, data, msg);
    }
    /**
     * 返回Result
     *
     * @param 
     * @param <T>  T 响应数据
     * @返回Result
     */
    public static <T> Result<T> success() {
        return new Result<>(ResultCodeEnum.SUCCESS);
    }
    /**
     * 返回Result
     *
     * @param msg 消息
     * @param <T> T 响应数据
     * @返回Result
     */
    public static <T> Result<T> success(String msg) {
        return new Result<>(ResultCodeEnum.SUCCESS, msg);
    }
    /**
     * 返回Result
     *
     * @param 
     * @param <T>  T 响应数据
     * @返回Result
     */
    public static <T> Result<T> success(ResultCodeEnum resultCodeEnum ) {
        return new Result<>(resultCodeEnum);
    }
    /**
     * 返回Result
     *
     * @param 
     * @param msg   提示信息
     * @param <T>  T 响应数据
     * @返回Result
     */
    public static <T> Result<T> success(ResultCodeEnum resultCodeEnum , String msg) {
        return new Result<>(resultCodeEnum, msg);
    }
    /**
     * 返回Result
     *
     * @param <T> T 响应数据
     * @返回Result
     */
    public static <T> Result<T> error() {
        return new Result<>(ResultCodeEnum.ERROR, ResultCodeEnum.ERROR.msg);
    }
    /**
     * 返回Result
     *
     * @param msg 消息
     * @param <T> T 响应数据
     * @返回Result
     */
    public static <T> Result<T> error(String msg) {
        return new Result<>(ResultCodeEnum.ERROR, msg);
    }
    /**
     * 返回Result
     *
     * @param code 状态码
     * @param msg  消息
     * @param <T>  T 响应数据
     * @返回Result
     */
    public static <T> Result<T> error(int code, String msg) {
        return new Result<>(code, null, msg);
    }
    /**
     * 返回Result
     *
     * @param 
     * @param <T>  T 响应数据
     * @返回Result
     */
    public static <T> Result<T> error(ResultCodeEnum resultCodeEnum ) {
        return new Result<>(resultCodeEnum);
    }
    /**
     * 返回Result
     *
     * @param 
     * @param msg   提示信息
     * @param <T>  T 响应数据
     * @返回Result
     */
    public static <T> Result<T> error(ResultCodeEnum resultCodeEnum , String msg) {
        return new Result<>(resultCodeEnum, msg);
    }
    /**
     * 
     * @param <T>
     * @param flag
     * @return
     */
    public static <T> Result<T> result(boolean flag) {
        return flag ? Result.success("操作成功") : Result.error("操作失败");
    }
}


PageResult类:


package com.gitegg.platform.boot.common.base;
import java.util.List;
import com.gitegg.platform.boot.common.enums.ResultCodeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @ClassName: PageResult
 * @Description: 通用分页返回
 * @author GitEgg
 * @date
 * @param <T>
 */
@Data
@ApiModel("通用分页响应类")
public class PageResult<T> {
    @ApiModelProperty(value = "是否成功", required = true)
    private boolean success;
    @ApiModelProperty(value ="响应代码", required = true)
    private int code;
    @ApiModelProperty(value ="提示信息", required = true)
    private String msg;
    @ApiModelProperty(value ="总数量", required = true)
    private long count;
    @ApiModelProperty(value ="分页数据")
    private List<T> data;
    public PageResult(long total, List<T> rows) {
        this.count = total;
        this.data = rows;
        this.code = ResultCodeEnum.SUCCESS.code;
        this.msg = ResultCodeEnum.SUCCESS.msg;
    }
}


3、自定义通用响应消息枚举类ResultCodeEnum。


package com.gitegg.platform.boot.common.enums;
/**
 * @ClassName: ResultCodeEnum
 * @Description: 自定义返回码枚举
 * @author GitEgg
 * @date 2020年09月19日 下午11:49:45
 */
public enum ResultCodeEnum {
    /**
     * 成功
     */
    SUCCESS(200, "操作成功"),
    /**
     * 系统错误
     */
    ERROR(500, "系统错误"),
    /**
     * 操作失败
     */
    FAILED(101, "操作失败"),
    /**
     * 未登录/登录超时
     */
    UNAUTHORIZED(102, "登录超时"),
    /**
     * 参数错误
     */
    PARAM_ERROR(103, "参数错误"),
    /**
     * 参数错误-已存在
     */
    INVALID_PARAM_EXIST(104, "请求参数已存在"),
    /**
     * 参数错误
     */
    INVALID_PARAM_EMPTY(105, "请求参数为空"),
    /**
     * 参数错误
     */
    PARAM_TYPE_MISMATCH(106, "参数类型不匹配"),
    /**
     * 参数错误
     */
    PARAM_VALID_ERROR(107, "参数校验失败"),
    /**
     * 参数错误
     */
    ILLEGAL_REQUEST(108, "非法请求"),
    /**
     * 验证码错误
     */
    INVALID_VCODE(204, "验证码错误"),
    /**
     * 用户名或密码错误
     */
    INVALID_USERNAME_PASSWORD(205, "账号或密码错误"),
    /**
     *
     */
    INVALID_RE_PASSWORD(206, "两次输入密码不一致"),
    /**
     * 用户名或密码错误
     */
    INVALID_OLD_PASSWORD(207, "旧密码错误"),
    /**
     * 用户名重复
     */
    USERNAME_ALREADY_IN(208, "用户名已存在"),
    /**
     * 用户不存在
     */
    INVALID_USERNAME(209, "用户名不存在"),
    /**
     * 角色不存在
     */
    INVALID_ROLE(210, "角色不存在"),
    /**
     * 角色不存在
     */
    ROLE_USED(211, "角色使用中,不可删除"),
    /**
     * 没有权限
     */
    NO_PERMISSION(403, "当前用户无该接口权限");
    public int code;
    public String msg;
    ResultCodeEnum(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}


4、自定义异常类BusinessException和SystemException


package com.gitegg.platform.boot.common.exception;
import com.gitegg.platform.boot.common.enums.ResultCodeEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
/**
 * @ClassName: BusinessException
 * @Description: 业务处理异常
 * @author GitEgg
 * @date
 */
@Getter
@Setter
public class BusinessException extends RuntimeException {
    private int code;
    private String msg;
    public BusinessException() {
        this.code = ResultCodeEnum.FAILED.code;
        this.msg = ResultCodeEnum.FAILED.msg;
    }
    public BusinessException(String message) {
        this.code = ResultCodeEnum.FAILED.code;
        this.msg = message;
    }
    public BusinessException(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    public BusinessException(Throwable cause) {
        super(cause);
    }
    public BusinessException(String message, Throwable cause) {
        super(message, cause);
    }
}


package com.gitegg.platform.boot.common.exception;
import com.gitegg.platform.boot.common.enums.ResultCodeEnum;
import lombok.Getter;
/**
 * @ClassName: SystemException
 * @Description: 系统处理异常
 * @author GitEgg
 * @date
 */
@Getter
public class SystemException extends RuntimeException {
    private int code;
    private String msg;
    public SystemException() {
        this.code = ResultCodeEnum.ERROR.code;
        this.msg = ResultCodeEnum.ERROR.msg;
    }
    public SystemException(String message) {
        this.code = ResultCodeEnum.ERROR.code;
        this.msg = message;
    }
    public SystemException(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    public SystemException(Throwable cause) {
        super(cause);
    }
    public SystemException(String message, Throwable cause) {
        super(message, cause);
    }
}


5、自定义统一异常处理类GitEggControllerAdvice.java


package com.gitegg.platform.boot.common.advice;
import com.gitegg.platform.boot.common.base.Result;
import com.gitegg.platform.boot.common.enums.ResultCodeEnum;
import com.gitegg.platform.boot.common.exception.BusinessException;
import com.gitegg.platform.boot.common.exception.SystemException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.ui.Model;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;
@Slf4j
@RestControllerAdvice
public class GitEggControllerAdvice {
    /**
     * 服务名
     */
    @Value("${spring.application.name}")
    private String serverName;
    /**
     * 微服务系统标识
     */
    private String errorSystem;
    @PostConstruct
    public void init() {
        this.errorSystem = new StringBuffer()
                .append(this.serverName)
                .append(": ").toString();
    }
    /**
     * 应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器
     */
    @InitBinder
    public void initBinder(WebDataBinder binder) {
    }
    /**
     * 把值绑定到Model中,使全局@RequestMapping可以获取到该值
     */
    @ModelAttribute
    public void addAttributes(Model model) {
    }
    /**
     * 全局异常捕捉处理
     */
    @ExceptionHandler(value = {Exception.class})
    public Result handlerException(Exception exception, HttpServletRequest request) {
        log.error("请求路径uri={},系统内部出现异常:{}", request.getRequestURI(), exception);
        Result result = Result.error(ResultCodeEnum.ERROR, errorSystem + exception.toString());
        return result;
    }
    /**
     * 非法请求异常
     */
    @ExceptionHandler(value = {
            HttpMediaTypeNotAcceptableException.class,
            HttpMediaTypeNotSupportedException.class,
            HttpRequestMethodNotSupportedException.class,
            MissingServletRequestParameterException.class,
            NoHandlerFoundException.class,
            MissingPathVariableException.class,
            HttpMessageNotReadableException.class
    })
    public Result handlerSpringAOPException(Exception exception) {
        Result result = Result.error(ResultCodeEnum.ILLEGAL_REQUEST, errorSystem + exception.getMessage());
        return result;
    }
    /**
     * 非法请求异常-参数类型不匹配
     */
    @ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
    public Result handlerSpringAOPException(MethodArgumentTypeMismatchException exception) {
        Result result = Result.error(ResultCodeEnum.PARAM_TYPE_MISMATCH, errorSystem + exception.getMessage());
        return result;
    }
    /**
     * 非法请求-参数校验
     */
    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    public Result handlerMethodArgumentNotValidException(MethodArgumentNotValidException methodArgumentNotValidException) {
        //获取异常字段及对应的异常信息
        StringBuffer stringBuffer = new StringBuffer();
        methodArgumentNotValidException.getBindingResult().getFieldErrors().stream()
                .map(t -> t.getField()+"=>"+t.getDefaultMessage()+" ")
                .forEach(e -> stringBuffer.append(e));
        String errorMessage = stringBuffer.toString();
        Result result = Result.error(ResultCodeEnum.PARAM_VALID_ERROR, errorSystem + errorMessage);
        return result;
    }
    /**
     * 非法请求异常-参数校验
     */
    @ExceptionHandler(value = {ConstraintViolationException.class})
    public Result handlerConstraintViolationException(ConstraintViolationException constraintViolationException) {
        String errorMessage = constraintViolationException.getLocalizedMessage();
        Result result = Result.error(ResultCodeEnum.PARAM_VALID_ERROR, errorSystem + errorMessage);
        return result;
    }
    /**
     * 自定义业务异常-BusinessException
     */
    @ExceptionHandler(value = {BusinessException.class})
    public Result handlerCustomException(BusinessException exception) {
        String errorMessage = exception.getMsg();
        Result result = Result.error(exception.getCode(), errorSystem + errorMessage);
        return result;
    }
    /**
     * 自定义系统异常-SystemException
     */
    @ExceptionHandler(value = {SystemException.class})
    public Result handlerCustomException(SystemException exception) {
        String errorMessage = exception.getMsg();
        Result result = Result.error(exception.getCode(), errorSystem + errorMessage);
        return result;
    }
}


6、重新将GitEgg-Platform进行install,在GitEgg-Cloud中的gitegg-service引入gitegg-platform-boot


<?xml version="1.0" encoding="UTF-8"?>
<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>GitEgg-Cloud</artifactId>
        <groupId>com.gitegg.cloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>gitegg-service</artifactId>
    <packaging>pom</packaging>
    <modules>
        <module>gitegg-service-base</module>
        <module>gitegg-service-bigdata</module>
        <module>gitegg-service-system</module>
    </modules>
    <dependencies>
        <!-- gitegg Spring Boot自定义及扩展 -->
        <dependency>
            <groupId>com.gitegg.platform</groupId>
            <artifactId>gitegg-platform-boot</artifactId>
        </dependency>
        <!-- gitegg数据库驱动及连接池 -->
        <dependency>
            <groupId>com.gitegg.platform</groupId>
            <artifactId>gitegg-platform-db</artifactId>
        </dependency>
        <!-- gitegg mybatis-plus -->
        <dependency>
            <groupId>com.gitegg.platform</groupId>
            <artifactId>gitegg-platform-mybatis</artifactId>
        </dependency>
        <!-- gitegg swagger2-knife4j -->
        <dependency>
            <groupId>com.gitegg.platform</groupId>
            <artifactId>gitegg-platform-swagger</artifactId>
        </dependency>
        <!-- spring boot web核心包 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- spring boot 健康监控 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>
</project>


7、修改SystemController.java、ISystemService.java和SystemServiceImpl.java增加异常处理的测试代码


SystemController.java:


package com.gitegg.service.system.controller;
import com.gitegg.platform.boot.common.base.Result;
import com.gitegg.platform.boot.common.exception.BusinessException;
import com.gitegg.service.system.service.ISystemService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "system")
@AllArgsConstructor
@Api(tags = "gitegg-system")
public class SystemController {
    private final ISystemService systemService;
    @GetMapping(value = "list")
    @ApiOperation(value = "system list接口")
    public Object list() {
        return systemService.list();
    }
    @GetMapping(value = "page")
    @ApiOperation(value = "system page接口")
    public Object page() {
        return systemService.page();
    }
    @GetMapping(value = "exception")
    @ApiOperation(value = "自定义异常及返回测试接口")
    public Result<String> exception() {
        return Result.data(systemService.exception());
    }
}


ISystemService.java:


package com.gitegg.service.system.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gitegg.service.system.entity.SystemTable;
import java.util.List;
public interface ISystemService {
    List<SystemTable> list();
    Page<SystemTable> page();
    String exception();
}


SystemServiceImpl.java:


package com.gitegg.service.system.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gitegg.platform.boot.common.exception.BusinessException;
import com.gitegg.service.system.entity.SystemTable;
import com.gitegg.service.system.mapper.SystemTableMapper;
import com.gitegg.service.system.service.ISystemService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 *
 */
@Service
@AllArgsConstructor
public class SystemServiceImpl implements ISystemService {
    private final SystemTableMapper systemTableMapper;
    @Override
    public List<SystemTable> list() {
        return systemTableMapper.list();
    }
    @Override
    public Page<SystemTable> page() {
        Page<SystemTable> page = new Page<>(1, 10);
        List<SystemTable> records = systemTableMapper.page(page);
        page.setRecords(records);
        return page;
    }
    @Override
    public String exception() {
        throw new BusinessException("自定义异常");
//        return "成功获得数据";
    }
}


8、运行GitEggSystemApplication,打开浏览器访问:http://127.0.0.1:8001/doc.html,然后点击左侧的异常处理接口,使用Swagger2进行测试,即可看到结果


微信图片_20220518090104.png

                                                             image.png


相关文章
|
10月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
10月前
|
监控 Cloud Native Java
Spring Boot 3.x 微服务架构实战指南
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Spring Boot 3.x与微服务架构,探索云原生、性能优化与高可用系统设计。以代码为笔,在二进制星河中谱写极客诗篇。关注我,共赴技术星辰大海!(238字)
1424 2
Spring Boot 3.x 微服务架构实战指南
|
12月前
|
负载均衡 监控 Java
微服务稳定性三板斧:熔断、限流与负载均衡全面解析(附 Hystrix-Go 实战代码)
在微服务架构中,高可用与稳定性至关重要。本文详解熔断、限流与负载均衡三大关键技术,结合API网关与Hystrix-Go实战,帮助构建健壮、弹性的微服务系统。
1028 1
微服务稳定性三板斧:熔断、限流与负载均衡全面解析(附 Hystrix-Go 实战代码)
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
1514 3
|
IDE Java API
Java 17 新特性与微服务开发的实操指南
本内容涵盖Java 11至Java 17最新特性实战,包括var关键字、字符串增强、模块化系统、Stream API、异步编程、密封类等,并提供图书管理系统实战项目,帮助开发者掌握现代Java开发技巧与工具。
751 0
|
缓存 负载均衡 监控
微服务架构下的电商API接口设计:策略、方法与实战案例
本文探讨了微服务架构下的电商API接口设计,旨在打造高效、灵活与可扩展的电商系统。通过服务拆分(如商品、订单、支付等模块)和标准化设计(RESTful或GraphQL风格),确保接口一致性与易用性。同时,采用缓存策略、负载均衡及限流技术优化性能,并借助Prometheus等工具实现监控与日志管理。微服务架构的优势在于支持敏捷开发、高并发处理和独立部署,满足电商业务快速迭代需求。未来,电商API设计将向智能化与安全化方向发展。
617 102
|
SpringCloudAlibaba 监控 Java
【SpringCloud微服务实战】搭建企业级应用开发框架(一):架构说明
SpringCloud分布式应用微服务系统组件列表: • 微服务框架组件:Spring Boot2 + SpringCloud Hoxton.SR8 + SpringCloud Alibaba • Spring Boot Admin: 管理和监控SpringBoot应用程序的微服务健康状态 • 数据持久化组件:MySql + Druid + MyBatis + MyBatis-Plus
1775 57
【SpringCloud微服务实战】搭建企业级应用开发框架(一):架构说明
|
存储 缓存 安全
SpringCloud微服务实战——搭建企业级开发框架(二十三):Gateway+OAuth2+JWT实现微服务统一认证授权
OAuth2是一个关于授权的开放标准,核心思路是通过各类认证手段(具体什么手段OAuth2不关心)认证用户身份,并颁发token(令牌),使得第三方应用可以使用该token(令牌)在限定时间、限定范围访问指定资源。   OAuth2中使用token验证用户登录合法性,但token最大的问题是不携带用户信息,资源服务器无法在本地进行验证,每次对于资源的访问,资源服务器都需要向认证服务器发起请求,一是验证token的有效性,二是获取token对应的用户信息。如果有大量的此类请求,无疑处理效率是很低,且认证服务器会变成一个中心节点
2136 57
SpringCloud微服务实战——搭建企业级开发框架(二十三):Gateway+OAuth2+JWT实现微服务统一认证授权
|
开发框架 前端开发 Java
SpringCloud微服务实战——搭建企业级开发框架(十九):Gateway使用knife4j聚合微服务文档
本章介绍Spring Cloud Gateway网关如何集成knife4j,通过网关聚合所有的Swagger微服务文档 1、gitegg-gateway中引入knife4j依赖,如果没有后端代码编写的话,仅仅引入一个swagger的前端ui模块就可以了
1635 57
SpringCloud微服务实战——搭建企业级开发框架(十九):Gateway使用knife4j聚合微服务文档
|
开发框架 负载均衡 算法
SpringCloud微服务实战——搭建企业级开发框架(十二):OpenFeign+Ribbon实现负载均衡
Ribbon是Netflix下的负载均衡项目,它主要实现中间层应用程序的负载均衡。为Ribbon配置服务提供者地址列表后,Ribbon就会基于某种负载均衡算法,自动帮助服务调用者去请求。Ribbon默认提供的负载均衡算法有多种,例如轮询、随即、加权轮训等,也可以为Ribbon实现自定义的负载均衡算法。 Ribbon有以下特性:
941 57
SpringCloud微服务实战——搭建企业级开发框架(十二):OpenFeign+Ribbon实现负载均衡