第4节 流程构建和分析

❤️💕💕Go语言高级篇章,在此之前建议您先了解基础和进阶篇。Myblog:http://nsddd.topopen in new window

Go语言基础篇open in new window

Go语言100篇进阶open in new window


[TOC]

创建一个go-mod和仓库

PS C:\Users\smile\Desktop\log-monitoring> go mod init github.com/3293172751/log-monitoring/tree/master
go: creating new go.mod: module github.com/3293172751/log-monitoring/tree/master

程序框架

package main

type LogProcess struct {
	rc chan string   //多个goroutine之间的数据同步和通信(channels)
	wc chan string   //写入模块同步数据
	//系统分为三个模块
	// + 实时读取  -- 文件路径
	// + 解析
	// + 写入  -- 写入的时候需要ip
	path       string //读取文件的路径
	influxDBsn string //写入的信息
}

func (l *LogProcess) ReadFromFile() {
	//读取模块
}

func (l *LogProcess) Process() {
	//解析模块
}

func (l *LogProcess) WriteToInfluxDB() {
	//写入模块
}

func main() {
	logprocess := &LogProcess{
		rc: make(chan string),
		wc: make(chan string),
		path:       "log/access.log",
		influxDBsn: "username&password..",
	}

	//使用goroutinue提高程序的性能
    go (*lp)logprocess.ReadFromFile()    //调用读取模块
	go logprocess.Process()         //调用解析模块
	go logprocess.WriteToInfluxDB() //调用写入模块

    //程序执行完后就自动退出了
	time.Sleep(1 * time.Second)
}

使用*LogProcess引用类型原因:

func (l *LogProcess) Process() {
	//解析模块
}
logprocess := &LogProcess{}
  • 不用拷贝,对于性能有很大的提升
  • 用引用就可以用l参数直接修改结构体的数值

程序测试

func (l *LogProcess) ReadFromFile() {
	//读取模块
	line := "message"
	l.rc <- line //数据的流向
}

func (l *LogProcess) Process() {
	//解析模块
	data := <-l.rc
	l.wc <- strings.ToUpper(data)
	//处理数据--将data中的所有字符修改为其大写格式。对于非ASCII字符,它的大写格式需要查表转换
}

func (l *LogProcess) WriteToInfluxDB() {
	//写入模块
	fmt.Println(<-l.wc)
}

编译结果

[Running] go run "c:\Users\smile\Desktop\log-monitoring\log_process.go"
MESSAGE

程序优化

我们只能往WriteToInfluxDB()中写入数据,如果有更多的数据(队列或者标准输出中),此时需要用到接口模式,把写入和读出模块抽象出来

用来约束实现类的功能。

package main

import (
	"fmt"
	"strings"
	"time"
)

type Reader interface {
	Read(rc chan string)
}

type Writer interface {
	Writer(wc chan string)
}

type LogProcess struct {
	rc chan string //多个goroutine之间的数据同步和通信(channels)
	wc chan string //写入模块同步数据
	//系统分为三个模块
	// + 实时读取  -- 文件路径
	// + 解析
	// + 写入  -- 写入的时候需要
	read  Reader //接口定义
	write Writer
}

type ReadFromFile struct {
	path string //读取文件的路径
}

type WriteToInfluxDB struct {
	influxDBsn string //写入的信息
}

func (r *ReadFromFile) Read(rc chan string) {
	//读取模块
	line := "messAge"
	rc <- line //数据的流向
}

func (l *LogProcess) Process() {
	//解析模块
	data := <-l.rc
	l.wc <- strings.ToUpper(data)
	//处理数据--将data中的所有字符修改为其大写格式。对于非ASCII字符,它的大写格式需要查表转换
}

func (w *WriteToInfluxDB) Writer(wc chan string) {
	//写入模块
	fmt.Println(<-wc)
}

func main() {
	r := &ReadFromFile{
		path: "log/access.log",
	}
	w := &WriteToInfluxDB{
		influxDBsn: "username&password..",
	}
	logprocess := &LogProcess{
		rc:    make(chan string),
		wc:    make(chan string),
		read:  r,
		write: w,
	}

	//使用goroutinue提高程序的性能
	go logprocess.read.Read(logprocess.rc)    //调用读取模块
	go logprocess.Process()                   //调用解析模块
	go logprocess.write.Writer(logprocess.wc) //调用写入模块

	//程序执行完后就自动退出了,需要等待
	time.Sleep(1 * time.Second)
}

程序编译

[Running] go run "c:\Users\smile\Desktop\log-monitoring\log_process.go"
MESSAGE

为什么我们定义了两个接口就提升了它的可扩展性呢?

看起来程序虽然更加复杂了,但是我们如果后期添加新的读取写入模块,只需要对接口修改

END 链接