微服务入门(go)
和单体服务对比:里面的服务仅仅用于某个特定的业务
一、领域驱动设计(DDD)
基本概念
领域和子域
领域:有范围的界限(边界)
子域:划分的小范围
核心域:业务系统的核心价值
通用子域:为所有子域提供通用子域
支撑子域:专注于业务的某一重要子域
举例:
- 电商——>领域
- 商品子域,订单子域,销售子域……——子域
- 销售子域——核心子域
- 邮件子域,短信子域——通用子域
界限上下文
目的:如何控制边界
领域模型
领域:对需要解决问题的抽象
模型:针对问题提出的解决方案
领域服务四层架构主要分为接口层,应用层,领域层,基础层四个部分
完整的DDD微服务相关的流程如下:
ps:要领域驱动,而不是数据驱动设计,也不是界面驱动设计
(确实一般的都是数据驱动设计)
ps:要边界清晰,而不是很小的单体,也不能过度拆分
二、Docker
为什么需要docker:
- 部署更新低效
- 环境一致性难保证
- 构建容易分发难(环境上的复刻)
应用场景
- 构建运行环境
- 微服务
- CICD(持续集成和部署)
重要概念
- client——可以运行docker的命令
- 服务器进程——管理镜像和容器
- 镜像仓库——存储镜像的仓库
docker架构的示意图
ps : docker daemon:docker的守护进程
Docker常用命令
◆Docker 仓库操作:pull,push
◆Docker 镜像管理:images,rmi,build
◆Docker生命周期管理:run,start,stop,rm
查看docker版本
sudo docker version
拉取镜像
sudo docker pull nginx
出现了报错
报错解决方案
按顺序执行下面的代码(主要功能是修改了docker的配置文件)
vim /etc/docker/daemon.json
进入了这个(可能是空白的)文件后输入:
{"registry-mirrors": ["https://2a6bf1988cb6428c877f723ec7530dbc.mirror.swr.myhuaweicloud.com","https://docker.m.daocloud.io","https://hub-mirror.c.163.com","https://mirror.baidubce.com","https://your_preferred_mirror","https://dockerhub.icu","https://docker.registry.cyou","https://docker-cf.registry.cyou","https://dockercf.jsdelivr.fyi","https://docker.jsdelivr.fyi","https://dockertest.jsdelivr.fyi","https://mirror.aliyuncs.com","https://dockerproxy.com","https://mirror.baidubce.com","https://docker.m.daocloud.io","https://docker.nju.edu.cn","https://docker.mirrors.sjtug.sjtu.edu.cn","https://docker.mirrors.ustc.edu.cn","https://mirror.iscas.ac.cn","https://docker.rainbond.cc"]
}
重新加载配置文件和重启docker服务
systemctl daemon-reload
systemctl restart docker
再次拉取
成功!
查看现有的镜像
docker images
查看在运行的镜像
三、go-mirco
rpc
远程过程调用,包含了传输协议和编码协议,不同计算机之间的程序可以进行调用
grpc
基于http2.0,是Google开发的,默认支持protocol buffers数据序列化协议
protocol buffers
是一种轻便高效的结构化数据的协议,通常用于存储数据和需要远程数据通信的程序上
优势:跨语言,更小,更快,更简单
常用概念
- message:描述了一个请求或者响应的消息格式
- 字段标识:消息的定义中,每个字段都有唯一的数值标签
(不可以重复)
- 常用数据类型:double,float,int32/int64,bool,string,bytes
- Service服务的定义:在service里面可以定义一个rpc服务接口
Protocol Buffers 数据类型与 Go 数据类型的对应
Protocol Buffers 类型 | Go 类型 | 描述 |
---|---|---|
double | float64 | 双精度浮点数,64 位 |
float | float32 | 单精度浮点数,32 位 |
int32 | int32 | 有符号整型,32 位 |
int64 | int64 | 有符号整型,64 位 |
uint32 | uint32 | 无符号整型,32 位 |
uint64 | uint64 | 无符号整型,64 位 |
sint32 | int32 | 有符号整型,32 位,采用 ZigZag 编码,适合存储负数 |
sint64 | int64 | 有符号整型,64 位,采用 ZigZag 编码,适合存储负数 |
fixed32 | uint32 | 无符号整型,32 位,占用固定 4 字节存储 |
fixed64 | uint64 | 无符号整型,64 位,占用固定 8 字节存储 |
sfixed32 | int32 | 有符号整型,32 位,占用固定 4 字节存储 |
sfixed64 | int64 | 有符号整型,64 位,占用固定 8 字节存储 |
bool | bool | 布尔值,表示 true 或 false |
string | string | UTF-8 编码的字符串 |
bytes | []byte | 二进制数据 |
枚举类型 (enum) | 自定义生成的枚举类型 | Protobuf 枚举会在 Go 中生成一个对应的枚举类型 |
消息类型 (message) | 自定义生成的结构体类型 | Protobuf 消息会在 Go 中生成一个对应的结构体类型 |
编写protocol buffer的格式规范
protocal buffer示例
syntax = "proto3";package go.mirco.service.product;
option go_package = "./;product";
service Product {rpc AddProduct (ProductInfo) returns (ResponseProduct){}
}message ProductInfo {int64 id = 1 ;string product_name = 2 ;// 尽量用1-15,超过15会用俩字节去装
}message ResponseProduct{int64 product_id = 1 ;}
生成对应的.go和.micro.go文件
打开终端,输入以下命令:
protoc --go_out=./ --micro_out=./ ./proto/account/account.proto
上面的命令执行后,我们会发现同级目录多了两个go文件,这就是自动生成好的编译之后的文件。
命令解释
- –go_out 指定当前的目录./
- –micro_out 指定当前micro目录./
- ./proto/account/account.proto 指定要编译的.proto文件地址
生成的文件的效果如下
go-mirco
mirco
是用于构建和管理分布式程序的生态系统
组成部分:
-
runtime(运行时)——管理认证,配置,网络等
是一个工具集,名称是“micro”
安装版本复杂, 所以一般是用docker安装和配置
组成:
- api:api网关
- broker:异步消息的代理
- network:网络工具集(不常用)
- new:服务模版生成器(重要)
- proxy:建立在go-mirco的透明代理
- registry:服务资源管理器(通过注册表的方式)
- store:简单状态存储
- web:仪表盘,可以浏览自己的服务
-
framework(程序开发框架)——便于编写微服务
-
clients(多语言的客户端)
go-mirco
是对分布式系统的高度抽象,提供分布式系统开发的核心库,属于可插拔按需使用的架构
组件
- 注册registry:提供服务发现机制
- 选择器selector:实现负载均衡
- 传输transport:服务与服务的通信组件
- broker:异步消息发布订阅的接口
- codec:消息的编码和解码
- server:服务端
- client:客户端
go-mirco结构图
消息通信架构图
省略了codec