Go语言核心36讲
郝林
《Go并发编程实战》作者,前轻松筹大数据负责人
立即订阅
24139 人已学习
课程目录
已完结 54 讲
0/4登录后,你可以任选4讲全文学习。
开篇词+学习路线 (3讲)
开篇词 | 跟着学,你也能成为Go语言高手
免费
预习篇 | 写给0基础入门的Go语言学习者
50 | 学习专栏的正确姿势
模块一:Go语言基础知识 (6讲)
01 | 工作区和GOPATH
02 | 命令源码文件
03 | 库源码文件
04 | 程序实体的那些事儿(上)
05 | 程序实体的那些事儿(中)
06 | 程序实体的那些事儿 (下)
模块二:Go语言进阶技术 (16讲)
07 | 数组和切片
08 | container包中的那些容器
09 | 字典的操作和约束
10 | 通道的基本操作
11 | 通道的高级玩法
12 | 使用函数的正确姿势
13 | 结构体及其方法的使用法门
14 | 接口类型的合理运用
15 | 关于指针的有限操作
16 | go语句及其执行规则(上)
17 | go语句及其执行规则(下)
18 | if语句、for语句和switch语句
19 | 错误处理(上)
20 | 错误处理 (下)
21 | panic函数、recover函数以及defer语句 (上)
22 | panic函数、recover函数以及defer语句(下)
模块三:Go语言实战与应用 (27讲)
23 | 测试的基本规则和流程 (上)
24 | 测试的基本规则和流程(下)
25 | 更多的测试手法
26 | sync.Mutex与sync.RWMutex
27 | 条件变量sync.Cond (上)
28 | 条件变量sync.Cond (下)
29 | 原子操作(上)
30 | 原子操作(下)
31 | sync.WaitGroup和sync.Once
32 | context.Context类型
33 | 临时对象池sync.Pool
34 | 并发安全字典sync.Map (上)
35 | 并发安全字典sync.Map (下)
36 | unicode与字符编码
37 | strings包与字符串操作
38 | bytes包与字节串操作(上)
39 | bytes包与字节串操作(下)
40 | io包中的接口和工具 (上)
41 | io包中的接口和工具 (下)
42 | bufio包中的数据类型 (上)
43 | bufio包中的数据类型(下)
44 | 使用os包中的API (上)
45 | 使用os包中的API (下)
46 | 访问网络服务
47 | 基于HTTP协议的网络服务
48 | 程序性能分析基础(上)
49 | 程序性能分析基础(下)
尾声与思考题答案 (2讲)
尾声 | 愿你披荆斩棘,所向无敌
新年彩蛋 | 完整版思考题答案
Go语言核心36讲
登录|注册

47 | 基于HTTP协议的网络服务

郝林 2018-11-28
我们在上一篇文章中简单地讨论了网络编程和 socket,并由此提及了 Go 语言标准库中的syscall代码包和net代码包。
我还重点讲述了net.Dial函数和syscall.Socket函数的参数含义。前者间接地调用了后者,所以正确理解后者,会对用好前者有很大裨益。
之后,我们把视线转移到了net.DialTimeout函数以及它对操作超时的处理上,这又涉及了net.Dialer类型。实际上,这个类型正是net包中这两个“拨号”函数的底层实现。
我们像上一篇文章的示例代码那样用net.Dialnet.DialTimeout函数来访问基于 HTTP 协议的网络服务是完全没有问题的。HTTP 协议是基于 TCP/IP 协议栈的,并且它也是一个面向普通文本的协议。
原则上,我们使用任何一个文本编辑器,都可以轻易地写出一个完整的 HTTP 请求报文。只要你搞清楚了请求报文的头部(header)和主体(body)应该包含的内容,这样做就会很容易。所以,在这种情况下,即便直接使用net.Dial函数,你应该也不会感觉到困难。
不过,不困难并不意味着很方便。如果我们只是访问基于 HTTP 协议的网络服务的话,那么使用net/http代码包中的程序实体来做,显然会更加便捷。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Go语言核心36讲》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(11)

  • 晨曦
    “人生的道路都是由心来描绘的,所以,无论自己处于多么严酷的境遇之中,心头都不应为悲观的思想所萦绕。”
    被老师的精神打动,真心祝愿早日康复!
    2018-11-28
    14
  • 嘎嘎
    看测试用例中是用 srv.Shutdown(context.Background()) 的方式停止服务,通过RegisterOnShutdown可添加服务停止时的调用

    作者回复: 对的。

    2019-04-04
    4
  • Michael
    看了下源码之后感觉应该这样做:

    quit := make(chan os.Signal, 1)
    signal.Notify(quit, os.Interrupt, syscall.SIGTERM)

    server := http.Server{..}

    go func(){
         server. ListenAndServe()
    }()

    <-quit

    server.Shutdown()

    Shutdown 并不会立即退出,他会首先停止监听,并且启动一个定时器,避免新的请求进来,然后关闭空闲链接,等待处理中的请求完成或者如果定时器到了,再退出,和 NGINX 的 平滑退出很像。
    2018-11-30
    2
  • My dream
    老师可以讲一下这个不:gomonkey,我看半天都没明白这个打桩是什么意思
    2018-11-28
    2
  • aebn
    谢谢老师分享,努力学习中^_^
    2018-11-28
    1
  • 袁树立
    如此一来,每当一个 HTTP 请求被递交时,就都会产生一个新的网络连接。这样做会明显地加重网络服务以及客户端的负载,并会让每个 HTTP 事务都耗费更多的时间。所以,在一般情况下,我们都不要去设置这个DisableKeepAlives字段。

    老师,针对这句话,有个问题。
    因为我们的服务调用其他内网接口,会通过公司的负载均衡。七层负载均衡是关闭了keep-alive的。所以我们的http就每次都是短链接。 那每次http事务耗费的时间大概是什么量级? 我这里看到,设置了500ms超时的情况下。在频繁请求的场景,每过几分钟就会有一批超时。报net/http timeout 。
    用http trace看,是在getConn前就耗费了500ms

    请问,这种情况正常吗?

    作者回复: 这个问题太复杂了。你们的网络拓扑、中间件版本和配置以及 Go 程序本身等等都可能会对此影响。你们需要有 request id,然后串起来进行分析。

    定位问题需要定位到某一个或某几行代码。只知道在 getConn 前耗时的话,粒度太粗了。有必要的话,需要跟进 net 包的源码。

    另外,怎样设置需要按照你们的实际情况来。我不知道你们具体因为什么关闭 ka,也许是合理的,也许不是。不论怎样,这相当于放弃了对操作系统底层优化机制的利用。

    2019-10-23
  • 上山的o牛
    学习中,衍生的内容可以看一周
    2019-10-12
  • qiushye
    http.Transport里没有MaxConnsPerHost字段了,article36/q1的程序运行报错

    作者回复: Go 1.13 里依然有啊。

    2019-10-11
    1
  • 路人
    这节老师讲得特别好,特别是问题的衍生能思考到很多go的其他重要模块,比如net、io等。
    2019-07-14
  • Timo
    demo91.go 例子中
    reqStrTpl := `HEAD / HTTP/1.1
    Accept: */*
    Accept-Encoding: gzip, deflate
    Connection: keep-alive
    Host: %s
    User-Agent: Dialer/%s
    `
    协议和头信息之间要空两行,才能正常发出信息
    2019-06-13
  • 虢国技匠
    打卡
    2019-03-15
收起评论
11
返回
顶部