From ff374c37464a549f35b79d097a8751f4c3d20292 Mon Sep 17 00:00:00 2001 From: gameloader Date: Tue, 19 Nov 2024 23:49:38 +0800 Subject: [PATCH] backend update --- content/posts/golang_backend.md | 119 ++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/content/posts/golang_backend.md b/content/posts/golang_backend.md index 2b5e4d4..2c7962b 100644 --- a/content/posts/golang_backend.md +++ b/content/posts/golang_backend.md @@ -86,3 +86,122 @@ func main(){ 使用gorm时使用它的sql表达式更新功能时发现会出现莫名其妙的bug, 更新表达式是减但是得到的sql语句是直接置零. 让我非常不解, 在研究文档的过程中, 我偶然发现当前的gorm文档是gorm 2.0,而我之前导入的包是gorm 1.0的包. 因此之前的1.0中可能并没有实现这个功能, 非常的尴尬. 将导入的包切换为gorm 2.0后一切功能正常. 这提醒我们在使用三方库时, 可能三方库会因为更新等原因有一些api上的重大变化, 要注意使用的包的版本. + +### 结构体成员可访问的作用域问题 + +上例子 + +```go + usrid, _ := c.Get("user") + var reqData struct { + prompt string `json:"prompt"` + } + if err := c.BindJSON(&reqData); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request data"}) + return + } +``` + +其中c是gin框架中的 `*gin.Context`, 这段代码乍一看好像没什么问题, 但实际运行就会发现reqData中的prompt无法通过bindjson绑定到post请求中的prompt字段的数据上. 在go语言中: + +> 当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 private )。 + +因此在绑定json数据到reqData结构体时, 实际上实在其他包中访问了reqData结构体中的prompt属性, 但由于这个属性不是导出属性, 因此在其他包(这里是gin框架中json处理相关的包)中无法访问到这个属性, 自然也就不能修改它的值. 因此后面访问这个结构体reqData中的prompt属性时就会永远为空字符串. + +正确代码应该如下 + +```go + usrid, _ := c.Get("user") + var reqData struct { + prompt string `json:"prompt"` + } + if err := c.BindJSON(&reqData); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request data"}) + return + } +``` + +### gorm中由于数据类型不同对空值的不同处理 + +在gorm中,如果某个字段是string类型,则当该字段不存在时默认授予这个字段空字符串,但sql中标准的空值类型应该为NULL。如果postgresql中某个字段不是字符串相关的类型,则想将这个字段默认设为NULL,应该在gorm的数据映射模型中将这个字段的类型映射为可能类型的指针。 + +## 架构设计思路 + +### 如何实现对有很长处理过程的图片生成任务的查询 + +对于midjourney, 自身提供了对任务进度的查询功能, 则直接将其自带的接口封装,由前端进行轮询, 当任务完成时将生成图片上传到自己的图床, 并更新数据库存入完成的图片url数据. + +对于dalle, 由于自身并未提供对任务进度的查询功能, 则为了接口的统一性, 自行封装一层, 只要绘图未完成进度就始终为0. 将未完成的任务id和用户id保存在redis中, 当完成绘图时同样上传到自己图床, 并更新redis和数据库中的数据, 前端调用接口查询到成功生成的图片数据后, 删除redis中的已完成数删除redis中的已完成数据. + +由此, 数据库中保存用户id, 调用的生图模型, 生图的提示词和成功生成的图片url即可. 生成的图片保存时间有限, 因此要将图片上传到图床以长时间保存. 而对于用户,先返回生成图片的url即可, 后续再次访问时从数据库中取数据则是图床的url. + +## 使用airbyte进行mysql和mongodb的数据库同步 + +### 设置mariadb的log-bin和server-id + +mariadb的同步设置在/etc/my.cnf或者/etc/my.cnf.d目录下, manjaro中是在/etc/my.cnf.d目录下, 打开这个目录下的server.conf文件, 在\[mariadb\]下面添加如下内容, 根据airbyte的mysql同步源的配置要求 + +```conf +[mariadb] +log-bin = mysql-bin +server-id = 223322 +max-binlog-size=400M +expire_logs_days = 7 +binlog_format=row +``` + +根据airbyte的官方教程, 使用官方一键安装脚本启动一个docker, 安装所有容器并启动即可, 官方的脚本是下载一个docker-compose.yml文件, 再使用docker命令启动这些docker. + +我在manjaro上启动时, worker会出现一个bug, 导致启动失败, 在ubuntu上就没有出现错误, 正常启动. + +启动后, 进入网页, 输入默认用户名密码 airbyte/password, 设置同步的mysql源和mysql目标, 创建一个connection进行同步即可. + +## 使用seatunnel进行mysql的同步 + +airbyte在同步decimal类型的数据时会默认转换为float, 从而丢失精度, 我的数据仅仅只有六位小数在同步的过程中最后两位的精度还会丢失. 因此尝试使用seatunnel进行mysql的同步. + +## kvm 启动问题 + +> WARNING /kvm/ubuntu-20.04.6-desktop-amd64.iso may not be accessible by the hypervisor. You will need to grant the 'libvirt-qemu' user search permissions for the following directories: [''] +> WARNING /kvm/ubuntu_disk.qcow2 may not be accessible by the hypervisor. You will need to grant the 'libvirt-qemu' user search permissions for the following directories: [''] +> WARNING /kvm/ubuntu-20.04.6-desktop-amd64.iso may not be accessible by the hypervisor. You will need to grant the 'libvirt-qemu' user search permissions for the following directories: [''] + +这些警告信息表明 libvirt-qemu 用户没有足够的权限来访问 警告对应的 目录及其子目录中的文件。 + +如果希望限制权限只给 libvirt-qemu 用户,而不是所有用户,可以这样做: + +```sh +sudo setfacl -m u:libvirt-qemu:x {目录名} +``` + +这个命令使用 ACL(访问控制列表)来专门给 libvirt-qemu 用户 对应 目录的执行权限。 + +确保 ISO 文件和 qcow2 文件有正确的读取权限: + +```sh +sudo chmod 644 /kvm/ubuntu-20.04.6-desktop-amd64.iso +sudo chmod 644 /kvm/ubuntu_disk.qcow2 +``` + +也给这些文件添加 libvirt-qemu 用户的读取权限: + +```sh +sudo setfacl -m u:libvirt-qemu:r /kvm/ubuntu-20.04.6-desktop-amd64.iso +sudo setfacl -m u:libvirt-qemu:r /kvm/ubuntu_disk.qcow2 +``` + +完成这些步骤后,再次尝试运行 virt-install 命令。 + +## casdoor接口开发问题 + +![11192ti5ijgPw2AI](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/11192ti5ijgPw2AI.png) + +此处的id后面括号的意思是这个id是由 owner/name这样的组合而成的,即owner加一个斜线再加一个name就构成了id。这个看源码可以发现,如果用错了id会类似下面的错误 + +> GetOwnerAndNameFromId() error, wrong token count for ID: + +同时对于接口`/api/get-user`restful api文档中声明的返回的数据 + +![1119dWSo2uhopXNf](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/1119dWSo2uhopXNf.png) + +并不是只返回这个数据对象,而是这个数据对象是在data中的数据,除此之外还默认会返回status, msg,sub这三个字段,就像post请求中一般的返回数据一样,除了这三个字段外还有data字段,这个字段会放Get请求中我们请求的目标数据。