cache教程 3.HTTP服务器

上一节我们实现了单机版的缓存服务,但是我们的目标是分布式缓存。那么,我们就需要把缓存服务部署到多态机器节点上,对外提供访问接口。客户端就可以通过这些接口去实现缓存的增删改查。

分布式缓存需要实现节点间通信,而通信方法常见的有HTTP和RPC。建立基于 HTTP 的通信机制是比较常见和简单的做法。

所以,我们基于 Go 语言标准库 http 搭建 HTTP Server。

net/http标准库

简单实现一个http服务端例子。

type server intfunc (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {w.Write([]byte("Hello World!"))
}func main() {var s serverhttp.ListenAndServe("localhost:9999", &s)
}//下面的是http源码
type Handler interface {ServeHTTP(w ResponseWriter, r *Request)
}

在该代码中,创建任意类型 server,并实现 ServeHTTP 方法。

http.ListenAndServe 接收 2 个参数,第一个参数是服务启动的地址,第二个参数是 Handler,实现了 ServeHTTP 方法的对象都可以作为 HTTP 的 Handler。

Cache HTTP 服务端

我们需要创建一个结构体去实现Handler接口,而该结构体应该是有些属性变量来支撑我们做一些事情的。

  • HTTPPool 有 2 个参数,一个是 addr,用来记录自己的地址,包括主机名/IP 和端口。
  • 另一个是 basePath,作为节点间通讯地址的前缀,默认是 /geecache/。比如http://example.com/geecache/开头的请求,就用于节点间的访问。因为一个主机上还可能承载其他的服务,加一段 Path 是一个好习惯。比如,大部分网站的 API 接口,一般以 /api 作为前缀。

HTTPPool实现了ServeHTTP方法,即是Handler接口。 

const defaultBasePath = "/geecache/"type HTTPPool struct {addr     string    //本地IP端口, 比如:"localhost:10000"basePath string
}func (pool *HTTPPool) ServeHTTP(w http.ResponseWriter, r *http.Request) {//处理请求和响应,后面会实现的
}//创建HTTPPool方法
func NewHTTPPool(addr string, basePath string) *HTTPPool {return &HTTPPool{addr:     addr,basePath: basePath,}
}

接下来实现最为核心的ServeHTTP方法。

func (pool *HTTPPool) ServeHTTP(w http.ResponseWriter, r *http.Request) {if !strings.HasPrefix(r.URL.Path, pool.basePath) {panic("HTTPPool serving unexpected path: " + r.URL.Path)}parts := strings.SplitN(r.URL.Path[len(pool.basePath):], "/", 2)if len(parts) != 2 {http.Error(w, "bad request", http.StatusBadRequest)return}groupName := parts[0]group := GetGroup(groupName)if group == nil {http.Error(w, "no such group: "+groupName, http.StatusNotFound)return}view, err := group.Get(parts[1])if err != nil {http.Error(w, err.Error(), http.StatusInternalServerError)return}w.Header().Set("Content-Type", "application/octet-stream")w.Write(view.ByteSlice())
}

该方法是先判断前缀是否相等,若不相等,返回错误,之后再判断分组名字,再判断key。

url.Path的格式是/<basepath>/<groupname>/<key>。举个例子,r.URL.Path是/geecache/scores/tom,那r.URL.Path[len(pool.basePath):]即是scores/tom,接着就是使用strings.SplitN函数进行分割来获取分组名字和key。

测试

// 缓存中没有的话,就从该db中查找
var db = map[string]string{"tom":  "100","jack": "200","sam":  "444",
}func main() {//传函数入参cache.NewGroup("scores", 2<<10, cache.GetterFunc(funcCbGet))//传结构体入参,也可以// cbGet := &search{}// cache.NewGroup("scores", 2<<10, cbGet)addr := "localhost:10000"peers := cache.NewHTTPPool(addr, cache.DefaultBasePath)log.Fatal(http.ListenAndServe(addr, peers))
}// 函数的
func funcCbGet(key string) ([]byte, error) {fmt.Println("callback search key: ", key)if v, ok := db[key]; ok {return []byte(v), nil}return nil, fmt.Errorf("%s not exit", key)
}// 结构体,实现了Getter接口的Get方法,
type search struct {
}func (s *search) Get(key string) ([]byte, error) {fmt.Println("struct callback search key: ", key)if v, ok := db[key]; ok {return []byte(v), nil}return nil, fmt.Errorf("%s not exit", key)
}

执行 go run main.go,查看效果

完整代码:https://github.com/liwook/Go-projects/tree/main/go-cache/3-httpServer

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/211322.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【面试经典150 | 二叉树】翻转二叉树

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;递归方法二&#xff1a;迭代 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题…

4-SpringMVC

文章目录 项目源码地址回顾-MVC什么是MVC&#xff1f;MVC各部分组成 回顾-ServletMaven创建Web项目1、创建Maven父工程pom&#xff0c;并导入依赖2、用Maven新建一个Web Module3、代码&#xff1a;HelloServlet.java3、代码-hello.jsp3、代码-web.xml4、配置Tomcat5、浏览器测试…

github使用方法【附安装包】

如果你是一枚Coder&#xff0c;但是你不知道Github&#xff0c;那么我觉的你就不是一个菜鸟级别的Coder&#xff0c;因为你压根不是真正Coder&#xff0c;你只是一个Code搬运工。说明你根本不善于突破自己&#xff01;为什么这么说原因很简单&#xff0c;很多优秀的代码以及各种…

高级系统架构设计师之路

前言&#xff1a;系 统 架 构 设 计 师 (System Architecture Designer)是项目开发活动中的众多角色之 一 &#xff0c;它可 以是 一个人或 一个小组&#xff0c;也可以是一个团队。架构师 (Architect) 包含建筑师、设计师、创造 者、缔造者等含义&#xff0c;可以说&#xff0…

边缘计算系统设计与实践:引领科技创新的新浪潮

文章目录 一、边缘计算的概念二、边缘计算的设计原则三、边缘计算的关键技术四、边缘计算的实践应用《边缘计算系统设计与实践》特色内容简介作者简介目录前言/序言本书读者对象获取方式 随着物联网、大数据和人工智能等技术的快速发展&#xff0c;传统的中心化计算模式已经无法…

基于ssm人力资源管理系统论文

摘 要 随着企业员工人数的不断增多&#xff0c;企业在人力资源管理方面负担越来越重&#xff0c;因此&#xff0c;为提高企业人力资源管理效率&#xff0c;特开发了本人力资源管理系统。 本文重点阐述了人力资源管理系统的开发过程&#xff0c;以实际运用为开发背景&#xff0…

【大数据】Hudi 核心知识点详解(一)

Hudi 核心知识点详解&#xff08;一&#xff09; 1.数据湖与数据仓库的区别 &#xff1f;1.1 数据仓库1.2 数据湖1.3 两者的区别 2.Hudi 基础功能2.1 Hudi 简介2.2 Hudi 功能2.3 Hudi 的特性2.4 Hudi 的架构2.5 湖仓一体架构 3.Hudi 数据管理3.1 Hudi 表数据结构3.1.1 .hoodie …

【C语言】位运算实现二进制数据处理及BCD码转换

文章目录 1&#xff0e;编程实验&#xff1a;按short和unsigned short类型分别对-12345进行左移2位和右移2位操作&#xff0c;并输出结果。2&#xff0e;编程实验&#xff1a;利用位运算实现BCD码与十进制数之间的转换&#xff0c;假设数据类型为unsigned char。3&#xff0e;编…

FPGA | Verilog基础语法

这里写自定义目录标题 Case语句系统任务$dumpfile | 为所要创建的VCD文件指定文件名。$dumpvar | 指定需要记录到VCD文件中的信号$fscanf$fread菜鸟教程连接 Case语句 case(case_expr)condition1 : true_statement1 ;condition2 : true_stat…

多线程(进阶二:CAS)

目录 一、CAS的简单介绍 CAS逻辑&#xff08;用伪代码来描述&#xff09; 二、CAS在多线程中简单的使用 三、原子类自增的代码分析 都看到这了&#xff0c;点个赞再走吧&#xff0c;谢谢谢谢谢 一、CAS的简单介绍 CAS的全称&#xff1a;“Compare And Swap”&#xff0c;字…

C语言——字符函数和字符串函数(一)

&#x1f4dd;前言&#xff1a; 这篇文章对我最近学习的有关字符串的函数做一个总结和整理&#xff0c;主要讲解字符函数和字符串函数&#xff08;strlen&#xff0c;strcpy和strncpy&#xff0c;strcat和strncat&#xff09;的使用方法&#xff0c;使用场景和一些注意事项&…

python常见库的汇总

python常见库 一、爬虫二、界面开发三、图片处理四、视频处理、视频剪辑五、音频处理六、数据处理七、数据库八、网页开发九、神经学习、AI开发十、打包十一、Excel处理十二、微信十三、控制鼠标键盘十四、手柄十五、控制外设十六、邮箱十七、短信 一、爬虫 Requests&#xff…

Java入门项目--蚂蚁爱购

简介 这是一个靠谱的Java入门项目实战&#xff0c;名字叫蚂蚁爱购。 从零开发项目&#xff0c;视频加文档&#xff0c;十天就能学会开发JavaWeb项目&#xff0c;教程路线是&#xff1a;搭建环境> 安装软件> 创建项目> 添加依赖和配置> 通过表生成代码> 编写Ja…

解锁MySQL的威力:针对常见问题的快速解决指南

数据库和表的创建 创建数据库&#xff1a; CREATE DATABASE IF NOT EXISTS MyDatabase; USE MyDatabase;案例&#xff1a; 想象您要开始一个博客项目。首先&#xff0c;您需要一个地方来存储所有的文章和用户信息。上述命令帮助您创建了这样一个存储空间&#xff0c;名为MyDa…

Tomcat使用https方式连接

Tomcat使用https方式连接 拢共分两步&#xff0c;第一步&#xff1a;生成密钥。第二步&#xff1a;修改配置。 第一步&#xff1a;生成密钥。 keytool -genkey -v -alias tomcat -keyalg RSA -validity 365 -keystore /usr/tomcat-8.5/conf/tomcat.keystore第二步&#xff1…

RocketMQ-源码架构二

梳理一些比较完整&#xff0c;比较复杂的业务线 消息持久化设计 RocketMQ的持久化文件结构 消息持久化也就是将内存中的消息写入到本地磁盘的过程。而磁盘IO操作通常是一个很耗性能&#xff0c;很慢的操作&#xff0c;所以&#xff0c;对消息持久化机制的设计&#xff0c;是…

华为机试真题 C++ 实现【字符串重新排列】

题目 给定一个字符串s&#xff0c;s包括以空格分隔的若干个单词&#xff0c;请对s进行如下处理后输出&#xff1a; 1、单词内部调整&#xff1a;对每个单词字母重新按字典序排序 2、单词间顺序调整&#xff1a; 1&#xff09;统计每个单词出现的次数&#xff0c;并按次数降序…

蒙特霍尔问题(选择三扇门后的车与羊)及其贝叶斯定理数学解释

1. 蒙特霍尔问题 有一个美国电视游戏节目叫做“Let’s Make a Deal”&#xff0c;游戏中参赛者将面对3扇关闭的门&#xff0c;其中一扇门背后有一辆汽车&#xff0c;另外两扇门后是山羊&#xff0c;参赛者如果能猜中哪一扇门后是汽车&#xff0c;就可以得到它。 通常&#xf…

笔记68:Pytorch中repeat函数的用法

repeat 相当于一个broadcasting的机制 repeat(*sizes) 沿着指定的维度重复tensor。不同与expand()&#xff0c;本函数复制的是tensor中的数据。 import torch import torch.nn.functional as F import numpy as np a torch.Tensor(128,1,512) B a.repeat(1,5,1) print(B.s…

OpenGL 着色器程序的保存和加载(二进制)

背景 为了提高OpenGL 着色器程序的编译和链接速度&#xff0c;我们可以将程序保存为二进制进行加载&#xff0c;可以大幅度提升加载效率。 方法 以下是加载和保存二进制程序的方法。 // 加载着色器程序的二进制文件到已创建的着色器程序中 bool loadPragram(const std::str…