(六)实战项目 - Go 语言笔记服务|青训营笔记

336 阅读4分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记

一、课前准备

1 安装

1.1 Linux

(1)Go环境

Linux下go环境的安装

(2)Docker

ubuntu 安装 docker 详细步骤

(3)Git

安装git(廖雪峰)

1.2 Windows

(1)postman

postman

(2)GoLand远程开发配置

GoLand远程开发配置

(3)Git

安装git(廖雪峰)

2 了解

2.1 Kitex

Kitex文档(仅支持Linux)

关于 Kitex

Kitex 是一个 RPC 框架,既然是 RPC,底层就需要两大功能:

  1. Serialization 序列化
  2. Transport 传输

Kitex 框架及命令行工具,默认支持 thrift 和 proto3 两种 IDL,对应的 Kitex 支持 thrift 和 protobuf 两种序列化协议。传输上 Kitex 使用扩展的 thrift 作为底层的传输协议(注:thrift 既是 IDL 格式,同时也是序列化协议和传输协议)。IDL 全称是 Interface Definition Language,接口定义语言。

为什么要使用 IDL

如果我们要进行 RPC,就需要知道对方的接口是什么,需要传什么参数,同时也需要知道返回值是什么样的,就好比两个人之间交流,需要保证在说的是同一个语言、同一件事。这时候,就需要通过 IDL 来约定双方的协议,就像在写代码的时候需要调用某个函数,我们需要知道函数签名一样。

Thrift IDL 语法可参考:Thrift interface description language

proto3 语法可参考:Language Guide(proto3)

2.2 Gorm

Gorm指南 一个注意点:

  • 检索单个对象没有找到记录时的错误 error.png

2.3 ETCD

Etcd是CoreOS基于Raft协议开发的分布式key-value存储,可用于服务发现、共享配置以及一致性保障(如数据库选主、分布式锁等)。 Etcd

2.4 Opentracing

二、项目介绍

此部分来源于[青训营学习资料]

1 项目简介

EasyNote 提供了一套比较完整的笔记后端API服务.

2 项目模块介绍

(juejin.cn/post/709597…)

image.png

  • 传输协议的不同仅为了作为example覆盖技术栈,在实际的开发中可以进行统一

3 项目服务调用关系

image.png

  • 由user服务与note服务与数据库进行交互,将ip、端口号、服务名等注册到ETCD
  • 由api通过服务发现去发现ETCD中的服务,然后用对应的协议向user与note服务发起请求
  • 实际开发过程中也推荐类似服务调用关系

4 项目模块功能介绍

image.png

5 项目技术栈

image.png

6 项目相关的使用框架资料

跳转链接

image.png

三、项目代码介绍

1 项目代码目录结构介绍

跳转链接 image.png

1.1 idl

image.png 这部分没什么好说的,就是按照各自的代码规范编写idl

1.1.1 note.thrift

//命名空间
namespace go notedemo

//每个响应的通用参数
struct BaseResp {
    1:i64 status_code
    2:string status_message
    3:i64 service_time
}

//笔记结构体
struct Note {
    1:i64 note_id
    2:i64 user_id
    3:string user_name
    4:string user_avatar
    5:string title
    6:string content
    7:i64 create_time
}

//创建笔记的请求参数
struct CreateNoteRequest {
    1:string title
    2:string content
    3:i64 user_id
}

//返回值
struct CreateNoteResponse {
    1:BaseResp base_resp
}

struct DeleteNoteRequest {
    1:i64 note_id
    2:i64 user_id
}

struct DeleteNoteResponse {
    1:BaseResp base_resp
}

//optional 选填
struct UpdateNoteRequest {
    1:i64 note_id
    2:i64 user_id
    3:optional string title
    4:optional string content
}

struct UpdateNoteResponse {
    1:BaseResp base_resp
}

//批量获取
struct MGetNoteRequest {
    1:list<i64> note_ids
}

struct MGetNoteResponse {
    1:list<Note> notes
    2:BaseResp base_resp
}

//后两个属性用于分页
struct QueryNoteRequest {
    1:i64 user_id
    2:optional string search_key
    3:i64 offset
    4:i64 limit
}

struct QueryNoteResponse {
    1:list<Note> notes
    2:i64 total
    3:BaseResp base_resp
}

//笔记服务对外的五个能力
service NoteService {
    CreateNoteResponse CreateNote(1:CreateNoteRequest req)
    MGetNoteResponse MGetNote(1:MGetNoteRequest req)
    DeleteNoteResponse DeleteNote(1:DeleteNoteRequest req)
    QueryNoteResponse QueryNote(1:QueryNoteRequest req)
    UpdateNoteResponse UpdateNote(1:UpdateNoteRequest req)
}

1.1.2 user.proto

syntax = "proto3";
package user;
option go_package = "userdemo";

message BaseResp {
    int64 status_code = 1;
    string status_message = 2;
    int64 service_time = 3;
}

message User {
    int64 user_id = 1;
    string user_name = 2;
    string avatar = 3;
}

message CreateUserRequest {
    string user_name = 1;
    string password = 2;
}

message CreateUserResponse {
    BaseResp base_resp = 1;
}

//repeated 等于 thrift的list
message MGetUserRequest {
    repeated int64 user_ids = 1;
}

message MGetUserResponse {
    repeated User users = 1;
    BaseResp base_resp = 2;
}

message CheckUserRequest{
    string user_name = 1;
    string password = 2;
}

message CheckUserResponse{
    int64 user_id = 1;
    BaseResp base_resp = 2;
}

service UserService {
    rpc CreateUser (CreateUserRequest) returns (CreateUserResponse) {}
    rpc MGetUser (MGetUserRequest) returns (MGetUserResponse) {}
    rpc CheckUser (CheckUserRequest) returns (CheckUserResponse) {}
}

1.2 kitex_gen

使用指南

image.png image.png

  • 为了避免重复生成,示例代码中的kitex_gen目录已经集成了cmd中三个服务的kitex_gen

image.png

1.3 pkg

1.3.1 errno(错误码)

没啥好说的.jpg

1.3.2 middleware(Kitex的中间件)

文档

middleware简介.png

1.3.3 tracer(Jarger初始化)

初始化jaeger参数,保证opentracing拓展能够把数据传入jaeger 文档

1.3.4 bound(Kitex Transport Pipeline-Bound 扩展)

文档

1.3.5 constans(常量)

package constants

const (
   //表名
   NoteTableName = "note"
   UserTableName = "user"
   //jwt插件变量
   SecretKey   = "secret key"
   IdentityKey = "id"
   //gorm查询时用到的参数
   Total  = "total"
   Notes  = "notes"
   NoteID = "note_id"
   //三个服务名
   ApiServiceName  = "demoapi"
   NoteServiceName = "demonote"
   UserServiceName = "demouser"
   //mysql默认dsn
   /*
   Data Source Name (DSN)的PDO命名惯例为:PDO驱动程序的名称,
   后面为一个冒号,再后面是可选的驱动程序连接数据库变量信息,
   如主机名、端口和数据库名。
   */
   MySQLDefaultDSN = "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local"
   //etcd地址
   EtcdAddress = "127.0.0.1:2379"
   //cpu限制
   CPURateLimit float64 = 80.0
   //默认分页
   DefaultLimit = 10
)

三、写demo

大作业按照了这个框架设计,所以贴上大作业的地址 github.com/buptZch/dy