惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
Simon Willison's Weblog
Simon Willison's Weblog
Microsoft Security Blog
Microsoft Security Blog
Y
Y Combinator Blog
The GitHub Blog
The GitHub Blog
Engineering at Meta
Engineering at Meta
F
Fortinet All Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
A
About on SuperTechFans
Last Week in AI
Last Week in AI
月光博客
月光博客
有赞技术团队
有赞技术团队
P
Proofpoint News Feed
MyScale Blog
MyScale Blog
Martin Fowler
Martin Fowler
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
Check Point Blog
U
Unit 42
The Register - Security
The Register - Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Hugging Face - Blog
Hugging Face - Blog
阮一峰的网络日志
阮一峰的网络日志
V
Visual Studio Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
D
DataBreaches.Net
WordPress大学
WordPress大学
aimingoo的专栏
aimingoo的专栏
H
Hacker News: Front Page
Recent Announcements
Recent Announcements
C
CXSECURITY Database RSS Feed - CXSecurity.com
Latest news
Latest news
小众软件
小众软件
P
Palo Alto Networks Blog
PCI Perspectives
PCI Perspectives
Security Latest
Security Latest
S
Secure Thoughts
Scott Helme
Scott Helme
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threat Research - Cisco Blogs
P
Proofpoint News Feed
M
MIT News - Artificial intelligence
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google DeepMind News
Google DeepMind News
Recorded Future
Recorded Future
O
OpenAI News
S
Securelist
云风的 BLOG
云风的 BLOG
H
Help Net Security
T
Troy Hunt's Blog

蛮荆

如何获取更多的免费服务器 Kubernetes 调度器队列 - 设计与实现 Kubernetes 调度器 - 核心流程 Kubernetes Networking Model & CNI Kubernetes 控制器管理总结 Kubernetes CronJob 设计与实现 Kubernetes Job 设计与实现 Kubernetes HPA 设计与实现 Kubernetes Deployment 滚动更新实现原理 Kubernetes GC 设计与实现 Kubernetes Pod 驱逐 - 设计与实现 Kubernetes Daemonset 设计与实现 Kubernetes ReplicaSet 设计与实现 Kubernetes EndPoint 设计与实现 Kubernetes Informer 设计与实现 降本增效之应用优化 (三) 日志存储与检索 Kubernetes Pod 设计与实现 - 创建流程 Kubernetes 探针设计与实现 Unix 编程艺术名句摘录 Kubernetes - CRI 概述 Golang 编译速度为什么这么快? Kubernetes Pod 设计与实现 - Pause 容器 Kubernetes - kube-proxy 代理模式工程优化 Kubernetes 应用最佳实践 - 优雅关闭长连接 Kubernetes Service 类型和会话亲和性 Kubernetes 为什么需要 Ingress Kubernetes 架构 - 控制平面和数据平面 降本增效之应用优化 (二) 大报表 Go 语言如何获取 CPU 利用率 降本增效之应用优化 (一) Redis 业务规则引擎演变过程简述 微服务中的熔断算法 漏桶算法和令牌桶算法 jsonparser 为什么比标准库的 encoding/json 快 10 倍 ? zap 高性能设计与实现 HTTP Router 算法演进 fastcache 高性能设计与实现 Web 常见的三个安全问题 ants Code Reading Go 线程安全 map 方案选型 布隆过滤器 死锁、活锁、饥饿、自旋锁 sync.Pool Code Reading Go 内存管理概述 Go netpoll Code Reading goroutine 泄漏与检测 time/Timer Code Reading GMP Scheduler Code Reading Go channel 的 15 条规则和底层实现 为什么 Linux “一切皆文件” context.Context Code Reading runtime/HACKING.md Goland 最佳实践 互联网开发与金庸武学 为什么 Redis 6.0 引入多线程模型? Kubernetes 应用最佳实践 - 金丝雀发布 容器中如何正确配置 GOMAXPROCS ? singleflight Code Reading sync.Map Code Reading sync.Cond Code Reading sync.WaitGroup Code Reading sync.RWMutex Code Reading sync.Mutex Code Reading sync.Once Code Reading Go 无锁编程 sync/atomic Code Reading goroutine 交替打印奇偶数 GODEBUG Go 并发模式 Go 汇编 UUID 通用技术选型 Kubernetes 应用最佳实践 - 水平自动伸缩 Go 高性能 Tips fasthttp 为什么比标准库 net/http 快 10 倍 ? 技术文章配图指南 ChatGPT 初体验 Docker 网络原理概览 iptables 的五表五链 Kubernetes 应用最佳实践 - 亲和性和污点容忍度 Go 的反射与三大定律 Docker 官方提供的最佳实践 Go 语言内置的设计模式 HTTP1 到 HTTP3 的工程优化 Kubernetes 应用最佳实践 - Sidecar 模式 Kubernetes 应用最佳实践 - init 容器和钩子函数 为什么 recover 必须在 defer 中调用? 为什么 defer 的执行顺序和注册顺序不同? Go map 设计与实现 Go 切片扩容底层实现 Go 语言中的零拷贝 Go Delve 云原生和边缘计算简介 Kubernetes Pod 服务质量等级 Kubernetes 应用最佳实践 - 探针 Kubernetes 应用最佳实践 - 资源请求和限制 CDN 原理 Kubernetes 应用最佳实践 - 开篇 缓存策略和模式 Go 内存模型 Kubernetes 核心概念
计算机网络中的设计模式
2022-07-25 · via 蛮荆

计算机网络中的设计模式

2022-07-25 计算机网络 设计模式

代理模式

代理模式可以在不改变客户端代码的情况下,通过代理对象来控制对实际对象的访问。

网络中最高频出现的设计模式之一,在传输层之上的应用层使用非常广泛。

  • HTTP 代理
  • DNS 代理
  • 防火墙

伪代码

// 代理处理器伪代码实现
func proxyHandler(w http.ResponseWriter, r *http.Request) {
    // 解析目标服务器 URL
    target, err := url.Parse("https://dbwu.tech/")

    ...

    // 将客户端的请求转发给目标服务器
    proxyReq, err := http.NewRequest(r.Method, ...)

    ...

    // 发送请求到目标服务器
    client := &http.Client{}
    resp, err := client.Do(proxyReq)

    ...

    // 复制目标服务器的响应头
    for key, values := range resp.Header {
        for _, value := range values {
            w.Header().Add(key, value)
        }
    }

    // 设置响应状态码
    w.WriteHeader(resp.StatusCode)

    // 将目标服务器的响应内容复制到客户端响应
    io.Copy(w, resp.Body)
}

func main() {
    // 将代理处理器注册到根路径
    http.HandleFunc("/", proxyHandler)

    // 启动 HTTP 服务器
    log.Fatal(http.ListenAndServe(":8080", nil))
}

装饰者模式

最经典的就是发送方从应用层到物理层的各类协议头部格式,层层包装,接收方从物理层到应用层,反过来,层层解包装。

伪代码

采用 Golang Functional Options 风格来实现。

package main

// 所有协议和装饰器都要实现这个 Packet 接口
type Packet interface {
	GetContent() string
}

// PacketDecorator 装饰器
type PacketDecorator struct {
	packet Packet
	header string
}

func (d *PacketDecorator) GetContent() string {
	return d.header + d.packet.GetContent()
}

// Option 设置 PacketDecorator 的属性
// Functional Options 模式
type Option func(*PacketDecorator)

// WithHeader 负责装饰,也就是各类协议的头部格式包装
func WithHeader(header string) Option {
	return func(d *PacketDecorator) {
		d.header = header
	}
}

// ApplicationLayer 应用层
type ApplicationLayer struct {
	data string
}

func (a *ApplicationLayer) GetContent() string {
	return a.data
}

// TransportLayer 传输层装饰器
func TransportLayer(packet Packet, opts ...Option) Packet {
	decorator := &PacketDecorator{packet: packet}
	for _, opt := range opts {
		opt(decorator)
	}
	return decorator
}

// NetworkLayer 网络层装饰器
func NetworkLayer(packet Packet, opts ...Option) Packet {
	decorator := &PacketDecorator{packet: packet}
	for _, opt := range opts {
		opt(decorator)
	}
	return decorator
}

// DataLinkLayer 数据链路层装饰器
func DataLinkLayer(packet Packet, opts ...Option) Packet {
	decorator := &PacketDecorator{packet: packet}
	for _, opt := range opts {
		opt(decorator)
	}
	return decorator
}

// PhysicalLayer 物理层装饰器
func PhysicalLayer(packet Packet, opts ...Option) Packet {
	decorator := &PacketDecorator{packet: packet}
	for _, opt := range opts {
		opt(decorator)
	}
	return decorator
}

func main() {
	// 创建应用层的数据
	appData := &ApplicationLayer{data: "Hello, World!"}

	// 逐层包装
	transportPkt := TransportLayer(appData, WithHeader("[TCP Header]"))
	networkPkt := NetworkLayer(transportPkt, WithHeader("[IP Header]"))
	dataLinkPkt := DataLinkLayer(networkPkt, WithHeader("[Ethernet Header]"))
	physicalPkt := PhysicalLayer(dataLinkPkt, WithHeader("[Physical Layer Header]"))

	// 打印物理层数据
	println(physicalPkt.GetContent())
}

运行上面的代码,输出如下:

[Physical Layer Header][Ethernet Header][IP Header][TCP Header]Hello, World!

状态模式

典型的例子就是 TCP 协议的实现 (一个复杂的状态机),使用状态模式可以简单地模拟 TCP 的状态机的工作机制,每个状态都可以表示为一个类,并且每个类都有相应的状态转换逻辑。

伪代码

一个完整的 TCP 状态机实现比较复杂,这里以 TCP 三次握手来演示状态模式。

为了节省篇幅,这里只演示 SYN_SENT, SYN_RECEIVED, Established, Closed 4 种 TCP 连接状态。

package main

import (
	"fmt"
)

// TCPState 定义状态行为接口
type TCPState interface {
	Handle(context *TCPConnection)
	String() string
}

// TCPConnection 是状态机上下文
// 包含当前状态机器所处状态
type TCPConnection struct {
	state TCPState
}

func (c *TCPConnection) SetState(state TCPState) {
	c.state = state
}

func (c *TCPConnection) Handle() {
	c.state.Handle(c)
}

func (c *TCPConnection) String() string {
	return c.state.String()
}

// 下面是具体的状态转移和变化过程

// SYN_SENT 代表 TCP SYN_SENT 状态
type SYN_SENT struct{}

// SYN_RECEIVED 代表 TCP SYN_RECEIVED 状态
type SYN_RECEIVED struct{}

// Established 代表 TCP ESTABLISHED 状态
type Established struct{}

// Closed 表示 TCP 连接已关闭状态
type Closed struct{}

func (s *Closed) Handle(context *TCPConnection) {
	fmt.Println("Received SYN, transitioning to SYN_SENT")
	context.SetState(&SYN_SENT{})
}

func (s *Closed) String() string {
	return "CLOSED"
}

func (s *SYN_SENT) Handle(context *TCPConnection) {
	fmt.Println("Received SYN-ACK, transitioning to SYN_RECEIVED")
	context.SetState(&SYN_RECEIVED{})
}

func (s *SYN_SENT) String() string {
	return "SYN_SENT"
}

func (s *SYN_RECEIVED) Handle(context *TCPConnection) {
	fmt.Println("Received ACK, transitioning to ESTABLISHED")
	context.SetState(&Established{})
}

func (s *SYN_RECEIVED) String() string {
	return "SYN_RECEIVED"
}

func (s *Established) Handle(context *TCPConnection) {
	fmt.Println("Connection is already ESTABLISHED")
}

func (s *Established) String() string {
	return "ESTABLISHED"
}

func main() {
	// 默认情况下,连接处于关闭状态
	connection := &TCPConnection{state: &Closed{}}
	fmt.Println("Current State:", connection)
	fmt.Println("--------------------------")

	// 客户端发起建立连接请求,状态转移到 SYN_SENT
	connection.Handle()
	fmt.Println("Current State:", connection)
	fmt.Println("--------------------------")

	// 服务端接收到建立连接请求,状态转移到 SYN_RECEIVED
	connection.Handle()
	fmt.Println("Current State:", connection)
	fmt.Println("--------------------------")

	// 客户端接收到服务端的 ACK,状态转移到 ESTABLISHED
	connection.Handle()
	fmt.Println("Current State:", connection)
	fmt.Println("--------------------------")

	connection.Handle()
}

运行上面的代码,输出如下:

Current State: CLOSED
--------------------------
Received SYN, transitioning to SYN_SENT
Current State: SYN_SENT
--------------------------
Received SYN-ACK, transitioning to SYN_RECEIVED
Current State: SYN_RECEIVED
--------------------------
Received ACK, transitioning to ESTABLISHED
Current State: ESTABLISHED
--------------------------
Connection is already ESTABLISHED

策略模式

策略模式可以将请求的处理逻辑封装到不同的策略类中,并在运行时选择合适的策略来处理请求,使具体的算法处理逻辑可以灵活地扩展和修改。

TCP 协议中的拥塞控制算法、路由选择算法等都可以使用策略模式来确定具体使用哪种算法。

伪代码

package main

import "fmt"

// CongestionControl 定义拥塞控制算法接口
type CongestionControl interface {
	Execute()
}

// Reno 拥塞控制算法实现
type Reno struct{}

func (r *Reno) Execute() {
	fmt.Println("Using Reno Algorithm")
}

// Cubic 拥塞控制算法实现
type Cubic struct{}

func (c *Cubic) Execute() {
	fmt.Println("Using Cubic Algorithm")
}

// BBR 拥塞控制算法实现
type BBR struct{}

func (b *BBR) Execute() {
	fmt.Println("Using BBR Algorithm")
}

// Connection 是连接,可以选择使用具体的算法
type Connection struct {
	strategy CongestionControl
}

// SetStrategy 设置当前的算法
func (c *Connection) SetStrategy(strategy CongestionControl) {
	c.strategy = strategy
}

// Handle 执行当前的拥塞控制算法
func (c *Connection) Handle() {
	c.strategy.Execute()
}

func main() {
	connection := &Connection{}

	// 使用 Reno 拥塞控制算法
	reno := &Reno{}
	connection.SetStrategy(reno)
	connection.Handle()

	// 使用 Cubic 拥塞控制算法
	cubic := &Cubic{}
	connection.SetStrategy(cubic)
	connection.Handle()

	// 使用 BBR 拥塞控制算法
	bbr := &BBR{}
	connection.SetStrategy(bbr)
	connection.Handle()
}

运行上面的代码,输出如下:

Using Reno Algorithm
Using Cubic Algorithm
Using BBR Algorithm

扩展阅读