iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > GO >Golang HTTP服务超时控制实现原理分析
  • 156
分享到

Golang HTTP服务超时控制实现原理分析

Golang HTTP服务超时控制Golang服务超时控制 2023-05-19 17:05:26 156人浏览 八月长安
摘要

目录前情提要Context封装自定义的Contextcontext.Gomain.goCore.gorouter.gomain.go前情提要 因为上一篇提过,每次来一个请求,然后就会

前情提要

因为上一篇提过,每次来一个请求,然后就会起一个goroutinue那么导致的可能就是一个树形结构的请求图,底下节点在执行中如果发生了超时,那么就有协程会堆积,所以超时控制是有必要的,一般的实现都由一个顶层设计一个Context进行自顶向下传递,这样可以从一个地方去避免多处执行异常,对于Context的过多细节我不在这里一一阐述,有需要的我将单独出一篇关于Context的介绍,下面我们就来看一下源码是如何设计的:

Context

// Context's methods may be called by multiple goroutines simultaneously.
type Context interface {
  // 当Context被取消或者到了deadline,返回一个被关闭的channel
  Done() <-chan struct{}
}
// 函数句柄
type CancelFunc func()

设计初衷最关注的两个点就是一个是如何主动结束下游,另一个是如何通知上游结束下游时

前者利用CancelFunc 后者利用Done,后者需要不断监听所以利用channel的返回值做监听

//创建退出Context
func WithCancel(parent Context)(ctx Context,cancel CancelFunc){}
//创建有超时时间的Context
func WithTimeout(parent Context,timeout time.Duration)(Context,CancelFunc){}
//创建有截止时间的Context
func WithDeadline(parent Context,d time.Time)(Context,CancelFunc){}

WithCancel/WithTimeout/WithDeadline都是通过定时器来自动触发终结通知的,也就是说为父节点生成一个Done的子节点,并且返回子节点的CancelFunc函数句柄.

封装自定义的Context

context.go

可以定义一个自己的Context,里面先拥有最基本的request和response两个参数,最后是因为思考到并发写resposne的writer所以需要加入成员变量以及防止重复写的超时标志位

package framework
import (
	"context"
	"encoding/JSON"
	"net/Http"
	"sync"
)
type Context struct {
	Request        *http.Request
	ResponseWriter http.ResponseWriter
	hasTimeOut     bool // 是否超时标记位
	writerMux      *sync.Mutex
}
func NewContext()*Context{
	return &Context{}
}
func (ctx *Context) BaseContext() context.Context {
	return ctx.Request.Context()
}
func (ctx *Context) Done() <-chan struct{} {
	return ctx.BaseContext().Done()
}
func (ctx *Context)SetHasTimeOut(){
	ctx.hasTimeOut=true
}
func (ctx *Context)HasTimeOut()bool{
	return ctx.hasTimeOut
}
// 自行封装一个json的方法
func (ctx *Context) Json(status int, obj interface{}) (err error) {
	if ctx.HasTimeOut(){
		return nil
	}
	bytes, err := json.Marshal(obj)
	ctx.ResponseWriter.WriteHeader(status)
	_, err = ctx.ResponseWriter.Write(bytes)
	return
}
// 对外暴露锁
func (ctx *Context) WriterMux() *sync.Mutex {
	return ctx.writerMux
}
// 统一处理器Controller方法
type ControllerHandler func(c *Context) error

main.go

业务方法使用一下自己封装的Context,里面考虑到了超时控制以及并发读写,以及处理panic

package main
import (
	"context"
	"fmt"
	"testdemo1/coredemo/framework"
	"time"
)
func FooController(ctx *framework.Context) error {
	durationCtx, cancel := context.WithTimeout(ctx.BaseContext(), time.Second)
	defer cancel()
	finish := make(chan struct{}, 1)
	panicChan := make(chan interface{}, 1)
	go func() {
		defer func() {
			if p := recover(); p != nil {
				panicChan <- p
			}
		}()
		time.Sleep(time.Second * 10)
		finish <- struct{}{}
	}()
	select {
	case p := <-panicChan: // panic
	fmt.Println("panic:",p)
	    ctx.WriterMux().Lock()  // 防止多个协程之前writer的消息乱序
		defer ctx.WriterMux().Unlock()
		ctx.Json(500, "panic")
	case <-finish: // 正常退出
		ctx.Json(200, "ok")
		fmt.Println("finish")
	case <-durationCtx.Done(): // 超时事件
		ctx.WriterMux().Lock()
		defer ctx.WriterMux().Unlock()
		ctx.Json(500, "timed out")
		ctx.SetHasTimeOut()  // 防止多次协程重复写入超时日志
	}
	return nil
}

Core.go

serverHandler的类,进行处理请求的逻辑,可以先注册对应的映射器和方法

package framework
import (
	"net/http"
)
type Core struct {
	RouterMap map[string]ControllerHandler
}
func (c Core) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
	http.DefaultServeMux.ServeHTTP(writer, request)
}
func NewCore() *Core {
	return &Core{
		RouterMap:make(map[string]ControllerHandler,0),
	}
}
// 注册Get方法
func (c *Core) Get(pattern string, handler ControllerHandler) {
	c.RouterMap["get"+"-"+pattern]=handler
}
// 注册Post方法
func (c *Core) Post(pattern string, handler ControllerHandler) {
	c.RouterMap["post"+"-"+pattern]=handler
}

router.go

router统一管理注册进我们对应的http方法到我们的请求逻辑类里去

package main
import "testdemo1/coredemo/framework"
func reGISterRouter(core *framework.Core){
	// 设置控制器
	core.Get("foo",FooController)
}

main.go

最后是主程序的执行http服务监听和调用初始化router的注册!传入我们自定义的Context

package main
import (
	"log"
	"net/http"
	"testdemo1/coredemo/framework"
)
func main() {
	server:=&http.Server{Addr: ":8080",Handler: framework.NewCore()}
	// 注册router
	registerRouter(framework.NewCore())
	err := server.ListenAndServe()
    if err!=nil{
    	log.Fatal(err)
	}
}

本文到此结束!可以自行实现一遍,体验一下,实际和gin的源码封装就是类似的~

我们下一篇再见

到此这篇关于golang HTTP服务超时控制实现原理分析的文章就介绍到这了,更多相关Golang HTTP服务超时控制内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文档:

--结束END--

本文标题: Golang HTTP服务超时控制实现原理分析

本文链接: https://www.lsjlt.com/news/213503.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Golang HTTP服务超时控制实现原理分析
    目录前情提要Context封装自定义的Contextcontext.gomain.goCore.gorouter.gomain.go前情提要 因为上一篇提过,每次来一个请求,然后就会...
    99+
    2023-05-19
    Golang HTTP服务超时控制 Golang服务超时控制
  • GoLang中的timer定时器实现原理分析
    // NewTimer creates a new Timer that will send // the current time on its channel after at ...
    99+
    2023-02-02
    Go timer定时器 Go timer Go定时器
  • C++ 超详细分析多态的原理与实现
    目录多态的定义及实现多态的构成条件虚函数重写C++11的override和final抽象类多态的原理虚函数表动态绑定与静态绑定单继承和多继承关系的虚函数表单继承中的虚函数表多继承中的...
    99+
    2024-04-02
  • 通过源码分析Golang cron的实现原理
    目录前言Demo示例源码实现结构体 Cron 和 EntryNew()实现AddFunc()实现Start()实现Run()实现Stop()实现Remove()实现小结前言 gola...
    99+
    2024-04-02
  • WCF服务控制程序实例分析
    这篇文章主要讲解了“WCF服务控制程序实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“WCF服务控制程序实例分析”吧!这个示例中创建了一个存储在Web服务器上的简单Web服务和控制台客...
    99+
    2023-06-17
  • MySQL时间戳的原理与实现机制解析
    MySQL时间戳的原理与实现机制解析 在MySQL数据库中,时间戳(Timestamp)是一种用于存储日期和时间信息的数据类型。它可以记录时间戳的秒数,精确到微秒级别,用于在数据库中记...
    99+
    2024-03-15
    mysql 时间戳 实现
  • golang定时器Timer的用法和实现原理解析
    目录一文搞懂golang定时器Timer的用法和实现原理前言Timertimer结构体创建定时器停止定时器重置定时器实现原理数据结构runtimeTimer创建Timer停止Time...
    99+
    2023-05-15
    golang定时器 golang定时器Ticker
  • Go语言文档解析:net.DialTimeout函数实现网络连接超时控制
    Go语言是一个开源的编程语言,被广泛应用于网络编程和服务器开发。在网络编程中,有时我们需要对网络连接的超时进行控制,以便在连接过程中避免长时间的等待。Go语言提供了一个非常方便的函数net.DialTimeout来实现网络连接超时控制。ne...
    99+
    2023-11-04
    Go语言 文档解析 netDialTimeout
  • fescar分布式事务实现原理实例分析
    这篇文章主要介绍了fescar分布式事务实现原理实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇fescar分布式事务实现原理实例分析文章都会有所收获,下面我们一起来看看吧。项目说明本博文所述代码为fes...
    99+
    2023-06-29
  • 深入探讨Golang实时更新功能的原理及实现机制
    Golang热更新原理浅析:探讨实时更新功能的实现机制,需要具体代码示例 随着软件的发展,实时更新功能成为了许多开发者和用户所期望的一个重要特性。Golang作为一门现代化的编程语言,自然也需要具备这样的能力...
    99+
    2024-01-20
    Golang 实时更新 热更新
  • Golang中怎么实现一个HTTP代理服务器
    本篇文章给大家分享的是有关Golang中怎么实现一个HTTP代理服务器,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。定义请求对象,接收客户端请求处理请求,把处理结果返回给客户端...
    99+
    2023-06-03
  • SpringBoot服务监控机制原理解析(面试官常问)
    目录前言SpringBoot 监控HTTP Endpoints 监控内置端点自定义监控端点JMX 监控如何手动注册一个 JMX MBean其他监控总结前言 任何一个服务如果没有监控,...
    99+
    2024-04-02
  • Golang 微服务:实现原理与应用实践
    《Golang 微服务:实现原理与应用实践》 随着云计算和容器化技术的发展,微服务架构越来越被广泛应用于各类软件系统中。而作为一种高效、轻量级的编程语言,Go 语言(Golang)在微...
    99+
    2024-02-29
    实践 golang 微服务 微服务开发 标准库
  • MySQL事务隔离实现并发控制的示例分析
    这篇文章主要介绍了MySQL事务隔离实现并发控制的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、并发访问控制实现的并发访问的控制技术是基于锁;锁分为表级锁和行级锁...
    99+
    2023-06-20
  • 解析探秘fescar分布式事务实现原理
    目录前言项目说明fescar的TXC模型项目结构解析通过【examples】模块的实例看下效果第一步、第二步、第三步、fescar事务过程分析首先分析配置文件【TM】模块启动全局事务...
    99+
    2024-04-02
  • ASP 响应实时 shell,如何实现远程控制服务器?
    在日常的工作中,我们经常需要远程控制服务器。这时候,如何实现远程控制服务器就成了一项非常重要的技能。本文将介绍如何使用 ASP 响应实时 shell 实现远程控制服务器的方法。 ASP(Active Server Pages)是一种用于创...
    99+
    2023-08-12
    响应 实时 shell
  • shell脚本怎样实现定时监控http服务的运行状态
    这篇文章主要为大家展示了“shell脚本怎样实现定时监控http服务的运行状态”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“shell脚本怎样实现定时监控http服务的运行状态”这篇文章吧。注意...
    99+
    2023-06-05
  • MySQL数据库分布式事务XA的实现原理分析
      1 原理   关于MySQL数据库的分布式事务XA,分布式事务实现的原理,可见[3];关于MySQL XA的说明,可见[1][2]。   MySQL XA分为两类,内部XA与外部XA;内部XA用于同一...
    99+
    2024-04-02
  • Linux利用inotify和rsync服务实现数据实时同步的原理解析
    目录文件定时同步的实现:文件实时同步的实现:inotifyinotify-tools包主要工具:inotifywait 命令:rsync工具rsync有三种工作方式:两种方式实现rsync服务器方式一:通过rsync守护...
    99+
    2024-04-02
  • Linux实现ARP缓存老化时间原理问题的示例分析
    这篇文章主要介绍Linux实现ARP缓存老化时间原理问题的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一.问题 众所周知,ARP是一个链路层的地址解析协议,它以IP地址为键值,查询保有该IP地址主机的MAC...
    99+
    2023-06-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作