项目源码地址 github.com/tsingson/go…html
文字有点长, 尽可能写得简单明了前端
文章归纳内容都写上了, 因为文档进一步细化并补充更多需求后, 须要拆分为设计文档/接口文档/测试文档/评审文档.....等等, 这里再也不持续更新.java
后续补充变动, 请访问 项目源码地址mysql
因为带一个朋友学习 golang 开发, 因此, 这个项目正在重写, 基本上, 本文提到的内容会所有变动, 主要变动以下:react
因为是 step by step 给朋友演示开发过程, 因此, 大约分红三个步骤开发:linux
架构变动以下:android
具体变动, 见 项目源码地址git
go-ums 开发目标是一个开源项目, 核心由 golang 开发, 提供用户管理(user-management-subsystem) / AAA 鉴权/受权/计账 / 多业务会话共享与管理等, 以支持分布式部署及云部署为主要目标github
这是一个从零开始的小项目, 持续渐进golang
在 reading-go 夜读 相关 issue 讨论中, 有个 gin 的练手项目, 有点意思.
这是一个相似的项目, 不一样的地方是, 这个项目是以文档开始的.
更多项目关联文档, 请访问 github.com/tsingson/go… , 在 readme 中列示并持续添加中
先有文档, 再写代码. 在文档简单说明一些个人设计套路
注: 这里的设计, Design, 不限于架构设计, 程序设计, 也包含我的在摄影/印刷/书籍/海报中找出问题/解决问题的一些"套路".
先文档, 后实施, 也是曾经做 SA/SE 的习惯了吧. 当年曾戏称本身是 Simple Editor , 哈, 怀念那8年, 大胡子, yaho BB, black more, 北京香山, 上海文广,三角洲岛.......
稍后在持续更新中一一道来, 看看横向之间的有趣关联.
不谈业务需求, 与业务场景中的人儿们,再好的技术也难以落地变现.
这就是原始需求的收集/整理/清理/梳理, 是开发贯串始终的目标与仲裁准则:
从一个简单而典型的业务场景开始, 来
这个开源项目是从 goim 在开源社区交流讨论后, 在 reading-go 讨论中偶然开始的
从业多年, 我的几乎不在网络上谈论我的在 iT 技术职业经历, 尤为是项目细节, 这里, 算是换个方式来公开谈谈吧
因此, 这里也从 goim 做为起点
不少朋友, 在阅读 goim 源码时, 都会感受到, 就算是 im 业务完整实施, 须要与用户管理结合:
因此, 咱们能够从上面描述到的, (不能省掉的) 基本业务功能开始
来, 来, 来 ...GO!
( 省略)
稍后补充示意图
(简化)
(简化)
(省略)
(省略)
注, 如下按开发进度做了分组.
分组的意思, 就是排优先级, 排优先级便是排重要/紧急程度(按 SWOT Analysis 方式), 以决定前后处理顺序.
用户相关操做
用户相关操做
参照 1.2.1 小节, 很容易做一个简单设计
用户对象名称 account
- 用户ID, 与 goim 配合, 就用 int64 吧, 一个全局惟一的正整数
- email , (简化), 都是字符串, email 格式也不验证, 其中 email 字符串长不得少于5个字符( >=5 ) ,
- password, (简化) 都是字符串, 密码不得少于6个字符( >= 6), 字符为 a..zA..Z0..9$%-
- access tokdn 通告令牌, 也用字符串代替吧, 字符串长度 >=32 字符
- 用户角色, 分别为 非会员, 会员
- 用户状态, 分别为注册未激活, 已激活, 禁用, 已删除
- 用户建立时间, 简单点, 用 int64 或 UTC timestamp
- 用户信息变动时间, 简单点, 用 int64 或 UTC timestamp
操做结果(状态)定义
- transaction ID 事务惟一标识
- 状态码, 整数, 操做成功返回 200 / 操做失败返回 500 / 请求接受并在处理中返回202
- 操做结果文本信息, 少于255字符, 操做成功, 文本信息, 要求标记业务操做名称, 如 register ), 操做失败, 返回失败缘由( 文本信息 )
注: transaction ID 事务惟一标识, 支持异步操做, 以支持分布式或集群, 以及操做失败时, 进行操做重试( 这样可让服务端处理上次操做失败的数据, 例如进行清理, 或继续使用, 以及在日志中进行检查/审计)
原型实现的约束与限制:
- 为了快速实现原型, 用户密码直接存储, 不加密
- 用户ID , 直接用用户建立的 utc 时间截( 纳秒 )
简化操做结果(状态定义), 这里先按 golang 实现习惯方式, 操做结果修改成 go 的 error 返回( 即 error = nil 或 != nil ) 注: 这个地方, 只是针对 go 的简化
(简化)
- 用户注册 register ------> 调用 exists 检查是否重复注册, 若是不是, 建立用户ID 并保存用户信信息, 返回用户数据( 不返回密码), 返回操做结果状态码
- 检查用户是否重复存在 exists, 返回操做结果
- 用户登陆 login ------> 以 email + pwd 登陆, 登陆成功, 建立并返回 access token, 返回操做结果状态码
- 用户登出 logout -----> 清除 access token , 返回操做结果状态码
- 用户认证 auth -------> 输入用户ID 或 token , 调用 verify 检查 会话中的token 是否合法, 若是 token 合法则返回成功, 返回操做结果状态码
- 用户令牌验证 verify --------> 检查 token 是否存在, 而且是否相等, 返回操做结果状态码
业务流程描述: 客户端 ----------> 服务端, 进行用户注册, 发送注册数据, 由服务器端返回注册成功(获取用户ID ) 或失败信息
大白话:
接口就是两个网元之间, 进行交互/通信的网络协议/控制通讯命令(信令)/以约定格式传输相关数据(数据封装)的简称
例如 web 浏览器与 web 服务器这两个网元之间, 通常采用 HTTP 协议, 信令是 GET / POST / PUT / PATCH / DELETE ...., 数据封装一般是以 MIME 来指定, 好比下面用到的 "application/json; charset=utf-8"
设计实现如下接口
接口设计, 事实是描述一下业务数据的输入/输出, 以及须要对接的两端业务主体的业务过程(业务上如何进行交流与处理) 这里简化掉了, 并细化得很"编程化"了
关于 RESTful 接口, 相关推荐规范, 请自行查询
这里先简要说明一下:
RESTful 一般是 HTTP + json 实现的接口, 其中
相似 /api/v1/account 这样的 URI 就是一个接口, 其中 /api/v1 前缀只是辅助管理
在下面咱们示例实现的用户注册接口, 能够定义为 /api/v1/register 或者 /xxx/yyyy 这样你喜欢的方式
HTTP 的 method 就是操做方式, 例如:
- GET:读取(Read)
- POST:新建(Create)
- PUT:更新(Update)
- PATCH:更新(Update),一般是部分更新
- DELETE:删除(Delete)
数据编码(序列化/反序列化) 是 "application/json; charset=utf-8” 标的 JSON 格式
少许操做关联数据, 能够在 HTTP header 中传递, 好比 transactionID/ token / cookie , 这些关联数据, 通常用来协助状态跟踪
对照 2.3.1 , 用户注册的接口, 能够设计以下
--------->input请求
请求资源
POST 请求如下网址 http://localhost:3001/api/v1/register
request header
Context-Type: "application/json; charset=utf-8"
TransactionID: "201001419845668864"
复制代码
request body
{
"email": "test@email.com",
"password": "201001419845668864"
}
复制代码
--------->output返回
response header
Context-Type: "application/json; charset=utf-8"
TransactionID: "201001419845668864"
复制代码
操做成功, 返回 http 状态码 200, 返回数据以下
response body
{
"email": "test@email.com",
"password": "201001419845668864"
}
复制代码
操做失败, 返回状态码 500, 返回数据以下
**
{
"transactionID":"201001419845668864"
"code": 500,
"msg": "用户Email已经被其余用户使用, 请选择其余email从新注册"
}
复制代码
其余部分, 稍后补充.........
先简化为如下架构做为验证原型开发
client ( 多个) <----> gateWay( HA热备, 支持路由/分流等) <-----> AAA (本地缓存, 多个部署)<-------> UMS ( 双机热备)
其中:
稍后补充.........
因为需求缘由, 咱们须要考虑达成如下目标:
因此, 先拍脑壳随意定义一下要实现目标, 以下所示. 接下来, 再评估哪些真正须要, 优先级, 以及具体实现方案
稍后补充说明部分
用户模型与操做的 golang 实现
(说明省略)
(说明省略)
(说明省略)
测试用例以下
见 /pkg/service 下测试代码
见 /pkg/web 下各测试代码
见 /cmd/cli 下代码
稍后补充..........
稍后补充.............
省略 ...
_
_
网名 tsingson (三明智, 江湖人称3爷)
原 ustarcom IPTV/OTT 事业部播控产品线技术架构湿/解决方案工程湿角色(8年), 自由职业者,
喜欢音乐(口琴,是第三/四/五届广东国际口琴嘉年华的主策划人之一), 摄影与越野,
喜欢 golang 语言 (商用项目中主要用 postgres + golang )
_
题图: 2018/12/24 香港黑白摄影展前, 与深圳影友在香港街头
_
tsingson 写于中国深圳
小罗号口琴音乐中心, 2019/05/11