Go HTTP 编程 | 01 - 使用 http 包创建 Web 服务器

简介: Go HTTP 编程 | 01 - 使用 http 包创建 Web 服务器

一、Go 的 HTTP 标准库 net/http

Go 已经拥有成熟的 HTTP 标准库 net/http,即使不使用 Go 的 Web 框架如 Gin、Iris 等也可以快速的搭建起一个可以运行的 Web 服务,同时这个标准库可以对 Web 路由、静态文件、模板和cookie 等数据进行处理,事实上这些 Web 框架也都是基于 net/http 标准库来构建的。

使用 net/http 建立 Web 服务器

首先创建一个请求处理函数 sayHelloHandler,该函数接收一个 http.ResponseWriter 和 一个请求指针 *http.Request 作为参数,通过对请求中数据的提取之后写入指定的信息到 http.ResponseWriter 中。

在 main 函数中通过 http.HandleFunc 定义一个路由并将该路由与 sayHelloHandler 函数映射,然后通过 http.ListenAndServe 监听端口。

运行 main.go 文件,一个简单的 Web 服务器就运行起来了。

package main
// filename main.go
//noinspection ALL
import (
   "fmt"
   "log"
   "net/http"
   "strings"
)
//noinspection ALL
func main(){
   http.HandleFunc("/", sayHelloName)
   err := http.ListenAndServe(":9000", nil)
   if err != nil {
      log.Fatal("ListenAndServer: ", err)
   }
}
func sayHelloHandler(w http.ResponseWriter, r *http.Request){
   r.ParseForm() // 解析参数,默认是不会解析的
   fmt.Println(r.Form) // 输出
   fmt.Println("path", r.URL.Path)
   fmt.Print("Scheme", r.URL.Scheme)
   fmt.Println(r.Form["url_long"])
   for k, v := range r.Form{
      fmt.Println("Key", k)
      fmt.Println("Val", strings.Join(v, ""))
   }
   fmt.Fprint(w, "Hello, Go HTTP")
}
复制代码

在浏览器中输入 http://localhost:9000/

image.png

控制台打印出的详细信息

image.png

net/http 运行机制

net/http 运行流程:

  1. 创建 Listen Socket 监听指定端口,等待客户端请求
  2. Listen Socket 接收客户端请求,得到 Client Socket,服务端通过 Clent Socket 与客户端进行通信
  3. 处理客户端请求,首先从 Client Socket 读取 HTTP 请求的信息,包括请求头和请求体,然后交给相应的 handler 函数处理,handler 处理完成后将数据通过 Client Socket 写给客户端。

image.png

整个过程我们需要了解三个问题:

  • net/http 是如何监听端口的?
  • net/http 是如何接收客户端请求的?
  • net/http 是如何分配 handler 的?

查看源码,点击 main.go 文件中 http.ListenAndServe(":9000", nil)ListenAndServe 函数,来到源码,再次点击 3222 行的 ListenAndServe

image.png

再次点击 2968 行的 Serve 函数:

image.png

image.png

Serve(l net.Listener) 函数就是处理接收客户端的请求信息。该函数中的 for 循环首先通过 net.Listener 接收请求 rw, err := l.Accept()for 循环之后又创建了一个 Conn,最后单独开了一个 goroutine go c.serve(connCtx);用户的每一次请求都是在一个单独的 goroutine 中执行的,不会相互影响。

点击 go c.serve(connCtx) 中的 serve(connCtx) 方法,在该方法中的第 1891 行通过 c.readRequest(ctx) 来解析请求:

image.png

然后在第 1966 行,根据请求解析结果通过 serverHandler{c.server}.ServeHTTP(w, w.req) 分配了一个 handler

image.png

点击查看 ServeHTTP 源码:

image.png

这里获取了一个 handler,调用 ListenAndServe 函数的时候传递的参数为 nil,因此这里默认分配了一个 DefaultServeMux 作为 handler。其实 DefaultServeMux 就是一个路由器,它用来匹配 URL 跳转到其响应的 handler 函数。

上述代码中 http.HandleFunc("/", sayHelloName) 就已经定义了路由规则,当请求为 / 时,路由就会转到 sayHelloName 方法,DefaultServeMux 就会调用 ServeHTTP 方法,则这个方法内部其实就是调用 sayHelloName 方法,然后将返回结果写入到 response 中,最后返回给客户端。

整个处理流程如下:

image.png


相关文章
|
5月前
|
Go 开发者
Go语言包的组织与导入 -《Go语言实战指南》
本章详细介绍了Go语言中的包(Package)概念及其使用方法。包是实现代码模块化、复用性和可维护性的核心单位,内容涵盖包的基本定义、命名规则、组织结构以及导入方式。通过示例说明了如何创建和调用包,并深入讲解了`go.mod`文件对包路径的管理。此外,还提供了多种导入技巧,如别名导入、匿名导入等,帮助开发者优化代码结构与可读性。最后以表格形式总结了关键点,便于快速回顾和应用。
265 61
|
1月前
|
Java 编译器 Go
【Golang】(1)Go的运行流程步骤与包的概念
初次上手Go语言!先来了解它的运行流程吧! 在Go中对包的概念又有怎样不同的见解呢?
129 4
|
4月前
|
JSON 中间件 Go
Go语言实战指南 —— Go中的反射机制:reflect 包使用
Go语言中的反射机制通过`reflect`包实现,允许程序在运行时动态检查变量类型、获取或设置值、调用方法等。它适用于初中级开发者深入理解Go的动态能力,帮助构建通用工具、中间件和ORM系统等。
300 63
|
4月前
|
人工智能 负载均衡 监控
使用 Go 和 Gin 实现高可用负载均衡代理服务器
本文基于Go语言和Gin框架,实现了一个企业级负载均衡代理服务器,支持动态路由、健康检查、会话保持等功能。具备高可用性与高性能,单节点支持100k+ QPS,延迟达亚毫秒级,并提供完整的压力测试方案与优化建议。
157 7
|
3月前
|
缓存 监控 安全
告别缓存击穿!Go 语言中的防并发神器:singleflight 包深度解析
在高并发场景中,多个请求同时访问同一资源易导致缓存击穿、数据库压力过大。Go 语言提供的 `singleflight` 包可将相同 key 的请求合并,仅执行一次实际操作,其余请求共享结果,有效降低系统负载。本文详解其原理、实现及典型应用场景,并附示例代码,助你掌握高并发优化技巧。
295 0
|
4月前
|
JSON 前端开发 Go
Go语言实战:创建一个简单的 HTTP 服务器
本篇是《Go语言101实战》系列之一,讲解如何使用Go构建基础HTTP服务器。涵盖Go语言并发优势、HTTP服务搭建、路由处理、日志记录及测试方法,助你掌握高性能Web服务开发核心技能。
|
4月前
|
Go
如何在Go语言的HTTP请求中设置使用代理服务器
当使用特定的代理时,在某些情况下可能需要认证信息,认证信息可以在代理URL中提供,格式通常是:
385 0
|
6月前
|
Go 持续交付 开发者
Go语言包与模块(module)的基本使用-《Go语言实战指南》
本章深入讲解Go语言中的包(Package)和模块(Module)概念。包是代码组织的最小单位,每个`.go`文件属于一个包,通过`import`实现复用;主程序包需命名为`main`。模块是Go 1.11引入的依赖管理机制,支持自动版本管理和私有/远程仓库,无需依赖GOPATH。通过实际示例,如自定义包`mathutil`和第三方模块`gin`的引入,展示其使用方法。常用命令包括`go mod init`、`go mod tidy`等,帮助开发者高效管理项目依赖。最后总结,包负责功能划分,模块实现现代化依赖管理,提升团队协作效率。
280 15
|
1月前
|
弹性计算 运维 安全
阿里云轻量应用服务器与云服务器ECS啥区别?新手帮助教程
阿里云轻量应用服务器适合个人开发者搭建博客、测试环境等低流量场景,操作简单、成本低;ECS适用于企业级高负载业务,功能强大、灵活可扩展。二者在性能、网络、镜像及运维管理上差异显著,用户应根据实际需求选择。
216 10
|
1月前
|
运维 安全 Ubuntu
阿里云渠道商:服务器操作系统怎么选?
阿里云提供丰富操作系统镜像,涵盖Windows与主流Linux发行版。选型需综合技术兼容性、运维成本、安全稳定等因素。推荐Alibaba Cloud Linux、Ubuntu等用于Web与容器场景,Windows Server支撑.NET应用。建议优先选用LTS版本并进行测试验证,通过标准化镜像管理提升部署效率与一致性。
下一篇
oss云网关配置