从 Echo Demo 模仿一个 Go HTTP 框架

因为 Echo 框架本身是没有 Main 入口的,我们只能通过官方给的一个小的基础 Demo,作为源码阅读的起点 Demo - Hello World package main import ( "net/http" "github.com/labstack/echo/v4" ) func main() { e := echo.New() e.GET("/", func(c echo.Context) error { return c.String(http.StatusOK, "Hello, World!") }) e.Logger.Fatal(e.Start(":1323")) } 解析 入口 - New func New() (e *Echo) { e = &Echo{ Server: new(http.Server), TLSServer: new(http.Server), AutoTLSManager: autocert.Manager{ Prompt: autocert.AcceptTOS, }, Logger: log.New("echo"), colorer: color.New(), maxParam: new(int), ListenerNetwork: "tcp", } e.Server.Handler = e e.TLSServer.Handler = e e.HTTPErrorHandler = e.DefaultHTTPErrorHandler e.Binder = &DefaultBinder{} e.Logger.SetLevel(log.ERROR) e.StdLogger = stdLog.New(e.Logger.Output(), e.Logger.Prefix()+": ", 0) e.pool.New = func() interface{} { return e.NewContext(nil, nil) } e.router = NewRouter(e) e.routers = map[string]*Router{} return } 该函数是整个框架的入口,也是用户调用的第一步,它返回了一个 Echo 接口,并同时初始化了几个参数 ...

January 8, 2022 · 4 min · Sxueck

Go Mutex 源码随笔

编写时间 2020.10 月,当时技术有限深度还是不足,文章仅提供思路 共享内存和信号量 共享内存是进程间通信最简单的方式之一,允许两个或更多进程访问同一块内存,我们可以通过给不同进程返回指向同一个物理内存区域的指针来做到这一点, 当一个进程改变了这块地址中的内容的时候,其他进程都会察觉到这个更改。 但是使用共享内存的时候,若一个进程正在向共享内存写入数据,则在它完成这一步操作之前,别的进程都不应该去读写这些数据,否则会造成数据覆盖或者难以预料的错误。 为了防止多进程竞争共享资源而造成的数据错乱,需要一个保护机制使得共享的资源在任意时刻只能被一个进程访问,正好信号量就实现了这一保护机制。 信号量其实是一个整型的计数器,主要用于实现进程间的互斥与同步,而不是用于缓存进程间通信的数据 信号量表示资源的数量,控制信号量的方式有两种原子操作: P 操作:这个操作会把信号量 -1,相减后如果信号量 < 0,则表明资源已被占用,进程需堵塞等待,如果信号量 ≥ 0,代表还有资源可用,进程可继续正常运行 V 操作,这个操作会把信号量加上 1,相加后如果信号量 ≤ 0,则表明当前有阻塞中的进程,于是会将该进程唤醒运行;相加后如果信号量 > 0,则表明当前没有阻塞中的进程 P 操作是在进入共享资源之前,V 操作是在离开共享资源之后,这两个操作必须同时出现 Mutex初级版本源码解读 我从 Github 上能拉到最早的带有 Mutex 的相关代码为 Go 1.4,加上注释也才 109 行,非常小巧 使用示例 mutex := &sync.Mutex{} mutex.Lock() // ..do something mutex.Unlock() 和 Slice 一样,Go 中的 Mutex 本质上还是一个结构体,而且零值 Mutex 为未上锁状态,Mutex一旦被使用禁止被拷贝 其中 Mutex 中的 state 字段代表当前锁的状态,而 sema 代表控制锁的信号量 type Mutex struct { state int32 sema uint32 } const ( mutexLocked = 1 << iota // mutex is locked mutexWoken mutexWaiterShift = iota ) state 是一个 32 位的整型字段 ...

January 8, 2022 · 2 min · Sxueck

阿里云 ACK 集群搭建内外网分流 KAFKA

正常来说,直接官方 Helm 使用 Service + ClusterIP 的在集群的搭建模式会导致分布式多节点的时候无法对集群外部提供服务,我们可以将错误复现一遍 正常模式的错误复现 首先存在一个官方给出的正常 Helm 模版,并且已经都配置好了 Zookeeper 依赖 total 168 drwxr-xr-x 5 root root 4096 Feb 18 11:05 . drwxr-xr-x 3 root root 4096 Feb 18 10:51 .. drwxr-xr-x 2 root root 4096 Feb 18 10:51 charts -rw-r--r-- 1 root root 548 Feb 18 10:51 Chart.yaml drwxr-xr-x 3 root root 4096 Feb 18 10:51 files -rw-r--r-- 1 root root 333 Feb 18 10:51 .helmignore -rw-r--r-- 1 root root 67927 Feb 18 10:51 README.md -rw-r--r-- 1 root root 227 Feb 18 10:51 requirements.lock -rw-r--r-- 1 root root 137 Feb 18 10:51 requirements.yaml drwxr-xr-x 2 root root 4096 Feb 18 10:51 templates -rw-r--r-- 1 root root 30782 Feb 18 10:51 values-test.yaml -rw-r--r-- 1 root root 30932 Feb 18 11:02 values.yaml 具体看关键的 listeners 配置 ...

January 8, 2022 · 4 min · Sxueck

手动更换 K8s APIServer 的证书

当我们遇到证书过期,或者遇到下面的情况的时候,可能需要手动更换一下证书了 Unable to connect to the server: x509: certificate is valid for 10.43.0.1, 127.0.0.1, 192.168.0.2, not xxx 查看并备份当前证书 这里以 K3s 为例,原理和 K8s 完全相同 $ cd /var/lib/rancher/k3s/server/tls $ openssl x509 -noout -text -in serving-kube-apiserver.crt Certificate: Data: Version: 3 (0x2) Serial Number: 5436315453726641788 (0x4b71ac1a3257ce7c) Signature Algorithm: ecdsa-with-SHA256 Issuer: CN = k3s-server-ca@1640660897 Validity Not Before: Dec 28 03:08:17 2021 GMT Not After : Dec 28 03:08:17 2022 GMT Subject: CN = kube-apiserver Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (256 bit) pub: 04:53:50:c3:aa:83:af:d5:0c:13:a2:b4:55:09:28: de:c6:65:b3:62:e6:78:06:90:22:69:b3:42:b5:e2: 5f:ed:f2:7d:4c:bc:a0:bc:ea:b5:ee:82:5e:36:16: 65:ad:7e:03:e0:73:ef:f3:26:35:8f:2e:36:d8:cf: 6a:0e:70:f4:b8 ASN1 OID: prime256v1 NIST CURVE: P-256 X509v3 extensions: X509v3 Key Usage: critical Digital Signature, Key Encipherment X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Authority Key Identifier: keyid:CC:B5:B8:3B:36:D9:2D:F0:E1:E2:F0:01:C5:85:A2:69:ED:1C:19:BD X509v3 Subject Alternative Name: DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, DNS:localhost, DNS:k8smaster, IP Address:127.0.0.1, IP Address:192.168.0.2, IP Address:10.43.0.1 Signature Algorithm: ecdsa-with-SHA256 30:45:02:20:78:49:86:38:cc:65:c2:0a:38:83:1f:98:84:1f: 50:85:4c:71:db:35:56:7c:af:44:3a:15:58:98:58:f9:e6:89: 02:21:00:fb:69:0b:66:a1:b8:c3:92:21:a6:23:cf:ed:19:03: 26:fc:f1:bd:b7:d9:3a:50:d8:4b:01:90:cf:c9:8a:8b:19 可以看到,我们这个证书的有效期为一年,同时 X509v3 Subject Alternative Name 这边,也有着对应的签名 ...

January 8, 2022 · 3 min · Sxueck

OSI 模型简介

当时写给朋友的网络基础 前言 对于我们每天使用的互联网来说,你有没有想过,它的底层是如何被实现的? 你的打开手机浏览器,想要搜索点什么,有没有想过消息是如何传递搜索引擎,又是如何从它那边拿到了你想要的结果,抛开那些很复杂的逻辑背后,我们可以来讲一讲互联网的基石 —— 网络协议。 什么是网络协议 网络协议,也被成为传输协议,这里我们指的是,在任何物理介质中允许两个或多个在传输系统中的终端之间传播信息的系统标准,也是指计算机通信或网路设备的共同语言,举一个现实的例子,一名土生土长的亚马逊丛林部落人 (MachineA) 和一名阿拉伯人 (MachineB) 之间肯定无法直接交流,正常来说,直接加配一个翻译即可,但是对于计算机而言,使用第三方插件 (用翻译) 远远没有统一标准化来的方便 (两个人都学同一门语言),只要将这个 “语言” 规范化,每台终端设备都将其内置,万物互联的网络就诞生了。 协议的运用 不只是网络,其实生活方方面面我们也能看的协议的存在,例如 WIFI6 协议、USB3.2 协议等等,注意这些属于公共协议,背后有相应的联盟在制定标准更新,与之相对的还有私有协议,例如各大手机厂家的快充协议,如果不是使用原厂充电头,协议无法被匹配,就无法使用快充模式,在后面我们也可以自己来写一套简单的私有协议 协议遵循的规范 在了解具体的协议详情之前,我们需要抛开细节,来着重讲解一下现行互联网络的参考模型,这是一个很抽象的结构,你可以将其具象化为一个 Request (请求) 所需要经过的流程,例如地址栏输入 [baidu.com](http://baidu.com) 后敲击回车,你可以简单理解为向百度服务器发起了一次 Request,正确理解这些术语可以让我们后面写代码的时候不至于两眼一抹黑。 每一本讲解网络原理的书本上,第一章或者第二章肯定会是 OSI 七层模型,足以说明它的重要性和必要,开放式系统互联模型 (Open System Interconnection Model, OSI) 是由国际标准化组织 ISO 提出,ISO的成员由来自世界上100多个国家的国家标准化团体组成,代表中国参加 ISO 的国家机构是中国国家技术监督局(CSBTS),可以看看牛奶包装上,是不是必须要经过 ISO 认证才能上市,所以很好记 —— ISO 组织提出了 OSI 模型。 OSI 模型将通信系统中的数据流划分为七个层,从分布式应用程序数据的最高层表示到跨通信介质传输数据的物理实现。每个中间层为其上一层提供功能,其自身功能则由其下一层提供,功能的类别通过标准的通信协议在软件中实现。先快速过一遍一次请求中,所需要停留的每一层的作用: 首先我们会发起一个 WebRequest 给 Baidu Server (百度服务器) —— 应用层 Request 数据如果包含图片等内容,会被压缩打包 —— 表示层 计算机选择如何建立连接以及附属工作,例如是否需要优先传递这个 Request —— 会话层 计算机在你和 Server 之间寻找出一条最优路由 —— 网络层 ...

June 8, 2021 · 3 min · Sxueck