Zipkin : Golang 微服务全链路监控(三)
Zipkin : Golang 微服务全链路监控(三)
Golang 微服务全链路监控实现
- broker-service -> auth-service -> postgres db
- zipkin 监控:需代码入侵
使用 zipkin 库的 serverMiddleware,其通过 Http 跟踪(trace)链路。若要连接数据库,需传 tracer
zipkinhttp "github.com/openzipkin/zipkin-go/middleware/http"
一、auth-service
- 通过 Http 传递 span
main.go
package mainimport ("database/sql""log""net/http""os""time""tracing/auth-service/data"zipkinhttp "github.com/openzipkin/zipkin-go/middleware/http"_ "github.com/jackc/pgconn"_ "github.com/jackc/pgx/v4"_ "github.com/jackc/pgx/v4/stdlib"
)const webPort = "80"const (// Our service name.serviceName = "authentication"// Host + port of our service.hostPort = "localhost:8090"// Endpoint to send Zipkin spans to.zipkinHTTPEndpoint = "http://localhost:9411/api/v2/spans"
)var counts int64type Config struct {DB *sql.DBModels data.Models
}func main() {log.Println("Starting authentication service: ", webPort)//connect to DBconn := connectToDB()if conn == nil {log.Panic("Can't connect to Postgres!")}//setup configapp := Config{DB: conn,Models: data.New(conn),}tracer := GetTracer(serviceName, hostPort, zipkinHTTPEndpoint)// create global zipkin http server middlewareserverMiddleware := zipkinhttp.NewServerMiddleware(tracer, zipkinhttp.TagResponseSize(true),)// create global zipkin traced http clientclient, err := zipkinhttp.NewClient(tracer, zipkinhttp.ClientTrace(true))if err != nil {log.Fatalf("unable to create client: %+v\n", err)}// initialize routerrouter := http.NewServeMux()// if need to trace db, transfer tracerrouter.HandleFunc("/authenticate", app.Authenticate(client, tracer))if err = http.ListenAndServe(hostPort, serverMiddleware(router)); err != nil {log.Panic(err)}
}
- auth 服务
handler.go
package mainimport ("errors""fmt""log""net/http""github.com/openzipkin/zipkin-go"zipkinhttp "github.com/openzipkin/zipkin-go/middleware/http"
)type AuthPayload struct {Email string `json:"email"`Password string `json:"password"`
}func (app *Config) Authenticate(client *zipkinhttp.Client, tracer *zipkin.Tracer) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {log.Printf("auth service called with method: %s\n", r.Method)var requestPayload AuthPayloadvar payload jsonResponsepayload.Error = truepayload.Message = "Authentication failed!"err := app.readJSON(w, r, &requestPayload)if err != nil {app.errorJSON(w, err)return}log.Println("requestPayload:", requestPayload)// retrieve span from context (created by zipkinhttp server middleware)span := zipkin.SpanFromContext(r.Context())defer span.Finish()span.Tag("event", "authenticate")ctx := zipkin.NewContext(r.Context(), span)// transfer tracer to dbuser, err := app.Models.User.GetByEmail(ctx, tracer, requestPayload.Email)if err != nil {app.errorJSON(w, errors.New("invalid credentials"), http.StatusBadGateway)span.Tag("Error: ", err.Error())return}log.Println("user:", user)valid, err := user.PasswordMatches(requestPayload.Password)if err != nil || !valid {app.errorJSON(w, errors.New("invalid credentials"), http.StatusBadGateway)span.Tag("Error: ", err.Error())return}payload = jsonResponse{Error: false,Message: fmt.Sprintf("Logged in user %s", user.Email),Data: user,}log.Println("auth response: ", payload)app.writeJSON(w, http.StatusOK, payload)}
}
二、models.go
func (u *User) GetByEmail(c context.Context, tracer *zipkin.Tracer, email string) (*User, error) {// tracer 通过 context,获取 spanspan, _ := tracer.StartSpanFromContext(c, "GetByEmail")defer span.Finish()span.Tag("query", "select id, email, first_name, last_name, password, user_active, created_at, updated_at from users where email = "+email)ctx, cancel := context.WithTimeout(context.Background(), dbTimeout)defer cancel()query := `select id, email, first_name, last_name, password, user_active, created_at, updated_at from users where email = $1`var user Userrow := db.QueryRowContext(ctx, query, email)err := row.Scan(&user.ID,&user.Email,&user.FirstName,&user.LastName,&user.Password,&user.Active,&user.CreatedAt,&user.UpdatedAt,)if err != nil {log.Println("Error GetByEmail: ", err)span.Tag("Error GetByEmail: ", err.Error())return nil, err}return &user, nil
}
三、说明
完整代码参考:
- Zipkin : Golang 微服务全链路监控(一)
- Zipkin : Golang 微服务全链路监控(二)
相关文章:
Zipkin : Golang 微服务全链路监控(三)
Zipkin : Golang 微服务全链路监控(三) Golang 微服务全链路监控实现 broker-service -> auth-service -> postgres dbzipkin 监控:需代码入侵 使用 zipkin 库的 serverMiddleware,其通过 Http 跟踪(trace&am…...
5.3 BGP路由黑洞
5.2.3实验3:BGP路由黑洞 1. 实验目的 熟悉BGP路由黑洞的应用场景掌握BGP水平分割的配置方法2. 实验拓扑 实验拓扑如图5-3所示: 图5-3:BGP路由黑洞 3. 实验步骤 配置IP地址 R1的配置 <Huawei>syst...
STM32 DFU模式烧录代码
什么是DFU? dfu的本质是isp,usb接口的isp,在系统编程,进入isp的方式我们先了解 如下图 boot0为高电平 boot1为低电平即可进入isp模式。 熟悉的场景 在我们使用flymcu软件下载代码时,本质也是isp 串口接口的isp。 傻瓜使用方式…...
松下PLC通过fpwin上传写入MRTC模块方法
目录 PLC程序上传方法 加密模块使用 PLC程序上传方法 手动将PLC模式设置为prog模式查看PLC是否设置为禁止上传查询指示灯是否变蓝,变蓝则需要将PLC禁止上传功能取消。 3.当上述动作操作完成后,将PLC程序导入到PLC中。为了配合加密程序使用,…...
就业大山之下的网络安全:安逸的安服仔
从去年开始,各个互联网大厂就接二连三的放出了裁员消息,整个互联网行业好像都处于寒冬状态。微博、小米、滴滴、知乎、拼多多等在内的一大批互联网知名企业,也相继传出“人员优化”的消息。 除了国内市场的萧条,国外市场也是不容…...
JavaWeb3-线程的3种创建方式7种写法
目录 1.方式一:继承Thread(2种写法) 写法①(常规): a.使用jconsole观察线程 b.启动线程——start方法 PS:(常见面试题)start 方法与 run 方法的区别: 写…...
驱动调试手段
文章目录 前言一、通过sysfs调试LCD查看电源:查看 pwm 信息查看管脚信息总结前言 本文记录在驱动中常用的调试手段 提示:以下是本篇文章正文内容,下面案例可供参考 一、通过sysfs 系统起来之后可以读取 sysfs 一些信息,来协助调试 示例: 调试LCD 输入如下命令 cat /…...
[RK3568 Android12] 音频及路由
1:概述(耳机 ,hdmiin ,板载喇叭) 在开发板上面,系统注册了三个音频输出通道,如下: [ 2.280612] ALSA device list: [ 2.280622] #0: rockchip,rk809-codec [ 2.280630] #1: ROCKCHIP,SPDIF [ 2.280638] #2: rockchip,hdmi console:/proc/asound # cat pcm …...
C++——C++11 第一篇
目录 统一的列表初始化 {}初始化 decltype 编辑 nullptr STL中一些变化 右值引用和移动语义 左值引用和右值引用 总结 左值引用优缺点 右值引用(将亡值) 拷贝赋值和移动赋值 万能引用|完美转发 移动构造和移动赋值注意…...
Spring Data JPA 中 CrudRepository 和 JpaRepository 的区别
1 问题描述Spring Data JPA 中,CrudRepository 和 JpaRepository 有何区别?当我在网上找例子的时候,发现它们可以互相替换使用。它们有什么不同呢?为什么你习惯用其中的一个而不是另一个呢?2 CrudRepository 和 JpaRep…...
推荐几款好用的数据库管理工具
本文主要介绍几款常用的数据库管理软件(客户端),包括开源/免费的、商用收费的,其中有一些是专用于 MySQL 数据库的,例如 MySQL Workbench、phpMyAdmin,有一些是支持多种 SQL、NoSQL 数据库的,例…...
DPDK — 性能优化手段
目录 文章目录 目录硬件布局层面的优化操作系统层面的优化Linux 操作系统版本应用程序层面的优化Cache 优化内存对齐内存预取SIMD 报文批处理DDIO使用高级 CPU 指令集硬件布局层面的优化 DPDK 在硬件布局层面的优化,主要体现在以下几个方面: CPU 频率的高低:CPU 频率越高,…...
Fedora Linux未来五年规划
Fedora 委员会一直致力于起草战略计划,以帮助 Fedora Linux 更好地发展。近日 Fedora 委员会公布了一份 “《未来五年的 Fedora Linux 》” 战略计划草案,这份草案里面包含了他们的雄心壮志:每周将 Fedora 的活跃贡献者人数增加一倍。 Fedora…...
【C++之容器篇】map和set常见函数接口的使用与剖析
目录前言一、set1. 简介2. 成员类型3. 构造函数(1) set()(2)set(InputIterator first,InputIterator last)(3)使用4. 拷贝构造函数和赋值运算符重载5. empty()6. size()7. insert()(1)pair<iterator,bool> insert(const K& key)(2)iterator insert(iterator pos,cons…...
虚拟DOM是什么
参考文章做的总结,如有不足之处请指正! 在讲虚拟dom之前,先讲讲,为什么前端操作dom会导致页面性能降低? 先说几个概念 有助于后面的理解 什么是 JavaScript 引擎? JavaScript引擎是一个专门处理JavaScript脚…...
进程通信方式
无名管道( pipe ): 管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。高级管道(popen): 将另一个程序当做一个新的进程在当前程序进…...
强化学习基础知识
强化学习是一种机器学习方法,通过agent与environment的互动,学习适当的action policy以取得更大的奖励reward。本篇博客介绍强化学习的基础知识,与两类强化学习模型。 目录强化学习的基础设定policy based 强化学习的目标3个注意事项实际训练…...
LeetCode230218_148、654. 最大二叉树
给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点,其值为 nums 中的最大值。 递归地在最大值 左边 的 子数组前缀上 构建左子树。 递归地在最大值 右边 的 子数组后缀上 构建右子树。 返回 nums 构建的 最大二叉树…...
WordPress 是什么?.com 和 .org 的 WordPress 有什么差异?
本篇文章会介绍这次WordPress 5.8核心版本所带来的其中一项新功能:内存块小工具(Widget)此次更新把小工具编辑设定的页面也改成用「内存块编辑」的概念,就跟内置的「古腾堡」编辑器一样,把所有元件都内存块化ÿ…...
java8新特性【2023】
Lambda表达式 新的一套语法规则 是一个匿名函数 Testpublic void test1(){Runnable r1 new Runnable(){Overridepublic void run() {System.out.println("线程A");}};r1.run();System.out.println("");Runnable r2 () -> System.out.println("…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
