最近开始接触golang,写了一个简单的用户管理系统练手:

  1. webserver 基于gin开发
  2. tcpserver 基于grpc
  3. redis / db

支持登入、登出;上传头像、修改昵称;尽量编写了足够的单元测试,并且代码都通过golint和go vet的检查。

项目地址在这:Git地址

 

代码结构说明如下:

 

主要功能点

  • 认证

用户登录时,会生成唯一的sessionid作为token,作为key缓存到redis中。其对应的value是全部的用户信息。这样做除了加快查询外,后续的其他接口的操作都需要用户传递用户名过来(假设用户名是全局唯一的),鉴权的时候不仅校验token,同时也比对用户名,防止token冲突的情况发生。用户登录的时候密码都以md5加密传输过来,然后在db中存储的用户密码是采用“密码加盐”的方式。

当然,这样没有办法避免中间人攻击。更可靠的是采用https传输。同时在登录的时候,前后端通过协商的方式生成秘钥对,进行加解密。

  • 日志

日志采用beego/logs,开始的时候考虑用open tracing与grpc结合起来做调用链追踪。后来为了简化起见,只是在请求一到达webserver的时候就生成唯一的请求ID,同时约定日志的第一个字段就是该ID。

然后通过context的metadata传递到grpc server。后者取出这个ID,以同样的方式记录日志。做到单个请求可追溯,同时又不破坏正常请求的传输。

  • MySQL

mysql采用gorm,由于考虑到数据量大的情况,可能需要做分表。因此在gorm db操作的时候要注意:

在查询的时候也可以指定tab名字:

配置文件采用yaml的方式,redis则使用go-redis

 

  • grpc连接池

grpc虽然支持http2.0多路复用,但是并发高的时候,还是需要连接池来做连接复用。

之前打算用sync.Pool来做连接池,后来有看到说sync.Pool主要是作为对象池,用来做连接池不太合适。于是边用chan 封装了一个简单的连接池。