您当前所在位置:首页攻略为什么选择GO语言?

为什么选择GO语言?

更新:2024-05-20 08:56:58编辑:游戏资讯归类:攻略

一、选择GO的原因

作为后端开发人员,我在日常工作中主要接触到两种编程语言,分别是 PHP和GO 。虽然我要承认,PHP的确是一门很棒的语言(开发者自嘲),编写起来确实非常舒适,毫无心智负担,而且字符串和整数类型根本无需区分,因此开发速度比GO快得多。目前,我们的一些老项目仍在使用PHP,但在2021年之后的新项目几乎都转向了GO。那么为什么我们还要选择GO,尽管PHP如此香呢?接下来,我将 解释一下我们新项目从PHP转向GO的原因 ,以下是几个重要的原因:

1、PHP无法满足我们的高并发业务需求 ,这是最主要的原因。(注:这里指的PHP是指官方的php-fpm模式下的开发,即每个请求一个进程的模式,而不是类似于swoole常驻进程的模式。关于为什么不使用swoole,确实也有相关原因,虽然swoole逐渐受到关注,但之前存在许多bug,使用起来心智负担较重。)我们部门负责直播业务,每天都需要应对高并发,因此我们只能将目光转向GO这位并发小王子的怀抱。

2、GO语言当时在市场上非常火爆 ,腾讯、百度、滴滴、好未来等大型公司都陆续从PHP转向GO,这也是一个信号,跟着大佬们走总不会错。

3、GO语言简单、简洁 ,相比JAVA,上手很快(但要真正掌握还是需要一定的时间)。我当时只用了大约两周时间学习语法,就能够和团队一起编写项目了。

二、GO解决的并发问题

在传统的PHP中,实现并发是相当困难的,除非借助一些扩展。 举个例子:每个用户进入直播间时,都需要获取大量信息,包括版本服务信息、直播基础信息、用户信息、直播关联权益信息、直播间信息统计等等。如果使用PHP的写法,就必须按照下面串行的流程进行操作,这将导致接口的耗时等于所有操作的时间总和,严重影响用户体验。

但如果使用GO来处理这个任务,就会非常简洁。 用户请求的耗时仅取决于最耗时的操作,如下图所示:

那么我们如何使用GO来实现这种并发逻辑呢?

方法1:使用sync.WaitGroup

//请求入口
func main() {
	var (
		VersionDetail, LiveDetail, UserDetail, EquityDetail, StatisticsDetail int
	)
	ctx := context.Background()
	GoNoErr(ctx, func() {
		VersionDetail = 1 //版本服务信息
		time.Sleep(1 * time.Second)
		fmt.Println("执行第一个任务")
	}, func() {
		LiveDetail = 2 //直播基础信息
		time.Sleep(2 * time.Second)
		fmt.Println("执行第二个任务")
	}, func() {
		UserDetail = 3 //用户信息
		time.Sleep(3 * time.Second)
		fmt.Println("执行第三个任务")
	}, func() {
		EquityDetail = 4 //直播关联权益信息
		time.Sleep(4 * time.Second)
		fmt.Println("执行第四个任务")
	}, func() {
		StatisticsDetail = 5 //直播间信息统计
		time.Sleep(5 * time.Second)
		fmt.Println("执行第五个任务")
	})
	fmt.Println(VersionDetail, LiveDetail, UserDetail, EquityDetail, StatisticsDetail)
}

//并发方法
func GoNoErr(ctx context.Context, functions ...func()) {
	var wg sync.WaitGroup
	for _, f := range functions {
		wg.Add(1)
		// 每个函数启动一个协程
		go func(function func()) {
			function()
			wg.Done()
		}(f)
	}
	// 等待执行完
	wg.Wait()
}

方法2:使用ErrGroup库

//请求入口
func main() {
	var (
		VersionDetail, LiveDetail, UserDetail, EquityDetail, StatisticsDetail int
		err                                                                   error
	)
	ctx := context.Background()
	err = GoErr(ctx, func() error {
		VersionDetail = 1 //版本服务信息
		time.Sleep(1 * time.Second)
		fmt.Println("执行第一个任务")
		return nil //返回实际执行的错误
	}, func() error {
		LiveDetail = 2 //直播基础信息
		time.Sleep(2 * time.Second)
		fmt.Println("执行第二个任务")
		return nil //返回实际执行的错误
	}, func() error {
		UserDetail = 3 //用户信息
		time.Sleep(3 * time.Second)
		fmt.Println("执行第三个任务")
		return nil //返回实际执行的错误
	}, func() error {
		EquityDetail = 4 //直播关联权益信息
		time.Sleep(4 * time.Second)
		fmt.Println("执行第四个任务")
		return nil //返回实际执行的错误
	}, func() error {
		StatisticsDetail = 5 //直播间信息统计
		time.Sleep(5 * time.Second)
		fmt.Println("执行第五个任务")
		return nil //返回实际执行的错误
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(VersionDetail, LiveDetail, UserDetail, EquityDetail, StatisticsDetail)
}

func GoErr(ctx context.Context, functions ...func() error) error {
	var eg errgroup.Group
	for i := range functions { 
		f := functions[i]  //请注意这里的写法,下面有讲解
		eg.Go(func() (err error) {
			err = f()
			if err != nil {
				//记日志
			}
			return err
		})
	}
	// 等待执行完
	return eg.Wait()
}

上面就是使用ErrGroup库的并发执行任务的方法, 可以直接拿来使用。ErrGroup是GO官方提供的一个同步扩展库 非常适合将一个通用的父任务拆分成多个子任务并发执行

上面的写法需要特别注意,下面有几种写法:

写法1:

for i := range functions { 
		f := functions[i]  
		eg.Go(func() (err error) {
			err = f()

写法2:

for _, f := range functions { 
		fs := f  
		eg.Go(func() (err error) {
			err = fs()

写法3:

for _, f := range functions { 
		eg.Go(func() (err error) {
			err = f()

如果使用写法3,会出现类似下图的错误结果

正确的预期结果(写法1、写法2)应该是这样的

这是因为在Go语言中,当使用闭包(匿名函数)时,如果闭包引用了外部的变量,闭包实际上会捕获这些变量的引用 。在循环中创建闭包时,如果直接将循环变量作为闭包的参数或在闭包中引用该变量,会导致所有生成的闭包都引用相同的变量,即最后一次迭代的值。

为了避免这个问题, 常见的做法是在循环内部创建一个新的变量 ,将循环变量的值赋给这个新变量,然后在闭包中引用该新变量。这样,每次循环迭代都会创建一个新的变量,闭包捕获的是不同的变量引用,而不是相同变量的引用。 这个技巧非常有用,可以在循环中创建多个独立的闭包,并确保它们捕获的是预期的变量值,而不会受到循环迭代的干扰

当然,还有一些第三方库也实现了上面的并发分组操作,大家感兴趣的可以去GitHub上看看,但功能和实现基本都大同小异 。以上就是 GO并发的基础,将一个父任务拆分成多个子任务去执行,提高程序的并发度,节省程序耗时 。我们平时在工作中, 两种方法都可以直接拿来使用 ,可以说这两个GO并发方法几乎贯穿了我的GO职业生涯,也是 最基础最实用的并发操作方法

以上就是电脑114游戏给大家带来的关于为什么选择GO语言?全部内容,更多攻略请关注电脑114游戏。

电脑114游戏-好玩游戏攻略集合版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

手办鉴赏室:妖精女王超帅气!阿尔托莉雅优雅战斗 朋友圈同步