(一)Eshop(异常处理中间件)


文章目录

  • 项目地址
  • 一、异常处理
    • [1.1 自定异常](#1.1 自定异常)
    • [1.2 自定义异常处理中间件](#1.2 自定义异常处理中间件)
    • [1.3 注册中间件](#1.3 注册中间件)
  • 二、grpc服务
    • [2.1 创建protos](#2.1 创建protos)
      • [1. 打折的protos](#1. 打折的protos)
      • [2. 设置grpc server](#2. 设置grpc server)
      • [3. program配置服务](#3. program配置服务)
      • [4. docker-compose](#4. docker-compose)
    • [2.2 CRUD](#2.2 CRUD)
      • [1. 查询](#1. 查询)
    • [2.3 测试](#2.3 测试)
      • [1. 发起查询请求](#1. 发起查询请求)
  • 三、grpc服务消费
    • [3.1 创建client](#3.1 创建client)
      • [1. 添加服务](#1. 添加服务)
      • [2. 选择需要添加的服务类型](#2. 选择需要添加的服务类型)
      • [3. 选择服务路径](#3. 选择服务路径)
      • [4. 添加成功后](#4. 添加成功后)
      • [5. Program里添加Client服务](#5. Program里添加Client服务)
      • [6. appSettings里添加grpc服务地址](#6. appSettings里添加grpc服务地址)
    • [3.2 grpc通讯](#3.2 grpc通讯)
      • [1. 在StoreBasketCommandHandler使用](#1. 在StoreBasketCommandHandler使用)

项目地址

  • 教程作者:
  • 教程地址:
复制代码
  • 代码仓库地址:
复制代码
  • 所用到的框架和插件:

    dbt
    airflow

一、异常处理

1.1 自定异常

  • BadRequestException
  • InternalServerException
  • NotFoundException

1.2 自定义异常处理中间件

  • 异常处理中间件
cs 复制代码
public class CustomExceptionHandler
    (ILogger<CustomExceptionHandler> logger)
    : IExceptionHandler
{
    public async ValueTask<bool> TryHandleAsync(HttpContext context, Exception exception, CancellationToken cancellationToken)
    {
        logger.LogError(
            "Error Message: {exceptionMessage}, Time of occurrence {time}",
            exception.Message, DateTime.UtcNow);

        (string Detail, string Title, int StatusCode) details = exception switch
        {
            InternalServerException =>
            (
                exception.Message,
                exception.GetType().Name,
                context.Response.StatusCode = StatusCodes.Status500InternalServerError
            ),
            ValidationException =>
            (
                exception.Message,
                exception.GetType().Name,
                context.Response.StatusCode = StatusCodes.Status400BadRequest
            ),
            BadRequestException =>
            (
                exception.Message,
                exception.GetType().Name,
                context.Response.StatusCode = StatusCodes.Status400BadRequest
            ),
            NotFoundException =>
            (
                exception.Message,
                exception.GetType().Name,
                context.Response.StatusCode = StatusCodes.Status404NotFound
            ),
            _ =>
            (
                exception.Message,
                exception.GetType().Name,
                context.Response.StatusCode = StatusCodes.Status500InternalServerError
            )
        };

        var problemDetails = new ProblemDetails
        {
            Title = details.Title,
            Detail = details.Detail,
            Status = details.StatusCode,
            Instance = context.Request.Path
        };

        problemDetails.Extensions.Add("traceId", context.TraceIdentifier);

        if (exception is ValidationException validationException)
        {
            problemDetails.Extensions.Add("ValidationErrors", validationException.Errors);
        }

        await context.Response.WriteAsJsonAsync(problemDetails, cancellationToken: cancellationToken);
        return true;
    }
}
  • 返回例

    {
    "title": "ValidationException",
    "detail": "参数验证失败",
    "status": 400,
    "instance": "/api/products",
    "traceId": "00-9d4a78437e-abc123def456-01",
    "ValidationErrors": [
    {
    "PropertyName": "Name",
    "ErrorMessage": "Name 不能为空"
    },
    {
    "PropertyName": "Age",
    "ErrorMessage": "Age 必须大于 0"
    }
    ]
    }

1.3 注册中间件

  • 给所有微服务注册

二、grpc服务

土耳其146

  • 这里主要实现了discount模块的grpc,我们可以通过api进行增删改查

2.1 创建protos

1. 打折的protos

  • 定义请求和返回值

    syntax = "proto3";

    option csharp_namespace = "Discount.Grpc";

    package discount;

    // The discount service definition.
    service DiscountProtoService {
    // Discount CRUD Operations
    rpc GetDiscount (GetDiscountRequest) returns (CouponModel);
    rpc CreateDiscount (CreateDiscountRequest) returns (CouponModel);
    rpc UpdateDiscount (UpdateDiscountRequest) returns (CouponModel);
    rpc DeleteDiscount (DeleteDiscountRequest) returns (DeleteDiscountResponse);
    }

    message GetDiscountRequest {
    string productName = 1;
    }

    message CouponModel {
    int32 id = 1;
    string productName = 2;
    string description = 3;
    int32 amount = 4;
    }

    message CreateDiscountRequest {
    CouponModel coupon = 1;
    }

    message UpdateDiscountRequest {
    CouponModel coupon = 1;
    }

    message DeleteDiscountRequest {
    string productName = 1;
    }

    message DeleteDiscountResponse {
    bool success = 1;
    }

2. 设置grpc server

  • 设置grpc服务
  • 设置成功后,可以在模块的包管理器看到

3. program配置服务

4. docker-compose

2.2 CRUD

1. 查询

2.3 测试

1. 发起查询请求

三、grpc服务消费

土167

  • Basket.Api 服务调用Discount.Grpc服务

3.1 创建client

  • Basket服务要去调用Discount服务,所以Basket是 Client, Discount是 service

1. 添加服务

2. 选择需要添加的服务类型

3. 选择服务路径

4. 添加成功后

  • 添加成功后,basket模块会有Protos文件夹

5. Program里添加Client服务

  • 在Basket模块的Program里添加

6. appSettings里添加grpc服务地址

  • 添加Grpc的服务地址

3.2 grpc通讯

1. 在StoreBasketCommandHandler使用

  • 在StoreBasketCommandHandler里进行折扣服务的扣减
相关推荐
徐先生 @_@|||1 小时前
Spark DataFrame常见的Transformation和Actions详解
大数据·分布式·spark
Gofarlic_oms12 小时前
通过Kisssoft API接口实现许可证管理自动化集成
大数据·运维·人工智能·分布式·架构·自动化
走遍西兰花.jpg4 小时前
spark配置
大数据·分布式·spark
hellojackjiang20114 小时前
如何保障分布式IM聊天系统的消息可靠性(即消息不丢)
分布式·网络安全·架构·信息与通信
BYSJMG5 小时前
计算机毕业设计选题推荐:基于Hadoop的城市交通数据可视化系统
大数据·vue.js·hadoop·分布式·后端·信息可视化·课程设计
一只大袋鼠5 小时前
分布式 ID 生成:雪花算法原理、实现与 MyBatis-Plus 实战
分布式·算法·mybatis
三水不滴6 小时前
对比一下RabbitMQ和RocketMQ
经验分享·笔记·分布式·rabbitmq·rocketmq
麦兜*6 小时前
深入解析分布式数据库TiDB核心架构:基于Raft一致性协议与HTAP混合负载实现金融级高可用与实时分析的工程实践
数据库·分布式·tidb
没有bug.的程序员6 小时前
Spring Boot 与 Sleuth:分布式链路追踪的集成、原理与线上故障排查实战
java·spring boot·分布式·后端·分布式链路追踪·sleuth·线上故障排查
Jackyzhe6 小时前
从零学习Kafka:配置参数
分布式·学习·kafka