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

143 阅读8分钟

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

1. 课程背景与目标

背景

通过项目实战帮助大家把前面学到的知识运用起来

目标

  • 将前面所学的知识应用到项目中
  • 熟悉项目的代码,可以将项目正常运行
  • 熟悉Kitex/Gorm框架的使用

2. Kitex基础教程

2.1 关于Kitex

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

  1. Serialization序列化
  2. Transport传输

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

RPC(Remote Procedure Call)

RPC(Remote Procedure Call)远程过程调用协议,一种通过网络从远程计算机上请求服务,而不需要了解底层网络技术的协议。RPC它假定某些协议的存在,例如TPC/UDP等,为通信程序之间携带信息数据。在OSI网络七层模型中,RPC跨越了传输层和应用层,RPC使得开发,包括网络分布式多程序在内的应用程序更加容易。

image.png RPC的三个过程:

  1. 通讯协议
  2. 寻址
  3. 数据序列化

为什么要使用RPC:

  1. 服务化/微服务、
  2. 分布式系统架构
  3. 服务可重用
  4. 系统间交互调用

RPC的流程:

  1. 客户端处理过程中调用client sub,就像调用本地方法一样,传入参数
  2. client sub将参数编组为消息,然后通过系统调用向服务端发送消息
  3. 客户端本地的操作系统将消息从客户端发送到服务端
  4. 服务端将接收到的数据包传递给server sub
  5. server sub将接收到的数据解组为参数
  6. server sub在调用服务端的过程,过程执行的结果以反方向的相同步骤相应给客户端

zhuanlan.zhihu.com/p/187560185

2.2 为什么要使用IDL

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

Thrift IDL语法参考:thrift.apache.org/docs/idl

proto3语法参考:developers.google.com/protocol-bu…

3. 环境配置

3.1 SSH简介及两种远程登录的方法

TCP/IP体系结构

TCP/IP协议与OSI模型的对应关系(五层分法)

image.png

  1. 应用层:为用户的应用程序提供接口,使用户可以访问网络。

    • HTTP:超文本传输协议(浏览网页服务)
    • TFTP:文件传输协议(较快,但是不可靠)
    • FTP:文件传输协议(提供文件上传,文件下载服务,较慢但是可靠)
    • NFS:网络文件系统(Unix和Linux系统之间共享文件)
    • SMTP:简单邮件传输协议(邮件的发送和转发)
    • POP3:接收邮件(由服务器下载到本地)
    • Talnet:远程登录功能(配置交换机、路由器)
    • SNMP:简单网络管理协议(通过网管软件来管理网络)
    • DNS:域名系统,将域名解析为IP地址(将百度的域名转换为服务器的IP地址)

image.png

  1. 传输层:提供端到端的通信(两台计算机上的软件间的连接),对信息流具有调节作用。

    TCP传输控制协议:面向连接(打电话)可靠服务,在通信之前要先建立连接,需要同时在线。

    UDP用户数据报协议:非面向连接(发快递)不可靠,不稳定,但速度更快。

image.png

TCP数据包格式:

  • 源端口(Source port) 目的端口(Desination Port)

  • 序列号(Sequence number)【数据包的序号】

  • 确认号(Acknowledgement number)(序列号+1)用于指示下一个数据包序号

  • Header length:报头的长度,以32字节为单位的报头长度

  • Reserved:保留域,设置为0.

  • Code Bits:编码位,用于控制段的传输(如会话的建立和终止)

    • 包括:URG/ACK/PSH/RST/SYN/FIN 6个位
    • SYN(synchronous):请求建立TCP连接
    • FIN:断开TCP连接
    • RST:重置TCP连接
    • ACK:确认、反馈连接情况
    • PSH:将数据立刻送到应用层进行处理的命令
    • URG:判断紧急指针是否有效的命令
  • Windows:窗口大小,接收方能够继续接收的字节数【控制发送的速度】

  • Checksum:校验和,包括TCP报头和数据在内的校验和【判断数据传输是否出错】

  • Urgent Pointer:紧急指针,当前序列号到紧急位置的偏移量

  • Options:选项,厂商根据需要自定义的内容

  • Data:数据,上层协议数据

image.png

TCP端口号:

  • HTTP:80
  • 端口范围是:0-6535

image.png

UDP数据结构

image.png

  1. Internet层:IP包的封装和路径的选择

    • 网络层的协议:

      • IP数据包的封装,定义IP地址
      • ICMP错误诊断(用ping测试网络连通性)
      • ARP将IP地址解析为MAC地址
      • RARP将MAC地址转换为IP地址

image.png

  1. 数据链路层

    MAC地址(网卡编号):48位的二进制数。表示位12位的16进制数。分为两部分:前24位为厂商编号,后24位为网卡的编号(由专门的机构分配)。

  2. 物理层

image.png

总结:

image.png

www.cnblogs.com/xiaomulei/p…

Secure Shell(SSH)是由IETF(The Internet Engineering Task Force)制定的建立在应用层基础上的安全网络协议。它是专为远程登录会话(甚至可以用Windows远程登录Linux服务器进行文件互传)和其他网络服务提供安全性的协议,可以有效弥补网络中的漏洞。通过SSH,可以把所有传输的数据进行加密,也能够防止DNS欺骗和IP欺骗。还有一个额外的好处就是传输的数据是经过压缩的,所以可以加快传输的速度。目前已经成为Linux系统的标准配置。

SSH只是一种协议,存在多种实现,既有商业实现,也有开源实现。本文主要介绍OpenSSH免费开源实现在Ubuntu中的应用,如果要在Windows中使用SSH,需要使用另一个软件PuTTY。

SSH的安全机制

SSH之所以能够保证安全,原因在于它采用了非对称加密技术(RSA)加密了所有传输的数据。

传统的网络服务程序,如FTP、Pop和Telnet其本质上都是不安全的;因为它们在网络上用明文传送数据、用户帐号和用户口令,很容易受到中间人(man-in-the-middle)攻击方式的攻击。就是存在另一个人或者一台机器冒充真正的服务器接收用户传给服务器的数据,然后再冒充用户把数据传给真正的服务器。

第一种级别(基于口令的安全验证):只要你知道自己帐号和口令,就可以登录到远程主机。所有传输的数据都会被加密,但是不能保证你正在连接的服务器就是你想连接的服务器。可能会有别的服务器在冒充真正的服务器,也就是受到“中间人攻击”这种方式的攻击。

第二种级别(基于密钥的安全验证):你必须为自己创建一对密钥,并把公钥放在需要访问的服务器上。如果你要连接到SSH服务器上,客户端软件就会向服务器发出请求,请求用你的密钥进行安全验证。服务器收到请求之后,先在该服务器上你的主目录下寻找你的公钥,然后把它和你发送过来的公钥进行比较。如果两个密钥一致,服务器就用公钥加密“质询”(challenge)并把它发送给客户端软件。客户端软件收到“质询”之后就可以用你的私钥在本地解密再把它发送给服务器完成登录。与第一种级别相比,第二种级别不仅加密所有传输的数据,也不需要在网络上传送口令,因此安全性更高,可以有效防止中间人攻击

export GOPATH=~/go
export PATH=$GOPATH/bin:$PATH

export GOROOT=/usr/local/go
export PATH=$PATH:/usr/local/go/bin

4. gorm的一些坑

查询

GORM提供了FirstTakeLast方法,以便从数据库中检索单个对象。当查询数据库时它添加了LIMIT 1条件,且没有找到记录时,它会返回ErrRecordNotFound错误。

更新多列(Updates)

Update方法支持structmap[string]interface{}参数。当使用struct更新时,默认情况下,GORM只会更新非零值的字段

注意:当通过struct更新时,GORM只会更新非零字段。如果您想确保指定字段被更新,你应该使用Select更新选定字段,或使用map来完成更新操作。

opentracing做链路追踪的支持