18910140161

高并发问题的解决方案

顺晟科技

2021-08-28 09:40:54

161

想要了解Golang高并发问题的解决方案,iGoogle.ink将在本文中详细讲解Golang高并发的相关知识和一些代码示例。欢迎大家阅读指正。让我们先关注高并发的Golang。让我们一起学习。

戈朗高并发问题的解决方案

与其他编程语言相比,Golang在高并发的问题上有很大的优势,即在相同的配置下,Golang可以以更低的成本处理更多的线程,线程数相同,占用的资源更少!这样,只有一部分问题得到了解决,因为每个协调过程中的处理逻辑仍然会有问题。

当并发性较高时,需要考虑服务器能够承受的更大压力、读取数据库时的io问题、连接数、带宽问题等

研究了并发解决方案,并记录在这里

参考文章:快速处理每分钟100万个请求

地址:http://marcio . io/2015/07/与golang一起处理每分钟100万个请求/

代码如下:

//==================================

//*姓名:杰瑞

//*电话:18017448610

//* DateTime:2019/2/24 14:02

//==================================

包装主体

导入(

github.com/lunny/log '

“运行时”

同步

时间

)

//工厂模型

工厂类型结构

Wg *同步。WaitGroup //任务监控系统

MaxWorker int //更大机器数

MaxJobs int //更大作业数

JobQueue chan int //工作队列管道

退出游戏//关闭机器

}

//创建工厂模型

func NewFactory(maxWorker int,wg *sync。WaitGroup)工厂(

返回工厂{

WG : WG//参考任务监控系统

maxWorker : maxWorker//机器数量(数量取决于服务器性能)

作业队列: make (chan int,max worker),//工作管道,数量大于或等于机器数量

Quit: make(chan bool),

}

}

//设置更大订单数量

func(f * Factory)SetMaxJobs(TaskNum int){ 0

f.MaxJobs=taskNum

}

//开始工作

功能(工厂)启动()

//机器已打开,MaxWorker

对于I :=0;i f . MaxWorker我

//每台机器开机后开始工作

go func(){ 0

//等待发出命令

对于{ 0

选择{

案例i :=-f.JobQueue:

//拿到工作就开始!

f.doWork(一)

案例-f.Quit:

日志。Println(“机器关机”)

返回

}

}

}()

}

}

//将每个任务分配给管道

函数(f *工厂)添加任务(TaskNum int){ 0

//系统监控任务1

f.工作组增编(1)

//将任务分配给管道

f.作业队列-任务编号

}

//模拟耗时的工作

func(f * Factory)DoWork(TaskNum int){ 0

//生产产品的工作

时间到了。睡眠(200 *时间。毫秒)

//完成工作报告

f.工作组已完成()

//日志。Println('完成:',taskNum)

}

//创建工厂

func Begin(){ 0

//配置工作审核

gomaxprocs :=运行时。运行时。NumCPU())

日志。Println('支票号码:',gomaxprocs)

//配置监控系统

wg :=新(同步。WaitGroup)

//开工厂

工厂:=新工厂(1000,工作组)

//订单数量

工厂。SetMaxJobs(10000)

//开始工作

工厂。开始()

日志。Println(“开始生产”)

//谈论所有订单并将其添加到任务队列中

对于I :=0;我是工厂。MaxJobs我

工厂。添加任务(I)

}

工厂。工作组等待()

日志。Println(“所有订单任务都已完成”)

}

测试代码和结果

在上面的代码中,MaxWorker的数量非常重要,这取决于服务器能够承受的压力。当然不能无限增加,合理的数值效率更高(多少合适,自己测试)

代码:

func Benchmark _ Begin(b *测试。b){ 0

开始()

}

结果:

在1000台机器和10000个工作负载的情况下,我的个人电脑测试结果如下:

2019/02/26 16:42:31号码:4

2019年2月26日,16:42:31开始生产

2019年2月26日,16:42:33,所有订单和任务完成

goos: windows

goarch: amd64

pkg:第11天

基准_高2-4 1 2035574000 ns/op

及格

进程已完成,退出代码为0

总结:

此方法仅仅是在代码层面解决一定的问题,高并发产生的原因还包括其他原因,如带宽,数据库读取速度等等,还需加大带宽,多级数据库,优化数据的检索等等方法

补充:golang高并发任务处理方案

这个主要用开发的陈和例行的属性做的,比很多语言方便多了,可以参考参考

//任务的请求

类型MtaskRequest结构{

史策国际公司

//[修订]

}

//作业队列工作池

var(

MaxWorker=os .Getenv('MAX_WORKERS ')

MaxQueue=os .Getenv('MAX_QUEUE ')

)

//作业代表要运行的作业

作业类型结构{

请求

}

//一个我们可以发送工作请求的缓冲通道。

//var JobQueue更改作业-这样申明会卡主,没有初始化

变量作业队列=生成(更改作业)

//工人表示执行作业的工作者

工作者类型结构{

工人变更工作

作业通道更改作业

退出chan bool

}

功能新工作人员(工作人员变更工作)工作人员(

返回工人{

WorkerPool: workerPool,

作业通道:制作(更改作业),

quit: make(chan bool)}

}

//停止向工作人员发出停止监听工作请求的信号。

功能(工作人员)停止()

go func(){ 0

w。退出-真

}()

}

类型分配器结构{

//向调度程序注册的工作通道池

工人变更工作

maxWorkers int

}

func new Dispatcher(MaxWorkers int)* Dispatcher {

池:=制作(更改更改作业,maxWorkers)

返回调度程序{工人池,更大工人:更大工人}

}

//开始方法启动工作程序的运行循环,监听中的退出通道

//以防我们需要阻止它

功能(工作人员)开始()

go func(){ 0

对于{ 0

//将当前工作进程注册到工作进程队列中。

w.工作通道

选择{

案例-w.JobChannel:

时间到了。睡眠(5 *时间。第二)

//我们收到了工作请求。

fmt .Println('调起工人)

case -w.quit:

//我们收到了停止的信号

返回

//不能写系统默认值

}

}

}()

}

函数(d *调度员)运行(){ 0

//启动一定数量的工人

fmt .Println('启动一定数量的工人)

对于I :=0;i d.maxWorkers我

工人:=新工人

工人。开始()

}

转到d .调度()

}

//分派任务

功能(d *调度程序)调度(){ 0

对于{ 0

选择{

案例作业:=-JobQueue: //接收一个工作请求

fmt .Println('JobQueue收到请求)

go func(作业作业){ 0

//尝试获取可用的工人工作渠道。

//这会一直阻塞,直到一个工作人员空闲

jobChannel :=-d.WorkerPool

//将作业发送到工人作业通道

作业通道-作业

}(作业)

}

}

}

//接收到红包数据

func(这个* TaskRedbao)用户getredbao(red _ id,uid,shop_id,rand_arr,Amoney字符串)错误{

fmt .Println('收到接收到红包数据超文本传送协议(超文本传输协议的缩写)请求)

mtaskRequest :=mtaskRequest { 67 }

工作:=工作{ mtaskRequest : mtaskRequest }

工作队列-工作

返回零

}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。

我们已经准备好了,你呢?
2024我们与您携手共赢,为您的企业形象保驾护航