首页 > 其他分享 >基于Golang协程实现流量统计系统项目开发

基于Golang协程实现流量统计系统项目开发

时间:2023-11-11 12:23:48浏览次数:38  
标签:5.0 协程 like url Mozilla 流量 Golang 日志 OS

基于Golang协程实现流量统计系统项目开发

上一节课我们已经架设好了一个网站。,但是因为我们的网站没有流量 。也生成不了大量的日志,靠我们自己点击生成那点日志也不够测试的。所以这次我们就用GO语言批量生成我们想要的日志。

好了。我们开始写代码

我用的IDE工具是GOLAND,没有为什么,只因为强大,好用。我承认我是小白。只会用GOLAND。用VIM开发的大神请忽略我。

首先介绍一下,本次生成的日志是根据网站生成的日志格式来模拟生成的。

功能是:

根据自定义的生成自己想要的条数的日志。

可以自定义生成路径。

可以批量随机生成日志。

生成大量真实的user_agent的日志。

有current和refer功能

好了。现在我们开始写代码吧。

首先。我觉得程序应该分三大块功能

第一部分,就是生成url集合,要生成的是首页,列表页,详情页。

第二部分。根据真实的日志模板来大量生成日志

第三部分,把日志写入到log中

先来写第一部分。

我们来分析一下网站的结构,

首页只有一个网页,没有分页。

列表页有分页。来看一下数据库有多少个分类

发现有21个分类。我们就知道。列表页网址要生成21个

再看一下详情页。详情页和列表页相似,我们看一下有多少个电影资源,就会有多少个网页

看了一下数据库,详情页有178个网址。也就是说有178个网页

再分析一下网址的规律

首页:http://www.rizhi.test:8888/

列表页:http://www.rizhi.test:8888/list/1.html

详情页:http://www.rizhi.test:8888/movie/174.html

首页就一个网址,不需要处理

列表页和详情页发现后面有一个id,只要换这个ID就可以改变网页的资源。所以我们可以利用程序来批量替换这个ID

我们先用一个结构体来处理替换ID这个方法

type resource struct {
   url string
target string
start int
end int
}

url 要替换的网址

target 要替换的关键字

start 开始页

end 终止页

有了这个结构体。我们就可以生成指定格式的url了

我们来创建一个函数

 

func ruleResource() []resource {
   var res []resource
r1:=resource{ //首页
url:"http://www.rizhi.test:8888",
target:"",
start:0,
end:0,
}
   r2:=resource{ //列表页
url:"http://www.rizhi.test:8888/list/{$id}.html",
target:"{$id}",
start:1,
end:21,
}
   r3:=resource{//详情页
url:"http://www.rizhi.test:8888/movie/{$id}.html",
target:"{$id}",
start:1,
end:178,
}
   res= append(append(append(res, r1), r2), r3)
   return res
}

该函数的功能是创建 首页,列表页,详情页的结构体对象,并赋值

有了这三个结构体对象,我们就可以生成网址了。

现在开始生成网址,看下面代码

 

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
}

先建一个 string字符串数组,用来存储生成后的url集合

遍历resource对象,首先判断一下首页需不需要target替换,如果 len(resItem.target)==0 那么就直接把resItem.url追加到list中

否则的话就把列表页和详情页的url也追加到list中,追的之前要先把{$id}替换一下

追加完后我们返回这个list集合就可以了,这样的话我们就得到了所有的url

现在有了网址后,我们就可以生成批量生成日志了。

因为我们的功能是想创建几条日志就可以创建几条,创建条数我们自定义。

因为是批量创建日志,我们用for循环就可以了。代码如下:

 

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)]
   //ioutil.WriteFile(*filepath,[]byte(logStr),0644)
logStr=logStr+makeLog(currentUrl,referUrl,ua)+"\n"
}

我们用一个func makeLog()来生成指定格式的日志

makeLog代码如下

 

func makeLog(current,refer,ua string) string  {
   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 - - [02/Jun/2018:14:53:12 +0800] \"OPTIONS /dig?{$paramsStr} HTTP/1.1\" 200 43 \"-\" \"{$ua}\" \"-\""
log:=strings.Replace(logTemplate,"{$paramsStr}",paramsStr,-1)
   log=strings.Replace(log,"{$ua}",ua,-1)
   return log
}

因为生成指定格式,我们按日志模板生成

127.0.0.1 - - [02/Jun/2018:14:53:12 +0800] "OPTIONS /dig?{paramsStr} HTTP/1.1" 200 43 "-" "{$ua}" "-"
以上是某条日志的模板,我们需要只需要替换两个地方。

第一个地方是包括refer,time,ua,url,用url.Value{}方法来生成

 

  u:=url.Values{} //解析url
   u.Set("time","1") //替换time的值为1
     u.Set("url",current) //替换url的值为current
   u.Set("refer",refer) //替换refer的值 为refer
   u.Set("ua",ua) //替换ua的值为ua
   paramsStr:=u.Encode() //对生成的串编码

refer=http%3A%2F%2Fwww.rizhi.test%3A8888%2Fmovie%2F145.html&time=1&ua=Mozilla%2F5.0+%28iPad%3B+U%3B+CPU+OS+4_3_3+like+Mac+OS+X%3B+zh-cn%29+AppleWebKit%2F533.17.9+%28KHTML%2C+like+Gecko%29+Mobile%2F8J2&url=http%3A%2F%2Fwww.rizhi.test%3A8888%2Fmovie%2F70.html

第二个地方是user_agent

Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8J2

 

   logTemplate:="127.0.0.1 - - [02/Jun/2018:14:53:12 +0800] \"OPTIONS /dig?{$paramsStr} HTTP/1.1\" 200 43 \"-\" \"{$ua}\" \"-\""
log:=strings.Replace(logTemplate,"{$paramsStr}",paramsStr,-1)
   log=strings.Replace(log,"{$ua}",ua,-1)

我们接下来对生成的模板替换一下相应的地方替换成我们的value

return log返回替换好的log模板即可。

然后我们将生成的日志写出到dig.log中就行了

还有一个问题。我们的current,refer,ua需要随机选择。模拟就要模拟的真实一些

 

 currentUrl:=list[randInt(0,len(list)-1)]
   referUrl:=list[randInt(0,len(list)-1)]
   ua:=ualist[randInt(0,len(ualist)-1)]

在for循环中我们把传到makeLog的参数随机选择。

randInt代码如下,产生随机数

 

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
}

最后我们一次性把生成的日志写出即可

 

fd,_:=os.OpenFile(*filepath,os.O_RDWR|os.O_APPEND,0644)
fd.Write([]byte(logStr))
fd.Close() //打开文件,一定要记得关闭

用的是os.OpenFile方法,用完记得close哦

好了。附上完整代码

 

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

var ualist = []string{
"Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_2 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5",
"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5",
"MQQBrowser/25 (Linux; U; 2.3.3; zh-cn; HTC Desire S Build/GRI40;480*800)",
"Mozilla/5.0 (Linux; U; Android 2.3.3; zh-cn; HTC_DesireS_S510e Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
"Mozilla/5.0 (SymbianOS/9.3; U; Series60/3.2 NokiaE75-1 /110.48.125 Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413",
"Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8J2",
"Mozilla/5.0 (Windows NT 5.2) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/534.51.22 (KHTML, like Gecko) Version/5.1.1 Safari/534.51.22",
"Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A5313e Safari/7534.48.3",
"Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A5313e Safari/7534.48.3",
"Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A5313e Safari/7534.48.3",
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; SAMSUNG; OMNIA7)",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; XBLWP7; ZuneWP7)",
"Mozilla/5.0 (Windows NT 5.2) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30",
"Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET4.0E; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET4.0E; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C)",
"Mozilla/4.0 (compatible; MSIE 60; Windows NT 5.1; SV1; .NET CLR 2.0.50727)",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)",
"Opera/9.80 (Windows NT 5.1; U; zh-cn) Presto/2.9.168 Version/11.50",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET4.0E; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C)",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; ) AppleWebKit/534.12 (KHTML, like Gecko) Maxthon/3.0 Safari/534.12",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld)",
}

//批量生成log日志功能
type resource struct {
   url string
target string
start int
end int
}

func ruleResource() []resource {
   var res []resource
r1:=resource{ //首页
url:"http://www.rizhi.test:8888",
target:"",
start:0,
end:0,
}
   r2:=resource{ //列表页
url:"http://www.rizhi.test:8888/list/{$id}.html",
target:"{$id}",
start:1,
end:21,
}
   r3:=resource{//详情页
url:"http://www.rizhi.test:8888/movie/{$id}.html",
target:"{$id}",
start:1,
end:178,
}
   res= append(append(append(res, r1), r2), r3)
   return res
}
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  {
   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 - - [02/Jun/2018:14:53:12 +0800] \"OPTIONS /dig?{$paramsStr} HTTP/1.1\" 200 43 \"-\" \"{$ua}\" \"-\""
log:=strings.Replace(logTemplate,"{$paramsStr}",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:=flag.Int("total",100,"how many log")
   filepath:=flag.String("filepath","D:\\nginx-1.13.12\\logs\\dig.log","log for filepath")
   flag.Parse()
   //需要构造出真实的网站URL集合
res:=ruleResource()
   list:=buildUrl(res)

   //按要求,生成$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)]
      //ioutil.WriteFile(*filepath,[]byte(logStr),0644)
logStr=logStr+makeLog(currentUrl,referUrl,ua)+"\n"
}
   fd,_:=os.OpenFile(*filepath,os.O_RDWR|os.O_APPEND,0644)
   fd.Write([]byte(logStr))
   fd.Close() //打开文件,一定要记得关闭
fmt.Println("done")
}
好了。下一章我们编写统计系统的框架。

 

 

标签:5.0,协程,like,url,Mozilla,流量,Golang,日志,OS
From: https://www.cnblogs.com/add1188/p/17825769.html

相关文章

  • GO实现分布式爬虫—掌握go语言通道与协程项目架构设计
    GO实现分布式爬虫—掌握go语言通道与协程项目架构设计Go高并发微服务分布式 1.命令行的用户管理 用户信息存储        =>内存        =>结构[]map        =>用户IDnameageteladdr            [len][]map......
  • 一文快速实战Kotlin协程与Flow
    前言不知道大家有没有跟我一样的感受:即使自己用心在网上学过协程和Flow了,但过了一段时间就又忘掉了。这大部分的原因其实是因为我们缺少实战。我平时工作里根本就接触不到协程和Flow,自己又不敢硬往上写,万一出问题了咋整?所以一直就处于理论学习阶段,导致我学了就跟没学一样。今天就带......
  • 14.5-3 - 14.5-7 流量治理实践
    一、超时策略(针对VirtualService)如果访问某个后端的服务非常卡顿,会严重影响到用户体验,所以可以在前端设置一个超时时间,如果超过该时间则直接返回一个错误码(504)而不是一直等待。在前面章节的学习中,我们了解到,天气预报应用中frontend会调用forecast,而forecast会调用recommendation......
  • 液体流量传感器有哪些
    液体流量传感器是一种用于检测流量多少,控制流量开关一种电子元器件,常用于咖啡机、啤酒机等需要控制流量的设备等。根据不同的工作原理,液体流量传感器有多种类型,其中常见的包括霍尔流量计和光电流量计。霍尔流量计是一种利用霍尔效应测量液体流量的传感器。当带有两极磁铁的叶轮在垂......
  • Golang使用nats
    nats自行安装packagemainimport( "fmt" "github.com/nats-io/nats.go")////nats-server在管理subject的时候是通过’.’进行分割的,server底层是使用treemodule分层管理subject.此处有两个通配符*和>。////*可以匹配以.分割的一切。如:////nc.Subscribe("aa.*......
  • Golang struct 结构体注意事项和使用细节
    结构体所有字段在内存当中是连续的typePointstruct{ x,yint}typeRectstruct{ leftUp,rightDownPoint}funcmain(){ //r1会在内存当中有四个整数 r1:=Rect{ leftUp:Point{ x:1, y:2, }, rightDown:Point{ x:3, y:4, }, } //r1有......
  • Golang锁简单使用
    golang主要有两种锁:互斥锁和读写锁互斥锁Mutex用于提供一种加锁机制(LockingMechanism),保证同一时刻只有一个goroutine在临界区运行packagemainimport( "fmt" "sync" "time")funcmain(){ varmutexsync.Mutex x:=0 gofunc(){ mutex.Lock() x=x+1......
  • Golang服务端断线重连
    断线重连的逻辑很简单,就是把用户存到服务器内存中,当客户端再次登录的时候,判断内存中是否有用户的值,有的话替换packagemainimport( "fmt" "github.com/gorilla/websocket" "log" "net/http" "sync" "time")typeClientstruct{ conn*we......
  • 车流量统计 车辆捕获功能
     高清卡口系统设计方案-智慧工地-工地实名制,智慧工地,监控安装-广州市海康智慧技术有限公司http://hkcctv.net.cn/news_114_148.html 本卡口系统采用双重捕获模式:地感线圈触发+视频触发。1)、当地感线圈方式有效时,即地感线圈及车检器均运行正常时,系统利用电磁感应的原理检......
  • Golang使用crontab
    要是记不住crontab格式,就去网上生成,在线crontab有很多。例如https://www.pppet.net/packagemainimport( "fmt" "github.com/robfig/cron/v3" "time")/**第一个*:second,范围(0-60)第二个*:min,范围(0-59)第三个*:hour,范围(0-23)第四个*:dayofmonth,......