第2节 Go并发编程–日志分析系统介绍
❤️💕💕Go语言高级篇章,在此之前建议您先了解基础和进阶篇。Myblog:http://nsddd.top
Go语言基础篇
Go语言100篇进阶
[TOC]
到这里默认你满足了高级篇的学习条件,如果你还没有满足,可以移步到基础篇
如果你一定要学习,又没有安装Go语言环境,可以来这里
参考链接
项目会完整发布到GitHub仓库,有需要的可以在GitHub上面⭐收藏,fock进行贡献
Golang是一门简单高效的编程语言,我在编写学习的过程中也被其特性所吸引,日志监控系统是生产环境中必备的功能系统,它的作用可以说仅次于核心系统 而Golang的协程实现可以很好的帮我们完成这一核心功能,通过模拟读取nginx输出的日志文件,使用log_proccess.go进行实时读取解析写入到influxdb存储, 再由grafana进行实时展现。mock_data.go是我用于模拟日志输出的一个应用程序。
下面是我们的开发流程图
graph LR
日志文件-->log_process-->influxdb-->grafana
Golang的并发实现可以通过goroutine执行,而多个goroutine间的数据同步与通信则是channel,且多个channel可以选择数据的读取与写入。 这里需要认真理解下并发与并行。并发:指同一时刻,系统通过调度,来回切换交替的运行多个任务,“看起来”是同时进行;并行:指同一时刻, 两个任务“真正的”同时进行;
日志分析系统实战
1、系统架构设计
2、读取模块的实现
打开文件
从文件末尾开始逐行读取
写入Read Channel
3、解析模块的实现
从Read Channel中读取每行日志数据
正则提取所需的监控数据(path、status、method等)
写入Write Channel
4、写入模块的实现
初始化influxdb client
从Write Channel中读取监控数据
构造数据并写入influxdb
5、绘制监控图
- 用grafana
6、监控模块的实现
总处理日志行数
系统吞出量
read channel长度
write channel长度
运行总时间
常见的并发模型
- 进程&线程(Apache) —C10k
- 异步非阻塞(Nginx,libevent,NodeJS) —复杂度高
- 协程(Golang,Erlang,Lua) —比线程更轻量、更高效
Golang并发实现
- 程序并发执行(goroutine)
- 多个goroutine之间的数据同步和通信(channels)
- 多个channel选择数据读取或者写入(select)
1. goroutine
foo() //执行函数foo,程序等待函数foo返回
go foo() //执行函数foo @2
bar() //不用等待foo返回(协程)并发执行--不会阻塞
此时引入了一个问题,在@2中程序是怎么在多个goroutine之间通信的呢?
2. channels
c := make(chan string) //创建一个channel
go func(){
time.Sleep(1*time.Second)
c <- "message from closure" //发送数据到channel中
}()
msg := <-c //阻塞直到接收到数据
3. Select
select从多个channel中读取或者写入数据
select {
case v := <- c1: //if c1 has date
println("channel 1 sends",v)
case v:= <- c2:
println("channel 2 sends",v)
default:
println("neither channel was ready")
}
Influxdb简介
Influxdb是一个开源的时序性的数据库,使用Go语言编写,被广泛应用于存储系统的监控数据,IoT行业的实时数据等场景。有以下特性:
部署简单,无外部依赖
内置http支持,使用http读写
类sql的灵活查询(max,min,sum等)