go-blog
项目简介
阿里巴巴Java开发手册中的DO、DTO、BO、AO、VO、POJO定义 - 知乎 (zhihu.com)
使用到的库:
golang.org/x/crypto/bcrypt
:由于加密库的是十分敏感的,因此crypto
库的代码需要审核后托管在官方仓库,bcrypt
是一种密码哈希函数结合了盐值(salt)和多轮哈希(rounds of hashing)。
前台:
redis
redis:是一个高性能的key-value数据库,将数据存储在内存中,方便高效读写
Redis默认支持16个数据库
超强、超详细Redis入门教程_这篇文章主要介绍了超强、超详细redis入门教程,本文详细介绍了redis数据库各个方-CSDN博客
支持持久化
RDB<快照持久化: 每隔一段时间写入>
AOF<追加文件持久化:每个写都会追加到AOF文件s>
- Redis的两种持久化RDB和AOF(超详细)_rdb aof-CSDN博客
主从复制:允许将数据从一个 Redis 服务器(称为“主节点”)复制到一个或多个 Redis 服务器(称为“从节点”),可用于数据冗余,故障转移,分散节点提高读性能。
- 高可用和分布式:
后台:
JSON Web Tokens (JWT)鉴权
通过JSON形式作为Web应用中的令牌
- 认证鉴权
- 信息交换
JWT与Session的区别
- 跨域问题:Session使用Cookie,而Cookie无法跨域,JWT没有这个问题。
- 服务器开销:Session需要在服务器存储每个用户的登录信息,而JWT自身携带用户信息,不需要额外的服务器存储空间。
- 分布式系统:JWT更适合分布式系统,因为它是无状态的
https://golang-jwt.github.io/jwt/
Golang 一日一库之jwt-go - 始識 - 博客园 (cnblogs.com)
CASBIN
- 访问控制框架,支持多种访问控制模型。
- 这个项目基于角色的访问控制(RBAC, Role-Based Access Control)是一种广泛使用的访问控制机制,它通过将权限与角色关联,再将角色分配给用户,从而实现对资源的访问控制
其他
前后端分离的核心:后台提供数据,前端负责显示
RESTful 风格
RESTful API 最佳实践 - 阮一峰的网络日志 (ruanyifeng.com)
RESTful 的核心思想就是,客户端发出的数据操作指令都是”动词 + 宾语”的结构。
APIFOX
集成的测试工具:Apifox = Postman + Swagger + Mock + JMeter
前端:
- Swagger:通常用于生成 API 文档,并为前端开发人员提供接口的说明和交互功能。
- Mock:用于模拟后端 API 响应。
后端:
- Postman:验证 API 的正确性、性能和响应数据。
- JMeter:后端的性能和压力测试。
docker compose&k8s
https://docker-practice.github.io/zh-cn/
- docker compose用于本地简单的容器编排
- k8s适用于适合于构建分布式、高可用的生产环境。
nginx&apache
nginx
- nginx适合处理静态内容
- 可作反向代理服务器、负载均衡器
apache
apache适合处理动态内容
Apache 采用多线程模型,每个请求由一个独立的线程处理。
nuxt3
1 | ├── global # 用于存储全局变量或整个应用程序中共享的设置的目录或包 |
2024/8/16
命令行参数解析&配置文件读取
- flag:解析命令行参数
- viper:用于解析配置文件
- viper有优先使用环境变量的配置,主要是方便程序在不同开发环境间迁移
2024/8/18
数据库
设计
https://mermaid.nodejs.cn/syntax/entityRelationshipDiagram.html
user
权限控制: 7 张表(4 模型 + 3 关联)
- UserAuth(用户认证):用户的基本信息。
- Role(角色):定义系统中的各种角色。
- Resource(资源):定义需要权限控制的资源,如API端点。
- Menu(菜单):定义系统的菜单结构,支持多级菜单。
- 用户认证:角色 1:n
- 角色:资源 1:n
- 角色:菜单 1:n
//TODO 关系
1 |
|
Article
1 | erDiagram |
gorm
https://gorm.io/zh_CN/docs/models.html
- ORM(Object-Relational Mapping,对象关系映射)是一种在面向对象编程语言中实现数据持久化的一种技术。它允许开发者以面向对象的方式来操作数据库,而无需编写原始的SQL语句。
gen
(代码生成器):生成与数据库表对应的模型和基本的数据库操作方法。DAO
层的主要职责是抽象和封装对底层数据源(如数据库、文件系统或其他持久化机制)的访问。- 客户端请求 -> Servlet层 -> Service层 -> Dao层 -> 数据库
- 当你使用 GORM 并调用
AutoMigrate
方法时,GORM 会检查数据库中是否存在指定的表,如果不存在,GORM 会根据提供的模型创建相应的表。 - 软删除:实际未删除,只是普通查找不返回该链接,可以通过设置标志位实现
预加载(Eager Loading)和连接(Joining)的区别:
N+1 查询问题:查询一个对象集合后对该集合的每个对象再进行
分别
的查询(1+n)Preload:查询一个对象集合后对该集合的每个对象再进行
一次总体
的查询(1+1)
Preload
适合:
- 数据关系复杂,多个关联关系。
- 需要避免数据冗余问题,返回的数据不希望有重复。
- 查询效率和性能不是最优先考虑的场景。
Joins
适合:
表的关系相对简单,适合通过一次
JOIN
查询获取结果。数据量较大,希望减少查询次数,提高性能。
需要尽量在一次查询中获取所有相关数据的场景。
slog
后端 - 万字解析 Go 官方结构化日志包 slog - 江湖十年 - SegmentFault 思否
Logger
又被称为 前端
,Handler
被称为 后端
,而 Record
用来表示一条日志。
前端 Logger
直接面向用户侧,我们可以对其进行二次封装,来定制自己的用户 API。
后端 Handler
可以统一日志处理接口,我们也可以在自定义的 Handler
中很方便的集成如 zap
、zerolog
等第三方日志库。你可以在 [Go Wiki: Resources for slog
gin
重量级来了!
面向切面编程AOP(Aspect-Oriented Programming)
系统实现“高内聚、低耦合”一直是我们程序开发者的追求。
使用路由组管理路由:方便不同路由的分组和中间件管理。
context
go提供context包用于在不同协程间传递数据。
context in gin
gin
的Context
是处理 HTTP 请求的核心数据结构。它包含了请求和响应的所有信息,以及处理请求的中间件链。
- 当一个 HTTP 请求到达 Gin 服务器时,它首先被分配到一个
Context
对象。 - 随后进入中间件链。每个中间件可以对
Context
进行读取和修改,执行特定的逻辑。(c.next()进入下一中间件
) - 处理函数生成响应,并通过
Context
返回给客户端。 - 在响应返回给客户端之前,中间件链会逆序执行。(
c.next()返回
)
为什么不设置全局变量而是使用上下文(context ctx)传递数据
- 线程安全:全局变量可能需要锁保护。
- 中间件链:Gin 框架使用中间件链来处理请求。通过在上下文中传递数据,可以在链中的任何位置访问或修改这些数据,而不需要在中间件之间显式传递参数。
- 数据隔离:在处理并发请求时,每个请求可能需要不同的数据副本。上下文允许每个请求拥有自己的数据副本,从而实现数据隔离。
- …….
中间件
中间件:中间件和处理函数是按照它们被注册的顺序执行的。
Gin框架默认提供了两个中间件:Logger 和 Recovery。
全局中间件(Global Middleware):
对所有请求都生效。
使用
r.Use()
方法添加到*gin.Engine
实例上。
路由组中间件(Group Middleware):
- 针对特定路由组,只对注册在该路由组下的所有路由生效。
- 使用
group.Use()
方法添加到*gin.RouterGroup
实例上。
自定义中间件(Custom Middleware):
第三方中间件(Third-Party Middleware):
- 可在
github.com/gin-gonic/contrib
寻找对应的库。
- 可在
单个session和多个session的区别:单个session用于
//TODO
自定义组件,主要是增加一些功能和替换一些组件的条件检查、以及使用slog替换日志输出。
基于 cookie 的 session:
- 当用户首次访问应用程序时,服务器会创建一个新的 Session,并生成一个唯一的 Session ID。
- 这个 Session ID 被发送到客户端浏览器,并存储在一个 Cookie 中。Cookie 通常包含 Session ID 和一些属性,如路径、域、过期时间、安全标志等。
用户进行后续请求时,浏览器会自动在请求的 HTTP Header 中携带这个 Cookie,服务器通过解析 Cookie 中的 Session ID 来检索对应的 Session 数据。
CROS
同源策略(Same-Origin Policy)
:禁止来自不同域的JavaScript脚本与另一个域的资源进行交互。同源
:相同的协议(protocol)、域名(host)和端口号(port)。CROS
:- 浏览器同源政策及其规避方法 - 阮一峰的网络日志 (ruanyifeng.com)
- 跨域资源共享 CORS 详解 - 阮一峰的网络日志 (ruanyifeng.com)
recovery
recover
的实现是内置的,不在 Go 的源代码中直接可见,因为它是编译器和运行时的一部分。recover
必须在defer
语句中调用,并且只能恢复当前的 panic。defer
延迟调用语句的用处是在程序执行结束,甚至是崩溃后,仍然会被调用的语句
为什么recover必须在defer语句中调用?
- 从源码解析Go语言中recover为什么一定要放在defer中执行-腾讯云开发者社区-腾讯云 (tencent.com)
- Go语言中的异常处理:理解panic与recover-阿里云开发者社区 (aliyun.com)
- 当
panic
被触发时,程序会开始回溯调用栈(栈展开(Stack Unwinding)),直到遇到一个defer
函数调用中包含recover
。- 我们知道,当一个函数被调用时,若其执行出现错误(如c语言返回-1),我们不可能假设该函数执行成功,而是应该释放资源回溯到能处理该错误的函数。
go
空结构体
- 空结构体不占用空间,可用作占位映射值
- 空结构体可以作为一个接口的唯一实现,任何具有空结构体类型的类型都自动满足了该接口
swagger
util
encrypt
context
- context用于在不同协程中传递数据
context定义
1 | type Context interface { |
context.TODO()和 context.Background()
context.Background()
是一个通用的构建块,用于构建整个Context
树的起点。context.TODO()
是一个临时的占位符,用于标记代码中尚未处理的部分。
传递数据
1 | func f1(ctx context.Context) context.Context { |
取消派生的context(timeout,deadline)
- 可以设置取消条件(如网络请求超时)
- 一旦
Context
被取消或超时,任何监听ctx.Done()
通道的 goroutine 都会收到一个通知。 - 通道关闭时,所有等待接收的协程都会被唤醒。因此可以在函数、协程、主函数打印状态
1 | package main |
参考: