GoRoutines高性能同时进行多个Api调用实现

目录
  • 正文
  • 原始调用
  • 高性能调用

正文

Golang是高效的,非常高效。这种效率在很大程度上要归功于它在处理并发性问题时的独特抽象。例如,Java将其线程映射为操作系统线程,而Go使用自己的goroutines调度器将其轻量级goroutines从操作系统线程中进一步抽象出来。简而言之,Golang在使用操作系统线程方面非常节俭;如果一个goroutine被阻塞了,Go的调度器会在它的位置上切换另一个goroutine,以尽可能地保持线程的忙碌。由于每个CPU核心处理的线程数量有限(而且产生新的线程是很昂贵的),保持这些线程的工作是一件很好的事情。

那么,我们如何使用Golang来并发地进行多个http调用呢?如果你使用过C#或现代JavaScript,你可能使用过async/await来进行多个api调用。Golang并不那么容易,但这都是以效率为名义的。Go总是至少有一个goroutine在运行,它负责运行main()。我们可以在函数调用前用关键字go催生新的例程。如果你从事过Java/C#的异步调用,那么goroutine可能会让你想起上下文的概念。[文章来源:janrs.com] Go Scheduler允许开发者制作成千上万个这种轻量级的goroutines,并为我们管理每个goroutines所花费的CPU时间。每当一个以go为前缀的函数被执行时,就会创建一个新的goroutine来运行该函数,主goroutine在生成一个新的goroutine后立即继续前进,直到它遇到一个阻塞操作符(类似于C#或Js中的await)。

原始调用

让我们从一个简单的控制台应用开始,它调用了几个GitHub配置文件,并检查连接是否成功。起初,这里没有goroutines,所有的调用都是连续进行的,效率不高。

// Auth: janrs.com
package main
import "fmt"
import "net/http"
func main() {
	links := []string{
		"https://github.com/fabpot",
		"https://github.com/andrew",
		"https://github.com/taylorotwell",
		"https://github.com/egoist",
		"https://github.com/HugoGiraudel",
	}
	checkUrls(links)
}
func checkUrls(urls []string) {
	for _, link := range urls {
		checkUrl(link)
	}
}
func checkUrl(url string) {
	_, err := http.Get(url)
	if err != nil {
		fmt.Println("We could not reach:", url)
	} else {
		fmt.Println("Success reaching the website:", url)
	}
}

高性能调用

首先,我们需要添加一个叫做通道的东西。由于在自己的goroutine中运行的Golang函数只是简单的函数,我们需要一种方法,通过它内部的goroutine可以把它们的结果告诉外部的goroutine;这就是使用通道来实现的。我们通过以下方式初始化它们: c := make(chan string) 我们能够使用<- 箭头将结果值发送到我们的通道,我们也可以使用这个箭头将通道的值分配出去。

第二,我们需要添加一个跟 踪 器,来跟踪我们应该期待多少个值从这个通道出来。这可以通过使用sync.WaitGroup.WaitGroup的类型来完成。

落实这两个想法,代码如下。

import (
	"fmt"
	"net/http"
	"sync"
)
func main() {
	links := []string{
		"https://github.com/fabpot",
		"https://github.com/andrew",
		"https://github.com/taylorotwell",
		"https://github.com/egoist",
		"https://github.com/HugoGiraudel",
	}
	checkUrls(links)
}
func checkUrls(urls []string) {
	c := make(chan string)
	var wg sync.WaitGroup
	for _, link := range urls {
		wg.Add(1)   // 这告诉wg,现在这里有一个待处理的操作。
		go checkUrl(link, c, &wg)
	}
	go func() {
		wg.Wait()	// 这将阻止Goroutine,直到WaitGroup计数器为零。#janrs.com
		close(c)    // 通道需要被关闭,否则下面的循环将永远持续下去
	}()
    // 这个简略的循环是一个无休止的循环的语法糖,它只是在等待结果通过'c'通道进入。
	for msg := range c {
		fmt.Println(msg)
	}
}
func checkUrl(url string, c chan string, wg *sync.WaitGroup) {
	defer (*wg).Done()
	_, err := http.Get(url)
	if err != nil {
		c <- "#janrs.com#We could not reach:" + url    // 将结果输入通道
	} else {
		c <- "Success reaching the website:" + url    // 将结果输入通道
	}
}

以上就是GoRoutines高性能同时进行多个Api调用实现的详细内容,更多关于GoRoutines多个Api同时调用的资料请关注我们其它相关文章!

(0)

相关推荐

  • goroutine 泄漏和避免泄漏实战示例

    目录 goroutine 泄漏和避免泄漏的最佳实践 什么是goroutine泄漏? 原因分析 伪代码 有什么方法可以解决这个问题? goroutine 泄漏和避免泄漏的最佳实践 Go的奇妙之处在于,我们可以使用goroutines和channel轻松地执行并发任务.如果在生产环境中使用goroutines和channel,但是不了解它们的行为方式,会造成一些严重的影响. 好吧,我们就面临着这样的影响,我们在goroutines中出现了泄漏,导致应用服务器随着时间的推移而膨胀,消耗了大量的CPU和

  • Go语言CSP并发模型goroutine channel底层实现原理

    目录 Go的CSP并发模型(goroutine + channel) 1.goroutine goroutine的优点: 2.channel 无缓存channel 有缓存channel 3.Go并发模型的底层实现原理 4.一个CSP例子 参考Go的CSP并发模型实现:M, P, G Go语言是为并发而生的语言,Go语言是为数不多的在语言层面实现并发的语言. 并发(concurrency):多个任务在同一段时间内运行. 并行(parallellism):多个任务在同一时刻运行. Go的CSP并发模

  • Go语言Goroutinue和管道效率详解

    目录 goroutinue基本介绍 进程和线程说明 并发和并行 同步和异步 Go协程和Go主线程 go协程特点 goroutinue基本使用 实验代码 效果图 执行流程图 goroutinue的调度模型 MPG MPG运行状态1 MPG运行状态2 管道(channel) 不同协程之间如何通讯 全局变量加锁同步缺陷 管道基本介绍 管道基本使用 声明和定义 管道关闭和遍历 关闭 遍历 管道注意事项 综合案例 goroutinue基本介绍 进程和线程说明 进程介绍程序在操作系统中的一次执行过程,是系统

  • 一文初探 Goroutine 与 channel基本用法

    目录 前言 Goroutine 基本用法 channel channel 的基本操作 带缓冲 channel 与无缓冲 channel 声明 channel 的只发送类型和只接收类型 channel 的关闭 小结 前言 本文介绍的内容是 Go 并发模块的两个重要角色 → goroutine 与 channel.如果本文对你有帮助,不妨点个赞,如果你是 Go 语言初学者,不妨点个关注,一起成长一起进步,如果本文有错误的地方,欢迎指出! Go 语言的 CSP 并发模型的实现包含两个主要组成部分:一个

  • Go语言使用goroutine及通道实现并发详解

    目录 使用通道接收数据 阻塞接收数据 非阻塞接收数据 接收任意数据,忽略掉接收的数据 循环接收数据 使用通道接收数据 在上一篇文章中介绍了通道以及使用通道发送数据,本篇接着了解通道的基本内容,如何使用通道接收数据: 通道的接收同样使用"<-"操作符: 使用通道接收数据的特性如下: 通道的发送和接收操作在不同的两个goroutine间进行,由于通道中的数据在没有接收方接收时会持续阻塞,所以通道的接收必定在另外一个goroutine中进行: 如果在接收方接收时,通道中没有发送方发送数

  • GoRoutines高性能同时进行多个Api调用实现

    目录 正文 原始调用 高性能调用 正文 Golang是高效的,非常高效.这种效率在很大程度上要归功于它在处理并发性问题时的独特抽象.例如,Java将其线程映射为操作系统线程,而Go使用自己的goroutines调度器将其轻量级goroutines从操作系统线程中进一步抽象出来.简而言之,Golang在使用操作系统线程方面非常节俭:如果一个goroutine被阻塞了,Go的调度器会在它的位置上切换另一个goroutine,以尽可能地保持线程的忙碌.由于每个CPU核心处理的线程数量有限(而且产生新的

  • Vue.js使用$.ajax和vue-resource实现OAuth的注册、登录、注销和API调用

    概述 上一篇我们介绍了如何使用vue resource处理HTTP请求,结合服务端的REST API,就能够很容易地构建一个增删查改应用. 这个应用始终遗留了一个问题,Web App在访问REST API时,没有经过任何认证,这使得服务端的REST API是不安全的,只要有人知道api地址,就可以调用API对服务端的资源进行修改和删除. 今天我们就来探讨一下如何结合Web API来限制资源的访问. 本文的主要内容如下: 介绍传统的Web应用和基于REST服务的Web应用 介绍OAuth认证流程和

  • 基于JAVA的短信验证码api调用代码实例

    本文实例为大家分享了JAVA的短信验证码api调用代码,供大家参考,具体内容如下 import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import jav

  • python爬虫之百度API调用方法

    调用百度API获取经纬度信息. import requests import json address = input('请输入地点:') par = {'address': address, 'key': 'cb649a25c1f81c1451adbeca73623251'} url = 'http://restapi.amap.com/v3/geocode/geo' res = requests.get(url, par) json_data = json.loads(res.text) g

  • 基于JAVA每月运势api调用代码实例

    本文实例为大家分享了JAVA每月运势api调用代码,供大家参考,具体内容如下 import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.

  • php有道翻译api调用方法实例

    本文实例讲述了php有道翻译api调用方法,这里我们利用了file_get_contents函数直接读取由api返回的数据进行处理,分享给大家供大家参考.具体分析如下: 调用之前我们需申请一个有道翻译API数据接口的key,地址如: 复制代码 代码如下: http://fanyi.youdao.com/openapi?path=data-mode 方法说明,数据接口: 复制代码 代码如下: http://fanyi.youdao.com/openapi.do?keyfrom=<keyfrom>

  • android 微信 sdk api调用不成功解决方案

    最近一直在调用微信的API,却发现一直调用不成功,纠结了好久,各方面找教程,找官方,官方里的文档也只是写得很模糊,说是按三步走. 1.申请App_ID 2.填写包名3. 获取程序签名的md5值, 这三步只要你走对了就能调通,可是大家都不知道有时候我们打包的keystore和我们打包的keystore获取到的程序签名的md5是不一样的.我们在申请的时候填的程序签名值是正式打包的,但我们在eclipse部署上去的却是用的我们默认的debug.keystore.而这样导致的后果就是程序签名不一样,会一

  • C#中API调用的多种方法

    介绍 API( Application Programming Interface ),我想大家不会陌生,它是我们Windows编程的常客,虽然基于.Net平台的C#有了强大的类库,但是,我们还是不能否认API在Windows编程中的重要性.大多数的编程语言都支持API编程,而.Net平台中的MFC(Microsoft Foundation Class Library)构架本身就封装了大部分的API. 做为程序员,我们需要了解API从字面上了解便是编程接口,因此,做为开发者,需要了解的只是API

  • ChatGPT介绍及Java API调用

    ChatGPT的基本介绍 ChatGPT是一个用来进行自然语言处理任务的预训练模型.要使用ChatGPT,需要了解以下几点: 理解预训练模型:预训练模型是通过在大量数据上训练得到的模型,可以在各种自然语言处理任务上进行迁移学习. API使用:OpenAI提供了一个API,可以通过发送请求来生成回答. 请求格式:请求必须包含模型的提问,并且可以包含上下文信息. 响应格式:响应将包含模型的回答,以及一些其他的信息,例如回答的概率等. 如果您需要进一步的指导,请查看OpenAI的API文档和代码示例.

  • 详解Spring Boot 中使用 Java API 调用 lucene

    Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言).Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎 全文检索概述 比如,我们一个文件夹中,或者一个磁盘中有很多的文件,记事本.world.Excel.pdf,我们

随机推荐