初学者友好:Go-Kratos 集成 go-crud,Ent ORM CRUD 无需重复编码,轻松上手

简介: 本文介绍如何基于 `kratos-ent-example` 项目,集成 `go-curd` 工具简化 Go-Kratos 微服务中 Ent ORM 的 CRUD 操作。通过封装重复逻辑,实现增删改查代码的极简编写,帮助初学者快速上手微服务开发,提升效率,降低学习成本。

初学者友好:Go-Kratos 集成 go-crud,Ent ORM CRUD 无需重复编码,轻松上手

对于刚接触 Go 微服务开发的初学者来说,直接上手 “框架 + ORM” 的组合常显复杂。而 kratos-ent-example 项目已为我们搭建好了 Go-KratosEnt 的基础集成框架,本文将基于该项目,聚焦如何快速接入 go-curd 工具简化 CRUD(增删改查)操作,全程以 step-by-step 的方式讲解,新手也能轻松跟随实操。

先明确核心工具关系:kratos-ent-example是 “基础骨架”(已整合 Kratos 与 Ent),go-curd是 “效率工具”(封装重复 CRUD 逻辑),我们的核心目标是 “在现有骨架上装工具,让数据操作更简单”。

一、核心工具速览:3 分钟理清分工

在动手前,先明确三个工具的分工,避免越做越乱:

  • Go-Kratos:微服务框架核心,负责 API 定义、服务启动、请求分发,kratos-ent-example 已完成其基础配置;
  • Ent:现代化 ORM 框架,通过代码生成实现类型安全的数据库操作,采用 schema 定义模型,比传统 ORM 更注重类型检查;
  • go-crud:Ent 的上层封装工具,把重复的 CRUD 逻辑(如创建、查询、更新、删除)做成现成方法,无需手动编写 Ent 原生查询语句。

二、环境准备:5 分钟搞定前置依赖

先完成基础环境搭建和项目准备,确保后续步骤无报错:

  1. 安装基础工具:要求 Go 1.24+(项目 go.mod 指定版本),安装后用go version验证;
  2. Git:用于克隆示例项目;
  3. 准备数据库:支持 PostgreSQL/MySQL(Ent 适配多种数据库),新建一个数据库(比如叫example),不用建表(后续 Ent 会自动生成);
  4. 获取 kratos-ent-example 项目
    • 打开终端,执行以下命令克隆项目并进入目录:git clone https://github.com/tx7do/kratos-ent-example.git
    • cd kratos-ent-example
  5. 引入 go-curd 依赖:项目已预设 go-curd 的 Ent 适配模块(见 go.mod 中的github.com/tx7do/go-crud/entgo),直接拉取依赖即可:go mod tidy
  6. 确认项目核心目录:无需关注所有文件,重点记住 3 个核心目录(kratos-ent-example 已预设):
    • api:放 API 定义文件(.proto),用于定义 “创建用户”“查询用户” 等接口;
    • app/user/service/internal/data/ent/schema:放 Ent 模型定义(通过 schema 描述数据库表结构);
    • app/user/service/internal/data:放业务逻辑,这里会调用 go-curd 操作 Ent 客户端。

三、核心步骤 1:在 kratos-ent-example 中集成 go-curd

kratos-ent-example 已完成 Ent 的初始化配置(如数据库连接、代码生成),我们只需在现有基础上,将 go-curd 的 Ent 客户端集成进来,让业务层可以调用其简化方法。

1.1 修改数据层:集成 go-curd 的 Ent 客户端

打开app/user/service/internal/data/user.go修改代码以集成go-curdEnt 适配模块:

package data

import (
  entCurd "github.com/tx7do/go-crud/entgo"
)

type UserRepo struct {
   
    data *Data
    log  *log.Helper

    mapper     *mapper.CopierMapper[userV1.User, *ent.User]
    repository *entCurd.Repository[
        ent.UserQuery, ent.UserSelect, ent.UserCreate, ent.UserCreateBulk, ent.UserUpdate, ent.UserUpdateOne, ent.UserDelete,
        predicate.User,
        userV1.User, ent.User,
    ]
}

func NewUserRepo(data *Data, logger log.Logger) *UserRepo {
   
    l := log.NewHelper(log.With(logger, "module", "user/repo/user-service"))
    repo := &UserRepo{
   
        data:   data,
        log:    l,
        mapper: mapper.NewCopierMapper[userV1.User, *ent.User](),
    }

    // 初始化go-curd的Ent仓库,传入映射器和Ent客户端
    repo.repository = entCurd.NewRepository[
        ent.UserQuery, ent.UserSelect, ent.UserCreate, ent.UserCreateBulk, ent.UserUpdate, ent.UserUpdateOne, ent.UserDelete,
        predicate.User,
        userV1.User, ent.User,
    ](repo.mapper)

    return repo
}

核心改动说明:新增repository字段存储go-curdEnt 客户端,通过entCurd.NewRepository()初始化,后续 CRUD 操作均通过该客户端完成。

1.2 确认数据库配置(无需修改,仅验证)

kratos-ent-example 已在配置文件中预设数据库连接,打开configs/data.yaml验证:

data:
  database:
    driver: "postgres"  # 支持mysql/postgres/sqlite
    source: "host=localhost port=5432 user=postgres password=your_password dbname=example sslmode=disable"
    migrate: true  # 启动时自动执行数据库迁移

注意:将source中的用户名、密码改为自己的数据库信息,确保能连接到之前新建的example数据库。

四、核心步骤 2:用 go-curd 实现 CRUD 业务逻辑

我们将以 “用户模块” 为例,基于项目现有的目录结构,用 go-curd 实现用户的增、删、改、查。kratos-ent-example 已预设部分基础代码,我们只需补充和修改。

2.1 定义用户模型(Ent Schema)

Ent 通过 schema 定义模型(而非传统结构体),打开app/user/service/internal/data/ent/schema/user.go,定义用户模型的 schema:

package schema

import (
    "time"
    "entgo.io/ent"
    "entgo.io/ent/dialect"
    "entgo.io/ent/schema/field"
    "entgo.io/ent/schema/index"
)

// User holds the schema definition for the User entity.
type User struct {
   
    ent.Schema
}

// Fields of the User.
func (User) Fields() []ent.Field {
   
    return []ent.Field{
   
        field.String("user_name").
            SchemaType(map[string]string{
   
                dialect.MySQL:    "varchar(64)", // MySQL特定类型
                dialect.Postgres: "varchar(64)", // PostgreSQL特定类型
            }).
            Unique(), // 用户名唯一
        field.String("nick_name").
            SchemaType(map[string]string{
   
                dialect.MySQL:    "varchar(64)",
                dialect.Postgres: "varchar(64)",
            }),
        field.String("password").
            SchemaType(map[string]string{
   
                dialect.MySQL:    "varchar(128)",
                dialect.Postgres: "varchar(128)",
            }),
        field.Time("created_at").
            Default(time.Now).
            SchemaType(map[string]string{
   
                dialect.MySQL: "datetime",
            }),
        field.Time("updated_at").
            Default(time.Now).
            UpdateDefault(time.Now).
            SchemaType(map[string]string{
   
                dialect.MySQL: "datetime",
            }),
        field.Time("deleted_at").
            Optional().
            Nillable().
            SchemaType(map[string]string{
   
                dialect.MySQL: "datetime",
            }),
    }
}

// Edges of the User.
func (User) Edges() []ent.Edge {
   
    return nil
}

// Indexes of the User.
func (User) Indexes() []ent.Index {
   
    return []ent.Index{
   
        index.Fields("user_name").Unique(), // 用户名索引(唯一)
    }
}

说明:Ent 会根据该 schema 自动生成 Go 代码(实体、查询器等),后续通过生成的代码操作数据库。在app/user/service目录下执行以下命令生成 Ent 代码:

make ent

生成的代码会放在app/user/service/internal/data/ent目录下,包含User实体及 CRUD 基础方法。

2.2 编写 Data 层:用 go-curd 实现 CRUD

打开app/user/service/internal/data/user.go,编写业务逻辑方法。核心优势:用 go-curd 的现成方法替代原生 Ent 代码,减少重复工作。

package data

// List 查询用户列表(带分页)
func (r *UserRepo) List(ctx context.Context, req *pagination.PagingRequest) (*userV1.ListUserResponse, error) {
   
    if req == nil {
   
        return nil, errors.New("request is nil")
    }

    builder := r.data.db.Client().Debug().User.Query()

    ret, err := r.repository.ListWithPaging(ctx, builder, builder.Clone(), req)
    if err != nil {
   
        return nil, err
    }
    if ret == nil {
   
        return &userV1.ListUserResponse{
   Total: 0, Items: nil}, nil
    }

    return &userV1.ListUserResponse{
   
        Total: ret.Total,
        Items: ret.Items,
    }, nil
}

// Get 查询单个用户(支持按ID或用户名查询)
func (r *UserRepo) Get(ctx context.Context, req *userV1.GetUserRequest) (*userV1.User, error) {
   
    if req == nil {
   
        return nil, errors.New("request is nil")
    }

    var whereCond []func(s *sql.Selector)
    switch req.QueryBy.(type) {
   
    case *userV1.GetUserRequest_Id:
        whereCond = append(whereCond, user.IDEQ(req.GetId()))
    case *userV1.GetUserRequest_UserName:
        whereCond = append(whereCond, user.UserNameEQ(req.GetUserName()))
    default:
        whereCond = append(whereCond, user.IDEQ(req.GetId()))
    }

    builder := r.data.db.Client().Debug().User.Query()
    dto, err := r.repository.Get(ctx, builder, whereCond, req.GetViewMask())
    if err != nil {
   
        return nil, err
    }

    return dto, err
}

// Create 创建用户(密码加密存储)
func (r *UserRepo) Create(ctx context.Context, req *userV1.CreateUserRequest) (*userV1.User, error) {
   
    if req == nil || req.Data == nil {
   
        return nil, errors.New("request is nil")
    }

    if req.Data.Password != nil && req.Data.GetPassword() != "" {
   
        cryptoPassword, err := crypto.HashPassword(req.Data.GetPassword())
        if err != nil {
   
            return nil, err
        }
        req.Data.Password = &cryptoPassword
    }

    builder := r.data.db.Client().Debug().User.Create()
    result, err := r.repository.Create(ctx, builder, req.Data, nil, func(dto *userV1.User) {
   
        builder.
            SetNillableUserName(req.Data.UserName).
            SetNillableNickName(req.Data.NickName).
            SetCreatedAt(time.Now())

        if req.Data.Password != nil {
   
            builder.SetPassword(req.Data.GetPassword())
        }
    })

    return result, err
}

// Update 更新用户信息
func (r *UserRepo) Update(ctx context.Context, req *userV1.UpdateUserRequest) (*userV1.User, error) {
   
if req == nil || req.Data == nil {
   
        return nil, errors.New("request is nil")
    }

    if req.Data.Password != nil && req.Data.GetPassword() != "" {
   
        cryptoPassword, err := crypto.HashPassword(req.Data.GetPassword())
        if err != nil {
   
            return nil, err
        }
        req.Data.Password = &cryptoPassword
    }

    builder := r.data.db.Client().Debug().User.UpdateOneID(req.Data.GetId())
    result, err := r.repository.UpdateOne(ctx, builder, req.Data, req.GetUpdateMask(),
        []predicate.User{
   
            func(s *sql.Selector) {
   
                s.Where(sql.EQ(user.FieldID, req.Data.GetId()))
            },
        },
        func(dto *userV1.User) {
   
            builder.
                SetNillableNickName(req.Data.NickName).
                SetUpdatedAt(time.Now())

            if req.Data.Password != nil {
   
                builder.SetPassword(req.Data.GetPassword())
            }
        },
    )

    return result, err
}

// Delete 删除用户
func (r *UserRepo) Delete(ctx context.Context, req *userV1.DeleteUserRequest) (bool, error) {
   
    if req == nil {
   
        return false, errors.New("request is nil")
    }

    builder := r.data.db.Client().Debug().User.Delete()
    affected, err := r.repository.Delete(ctx, builder, []predicate.User{
   
        func(s *sql.Selector) {
   
            s.Where(sql.EQ(user.FieldID, req.GetId()))
        },
    })

    return err == nil && affected > 0, err
}

核心简化点:对比原生 Entgo-curdListWithPagingGetCreate等方法封装了查询条件构建、结果映射等重复逻辑,直接传入 DTO(数据传输对象)即可完成操作。

2.3 定义 API 接口(Proto)并生成代码

kratos-ent-example已在api/protos/user/service/v1/user.proto中预设了用户 API 定义(与 GORM 示例类似),我们只需确认内容,然后生成 Go 代码:

syntax = "proto3";

package user.service.v1;

import "google/api/annotations.proto";
import "pagination/v1/pagination.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";

// 用户服务
service UserService {
  rpc ListUser (pagination.PagingRequest) returns (ListUserResponse) {
    option (google.api.http) = { get: "/users" };
  }
  rpc GetUser (GetUserRequest) returns (User) {
    option (google.api.http) = { get: "/users/{id}" };
  }
  rpc CreateUser (CreateUserRequest) returns (User) {
    option (google.api.http) = { post: "/users", body: "*" };
  }
  rpc UpdateUser (UpdateUserRequest) returns (User) {
    option (google.api.http) = { put: "/users/{data.id}", body: "*" };
  }
  rpc DeleteUser (DeleteUserRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = { delete: "/users/{id}" };
  }
}

// 用户
message User {
  uint32 id = 1;

  optional string user_name = 2 [json_name = "userName", (gnostic.openapi.v3.property) = {description: "账户名"}];// 账户名
  optional string nick_name = 3 [json_name = "nickName", (gnostic.openapi.v3.property) = {description: "昵称"}];// 昵称
  optional string password = 4 [json_name = "password", (gnostic.openapi.v3.property) = {description: "密码"}];// 密码

  optional google.protobuf.Timestamp created_at = 200 [json_name = "createdAt", (gnostic.openapi.v3.property) = {description: "创建时间"}];// 创建时间
  optional google.protobuf.Timestamp updated_at = 201 [json_name = "updatedAt", (gnostic.openapi.v3.property) = {description: "更新时间"}];// 更新时间
  optional google.protobuf.Timestamp deleted_at = 202 [json_name = "deletedAt", (gnostic.openapi.v3.property) = {description: "删除时间"}];// 删除时间
}

// 获取用户列表 - 答复
message ListUserResponse {
  repeated User items = 1;
  uint64 total = 2;
}

// 获取用户数据 - 请求
message GetUserRequest {
  oneof query_by {
    uint32 id = 1 [
      (gnostic.openapi.v3.property) = {description: "用户ID", read_only: true},
      json_name = "id"
    ]; // 用户ID

    string user_name = 2 [
      (gnostic.openapi.v3.property) = {description: "用户登录名", read_only: true},
      json_name = "userName"
    ]; // 用户登录名
  }

  optional google.protobuf.FieldMask view_mask = 100 [
    json_name = "viewMask",
    (gnostic.openapi.v3.property) = {
      description: "视图字段过滤器,用于控制返回的字段"
    }
  ]; // 视图字段过滤器,用于控制返回的字段
}

// 创建用户 - 请求
message CreateUserRequest {
  User data = 1;

  uint32 operator_id = 2 [json_name = "operatorId", (gnostic.openapi.v3.property) = {description: "操作者用户ID"}];// 操作者用户ID
}

// 更新用户 - 请求
message UpdateUserRequest {
  User data = 1;

  google.protobuf.FieldMask update_mask = 2 [
    json_name = "updateMask",
    (gnostic.openapi.v3.property) = {
      description: "要更新的字段列表",
      example: {yaml : "id,realname,username"}
    }
  ]; // 要更新的字段列表

  optional bool allow_missing = 3 [
    json_name = "allowMissing",
    (gnostic.openapi.v3.property) = {description: "如果设置为true的时候,资源不存在则会新增(插入),并且在这种情况下`updateMask`字段将会被忽略。"}
  ]; // 如果设置为true的时候,资源不存在则会新增(插入),并且在这种情况下`updateMask`字段将会被忽略。
}

// 删除用户 - 请求
message DeleteUserRequest {
  uint32 id = 1;

  uint32 operator_id = 2 [json_name = "operatorId", (gnostic.openapi.v3.property) = {description: "操作者用户ID"}];// 操作者用户ID
}

执行以下命令生成 Go 代码(项目已预设make api命令):

make api

生成的代码会放在api/gen/go/user/service/v1目录下,供 Data 层和 Service 层调用。

2.4 Server 层绑定接口与 Service

kratos-ent-example 通过NewRESTServer方法完成 HTTP Server 的创建,并将 UserService 注册到 KratosHTTP 服务中,实现 API 接口与 Service 层的绑定。核心代码如下(文件路径:app/user/service/internal/server/rest.go):

// NewRESTServer new an HTTP server.
func NewRESTServer(
    cfg *conf.Bootstrap, logger log.Logger,
    userService *service.UserService,
) *http.Server {
   
    if cfg == nil || cfg.Server == nil || cfg.Server.Rest == nil {
   
        return nil
    }

    srv := bootstrap.CreateRestServer(cfg, logging.Server(logger))

    userV1.RegisterUserServiceHTTPServer(srv, userService)

    if cfg.GetServer().GetRest().GetEnableSwagger() {
   
        swaggerUI.RegisterSwaggerUIServerWithOption(
            srv,
            swaggerUI.WithTitle("Kratos Ent Example User Service API"),
            swaggerUI.WithMemoryData(assets.OpenApiData, "yaml"),
        )
    }

    return srv
}

代码说明:

  1. bootstrap.CreateRestServer:基于配置创建 Kratos 的 HTTP Server 实例,包含端口、中间件等基础配置;
  2. userV1.RegisterUserServiceHTTPServer:将实现了UserService接口的userService实例注册到 HTTP Server 中,完成 API 接口(如/users)与 Service 层方法的绑定;
  3. Swagger 相关配置:可选开启 Swagger UI,方便调试 API 接口。

此步骤无需手动修改代码(项目已实现),只需验证该文件存在且代码完整即可 —— 启动服务后,Kratos 会自动将 HTTP 请求转发到对应的 Service 层方法。

五、核心步骤 3:运行项目并测试 CRUD 接口

所有代码修改完成后,启动项目并测试接口,验证 go-curdEnt 的集成是否正常工作。

3.1 自动创建数据库表(Ent 迁移)

kratos-ent-example 已在app/user/service/internal/data/ent_client.go中实现 Ent 自动迁移逻辑,启动项目时会根据 schema 创建数据库表:

// 关键迁移代码(项目已实现)
if cfg.Data.Database.GetMigrate() {
   
  if err = client.Schema.Create(context.Background(), migrate.WithForeignKeys(true)); err != nil {
   
    l.Fatalf("failed creating schema resources: %v", err)
  }
}

3.2 启动项目

在项目的服务目录app/user/service下执行以下命令启动服务:

make run

看到终端输出类似以下日志,说明项目启动成功:

DEBUG msg=config loaded: data.yaml format: yaml
DEBUG msg=ent: connecting to postgres://postgres:***@localhost:5432/example?sslmode=disable
DEBUG msg=ent: schema migrated successfully

3.3 测试接口(用 curl 或 Postman)

以下用 curl 命令测试 4 个 CRUD 接口,确保功能正常:

1. 创建用户:

curl -X 'POST' \
  'http://localhost:7788/users' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "data": {
    "id": 0,
    "userName": "zhangsan",
    "nickName": "张三",
    "password": "123456"
  }
}'

成功响应:

{
   
  "id": 1, //(ID为自动生成的主键)。
  "userName": "zhangsan",
  "nickName": "张三",
  "password": "$2a$10$Jd34ATGgTJ2sV7xvPruMLONArXk9KYQ2O6XDY42UxVO37p5DO8CVu",
  "createdAt": "1970-01-01T00:00:00Z",
  "updatedAt": "1970-01-01T00:00:00Z"
}

2. 查询用户(使用上面返回的ID=1):

curl -X 'GET' \
  'http://localhost:7788/users/1' \
  -H 'accept: application/json'

成功响应:

{
   
  "id": 1,
  "userName": "zhangsan",
  "nickName": "张三",
  "password": "$2a$10$Jd34ATGgTJ2sV7xvPruMLONArXk9KYQ2O6XDY42UxVO37p5DO8CVu",
  "createdAt": "1970-01-01T00:00:00Z",
  "updatedAt": "1970-01-01T00:00:00Z"
}

3. 更新用户:

curl -X 'PUT' \
  'http://localhost:7788/users/1' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "data": {
    "id": 1,
    "userName": "zhangsan",
    "nickName": "张三三"
  }
}'

成功响应:

{
   
  "id": 1,
  "userName": "zhangsan",
  "nickName": "张三三",
  "password": "$2a$10$Jd34ATGgTJ2sV7xvPruMLONArXk9KYQ2O6XDY42UxVO37p5DO8CVu",
  "createdAt": "1970-01-01T00:00:00Z",
  "updatedAt": "1970-01-01T00:00:00Z"
}

4. 删除用户:

curl -X 'DELETE' \
  'http://localhost:7788/users/1' \
  -H 'accept: */*'

成功响应:

{
   }

六、新手避坑注意事项

  1. Ent 代码生成必须执行:修改 schema 后必须运行make ent生成新代码,否则会报 “未定义字段 / 方法” 错误;
  2. 数据库驱动适配:Ent 对不同数据库的字段类型支持有差异(如时间类型),schema 中需用SchemaType指定数据库特定类型;
  3. 查询条件构建:Ent 的查询条件通过函数闭包实现(如q.Where(ent.User.ID(1))),与 GORM 的链式调用不同,需注意语法;
  4. go-curd 版本兼容:项目依赖的github.com/tx7do/go-crud/entgo版本需与 Ent 版本(项目中为 v0.14.5)匹配,否则可能出现方法不兼容;
  5. 迁移操作谨慎执行:生产环境中,migrate.WithForeignKeys(true)可能导致表结构变更风险,建议先通过ent migrate plan预览变更。

七、总结

基于 kratos-ent-example 项目集成 go-curd 的核心逻辑是:在 Ent 自动生成的代码基础上,通过 go-curd 封装 CRUD 逻辑,减少重复的查询构建和结果映射工作。相比直接使用 Ent 原生 API,go-curd 让业务代码更简洁,尤其适合快速开发。

如果需要扩展其他模块(如订单、商品),只需复制用户模块的逻辑:定义 Ent schema→生成代码→用 go-curd 实现 CRUD→绑定 API 接口。若遇到问题,可参考项目的官方文档(go-curd、kratos-ent-example)获取更多细节。

目录
相关文章
|
前端开发 安全 API
开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:自动化解放双手,初学者快速搭建系统并自动生成前端接口
GoWind Admin 是基于 Go-Kratos 与 Vue3 的企业级中后台框架,开箱即用,集成用户、权限、租户等核心模块。搭配 protoc-gen-typescript-http,可从 Protobuf 自动生成类型安全的前端接口,大幅降低联调成本,提升开发效率,助力初学者快速搭建系统,实现前后端高效协作。
301 0
|
2月前
|
关系型数据库 API Go
初学者友好:Go-Kratos 集成 go-crud,GORM ORM CRUD 无需重复编码,轻松上手
本文介绍如何在Go-Kratos微服务中集成go-curd与GORM,实现CRUD操作免重复编码。基于kratos-gorm-example项目,通过step-by-step教程,帮助初学者快速上手:从环境搭建、模型定义到API开发,全程简化数据操作,显著提升开发效率,适合Go新手快速构建微服务应用。
195 2
|
JSON 前端开发 API
开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:API管理
GoWind Admin基于Kratos与Protobuf,实现gRPC与REST双协议支持,通过Buf统一管理API定义,结合Make自动化生成多语言代码,提升前后端协作效率,构建企业级中后台系统。
340 0
|
2月前
|
运维 Cloud Native 应用服务中间件
阿里云微服务引擎 MSE 及 API 网关 2025 年 11 月产品动态
阿里云微服务引擎 MSE 面向业界主流开源微服务项目, 提供注册配置中心和分布式协调(原生支持 Nacos/ZooKeeper/Eureka )、云原生网关(原生支持Higress/Nginx/Envoy,遵循Ingress标准)、微服务治理(原生支持 Spring Cloud/Dubbo/Sentinel,遵循 OpenSergo 服务治理规范)能力。API 网关 (API Gateway),提供 APl 托管服务,覆盖设计、开发、测试、发布、售卖、运维监测、安全管控、下线等 API 生命周期阶段。帮助您快速构建以 API 为核心的系统架构.满足新技术引入、系统集成、业务中台等诸多场景需要。
阿里云微服务引擎 MSE 及 API 网关 2025 年 11 月产品动态
|
4月前
|
负载均衡 算法 Java
【SpringCloud(2)】微服务注册中心:Eureka、Zookeeper;CAP分析;服务注册与服务发现;单机/集群部署Eureka;连接注册中心
1. 什么是服务治理? SpringCloud封装了Netfix开发的Eureka模块来实现服务治理 在传统pc的远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务于服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册
350 0
|
前端开发 Go API
开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:数据脱敏和隐私保护
GoWind Admin基于Protobuf生态,集成protoc-gen-redact插件,实现开箱即用的数据脱敏与隐私保护。通过注解定义规则,自动生成脱敏代码,支持多语言、灵活配置,零侵入业务逻辑,适用于微服务、日志、前端等场景,保障数据安全合规。
179 0
|
2月前
|
前端开发 JavaScript Go
开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:为什么选 Golang+Vue3 这套组合?
go-wind-admin 采用 Golang + Vue3 技术栈,融合高性能后端与高效前端生态。后端基于 go-kratos、ent/gorm 灵活适配复杂业务,前端结合 Vue3、TypeScript 与 Vben Admin,提升开发效率与可维护性,兼顾性能、扩展性与企业级需求,是中后台系统的理想选择。(239字)
345 6
|
存储 前端开发 Go
开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:站内信
GoWind Admin 基于 Kratos 框架,提供开箱即用的站内信模块,支持消息推送、实时通知、分类管理与多用户收发,助力企业级后台高效集成通信功能。
281 0
|
2月前
|
存储 JSON 数据建模
构建数据资产“导航地图”:详解 UModel 数据发现与全链路分析能力
你是否曾面对一个庞大的可观测系统,却不知从何下手?成百上千个实体定义散落在 APM、K8s、云产品等不同域中,关系错综复杂,文档滞后,新人上手难,模型演进无迹可循……阿里云 UModel 查询为此而生。它不是查询日志或指标,而是查询“模型本身”——让你一键看清:系统里定义了哪些实体?它们之间如何关联?哪些模型字段过多、描述缺失?跨域依赖是如何构建的?
140 28
|
3月前
|
运维 Cloud Native 应用服务中间件
阿里云微服务引擎 MSE 及 API 网关 2025 年 10 月产品动态
阿里云微服务引擎 MSE 面向业界主流开源微服务项目, 提供注册配置中心和分布式协调(原生支持 Nacos/ZooKeeper/Eureka )、云原生网关(原生支持Higress/Nginx/Envoy,遵循Ingress标准)、微服务治理(原生支持 Spring Cloud/Dubbo/Sentinel,遵循 OpenSergo 服务治理规范)能力。API 网关 (API Gateway),提供 APl 托管服务,覆盖设计、开发、测试、发布、售卖、运维监测、安全管控、下线等 API 生命周期阶段。帮助您快速构建以 API 为核心的系统架构.满足新技术引入、系统集成、业务中台等诸多场景需要
阿里云微服务引擎 MSE 及 API 网关 2025 年 10 月产品动态