当前位置: 首页 > news >正文

go-zero整合单机版ClickHouse并实现增删改查

go-zero整合单机版ClickHouse并实现增删改查

本教程基于go-zero微服务入门教程,项目工程结构同上一个教程。

本教程主要实现go-zero框架整合单机版ClickHouse,并暴露接口实现对ClickHouse数据的增删改查。

go-zero微服务入门教程:https://blog.csdn.net/u011019141/article/details/136233473
本文源码:https://gitee.com/songfayuan/go-zero-demo (教程源码分支:5.zero整合单机ClickHouse)

准备工作

  • 如不熟悉go-zero项目的,请先查看上一篇go-zero微服务入门教程
  • 请自行安装好单机版ClickHouse,建议采用docker安装。

安装依赖

项目工程父级目录下执行如下指令安装依赖:

# 下载安装clickhouse-go
go get github.com/ClickHouse/clickhouse-go/v2
# 下载安装otel/sdk/trace
go get -u go.opentelemetry.io/otel/sdk/trace

rpc新增ClickHouse配置

以下操作在rpc模块执行。

sys.yaml

sys.yaml配置文件新增ClickHouse配置信息,如下:

# ClickHouse配置
ClickHouse:Addr:- "192.168.2.204:9000"Auth:Database: dsmsUsername: defaultPassword:Table: http_captureInterval: 3MaxNum: 1000MaxChunkBytes: 10485760Debug: falseDatasource: clickhouse://default:@192.168.2.204:9000/dsms?debug=false

config.go

config.go文件中新增ClickHouseConf配置信息,如下:

package configimport ("github.com/zeromicro/go-zero/zrpc""go-zero-demo/common/task/kafkaconf"
)type Config struct {zrpc.RpcServerConfClickHouse ClickHouseConf
}type ClickHouseAuthConf struct {Database stringUsername stringPassword string `json:",optional"`
}type ClickHouseConf struct {Addr []stringAuth ClickHouseAuthConfOpt1 struct {MaxIdleConns int `json:",optional"`MaxOpenConns int `json:",optional"`} `json:",optional"`Opt2 struct {MaxIdleConns int `json:",optional"`MaxOpenConns int `json:",optional"`} `json:",optional"`Table   stringColumns []string `json:",optional"`Debug   bool     `json:",default=false"`Datasource string `json:",optional,default="`
}

servicecontext.go

servicecontext.go文件新增ClickHouse配置信息,完整代码如下:

package serverimport ("github.com/ClickHouse/clickhouse-go/v2""go-zero-demo/rpc/sys/internal/config""log""time"
)type ServiceContext struct {Config      config.ConfigClickhouseConn clickhouse.Conn
}func NewServiceContext(c config.Config) *ServiceContext {return &ServiceContext{Config:      c,ClickhouseConn: NewClickHouseConn(c.ClickHouse),}
}// NewClickHouseConn 创建clickhouse链接 【clickhouse-go】
func NewClickHouseConn(ckConfig config.ClickHouseConf) clickhouse.Conn {maxIdleConns := 20if ckConfig.Opt2.MaxIdleConns > 0 {maxIdleConns = ckConfig.Opt2.MaxIdleConns}maxOpenConns := 2000if ckConfig.Opt2.MaxOpenConns > 0 {maxOpenConns = ckConfig.Opt2.MaxOpenConns}conn, err := clickhouse.Open(&clickhouse.Options{Addr: ckConfig.Addr,Auth: clickhouse.Auth{Database: ckConfig.Auth.Database,Username: ckConfig.Auth.Username,Password: ckConfig.Auth.Password,},Settings: clickhouse.Settings{"max_execution_time": 60,},DialTimeout:  30 * time.Second,MaxIdleConns: maxIdleConns,MaxOpenConns: maxOpenConns,Debug:        ckConfig.Debug,})if err != nil {log.Fatalf("error: 启动clickhouse client失败, %v", err)}return conn
}

编写rpc服务

修改sys.proto文件

新增ClickHouse操作请求的配置,如下:

message ClickhouseReq{string name = 1;string nickName = 2;string password = 3;string email = 4;
}message  ClickhouseResp{string name = 1;string nickName = 2;string password = 3;string email = 4;
}service Sys{// clickhouse增删改查rpc ClickhouseAdd(ClickhouseReq)returns(ClickhouseResp);rpc ClickhouseDelete(ClickhouseReq)returns(ClickhouseResp);rpc ClickhouseUpdate(ClickhouseReq)returns(ClickhouseResp);rpc ClickhouseGet(ClickhouseReq)returns(ClickhouseResp);
}

用goctl生成rpc代码

生成方法同上篇文章,自行查看。

编写API Gateway代码

编写api文件

clickhouse.api

在api目录下创建新目录doc/clickhouse,在clickhouse目录下创建clickhouse.api文件。

syntax = "v1"info(title: "clickhouse操作相关"desc: "clickhouse操作相关"author: "宋发元"
)type (ApiClickhouseReq {Name     string `json:"name"`NickName string `json:"nickName"`Password string `json:"password,optional"`Email    string `json:"email"`}ApiClickhouseResp {Code    int64       `json:"code"`Message string      `json:"message"`Data    ApiClickhouseReq `json:"data"`}ApiClickhouseGetReq {Key string `form:"key"`}
)@server (group : clickhouse/testprefix : /clickhouse/test
)service admin-api{@doc(summary : "Clickhouse新增数据")@handler ClickhouseAddpost /clickhouseAdd(ApiClickhouseReq)returns(ApiClickhouseResp)@doc(summary : "Clickhouse删除数据")@handler ClickhouseDeletepost /clickhouseDelete(ApiClickhouseReq)returns(ApiClickhouseResp)@doc(summary : "Clickhouse修改数据")@handler ClickhouseUpdatepost /clickhouseUpdate(ApiClickhouseReq)returns(ApiClickhouseResp)@doc(summary : "Clickhouse查询数据")@handler ClickhouseGetget /clickhouseGet(ApiClickhouseGetReq)returns(ApiClickhouseResp)
}
admin.api

在api/doc/admin.api文件添加配置信息。

import "clickhouse/clickhouse.api"

用goctl生成API Gateway代码

生成方法同上篇文章,自行查看。但是此处要基于admin.api文件去生成代码,如果基于clickhouse.api生成,则生成的代码只有clickhouse.api定义的接口代码,其他api文件定义的接口代码不被生成。

修改API Gateway代码调用rpc服务

clickhouseaddlogic.go

修改api/internal/logic/clickhouse/test/clickhouseaddlogic.go里的ClickhouseAdd方法,如下:

func (l *ClickhouseAddLogic) ClickhouseAdd(req *types.ApiClickhouseReq) (resp *types.ApiClickhouseResp, err error) {res, err := l.svcCtx.Sys.ClickhouseAdd(l.ctx, &sysclient.ClickhouseReq{Name:     req.Name,NickName: req.NickName,Password: req.Password,Email:    req.Email,})if err != nil {reqJson, _ := json.Marshal(res)logx.WithContext(l.ctx).Errorf("新增Clickhouse信息失败,请求参数:%s,异常信息:%s", reqJson, err.Error())return nil, rpcerror.New(err)}return &types.ApiClickhouseResp{Code:    200,Message: "新增成功",Data: types.ApiClickhouseReq{Name:     req.Name,NickName: req.NickName,Password: req.Password,Email:    req.Email,},}, nil
}

clickhousedeletelogic.go

修改api/internal/logic/clickhouse/test/clickhousedeletelogic.go里的ClickhouseDelete方法,如下:

func (l *ClickhouseDeleteLogic) ClickhouseDelete(req *types.ApiClickhouseReq) (resp *types.ApiClickhouseResp, err error) {l.svcCtx.Sys.ClickhouseDelete(l.ctx, &sysclient.ClickhouseReq{})return &types.ApiClickhouseResp{Code:    200,Message: "删除成功",Data:    types.ApiClickhouseReq{},}, nil
}

clickhousegetlogic.go

修改api/internal/logic/clickhouse/test/clickhousegetlogic.go里的ClickhouseGet方法,如下:

func (l *ClickhouseGetLogic) ClickhouseGet(req *types.ApiClickhouseGetReq) (resp *types.ApiClickhouseResp, err error) {param := &sysclient.ClickhouseReq{}copier.Copy(param, req)getRes, err := l.svcCtx.Sys.ClickhouseGet(l.ctx, param)if err != nil {resJson, _ := json.Marshal(getRes)logx.WithContext(l.ctx).Errorf("获取数据测试:操作失败,请求参数param = %s,异常信息errMsg = %s", resJson, err.Error())return nil, rpcerror.New(err)}return &types.ApiClickhouseResp{Code:    200,Message: "操作成功",Data: types.ApiClickhouseReq{Name:     getRes.Name,NickName: getRes.NickName,Password: getRes.Password,Email:    getRes.Email,},}, nil
}

clickhouseupdatelogic.go

修改api/internal/logic/clickhouse/test/clickhouseupdatelogic.go里的ClickhouseUpdate方法,如下:

func (l *ClickhouseUpdateLogic) ClickhouseUpdate(req *types.ApiClickhouseReq) (resp *types.ApiClickhouseResp, err error) {updateRes, err := l.svcCtx.Sys.ClickhouseUpdate(l.ctx, &sysclient.ClickhouseReq{Name:     req.Name,NickName: req.NickName,Password: req.Password,Email:    req.Email,})if err != nil {resJson, _ := json.Marshal(updateRes)logx.WithContext(l.ctx).Errorf("Clickhouse更新数据测试:操作失败,请求参数param = %s,异常信息errMsg = %s", resJson, err.Error())return nil, rpcerror.New(err)}return &types.ApiClickhouseResp{Code:    200,Message: "操作成功",Data: types.ApiClickhouseReq{Name:     updateRes.Name,NickName: updateRes.NickName,Password: updateRes.Password,Email:    updateRes.Email,},}, nil
}

修改rpc代码调用crud代码

clickhouseaddlogic.go

  • 修改rpc/sys/internal/logic/clickhouseaddlogic.go,如下内容:
// clickhouse增删改查
func (l *ClickhouseAddLogic) ClickhouseAdd(in *sysclient.ClickhouseReq) (*sysclient.ClickhouseResp, error) {// 创建表createTable(l.ctx, l.svcCtx.ClickhouseConn)// 插入数据insertData(l.ctx, l.svcCtx.ClickhouseConn, "Alice", "Ally", "password123", "alice@example.com")insertData(l.ctx, l.svcCtx.ClickhouseConn, "Bob", "Bobby", "password456", "bob@example.com")// 批量插入数据batchInsertData(l.ctx, l.svcCtx.ClickhouseConn, []User{{"Alice", "Ally", "password123", "alice@example.com"},{"Bob", "Bobby", "password456", "bob@example.com"},{"Charlie", "Char", "password789", "charlie@example.com"},})return &sysclient.ClickhouseResp{}, nil
}// 创建表
func createTable(ctx context.Context, conn clickhouse.Conn) {query := `CREATE TABLE IF NOT EXISTS demo (Name String,NickName String,Password String,Email String) ENGINE = MergeTree()ORDER BY Name`err := conn.Exec(ctx, query)if err != nil {log.Fatal(err)}fmt.Println("成功创建demo表...")
}// 插入数据
func insertData(ctx context.Context, conn clickhouse.Conn, name, nickName, password, email string) {batch, err := conn.PrepareBatch(ctx, "INSERT INTO demo (Name, NickName, Password, Email)")if err != nil {log.Fatal(err)}err = batch.Append(name, nickName, password, email)if err != nil {log.Fatal(err)}err = batch.Send()if err != nil {log.Fatal(err)}fmt.Println("成功插入数据...")
}// 批量插入数据
func batchInsertData(ctx context.Context, conn clickhouse.Conn, users []User) {batch, err := conn.PrepareBatch(ctx, "INSERT INTO demo (Name, NickName, Password, Email)")if err != nil {log.Fatal(err)}for _, user := range users {err := batch.Append(user.Name, user.NickName, user.Password, user.Email)if err != nil {log.Fatal(err)}}err = batch.Send()if err != nil {log.Fatal(err)}fmt.Println("成功批量插入数据...")
}

clickhousedeletelogic.go

  • 修改rpc/sys/internal/logic/clickhousedeletelogic.go,如下内容:
func (l *ClickhouseDeleteLogic) ClickhouseDelete(in *sysclient.ClickhouseReq) (*sysclient.ClickhouseResp, error) {// 删除数据deleteData(l.ctx, l.svcCtx.ClickhouseConn, "Bob")return &sysclient.ClickhouseResp{}, nil
}// 删除数据
func deleteData(ctx context.Context, conn clickhouse.Conn, name string) {query := `ALTER TABLE demo DELETE WHERE Name = ?`err := conn.Exec(ctx, query, name)if err != nil {log.Fatal(err)}fmt.Println("删除数据成功...")
}

clickhouseupdatelogic.go

  • 修改rpc/sys/internal/logic/clickhouseupdatelogic.go,如下内容:
func (l *ClickhouseUpdateLogic) ClickhouseUpdate(in *sysclient.ClickhouseReq) (*sysclient.ClickhouseResp, error) {// 更新数据updateData(l.ctx, l.svcCtx.ClickhouseConn, "Alice", "newpassword321")return &sysclient.ClickhouseResp{}, nil
}// 更新数据
func updateData(ctx context.Context, conn clickhouse.Conn, name, newPassword string) {query := `ALTER TABLE demo UPDATE Password = ? WHERE Name = ?`err := conn.Exec(ctx, query, newPassword, name)if err != nil {log.Fatal(err)}fmt.Println("Data updated successfully")
}

clickhousegetlogic.go

  • 修改rpc/sys/internal/logic/clickhousegetlogic.go,如下内容:
func (l *ClickhouseGetLogic) ClickhouseGet(in *sysclient.ClickhouseReq) (*sysclient.ClickhouseResp, error) {// 查询数据queryData(l.ctx, l.svcCtx.ClickhouseConn)return &sysclient.ClickhouseResp{}, nil
}// 查询数据
func queryData(ctx context.Context, conn clickhouse.Conn) {rows, err := conn.Query(ctx, "SELECT Name, NickName, Password, Email FROM demo")if err != nil {log.Fatal(err)}defer rows.Close()for rows.Next() {var name, nickName, password, email stringif err := rows.Scan(&name, &nickName, &password, &email); err != nil {log.Fatal(err)}fmt.Printf("Name: %s, NickName: %s, Password: %s, Email: %s\n", name, nickName, password, email)}
}

完整调用演示

最后,在根目录go-zero-demo执行下命令。

go mod tidy

运行rpc服务

运行方法同上篇文章,具体查看教程go-zero微服务入门教程完整调用演示部分。

运行api

运行方法同上篇文章,具体查看教程go-zero微服务入门教程完整调用演示部分。

api调用

以下调用采用curl进行,你也可以用postman调用。

新增接口
 songfayuan@MacBook-Pro  ~  curl -X POST -H "Content-Type: application/json" -d '{"name":"songfayuan","nickName":"宋发元","email":"1414@qq.com"}' localhost:8888/clickhouse/test/clickhouseAdd{"code":200,"message":"操作成功","data":{"name":"songfayuan","nickName":"宋发元","password":"","email":"1414@qq.com"}}%
删除接口
 songfayuan@MacBook-Pro  ~  curl -X POST -H "Content-Type: application/json" -d '{"name":"songfayuan","nickName":"宋发元6666","email":"1414@qq.com"}' localhost:8888/clickhouse/test/clickhouseDelete{"code":200,"message":"操作成功","data":{"name":"","nickName":"","password":"","email":""}}%
修改接口
 songfayuan@MacBook-Pro  ~  curl -X POST -H "Content-Type: application/json" -d '{"name":"songfayuan","nickName":"宋发元6666","email":"1414@qq.com"}' localhost:8888/clickhouse/test/clickhouseUpdate{"code":200,"message":"操作成功","data":{"name":"songfayuan","nickName":"宋发元6666","password":"","email":"1414@qq.com"}}%
查询接口
 songfayuan@MacBook-Pro  ~  curl "localhost:8888/clickhouse/test/clickhouseGet?key=121212"{"code":200,"message":"操作成功","data":{"name":"songfayuan","nickName":"宋发元6666","password":"","email":"1414@qq.com"}}%

相关文章:

go-zero整合单机版ClickHouse并实现增删改查

go-zero整合单机版ClickHouse并实现增删改查 本教程基于go-zero微服务入门教程,项目工程结构同上一个教程。 本教程主要实现go-zero框架整合单机版ClickHouse,并暴露接口实现对ClickHouse数据的增删改查。 go-zero微服务入门教程:https://b…...

行政工作如何提高效率?桌面备忘录便签软件哪个好

在行政管理工作中,效率的提高无疑是每个行政人员都追求的目标。而随着科技的发展,各种便捷的工具也应运而生,其中桌面备忘录便签软件便是其中的佼佼者。那么,这类软件又如何帮助我们提高工作效率呢? 首先,…...

利用向日葵和微信/腾讯会议实现LabVIEW远程开发

利用向日葵远程控制软件结合微信或腾讯会议的视频通话功能,可以实现LabVIEW的远程开发和调试。通过向日葵进行远程桌面访问,配合视频通话工具进行实时沟通与问题解决,不仅提高了开发效率,还减少了地域限制带来的不便。介绍这种远程…...

SpringBoot 单元测试 指定 环境

如上图所示,在配置窗口中添加--spring.profiles.activedev,就可以了。...

Flutter 中的 SliverOpacity 小部件:全面指南

Flutter 中的 SliverOpacity 小部件:全面指南 Flutter 是一个功能强大的 UI 框架,由 Google 开发,允许开发者使用 Dart 语言来构建高性能、美观的跨平台应用。在 Flutter 的滚动组件体系中,SliverOpacity 是一个用来为其子 Slive…...

源码分析の前言

源码分析路线图: 初级部分:ArrayList->LinkedList->Vector->HashMap(红黑树数据结构,如何翻转,变色,手写红黑树)->ConcurrentHashMap 中级部分:Spring->Spring MVC->Spring Boot->M…...

接口性能测试复盘:解决JMeter超时问题的实践

在优化接口并重新投入市场后,我们面临着一项关键任务:确保其在高压环境下稳定运行。于是,我们启动了一轮针对该接口的性能压力测试,利用JMeter工具模拟高负载场景。然而,在测试进行约一分钟之后,频繁出现了…...

[数据集][目标检测]猕猴桃检测数据集VOC+YOLO格式1838张1类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):1838 标注数量(xml文件个数):1838 标注数量(txt文件个数):1838 标注…...

摸鱼大数据——Hive函数7-9

7、日期时间函数 Hive函数链接:LanguageManual UDF - Apache Hive - Apache Software Foundation SimpleDateFormat (Java Platform SE 8 ) current_timestamp: 获取时间原点到现在的秒/毫秒,底层自动转换方便查看的日期格式 常用 to_date: 字符串格式时间…...

python连接数据库

python连接MYSQL、postgres、oracle等的基本操作 python连接mysql MySQLdb MySQLdb又叫MySQL-python ,是 Python 连接 MySQL 的一个驱动,很多框架都也是基于此库进行开发,只支持 Python2.x,而且安装的时候有很多前置条件&#…...

能不能接受这些坑?买电车前一定要看

图片来源:汽车之家 文 | Auto芯球 作者 | 雷慢 刚有个朋友告诉我,买了电车后感觉被骗了, 很多“坑”都是他买车后才知道的。 不提前研究,不做功课,放着我这个老司机不请教, 这个大冤种他不当谁当&…...

k8s中pod如何排错?

排除Kubernetes Pod故障通常涉及一系列步骤,以诊断问题并找到解决方案。以下是一些常见的故障排除方法: 检查Pod状态: 使用kubectl get pods查看Pod的状态。如果Pod没有处于Running状态,查看更详细的信息,使用kubectl describe …...

【手撕面试题】Vue(高频知识点二)

每天10道题,100天后,搞定所有前端面试的高频知识点,加油!!!,在看文章的同时,希望不要直接看答案,先思考一下自己会不会,如果会,自己的答案是什么&…...

四、.Net8对接Ollama实现文字翻译(.Net8+SemanticKernel+Ollama)本地运行自己的大模型

.Net8SemanticKernelOllama 一、Semantic Kernel官方定义SK能做什么? 二、基本使用1、普通对话2、使用插件实现文本翻译功能 三、IChatCompletionService、ITextGenerationService、ITextEmbeddingGenerationService 很多情况都有这样的需求,使用自有系统…...

初始C++

感谢大佬的光临各位,希望和大家一起进步,望得到你的三连,互三支持,一起进步 个人主页:LaNzikinh-CSDN博客 文章目录 前言一.引用二.内联函数三.类和对象总结 前言 之前讲c的命令空间和第一个程序的运行,继…...

Chapter 5 Current Mirrors and Biasing Techniques

Chapter 5 Current Mirrors and Biasing Techniques 这一章介绍电流镜 5.1 Basic Current Mirrors MOS工作在饱和区, 表现为一个电流源. 考虑电源变化, PVT波动, 我们会首先产生一路精准电流源, 再复制这路电流. 如何复制呢? 电流转电压再转电流就行了, 如下图所示 考虑到…...

Avalonia Image控件上通过鼠标拖动画出矩形框

注册鼠标事件&#xff1a;首先&#xff0c;你需要注册 Image 控件上的鼠标事件&#xff0c;包括 PointerPressed、PointerMoved 和 PointerReleased。你可以在 XAML 文件或代码中注册这些事件。 <Image PointerPressed"Image_PointerPressed" PointerMoved"…...

Wireshark Lua插件入门

摘要 开发中经常通过抓包分析协议&#xff0c;对于常见的协议如 DNS wireshark 支持自动解析&#xff0c;便于人类的理解&#xff0c;对于一些私有协议&#xff0c;wireshark 提供了插件的方式自定义解析逻辑。 1 动手 废话少说&#xff0c;直接上手。 第一步当然是装上wiresh…...

XXE漏洞简介

目录 漏洞原理 漏洞危害 前置知识 XML简介 DTD简介 DTD的两种声明方式 实体 实体分类 内置实体(Built-inentities) 字符实体&#xff08;Characterentities&#xff09; 通用实体&#xff08;Generalentities&#xff09; 参数实体(Parameterentities) XXE漏洞…...

小白跟做江科大32单片机之蜂鸣器

1.复制之前编写的工程库项目&#xff0c;详细工程库创建过程如下链接&#xff1a; 小白跟做江科大32单片机之LED闪烁-CSDN博客https://blog.csdn.net/weixin_58051657/article/details/139295351?spm1001.2014.3001.55022.按照江科大老师给的图片进行连接蜂鸣器 接线时要用公…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

消息队列系统设计与实践全解析

文章目录 &#x1f680; 消息队列系统设计与实践全解析&#x1f50d; 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡&#x1f4a1; 权衡决策框架 1.3 运维复杂度评估&#x1f527; 运维成本降低策略 &#x1f3d7;️ 二、典型架构设计2.1 分布式事务最终一致…...

GraphQL 实战篇:Apollo Client 配置与缓存

GraphQL 实战篇&#xff1a;Apollo Client 配置与缓存 上一篇&#xff1a;GraphQL 入门篇&#xff1a;基础查询语法 依旧和上一篇的笔记一样&#xff0c;主实操&#xff0c;没啥过多的细节讲解&#xff0c;代码具体在&#xff1a; https://github.com/GoldenaArcher/graphql…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...

跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践

在电商行业蓬勃发展的当下&#xff0c;多平台运营已成为众多商家的必然选择。然而&#xff0c;不同电商平台在商品数据接口方面存在差异&#xff0c;导致商家在跨平台运营时面临诸多挑战&#xff0c;如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...

前端工具库lodash与lodash-es区别详解

lodash 和 lodash-es 是同一工具库的两个不同版本&#xff0c;核心功能完全一致&#xff0c;主要区别在于模块化格式和优化方式&#xff0c;适合不同的开发环境。以下是详细对比&#xff1a; 1. 模块化格式 lodash 使用 CommonJS 模块格式&#xff08;require/module.exports&a…...