package main

import (
"flag"
"fmt"
"os"
"log"
"net/http"
"io/ioutil"
"github.com/bitly/go-simplejson"
"encoding/csv"
"io"
"time"
"sync"
"net/url"
"strconv"
"errors"
) var (
concurrency int
timeout int
infile string
outfile string
)
var usage = `Usage:%s [options]
Options are:
-c concurrency Number of request to preform
-t timeout Request timeout
-i infile Input file
-o outfile Output file
` func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, usage, os.Args[0])
}
flag.IntVar(&concurrency, "c", 10, "")
flag.IntVar(&timeout, "t", 60, "")
flag.StringVar(&infile, "i", "", "")
flag.StringVar(&outfile, "o", "", "")
flag.Parse()
_, err := os.Stat(infile)
if err != nil {
log.Fatalln("error:", err)
}
f, err := os.Create(outfile)
if err != nil {
log.Fatalln("error:", err)
}
defer f.Close()
var lock sync.Mutex
w := &Worker{
concurrency:concurrency,
timeout:timeout,
infile:infile,
lw:&LockWriter{
m:lock,
writer:f,
},
}
w.Run()
} type LockWriter struct {
m sync.Mutex
writer io.Writer
} func (lw LockWriter) write(b []byte) (n int, err error) {
lw.m.Lock()
defer lw.m.Unlock()
return lw.writer.Write(b)
} type CarInfo struct {
Carno string
Ecode string
Vcode string
} type Worker struct {
concurrency int
timeout int
infile string
jobs chan *CarInfo
lw *LockWriter
} func (w *Worker) Run() {
var wg sync.WaitGroup
wg.Add(w.concurrency + 1)
w.jobs = make(chan *CarInfo, w.concurrency)
go func() {
w.loadJobs()
wg.Done()
}()
//并发数
for i := 1; i <= w.concurrency; i++ {
go func(n int) {
w.doWork(n)
wg.Done()
}(i)
}
wg.Wait()
} func (w *Worker) loadJobs() {
fin, err := os.Open(w.infile)
if err != nil {
log.Fatalln("file open failed,error:", err.Error())
}
defer fin.Close()
reader := csv.NewReader(fin)
for {
row, err := reader.Read()
if err != nil {
if err != io.EOF {
log.Println("file read error:", err)
}
break
}
time.Sleep(time.Duration(1) * time.Second)
w.jobs <- &CarInfo{Carno:row[3], Vcode:row[4], Ecode:row[5]}
}
close(w.jobs)
} func (w *Worker) doWork(num int) {
total := 0
log.Println("worker:", num)
uriParams := url.Values{}
uriParams.Add("openUDID", "3122dcf3-3a2a-34e9-8da5-e9dde29579a4")
uriParams.Add("appid", "1")
uriParams.Add("cartype", "02")
uriParams.Add("os", "android")
uriParams.Add("appVersion", "6.6.6")
uriParams.Add("prefetch", "1")
uriParams.Add("reqfrom", "1")
uriParams.Add("secret", "UBjUFDL9kZSDUqivn4wb063QI4Es3mZhvWvT")
httpClient := &http.Client{
Timeout:time.Duration(w.timeout) * time.Second,
}
for carInfo := range w.jobs {
log.Println(carInfo.Carno, "|", carInfo.Vcode, "|", carInfo.Ecode)
uriParams.Set("carno", carInfo.Carno)
uriParams.Set("vcode", carInfo.Vcode)
uriParams.Set("ecode", carInfo.Ecode)
uri := fmt.Sprintf("http://xxx.cn/common_prefix?%s", uriParams.Encode())
fmt.Println(uri)
code, err := w.doRequest(httpClient, uri)
if err != nil {
log.Println("url request error:", err)
}
switch code {
case 203, 9999:
w.writeResult(carInfo)
}
total++
}
log.Println("worker[", num, "] total:", total)
} func (w *Worker) doRequest(client *http.Client, uri string) (int, error) {
req, err := http.NewRequest("GET", uri, nil)
if err != nil {
log.Println("get new request failed!")
return -1, err
}
resp, err := client.Do(req)
if err != nil {
log.Println("error:", err)
return -1, err
}
defer resp.Body.Close()
result, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("read respose body failed")
return -1, err
}
log.Println("resonse:", string(result))
if resp.StatusCode != 200 {
log.Println("status code:", resp.StatusCode)
return -1, errors.New("stats code error:" + strconv.Itoa(resp.StatusCode))
}
js, err := simplejson.NewJson(result)
if err != nil {
return -1, err
}
code, err := js.Get("code").Int()
return code, nil
} func (w *Worker) writeResult(carInfo *CarInfo) {
line := fmt.Sprintf("%s,%s,%s\n", carInfo.Carno, carInfo.Vcode, carInfo.Ecode)
w.lw.write([]byte(line))
}

  

golang实现任务分发处理的更多相关文章

  1. nginx 匹配路由分发php和golang

    大概这么个形式,可以走通 server { listen ; server_name localhost; root "E:/wwwroot180/public"; # 匹配指定路 ...

  2. 【GoLang】golang 的精髓--流水线,对现实世界的完美模拟

    直接上代码: package main import ( "fmt" "runtime" "strconv" "sync" ...

  3. golang 管道

    2.管道简介Golang的原子并发特性使得它很容易构造流数据管道,这使得Golang可有效的使用I/O和多CPU特性.本文提出一些关于管道的示例,在这个过程中突出了操作失败的微妙之处和介绍处理失败的具 ...

  4. Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳实践

    目录 [TOC] 1.RabbitMQ介绍 1.1.什么是RabbitMQ?   RabbitMQ 是由 LShift 提供的一个 Advanced Message Queuing Protocol ...

  5. GoLang之基础

    GoLang之基础 Go是一种并发的.带垃圾回收的.快速编译的语言. 经典的"hello world"入门: package main import "fmt" ...

  6. Golang、Php、Python、Java基于Thrift0.9.1实现跨语言调用

    目录: 一.什么是Thrift? 1) Thrift内部框架一瞥 2) 支持的数据传输格式.数据传输方式和服务模型 3) Thrift IDL 二.Thrift的官方网站在哪里? 三.在哪里下载?需要 ...

  7. 深入学习golang(2)—channel

    Channel 1. 概述 “网络,并发”是Go语言的两大feature.Go语言号称“互联网的C语言”,与使用传统的C语言相比,写一个Server所使用的代码更少,也更简单.写一个Server除了网 ...

  8. Gravitational Teleport 是一个先进的 SSH 服务器,基于 Golang SSH 构建,完全兼容 OpenSSH

    Gravitational Teleport 是一个先进的 SSH 服务器,可通过 SSH 或者 HTTPS 远程访问 Linux 服务器.其目的是为了替代 sshd.Teleport 可以轻松让团队 ...

  9. Golang性能调优入门

    如何利用golang自带的profile工具进行应用程序的性能调优,前一段时间我做的日志分析系统在线上遇到了一个问题,就是分任务的系统down机了,日志处理延迟了10几个小时,这个时候任务分发系统重启 ...

随机推荐

  1. var与dynamic

    var与dynamic 如果你用MVC写过程序,那么你应该知道ViewBag这个用于前后台的数据传递工具,那么你是否对ViewBag的用法感到过疑惑呢? ViewBag.Mode1l=new obje ...

  2. Ubuntu16安装QQ

    安装教程: 一:安装依赖库 在终端输入sudo apt-get install libgtk2.0-0:i386 另外,如果是64位系统还要安装ia32-libs 这里我们选择安装lib32ncurs ...

  3. 原型模式(ProtoType)

    用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象. 原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节. .Net 在 system 命名空间中提供了I ...

  4. css之为文本添加线性渐变和外描边

    css之为文本添加线性渐变和外描边  一.效果: 描边:描边+渐变: 二.描边: api:text-stroke 问题:text-stroke的描边是居中描边,无法直接设置外描边 解决:在before ...

  5. eclipse web run on server 404

    eclipse真是个坑爹玩意儿,前期在idea开发的web,移到eclipse遇到各种问题 刚开始好好的,突然404,不明所以,搞了好几天 参考eclipse修改web项目部署路径 解决了问题 后来发 ...

  6. delphi android路径 TPath 文件路径,文件管理

    获取Android相关文档路径 delphi 新路径.文件功能 IOUtils单元,文件路径,文件管理 http://docwiki.embarcadero.com/RADStudio/Berlin/ ...

  7. Struts2 利用AJAX 导出大数据设置遮罩层

    Struts2 利用AJAX 导出大数据设置遮罩层 需求背景: 每次我们导出excel的时候 ,如果数据量很大,导出花费的时间会很长,页面却有没人任何反应,这个时候用户会认为系统有问题,要么关了页面, ...

  8. 配置tomcat日志分割

    由于Tomcat在默认情况下会将没有经过配置的web应用所产生的日志输出已及其本身的日志内容都输出到这个文件中,那么随着时间的推移,这个文件的尺寸将会越来越大,当需要检查日志内容时间会导致文件难以打开 ...

  9. 2018 Jar_Feb_Newwords

    检测钩子程序 开发一个检测钩子程序的工具 - 豆丁网http://www.docin.com/p-1363993661.html pdf掺杂病毒的方法 Java的:xml文件中跳过的二进制数据在解析 ...

  10. 在SQL Server中使用CLR调用.NET方法

    介绍    我们一起来做个示例,在.NET中新建一个类,并在这个类里新建一个方法,然后在SQL Server中调用这个方法.按照微软所述,通过宿主 Microsoft .NET Framework 2 ...