Homelab - Linux挂载TrueNAS中的iSCSI
基本概念NAS:(Network Attached Storage,网络附加存储) 使用的是基于文件的通信协议,例如NFS或SMB/CIFS,计算机请求访问的是抽象文件的一段内容,而非对磁盘进行的块设备操作。
SAN:(storage area network,存储区域网络)是一种连接外接存储设备和服务器的架构。该架构的特点是,连接到服务器的存储设备,将被操作系统视为直接连接的存储设备。
NAS和SAN都是为了实现存储共享。不同的是NAS以文件为基础,客户端可以操作远程共享出的文件或文件夹。而SAN以更底层的磁盘块为基础,客户端可以像使用本地磁盘一样使用SAN共享出的磁盘块,可以在上面创建独立的文件系统。
SCSI:(Small Computer System Interface,小型计算机系统接口)是一种用于计算机及其周边设备之间(硬盘、软驱、光驱、打印机、扫描仪等)的通信协议。
iSCSI(Internet Small Computer System Interface,基于Internet的SCSI)又称为IP-SAN,利用了TCP/IP的port 860 和 ...
Go设计模式 - 单例模式
单例模式的php实现单例模式在所有设计模式中算是最简单的了,主要是保证一个类始终只有一个实例。在php中因为是单线程,所以实现起来非常简单:“三私一公”,私有化静态属性,私有化克隆方法,私有化构造方法,然后创建一个公有的静态方法做实例化的操作。代码示例:
class Singleton {
private static $instance = null;
private function __clone(){}
private function __construct(){}
public static function GetInstance(){
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
}
$a = Singleton::GetInst ...
K8s集群中使用helm安装wordpress
在k8s集群中使用helm安装wordpress前置条件需要自己搭建一个nfs服务器作为集群的持久化存储,因为局域网中已经有一台TrueNas服务器,所以这里不再介绍nfs服务的搭建过程。
安装Helmhelm就是一个k8s集群下的包管理工具,类似与debian系统下的apt,安装方式参考:官方文档。helm需要安装在k8s的管理节点,或者master节点
使用系统的包管理工具进行安装,具体操作如下,这种方式可能需要科学上网。其实helm就是一个二进制的可执行文件,也可以参考官方文档自己使用其它方式安装。
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] h ...
kubeadm搭建多个master节点的k8s集群
环境规划虚拟机环境是ProxmoxVE,当然你也可以用VMware或VirtualBox。
另外:最好有科学上网的环境,操作过程中尽量把需要科学上网的源都改成了国内源,但是并不是所有的镜像都有国内源。
虚拟机操作系统:Debian11,从Debian官网下载的iso镜像,最小化安装,不包含图形界面。
虚拟机配置:
主机名
IP地址
配置
节点角色
k8s-master1
192.168.32.204
2核2G
master
k8s-master2
192.168.32.205
2核2G
master
k8s-master3
192.168.32.206
2核2G
master
k8s-worker1
192.168.32.207
2核2G
worker
k8s-worker2
192.168.32.208
2核2G
worker
k8s-worker3
192.168.32.209
2核2G
worker
VIP(虚拟IP):192.168.32.250
3个master节点,主要作用是使master节点高可用,实际工作过程中只有一个maste ...
Golang垃圾回收
常见垃圾回收算法1. 引用计数优点:对象可以被很快回收,不会出现内存耗尽或达到某个阈值时才开始回收
缺点:1. 一些没有破坏性的操作,如只读操作也需要更新引用计数;
必须原子更新,不适用于多线程以及高并发
还有一个循环引用的问题,参考PHP解决循环引用
代表语言:php,python
2.标记-清扫是一种间接的垃圾回收算法,不直接查找垃圾对象,而是通过活着的对象推断垃圾对象
优点:解决了引用计数的缺点
缺点:1. 可能产生内存碎片或空洞
需要STW
代表语言:Golang
3. 标记-压缩分为两个阶段:标记、压缩。通过将分散的、活着的对象移动到更紧密的空间来解决碎片问题。
缺点:内存对象在内存的位置是随机的,这常常会破坏缓存的局部性,并且时常需要一些额外的空间来标记当前对象已经移动到了其它地方
4. 半空间复制是一种空间换时间的算法,使用一半内存空间,保留另一半的内存空间用于快速压缩内存。
半空间复制的压缩性消除了内存碎片问题。半空间复制不分阶段,在扫描根对象时就可以直接压缩,每个扫描到的对象会从fromspace空间复制到topspace空间。一旦扫描完成就得到了一个压缩后的 ...
Golang内存管理
内存管理方案page、span、元素Go语言的内存分配算法源自于TCMalloc,是Google开发的内存分配算法库,TCMalloc的内存分配单位叫page,也就是用固定大小的page来执行内存获取、分配、释放等操作。一个page的大小为8KB
go语言的内存管理的基本单位叫span,每个span用于管理特定大小的内存。go语言将内存分成了大大小小67个级别的span,各级span与其元素大小如下所示:每个span的大小都是page的整数倍。
// class bytes/obj bytes/span objects waste bytes
// 1 8 8192 1024 0
// 2 16 8192 512 0
// 3 32 8192 256 0
/ ...
Golang并发控制 - Channel
CSP并发编程CSP(Communicating Sequential Processes,通信顺序进程):是用户描述并发系统中交互模式的形式化语言,其通过通道传递消息。核心思想是:不要通过共享内存来通信,通过通信来共享内存
通道结构与环形队列 通道在运行时是一个特殊的hchan结构体:runtime/chan.go
type hchan struct {
qcount uint // total data in the queue
dataqsiz uint // size of the circular queue
buf unsafe.Pointer // points to an array of dataqsiz elements
elemsize uint16
closed uint32
elemtype *_type // element type
sendx uint // send index
recvx uint // receive index
re ...
Golang并发控制 - Context
为什么需要context
一句关于Go的名言:如果你不知道如何退出一个协程,那么就不要创建它
在context之前,要管理协程退出需要借助通道的close机制,但是在不同的项目之间,在命名及处理方式上都会有所不同,如果有一套统一的规范,那么语义将更加清晰。例如都使用 <-ctx.Done()
协程之间时常存在级联关系,退出需要具有传递性。为了优雅的管理协程的退出,特别时多个协程甚至是网络服务之间的退出,Go引入了context包
context接口context.Context其实时一个接口,提供了以下4种方法
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key any) any
}
Deadline():第一个返回值表示还有多久到期,第二个返回值表示是否到期
Done():返回一个通道,一般做法时监听该通道信号,如果收到信 ...
Golang数据类型 - Map
map基本操作map初始化// 直接定义
var m map[int]string
m[1]="hello" // 未对map进行初始化操作,值为nil,会报panic。但是可以进行访问
// 使用make初始化
var m = make(map[int]string, 2) // 第二个参数代表map的长度,为空时,默认为0
// 使用字面量初始化
var country = map[string]string{
"China": "Beijing"
"Japan": "Tokyo"
}
map访问v := map[key] // 可以只接收值
v, ok := map[key] // 也可以用第二个参数判断key是否存在
map修改m[key] = value
delete(m, key) // 删除m中的key,可以对相同的key进行多次删除操作而不会报错
map底层原理底层结构map中的数据被存放于一个数组中的,数组的元素是桶(bucket),每个桶至多包含8个键值对数据。哈希值低位(low-order b ...
Golang反射
什么是反射反射是指在程序运行期对程序本身进行访问和修改的能力。程序在编译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分。在运行程序时,程序无法获取自身的信息。
支持反射的语言可以在程序编译期将变量的反射信息,如字段名称、类型信息、结构体信息等整合到可执行文件中,并给程序提供接口访问反射信息,这样就可以在程序运行期获取类型的反射信息,并且有能力修改它们。
Go语言提供了一种机制在运行时更新变量和检查它们的值、调用它们的方法,但是在编译时并不知道这些变量的具体类型,这称为反射机制。
为什么使用反射反射给人的第一印象是:使用起来很危险,能不用就不要用,但是go语言既然提供了这个能力,必然有其不可替代的作用:
有时我们需要一个函数,有能力统一处理各种类型,比如fmt.Printf
reflect包reflect包的两个重要的类型
reflect.Type: 是一个有很多方法的接口,这些方法可以识别类型,以及透视类型的组成部分。同时满足fmt.Stringer(实现了String方法,可以通过fmt.Printf 打印)
reflect.TypeOf():接收一个任意类型的参数 ...