你的单体服务架构是否遇到一些问题, 不能满足业务需求? 那么微服务会是好的解决方案.
Cinch是一套轻量级微服务脚手架, 基于Kratos, 节省基础服务搭建时间, 快速投入业务开发.
我们参考了Go的许多微服务架构, 结合实际需求, 最终选择简洁的Kratos作为基石(B站架构), 从架构的设计思路以及代码的书写格式和我们非常匹配.
cinch意为简单的事, 小菜. 希望把复杂的事变得简单, 提升开发效率.
若你想深入学习微服务每个组件, 建议直接看Kratos官方文档. 本项目整合一些业务常用组件, 开箱即用, 并不会把每个组件都介绍那么详细.
Go- 最新分支Go版本已更新至v1.22Proto- proto协议同时开启gRPC & HTTP支持, 只需开发一次接口, 不用写两套Jwt- 认证, 用户登入登出一键搞定Action- 权限, 基于行为的权限校验Redis- 缓存, 内置防缓存穿透/缓存击穿/缓存雪崩示例Gorm- 数据库ORM管理框架, 可自行扩展多种数据库类型, 目前使用MySQL, 其他自行扩展Gorm Gen- Gorm实体自动生成, 无需再写数据库实体映射Tenant- 基于Gorm的schema层面的多租户(一个租户一个数据库schema)SqlMigrate- 数据库迁移工具, 每次更新平滑迁移Asynq- 分布式定时任务(异步任务)Log- 日志, 在Kratos基础上增加一层包装, 无需每个方法传入Embed- go 1.16文件嵌入属性, 轻松将静态文件打包到编译后的二进制应用中Opentelemetry- 链路追踪, 跨服务调用可快速追踪完整链路Idempotent- 接口幂等性(解决重复点击或提交)Pprof- 内置性能分析开关, 对并发/性能测试友好Wire- 依赖注入, 编译时完成依赖注入Swagger- Api文档一键生成, 无需在代码里写注解I18n- 国际化支持, 简单切换多语言Minio- 对象存储
建议直接使用最后一个版本
git clone -b v1.1.1 https://github.com/go-cinch/authVue3入口 super/cinch123(超级管理员) guest/cinch123(访客) write/cinch123(读写权限) readonly/cinch123(只读权限) nodelete/cinch123(不能删除权限)
React入口 同上
Argocd入口 guest/guest123
Asynqmon入口 查看定时任务运行情况
Minio入口 对象存储 cinch/cinch123456
Grafana入口 监控面板 cinch/cinch123456
Auth是基于layout生成的一个通用权限验证微服务, 节省鉴权服务搭建时间, 快速投入业务开发.
Golang主流的权限管理基本上用的是Casbin, 曾经的项目中也用到过, 如gin-web, 设计模式很好, 但实际使用过程中遇到一些问题
以RBAC为例以及结合常见的web管理系统, 你大概需要这么设计
- api表 - 接口表, 存储所有的api, 如
GET /user,POST /login(method+path) - casbin表 - casbin关系表, 存储对象和api之间的关系, 如用户admin有
GET /user的访问权限, 数据记录可能是v0=admin, v1=GET, v2=/user - menu表 - 菜单表(可能包含关联表, 这里不细说), 存储所有的菜单
- 和api关联, 如
用户管理菜单下有GET /user,POST /user,PATCH /user,DELETE /user - 和role关联, 如角色是超级管理员可以展示所有页面, 访客只能查看首页
 
 - 和api关联, 如
 - 若还需要增加单个按钮, 那需要btn表, 和menu类似
 - 若还需要单个用户权限不一样, 那user表与menu/btn要建立关联
 - 若还需要用户组权限, 那用户组与上面的表要建立关联
 
那么问题来了
- 新增或删除接口, 你怎么维护上述各个表之间的关联关系?
 - app没有菜单, 怎么来设计
 
或许这并不是casbin的问题, 这是业务层的问题. 你有更好的方案欢迎讨论
name- 名称, 可以重复, 定义行为名, 描述当前action用途code- 唯一标识, 主要用于其他表关联word- 英文关键字, 唯一, 方便前端展示resource- 资源列表(\n隔开), 可以是http接口地址, 也可以是grpc接口地址menu- 菜单列表(\n隔开), 和前端路由有关btn- 按钮列表(\n隔开), 和前端有关
Tip: menu/btn是给前端看的, 前端来决定是否需要显示, 后端不单独存储menu表/btn表
action- 行为code列表(逗号隔开), 包含用户/角色/用户组具有的所有行为
优点
- 权限变更高效
- 程序员只需关心action表, 修改action表对应内容即可
 - 使用者勾选或添加action, action通过name显示, 简单易懂
 
 - action不区分pc/app
 - 减少关联表
 
缺点
- 增加冗余性(这个和减少关联表是相悖的)
 - 菜单等更新由前端管理, 若需更新, 必须重新发布前端代码
 
http接口推荐配合nginx auth_request使用
- 所有请求全部通过auth_request转发至
/permission - 校验当前用户是否有resource的权限, 有直接返回(resource=
method+path) - 校验当前用户所在角色是否有参数resource的权限, 有直接返回
 - 校验当前用户所在用户组是否有参数resource的权限
 
grpc无法使用nginx auth_request
- 所有请求直接到各自微服务
 - 通过权限中间件转发到
/auth.v1.Auth/Permission, auth服务执行后续逻辑 - 校验当前用户是否有resource的权限, 有直接返回(resource=
/game.v1.Game/FindGame) - 校验当前用户所在角色是否有参数resource的权限, 有直接返回
 - 校验当前用户所在用户组是否有参数resource的权限
 
权限源码参见auth.Permission
中间件参加layout.Permission
/auth.v1.Auth/Register- 用户注册/auth.v1.Auth/Pwd- 修改密码/auth.v1.Auth/Status- 获取用户状态, 是否锁定/需要输入验证码等/auth.v1.Auth/Captcha- 获取验证码base64图片, 默认4位数字/auth.v1.Auth/Login- 登入, 获取jwt token/auth.v1.Auth/Logout- 登出/auth.v1.Auth/Refresh- 刷新jwt token/auth.v1.Auth/Idempotent- 获取幂等性token(登陆后)/auth.v1.Auth/Info- 获取用户信息(登陆后)
其他接口是Action/User/Role/UserGroup的CRUD, 完整接口参见auth.proto
微服务设计思想可参考Kratos