golang 流量统计系统视频总结(一)

版权声明: https://blog.csdn.net/qq_29785317/article/details/86112759

总体流程

在这里插入图片描述

由于是模拟项目,所以先用golang生成一些假的用户访问日志数据,以便后面作分析。

模拟用户访问日志部分

代码实现(log.go):

package main

import (
	"flag"
	"fmt"
	"math/rand"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"
)

var uaList = []string{
	"Mpzilla/5.0",
	"IE/10",
	"Chorme/34.2",
	"Safari/2.12",
}

// 资源结构体,存放模拟url的生成配置
type resource struct {
	url string   // 用户访问页面的url
	target string    // 用户访问页面的具体资源对象,id表示
	start int    // 资源数的起始量
	end int    // 资源数的结束量
}

/*
* 获取初始化的url生成配置,以便生成用户访问日志数据
*/
func ruleResource() []resource {
	var res []resource
	r1 := resource{
		url:    "http://localhost:8888",
		target: "",
		start: 0,
		end: 0,
	}
	r2 := resource{
		url:    "http://localhost:8888/list/{$id}.html",
		target: "{$id}",
		start:  1,
		end:    21,
	}
	r3 := resource{
		url:    "http://localhost:8888/movie/{$id}.html",
		target: "{$id}",
		start:  1,
		end:    12924,
	}
	res = append(res,r1,r2,r3)
	return res
}

/*
* 根据url生成配置,构造用户访问的url,返回生成好的切片
*/
func buildUrl(res []resource) []string {
	var list []string
	for _,resItem := range res {
		if len(resItem.target) == 0 {    // 如果访问的是首页
			list = append(list,resItem.url)
		} else {
			for i:=resItem.start;i<=resItem.end;i++{
				urlStr := strings.Replace(resItem.url,resItem.target,strconv.Itoa(i),-1)
				list = append(list,urlStr)
			}
		}
	}
	return list
}

/*
* 生成具体的日志数据
*/
func makeLog( current, refer, ua string) string {
	// 生成url query部分字符串
	u := url.Values{}
	u.Set( "time","1")
	u.Set( "url",current)
	u.Set( "refer",refer)
	u.Set( "ua",ua)
	paramsStr := u.Encode()

	logTemplate := "127.0.0.1 - - [08/Mar/2018:00:48:34 +0800] \"OPTIONS /dig?{$paramsStr} HTTP/1.1\" 200 43 \"-\" \"{$ua}\" \"-\" "
	// 替换掉模板的 $paramsStr 和 ua 部分
	log := strings.Replace(logTemplate,"{paramStr}",paramsStr,-1)
	log = strings.Replace(log,"{ua}",ua,-1)
	return log
}

/*
* 获取随机数
*/
func randInt(min, max int) int {
	r := rand.New( rand.NewSource( time.Now().UnixNano()))
	if min > max {
		return max
	}
	return r.Intn(max-min)+min
}


func main() {
	// 通过命令行收集参数 total-要创建的日志行数,filepath-要保存的日志文件路径
	total := flag.Int("total",100,"rows be created")
	filePath := flag.String("filePath","~/go/dig.log","file path")
	flag.Parse()

	// 需要构造出真实的网站url集合
	res := 	ruleResource()
	list := buildUrl( res )

	// 随机取currentUrl,referUrl,ua,循环拼接 total 行日志
	logStr := ""
	for i := 0; i < *total; i++{
		currentUrl := list[ randInt(0, len(list)-1) ]
		referUrl := list[ randInt(0, len(list)-1) ]
		ua := uaList[ randInt(0, len(uaList)-1) ]
		logStr = logStr + makeLog( currentUrl, referUrl, ua ) + "\n"
		//ioutil.WriteFile(*filePath,[]byte(logStr),0644)
	}
	// 写日志
	fd,_ := os.OpenFile(*filePath,os.O_RDWR|os.O_APPEND,0644)
	fd.Write([]byte( logStr ))
	fd.Close()

	//按照要求,生成total行日志内容,源自上面的这个集合
	fmt.Println("done.\n")
}

基本流程:

1.从命令行收集用户想要生成的日志行数(total),一行相当于一个请求,以及要保存日志文件的路径(filePath)。
2.通过函数ruleResource()获取生成url的配置,这个配置用切片存储,切片里面是程序最开始时定义好的 用于放具体url生成配置的 结构体。
3.根据配置生成具体url,放进一个叫list的切片里,返回这个切片。
4.基于list切片和程序开始时定义的uaList切片,随机取值分别赋值给currentUrl,referUrl,ua,然后循环拼接 total 行日志。
5.将拼接好的日志字符串以追加写得方式写进指定的日志文件。

涉及的点

  • 字符串替换
    usage:strings.Replace(resItem.url,resItem.target,strconv.Itoa(i),-1)
    要引入strings包
  • 整形转化为字符串
j := strconv.Itoa(i)
  • 随机数
    先说结论:
    1.伪随机数并不是假随机数,这里的“伪”是有规律的意思,就是计算机产生的伪随机数既是随机的又是有规律的。
    2.随机种子来自系统时钟,确切地说,是来自计算机主板上的定时/计数器在内存中的记数值。
    3.随机数是由随机种子根据一定的计算方法计算出来的数值。所以,只要计算方法一定,随机种子一定,那么产生的随机数就不会变。也就是说,伪随机数也是某种对应映射的产物,只不过这个自变量是系统的时间而已
    4.如果你每次调用时都提随机函数时供相同的种子值,那么,你将会得到相同的随机数序列
    可参考这个链接 => 传送门
    c语言的随机数请看这个链接 => 传送门

golang中生成随机数的方式(引入 math/rand 包):

import math/rand
// Rand对象
r := rand.New( rand.NewSource( time.Now().UnixNano()))
r.Intn(100)   // 返回[0,100)的随机整数
/**------或者-------**/
// 全局函数
rand.Seed(time.Now().Unix())
rand.Intn(100)
  • 收集命令行参数
total := flag.Int("total",100,"rows be created")
filePath := flag.String("filePath","~/go/dig.log","file path")
flag.Parse()
// 后面要获取total和filePath的值时,需要解引用,即 *total 和 *filePath才能拿到值
  • 文件读写
logStr := "log str here"
fd,_ := os.OpenFile(*filePath,os.O_RDWR|os.O_APPEND,0644)
fd.Write([]byte( logStr ))
fd.Close()
  • query字符串生成
u := url.Values{}
u.Set( "time","1")
u.Set( "url",current)
u.Set( "refer",refer)
u.Set( "ua",ua)
paramsStr := u.Encode()

猜你喜欢

转载自blog.csdn.net/qq_29785317/article/details/86112759
今日推荐