手撕分布式缓存---HTTP Server搭建
经过了前两个章节的学习,分布式缓存的存储与新增我们已经实现了,并且对其做了高可用处理。本章节我们剥离和缓存强相关的逻辑,开始搭建一个HTTP服务器,毕竟缓存数据库搭建完之后别人没法访问也是没有用处的。这一章节我们重点学习go原生的HTTP标准库。
前文链接
手撕分布式缓存之一 | 定义缓存结构体与实现底层功能函数
手撕分布式缓存之二 | 互斥锁的优化
系列目录
- (1)HTTP Server 的搭建
- (1.1)前言
- (1.2)HTTP 核心数据结构的构造及初始化函数的实现
- (1.3)单节点HTTP Server核心Get方法的实现
- (1.4)代码实现及解释
(1)HTTP Server 的搭建
(1.1)前言
通过本篇文章可以学习到 go 语言原生的 HTTP Server 的使用,虽然不像成熟的Web框架那样,方法、机制都很完全,但是通过学习底层的功能实现,对于我们整体项目结构搭建是非常重要的。如果将go语言、go衍生技术(gin,MiddleWare等)等一系列相关的技术看做一整个项目结构,那么哪些技术我们要实现哪些功能呢?这些功能做出来实际上使用的人有多少呢?能给我们带来多少价值?这些问题具象来看的话是与我们开发人员息息相关的,因此我们有必要去学习这种看似吃力不讨好实际却会给我们带来很深远的收益的知识。
(1.2)HTTP 核心数据结构的构造及初始化函数的实现
go语言的HTTP服务为我们提供了 ListenAndServe(addr string, handler Handler) error 这个方法,handler是HTTP服务的主体处理函数,任何实现了 ServeHTTP 方法的对象都可以作为handler的值传递给ListenAndServe 方法。该方法除了handler参数还需要接收一个addr,用来标识服务启动的地址和端口,这个也是服务启动之后其他请求者访问的域名。因此我们可以定义一个数据结构HTTPPool,里面有属性 self string 和 basePath string,self是就是上面说的addr,basePath是用于区分服务器上其他服务的请求Url,避免重复,比如我们可以默认 /_geecache/ 作为我们请求URI(统一资源标识符)第一级的值。
(1.3)单节点HTTP Server核心Get方法的实现
在1.2小节我们解释了HTTP的核心数据结构,这一小节我们讨论下HTTP服务的核心服务ServeHTTP。在前言中我们概括性的讨论了go的HTTP原生包(下称HTTP原生包)与成熟框架是有区别的,从相关的代码中(gin和geeCache的相关实现中)了解到,HTTP原生包对于方法的直接操作只有ServeHTTP方法,也就是说如果只使用HTTP原生包构建HTTP Server,所有的请求都是由 ServeHTTP 方法首先处理的,而例如Gin框架,可以将方法绑定在URI上,在路由注册之后,可以通过URI访问与其绑定的功能方法;从HTTP原生包来看,我能想到的实现Gin这一功能的方法是,在ServeHTTP方法中通过判断请求的URI的值与if语句过滤来实现不同的URI访问不同的功能函数。
HTTP Get方法的实现并不复杂,主要流程还是调用下层我们封装的Get方法(如何封装的可以阅读 分布式系列 的前两章内容)。
(1.4)代码实现及解释
自定义默认的URI第一级的值 和 定义HTTP的核心数据结构
- 自定义URI的第一级的值为 _geecache ,使用下划线开头的值用作区分重复的可能性更低,因此我们使用下划线开头。
// this is the defaultPath, user it to distinguish geeCache Project and other Project.
const defaultBasePath = "/_geecache/"type HTTPPool struct {// this peer's base URL, e.g. self is "https://example.net:8000"self stringbasePath string
}// NewHTTPPool initializes an HTTP pool of peers.
func NewHTTPPool(self string) *HTTPPool {return &HTTPPool{self: self,basePath: defaultBasePath,}
}
核心功能Get函数的实现
- 在通过URI获取GroupName之前,首先判断URI的第一级值是否与defaultPath一致
- 通过strings.SplitN根据 字符 \ 进行截取,并获得groupName 和 key
- 调用下层已经实现的函数功能,以从中获取key对应的value
- 使用 w.Write(view.ByteSlice()),返回给 请求者一个 copy的对象,避免返回给请求者原对象后遭到恶意修改吗,view.ByteSlice() 的具体实现在上一章节有具体说明和实现 。
// ServeHTTP handle all http requests
func (p *HTTPPool) ServeHTTP(w http.ResponseWriter, r *http.Request) {// 1. judge the first layer of uri is defaultBasePath.if !strings.HasPrefix(r.URL.Path, p.basePath) {panic("HTTPPool serving unexpected path: " + r.URL.Path)}// begin from the defaultPath, then start to split the rest of uri and get groupName from this operationparts := strings.SplitN(r.URL.Path[len(p.basePath):], "/", 2)// 2. judge the structure have two layers, first is groupName, second is key// the structure is /<basepath>/<groupname>/<key>if len(parts) != 2 {http.Error(w, "bad request", http.StatusBadRequest)return}// 3. get GroupName and keygroupName := parts[0]key := parts[1]// 4. call Underlying interface to get Groupgroup := GetGroup(groupName)if group == nil {http.Error(w, "no such group: "+groupName, http.StatusNotFound)return}// 5. call Underlying interface to get key-valueview, err := group.Get(key)if err != nil {http.Error(w, err.Error(), http.StatusInternalServerError)return}w.Header().Set("Content-Type", "application/octet-stream")// return key-valuew.Write(view.ByteSlice())
}
HTTP Server 服务的启动(main函数的编写),参数的声明
- db 用于验证GetterFunc方法是否生效。
- 2<<10是二进制左移10位,对应的十进制为4096。
- http.ListenAndServe 是服务的启动代码。
// not necessary, just is a test demo in here
var db = map[string]string{"Tom": "630","Jack": "589","Sam": "567",
}func main() {// 2<<10 means Binary Left Shift 10 bits, its value is 2048// GetterFunc can ignore the data's addition, cause it initialize the group scores, and state the maxBytesgeecache.NewGroup("scores", 2<<10, geecache.GetterFunc(func(key string) ([]byte, error) {log.Println("[SlowDB] search key", key)if v, ok := db[key]; ok {return []byte(v), nil}return nil, fmt.Errorf("%s not exist", key)}))addr := "localhost:9999"peers := geecache.NewHTTPPool(addr)log.Println("geecache is running at", addr)// log the ListenAndServe's errorlog.Fatal(http.ListenAndServe(addr, peers))
}
相关文章:
手撕分布式缓存---HTTP Server搭建
经过了前两个章节的学习,分布式缓存的存储与新增我们已经实现了,并且对其做了高可用处理。本章节我们剥离和缓存强相关的逻辑,开始搭建一个HTTP服务器,毕竟缓存数据库搭建完之后别人没法访问也是没有用处的。这一章节我们重点学习…...

2. PyTorch——Tensor和Numpy
2.1Tensor和Numpy Tensor和Numpy数组之间具有很高的相似性,彼此之间的互操作也非常简单高效。需要注意的是,Numpy和Tensor共享内存。由于Numpy历史悠久,支持丰富的操作,所以当遇到Tensor不支持的操作时,可先转成Numpy…...
C#随笔 | List.Sort()使用小计
1、使用List.Sort()对基本数值类型数据进行排序 案例:对存放int数据的List进行排序 其实C#中的List的Sort函数中的比较函数CompareTo有三种结果 1, -1 ,0分别代表大,小,相等。默认List的排序是升序排序。 举个例子:在比较函数Co…...

【WebRTC】用WebRTC做即时视频聊天应用
【配套项目源码】 打开即用,设置一个免费的Agora账户就可以实现视频电话。非常好的WebRTC学习和应用项目。 用VSCode打开即可。 https://download.csdn.net/download/weixin_41697242/88630069 【什么是WebRTC?】 WebRTC是一套基于JS的API,能够建立端对端的直接通信,实…...

GPT-4.5 要来了!谷歌大模型 Gemini 确实给够压力
GPT-4 还没用明白,GPT-4.5 就要发布了。 最近,OpenAI 泄露了 GPT-4.5 的发布页面,除了进一步增强复杂推理和跨模态理解,GPT-4.5 增加了一个更加强大的功能——3D。 3D 功能的进一步支持,也就意味着多模态最后一块版图…...

美易官方:加密资产将破坏金融稳定,无法取消就要加强监管
在近日的一次公开演讲中,国际货币基金组织(IMF)总裁格奥尔基耶娃表示,如果世界各国大量采用加密资产,将会对金融稳定造成破坏,并且无法取消这种破坏,因此需要加强对加密资产的监管。我们的目标是…...

一文读懂Java中的设计模式——适配器模式,对于兼容不同系统特别适用!
适配器模式概念 适配器(变压器)模式:这种模式的核心是当你想实现一个接口但又不想实现所有接口方法,只想去实现一部分方法时,就用默认的适配器模式,他的方法是在接口和具体实现类中添加一个抽象类…...

2023年国内外评分前十的项目管理软件推荐
1、进度猫 作为国产项目进度管理软件新秀,是一款以甘特图为向导的轻量级可视化在线项目管理工具 通过甘特图/思维导图为核心进行项目管理计划,使项目经理能够计划、可视化目标和里程碑、设置任务和到期日期。 甘特图进行有序的项目规划,及…...

3.electron之vue3.0的桌面应用程序
如果可以实现记得点赞分享,谢谢老铁~ Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 Electron 将 Chromium 和 Node.js 嵌入到了一个二进制文件中,因此它允许你仅需一个代码仓库,就可以撰写支持 Windows、…...
数字图像处理(实践篇)二十二 使用opencv进行人脸、眼睛、嘴的检测
目录 1 xml文件 2 涉及的函数 3 实践 使用opencv进行人脸、眼睛、嘴的检测。 1 xml文件 方法① 下载 地址:https://github.com/opencv/opencv/tree/master/data/haarcascades 点击haarcascade_frontalface_default.xml文件 对着Raw右键,选择“链接另存为”,选择代码所…...

旺店通·企业奇门对接打通金蝶云星空查询仓库接口与仓库新增接口
旺店通企业奇门对接打通金蝶云星空查询仓库接口与仓库新增接口 接通系统:旺店通企业奇门 旺店通是北京掌上先机网络科技有限公司旗下品牌,国内的零售云服务提供商,基于云计算SaaS服务模式,以体系化解决方案,助力零售企…...
PostgreSQL获取以前的时间
要在 PostgreSQL 中获取前10秒的数据,可以使用以下查询语句: SELECT * FROM your_table WHERE timestamp_column > now() - interval 10 seconds;要获取前 10 分钟的数据,可以使用以下查询语句: SELECT * FROM your_tabl…...

逆向获取某音乐软件的加密(js逆向)
本文仅用于技术交流,不得以危害或者是侵犯他人利益为目的使用文中介绍的代码模块,若有侵权请联系作者更改。 老套路,打开开发者工具,直接开始找到需要的数据位置,然后观察参数,请求头,cookie是…...

C语言—每日选择题—Day42
第一题 1. 下面程序输出的结果是() #include <stdio.h> int main () {int x;x printf("I See, Sea in C");printf("x%d" , x); } A:2 B:随机值 C:都不是 D:15 答案及解析 D p…...

jsp文件引用的css修改后刷新不生效问题
问题 在对 JavaWeb 项目修改的过程中,发现修改了 jsp 文件引入的 css 文件的代码后页面的样式没有更新的问题。 原因 导致这个问题的原因可能是因为浏览器缓存的问题。 解决方法 下面介绍两种解决方法,供大家参考: 1、给 link 标签的 c…...

SpringBoot运维中的高级配置
🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 ps:点赞👍是免费的,却可以让写博客的作者开心好久好久😎 📚系列专栏:Java全栈,…...
Centos7下OpenLDAP安装
openldap server 安装配置 openldap server 安装 # yum 安装相关包 $ sudo yum -y install openldap openldap-servers openldap-devel compat-openldap openldap-clients# 复制一个默认配置到指定目录下,并授权,这一步一定要做,然后再启动服务,不然生产密码时会报错 # Op…...

2036开关门,1109开关门
一:2036开关门 1.1题目 1.2思路 1.每次都是房间号是服务员的倍数的时候做处理,所以外层(i)枚举服务员1~n,内层(j)枚举房间号1~n,当j % i0时,做处理 2.这个处理指的是&…...

最简单的pixel刷机和安装面具、lsposed
一 下载手机对应的系统 1,手机usb连接然后重启进入Fastboot模式:adb reboot bootloader2,找到你下载的系统,Windows 系统 直接运行 flash-all.bat上图 :左边就是安卓11和12的系统,右边是对应的手机型号 下…...

深度学习第5天:GAN生成对抗网络
☁️主页 Nowl 🔥专栏 《深度学习》 📑君子坐而论道,少年起而行之 文章目录 一、GAN1.基本思想2.用途3.模型架构 二、具体任务与代码1.任务介绍2.导入库函数3.生成器与判别器4.预处理5.模型训练6.图片生成7.不同训练轮次的结果对比 一…...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...