第四课 Go容器化微服务系统实战-链路追踪观望台
tags:
- GO
- 慕课网
categories:
- 链路追踪jaeger
- 数据库外键
- 数据库事务
第一节 链路追踪简介
1.1 链路追踪jaeger基本介绍
- 微服务链路追(jaeger)踪作用: 它是用来监视和诊断基于微服务的分布式系统
- 用于服务依赖性分析,辅助性能优化
- 微服务链路追踪(jaeger)主要特性
- 高扩展性
- 原生支持OpenTracing
- 可观察性
1.2 jaeger-术语Span
- Span是Jaeger 中的逻辑工作单元
- Span具有操作名称,操作的开始时间和持续时间
- 它的跨度可以嵌套并排序以建立因果关系模型
- 微服务链路追踪(jaeger)-术语Span包含的对象
- Operation name:操作名称(也可以称作Span name )
- Start timestamp:起始时间
- Finish timestamp:结束时间
- Span tag :一组键值对构成的Span标签集合
- Span log :一组Span的日志集合
- SpanContext: span 上下文对象
- References ( Span间关系)︰相关的零个或者多个Span
1.3 jaeger的调用过程
- 一次调用链分析
1.4 jaeger的组件
-
Jaeger Client的调用原理。
的五个重要组件
- Jaeger-client(客户端库, 不同语言有不同库)
- Agent(客户端代理,是一个监听的守护程序。把client的数据传给Collector)
- Collector (数据收集处理)
- Data Store (数据存储)
- UI(数据查询与前端界面展示)
1.5 jaeger安装和常用端口
- 推荐博客:https://www.cnblogs.com/jiujuan/p/13235748.html
# 获取镜像all-in-one:docker地址:https://hub.docker.com/r/jaegertracing/all-in-one
docker pull jaegertracing/all-in-one:latest
# 启动容器
docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
-p 5775:5775/udp \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 14268:14268 \
-p 9411:9411 \
jaegertracing/all-in-one:latest
第二节 商品模块开发
2.1 商品模块目录建立
- 用上节课方法自动生成我们的目录文件。
sudo docker pull micro/micro
sudo docker run --rm -v $(pwd):$(pwd) -w $(pwd) micro/micro new product
- 新建domain文件夹,并在domain中创建model、repository、service三个文件夹。
- 删除go.mod,重新通过下面命令生成。
go mod init git.imooc.com/qnhyn/product
go mod tidy
- 新建common文件夹。
2.2 商品模块代码proto开发
- 编写proto。把product.proto文件放到product文件夹下。
- 编译生成go文件。
# 生成之后看下product.pb.micro.go 用到的版本 主要要是v2(v3会在编译时报错)
protoc *.proto --gofast_out=. --micro_out=.
syntax = "proto3";
package go.micro.service.product;
service Product {
rpc AddProduct(ProductInfo) returns (ResponseProduct){}
rpc FindProductByID(RequestID) returns (ProductInfo){}
rpc UpdateProduct(ProductInfo) returns (Response) {}
rpc DeleteProductByID(RequestID) returns (Response) {}
rpc FindAllProduct(RequestAll) returns (AllProduct){}
}
message ProductInfo {
int64 id = 1;
string product_name = 2;
string product_sku = 3;
double product_price = 4;
string product_description = 5;
int64 product_category_id = 6;
// repeated 结构体对象
repeated ProductImage product_image = 7;
// 商品的尺寸
repeated ProductSize product_size = 8;
// 搜索引擎优化的展示的信息
ProductSeo product_seo = 9;
}
message ProductImage {
int64 id = 1;
string image_name = 2;
// 保证插入数据的幂等性
string image_code = 3;
string image_url = 4;
}
message ProductSize{
int64 id = 1;
string size_name = 2;
string size_code = 3;
}
message ProductSeo {
int64 id = 1;
string seo_title = 2;
string seo_keywords = 3;
string seo_description =4;
string seo_code = 6;
}
message ResponseProduct {
int64 product_id = 1;
}
message RequestID {
int64 product_id = 1;
}
message Response {
string msg = 1;
}
message RequestAll{
}
message AllProduct{
repeated ProductInfo product_info =1;
}
2.3 商品模块domain的model开发
- product.go
package model
type Product struct{
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
ProductName string `json:"product_name"`
ProductSku string `gorm:"unique_index:not_null" json:"product_sku"`
ProductPrice float64 `json:"product_price"`
ProductDescription string `json:"product_description"`
ProductImage []ProductImage `gorm:"ForeignKey:ImageProductID" json:"product_image"`
ProductSize []ProductSize `gorm:"ForeignKey:SizeProductID" json:"product_size"`
ProductSeo ProductSeo `gorm:"ForeignKey:SeoProductID" json:"product_seo"`
}
- product_image.go 字段ImageCode可以保证数据的幂等性。
package model
type ProductImage struct {
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
ImageName string `json:"image_name"`
ImageCode string `gorm:"unique_index;not_null" json:"image_code"`
ImageUrl string `json:"image_url"`
ImageProductID int64 `json:"image_product_id"`
}
- product_size.go
package model
type ProductSize struct {
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
SizeName string `json:"size_name"`
SizeCode string `gorm:"unique_index;not_null" json:"size_code"`
SizeProductID int64 `json:"size_product_id"`
}
- product_seo.go
package model
type ProductSeo struct {
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
SeoTitle string `json:"seo_title"`
SeoKeywords string `json:"seo_keywords"`
SeoDescription string `json:"seo_description"`
SeoCode string `json:"seo_code"`
SeoProductID int64 `json:"seo_product_id"`
}
2.4 商品模块domain的repository开发
- product_repository.go 和前面不同。
- 这里初始化表,一下可以初始化四张表
- 删除时有开启事务回滚。
package repository
import (
"git.imooc.com/qnhyn/product/domain/model"
"github.com/jinzhu/gorm"
)
type IProductRepository interface{
InitTable() error
FindProductByID(int64) (*model.Product, error)
CreateProduct(*model.Product) (int64, error)
DeleteProductByID(int64) error
UpdateProduct(*model.Product) error
FindAll()([]model.Product,error)
}
// NewProductRepository 创建productRepository
func NewProductRepository(db *gorm.DB) IProductRepository {
return &ProductRepository{
mysqlDb:db}
}
type ProductRepository struct {
mysqlDb *gorm.DB
}
// InitTable 初始化表 同时初始化四张表
func (u *ProductRepository)InitTable() error {
return u.mysqlDb.CreateTable(&model.Product{
},&model.ProductSeo{
},&model.ProductImage{
},&model.ProductSize{
}).Error
}
// FindProductByID 根据ID查找Product信息
func (u *ProductRepository)FindProductByID(productID int64) (product *model.Product,err error) {