个人
2025-07-20
给女儿打样...
7/19 周六
上午爸爸带我和图图出门吃早餐,妈妈说她什么都不想吃,不要给她买。我们吃完回家的时候碰到妈妈,出门吃早餐 + 买菜。
妈妈不愿意出门,说是带孩子太累,要好好休息。爸爸带我和图图出门去附近的商场 “巡逻”,走 “百捷国际广场 - 友邻天地 - 世达广场” 路线。
百捷国际广场 和 友邻天地都是去看名创优品,常规操作,“不买只看看,名创也高兴”。世达广场就是去超市里面逛逛,图图在里面推着一个小车子跑来跑去都不愿回家。
中午吃饭之后,图图很早就去睡觉了,可能是上午一起出去消耗了太多体力。
妈妈陪图图在睡觉,爸爸说等他休息十分钟,然后带我去九凤头(徒步走过去,往返大概一小时路程),然后等图图一两个小时之后睡醒,再一起去武汉大学玩。
结果爸爸自己在床上玩手机睡着了,我只好一个人在看书、玩游戏。最后爸爸睡到图图都醒了,才被妈妈叫醒。我们只好跳过 Step1 九凤头,直接去 Step2 武汉大学。
我们一家四口(妈妈这个时候又愿意一起玩了),坐地铁到广埠屯,步行到武汉大学三门。没有带身份证,但是保安叔叔让我们填写表单,就放行了。
三门进入走的不是我和爸爸之前走的线路,爸爸要靠导航。因为已经五点四十了,爸爸直接导航到梅园教工食堂吃完饭。
墙上贴了一个不能使用支付宝微信的提醒,但实际上工作人员说可以用支付宝和微信。
爸爸选了好些食物,我记得有一个鸡腿,蒸蛋,小炒黄牛肉(可能),鹌鹑蛋,一碟炸虾(三个),还有一瓶百事可乐(玻璃瓶)和两个小盒装的蒙牛酸奶,一共三十几块钱。我和图图吃的很开心。
然后妈妈说挺好的,也去加了一些饭菜。
爸爸打菜时食堂几乎没有人,我们吃饭的时候陆陆续续来了不少人,等这个时候妈妈再去,她想要的鸡腿、牛肉都已经没有了。😂
里面还有两块腐乳,爸爸说不是老家的风味,倒像是 “炕豆腐”,非常咸。
吃完饭之后,我们四个一起去爬山。现在是夏天,虽然已经六点半了,但天还是非常亮。
我和妈妈一组,爸爸和图图一组,比赛谁先到山顶。
图图走的很慢,肯定是我们赢啊,就算爸爸抱,也肯定不如我和妈妈轻装上阵快。
爬了大概半个小时,爸爸指了一个石头,说这是最高的位置,确实也没有看到前面有继续往上的山坡。
我连忙冲过去,第一个站在石头上,正在高兴我们组赢了。但是爸爸抱着图图爬上来之后说他们组赢了,说如果是个人赛,那是我赢了,但是团队赛要看最后的那个人的成绩,这个时候妈妈还傻乎乎在后面慢慢走。
虽然不太服气,但是爸爸说的确实有道理,我只好承认他们赢了。
我继续提议,要比下山谁更快。有了前面的教训,我一直催妈妈快点,在我们的共同努力下,琪妈队终于获得胜利。
这个时候天色已经暗了下来,我们要回家了。
爸爸却带我们一起绕了一点远路到武汉大学牌楼那边拍照打卡。
因为背景有好些路灯,拍的效果总是不太好。而且还有不少可能是和我们一样来玩的人也在那里拍照。
总之,我们从牌楼旁边出武大(这是我们之前走的路线),然后走了大概十分钟到街道口站做地铁回家。
回到家的时候都十点半了。
7/20 周五
上午还是固定的行程,周三、周五、周日和第一医院医生约好的图图的语言康复课程,时间是 10:40 ~ 11:30。
出发之前,爸爸和妈妈规划了去两江游览粤汉码头坐船(上次在红巷码头体验非常好,我们都很开心)。
我们在地铁站旁边的蔡林记吃的早餐,我吃的是包子、妈妈吃的是糊米粉、爸爸吃的是热干面、图图吃了我的一个包子还有妈妈的糊米粉(他出门之前已经喝了牛奶)。
吃完早饭之后,我们坐地铁到汉正街站,然后走一小段路就到医院了(大约一个小时)。
到医院之后,妈妈陪图图上课,爸爸带我读英语(爸爸在网上买的三年级英语课本)(爸爸非说是收获满满的速速大王英语时光,我说是痛苦时光)。
中午我们步行到医院附近的恒隆广场四楼吃了西贝。
我吃了番茄挂面,很好吃,和奶奶做的味道差不多美味。还吃了奶牛慕斯、还有橙子沙棘汁(?),都不错。
妈妈还点了一盘牛肉,128 元,占总餐费的一大半(总共 230 的样子),这点牛肉还挺贵的。爸爸给我夹了几块,但是我吃的时候发现里面有一些不是瘦肉的部分,就把这部分留给爸爸吃了。
快吃完的时候,妈妈带图图去上厕所,可能半个小时才回来。我和爸爸就一直在西贝里面聊天等他们。
离开西贝之后,爸爸带我去了旁边的一鹿有你,这是一家抓娃娃店,之前妈妈带我来过一次,这里抓到娃娃的几率比较大。
爸爸付了 100 元,买了 130 个币。这次汲取上次的教训,没有在机器上购买,而是找老板扫码购买,可以多一次转盘抽奖活动,我抽到了一个直接选一个娃娃的机会,我选了一个可爱的小羊羔。
最后我一共搞到十几个娃娃。其中有一个乌龟形状的小玩具被爸爸摔破了,真实太虾了。
妈妈说我们要做地铁,带太多娃娃不好拿,最后找老板用其中的 5 个娃娃(包括那个可爱的小羊)换了几个好拿的玩具。
还有意见事情值得一说,在我抓娃娃的时候,爸爸发现图图要拉屎(闻到臭味),妈妈带图图去厕所。但是过一会儿,爸爸发现店门口有一坨屎,不知道是不是图图刚掉下来的。
爸爸说如果是图图刚拉的,他肯定要处理,如果不是,他就不管。
最后在厕所那边和妈妈确认,妈妈说肯定是刚才抱图图的时候,图图从衣服里面掉出来的。爸爸就跑回去把这个粑粑用纸捡起来,并把地上擦干净了。
幸好,幸好还没有人踩到,我都不敢想象有人踩到的样子 😖。
图图拉完屎之后变得活力四射,不像刚才有点没精神。但是没有持续多久,我们在去地铁的路上,他就在推车中睡着了。
爸爸查了两江游览最早在七点钟开始,现在才两点多,爸爸和妈妈决定去坐地铁去粤汉码头,主要是地铁站比较凉快,适合图图睡觉。
图图大概没有睡一个小时就醒了,我们就离开了大智路地铁站,走路去码头。
路上看到一个蜜雪冰城买水喝,我们每人一杯,我依然是棒打鲜橙(常温三分糖),图图是柠檬水(常温无糖,后来爸爸妈妈喝了他剩下的一点点,发现没有糖的好酸)。
正在喝水的时候,妈妈说图图要拉尿了,于是爸爸就抱着图图拉尿,但是好久了都没有拉出来,图图都要哭了。爸爸就说算了,妈妈却怪爸爸不一鼓作气,最后又怪到奶奶,他们吵了起来。
最后我们没人说话一直走到码头那边,妈妈带我和图图在江边玩了一会儿才好。
这次坐的船是两江盘龙号,比上次坐的钟子期号大太多了,爸爸说有钟子期号两倍大(发船的时候,爸爸发现江边有一艘船是俞伯牙号,正好和钟子期号是一对,爸爸讲的那个知音的故事)。
船有三层,一楼是餐厅、二楼是客房、三楼是观景台。几乎所有乘客都坐在三楼看江景,爸爸也在最靠边上的一排选了四个位置。
我们在船上看风景,吃零食,非常开心。船一直从码头(大圆球)那个位置,穿过长江大桥,到鹦鹉洲长江大桥附近才返航。返航明显要快很多,可能着就是所谓 “归心似箭” 吧!
看到大桥下面有火车一直在通行,而且大桥看起来像是几个大墩子上搞的一个复杂的钢结构桥体。
对了,水里面有人在游泳,每个人身后都有一个橙色的球球,爸爸说这是跟屁虫,里面放水和食物、干衣服,也不知道是不是真的是这样。
船靠岸之后,我们为了节约时间,先打车到循礼门站,这样可以直接坐二号线直达友邻天地(坐出门的时候骑过来的电动车和自行车回家),不用换乘。
图图在地铁上又拉尿了,几乎每次坐地铁都拉尿。确实做地铁的时间有点长,图图又不会说话。怕捂出痱子来,天气太热就没有给图图穿尿不湿,可能坐公共交通还是得穿上,总是搞得地上很长的“尿流”,容易招人嫌弃,我们自己也尴尬。
PS:在船上,图图也拉了尿,在楼梯上。
到家很晚了,我们都很累,和昨天一样,洗了澡就睡觉了。
个人
2025-07-19
等级 |
英文名 |
消费区间 |
服务方式 |
响应时间 |
问题处理 |
钻石客户 ① |
Diamond |
|
专属客户群 + 客户经理 + 技术专家 + 高管对接 |
≤30 分钟 |
7×24 |
铂金客户 ② |
Platinum |
1,000,000 |
专属客户群 + 客户经理 + 技术专家 |
≤30 分钟 |
工作时间 |
黄金客户 ③ |
Gold |
100,000 |
专属客户群 + 高级客服 |
≤1 小时 |
每日同步 |
白银客户 ④ |
Silver |
10,000 |
专属客户群 + 客服 |
≤3 小时 |
专项跟进 |
青铜客户 ⑤ |
Bronze |
1,000 |
工单系统 (免费额度) + 邮件/反馈系统 |
- |
- |
黑铁客户 ⑥ |
Iron |
100 |
工单系统 (免费额度) + 邮件/反馈系统 |
- |
- |
基础客户 ⑦ |
Ordinary |
0 |
工单系统 (付费) + 邮件/反馈系统 |
- |
- |
- 每个季度初(1/1、4/1、7/1、10/1)根据上个季度的消费金额,系统自动计算客户等级。
- 商务部门可以手动指定客户等级(申请流程),优先级高于系统自动计算结果。
- 系统自动创建客户群,按照标准拉指定人员进群提供支持。
如果客户等级下调,不符合建群标准,保留原权益一个月,然后通知客户,并在两周后将客户群冻结。
- 黄金、铂金、钻石客户问题专项跟进,每周总结,每月总结,季度总结,年度总结。
权益:
- 知识库
- 产品简报
- 线上培训
- 线下活动
- 优惠券
- 定制开发
Diamond
Platinum
Gold
Silver
Bronze
Iron
Basic
SMS
2025-07-10
JavaScript
2025-07-01
主要变化
异步处理改进
- 新增 Promise.try () 方法 :用于统一封装同步返回值或抛错的函数,相比以往的 Promise.resolve ().then (fn) 或 new Promise (resolve => resolve (fn ())),Promise.try (fn) 更简洁高效。例如,对于一个可能会抛出异常的函数,使用 Promise.try () 可以更方便地进行错误处理。
- 可立即抛出同步异常 :使用 Promise.try () 时,若函数同步抛出异常,能够立即捕获并处理,避免了使用 Promise.resolve ().then (fn) 时引入的微任务延迟,提高了错误可见性与调试效率,适用于封装第三方同步 API,使其具备统一的异步处理能力。
集合操作增强
- 新增 Set 实例方法 :为 Set 实例新增了七个方法,包括集合运算方法 intersection ()(交集)、union ()(并集)、difference ()(差集)、symmetricDifference ()(对称差集),以及集合关系方法 isSubsetOf ()(是否为子集)、isSupersetOf ()(是否为超集)、isDisjointFrom ()(是否无交集),使集合操作更加方便快捷,符合数学上的集合运算逻辑。
迭代器功能扩展
- 新增同步迭代器辅助函数 :为所有同步迭代器添加了一系列辅助方法,如 .map (fn)、.filter (fn)、.flatMap (fn)、.some (fn)、.every (fn)、.find (fn)、.reduce (fn, init)、.forEach (fn)、.drop (n)、.take (n)、.toArray () 等。这些方法支持链式调用,可用于链式处理可迭代对象的数据,实现惰性求值,避免创建多个中间数组,提升内存效率,特别适合处理大型或无限可迭代数据,如生成器、流数据等。
正则表达式增强
- 新增 RegExp.escape () 方法 :可将字符串中的正则元字符转义,使其能够安全地嵌入正则表达式中,避免动态生成正则表达式时出现语法错误,防止正则注入漏洞,替代手动维护的转义函数。
- 正则表达式内联标志 :允许在正则表达式内部使用内联语法 (?flags:...) 或 (?flags1-flags2:...) 以局部开启或关闭某些标志位,如 i、m、s 等。例如,在正则 /^x (?i:HELLO) x$/ 中,整个表达式外部没有 i 标志,而只对子串 HELLO 应用忽略大小写,避免了正则拆分与多轮匹配逻辑。
- 重复命名捕获组 :允许在正则表达式的不同分支中使用相同的命名捕获组名称,只要这些同名组不可能同时匹配。这便于对形式不同但结构类似的文本进行统一处理,如解析多种日期格式、键值对格式等,可简化后续处理逻辑,避免代码冗余。
模块系统优化
新增导入属性,允许在 import 语句中指定附加信息,以指定如何加载模块,主要用于引入非 JavaScript 资源,如 JSON 文件或 CSS 模块。静态导入时,可在路径后加上 with 选项;动态导入时,将其放在第二个参数的 with 字段中,使用起来更加方便简洁,可直接像引用 JS 模块一样使用 JSON 数据等。
数值表示扩展
提供对 16 位浮点数的原生支持,包括 Float16Array、DataView.prototype.getFloat16 ()/setFloat16 () 以及 Math.f16round (number)。这在 WebGPU / WebGL 中可节省带宽与内存,在深度学习中便于传递模型参数,也可用于模拟硬件精度限制。
其他特性
- 后置检查的声明式控制流 :引入了 checked { } 块和 assert 关键字,在 checked 块中的操作会在执行后立即检查是否出界等,assert 用于断言,若条件不成立会直接抛出异常,为开发者提供了更灵活的错误检查方式。
- ArrayBuffer 的构造共享数组 :新增了 ArrayBuffer 构造函数的 shared 构造标志,可创建一个共享的 ArrayBuffer,其视图成为共享数组,所有代理都具有相同的内存视图,允许多个 JavaScript 工作线程之间共享和传递 ArrayBuffer,提高了数据共享和传递的效率。ÎÍ
历史变革
ECMAScript(简称 ES)作为 JavaScript 的标准化规范,自 1997 年发布首个版本以来,已经历了多次重要更新。下面为你介绍 ECMAScript 各主要版本及其核心变化:
- ES1(1997 年):这是 ECMAScript 的首个版本,它的制定参考了 JavaScript 1.1,是一个基础版本,为后续的发展奠定了基础。
- ES2(1998 年):此版本主要是为了使规范与 ISO/IEC 16262 国际标准保持一致,并没有对语言功能进行实质性的扩展。
- ES3(1999 年):这是一个具有重要意义的版本,引入了众多核心特性,包括正则表达式、try/catch 异常处理、do-while 循环以及更完善的字符串处理功能等,极大地丰富了 ECMAScript 的功能。
- ES4(未发布):该版本计划进行大幅更新,但由于各方在设计理念上存在较大分歧,最终未能正式发布。
- ES5(2009 年):引入了严格模式(strict mode),对 JSON 对象进行了标准化,还新增了数组方法(如 forEach、map、filter)和
Object.defineProperty
等特性,提升了代码的规范性和可维护性。
- ES5.1(2011 年):这是一个修正版本,主要是对 ES5 的规范进行了澄清和完善,使其更加严谨。
- ES6(ES2015):带来了众多革命性的特性,如箭头函数、let/const 块级作用域、Promise 异步编程、class 类和继承、模块系统(import/export)以及解构赋值等,使 ECMAScript 的语法更加现代化。
- ES2016(ES7):新增了数组 includes 方法和指数运算符(**),进一步扩展了 ECMAScript 的功能。
- ES2017(ES8):引入了 async/await 异步编程模式、
Object.values/entries
、字符串填充(padStart/padEnd)以及共享内存和原子操作等特性,提升了异步编程的便利性。
- ES2018(ES9):支持异步迭代器、Rest/Spread 属性、
Promise.finally
以及正则表达式的一些增强功能,如后行断言等,增强了语言的灵活性。
- ES2019(ES10):新增了
Array.flat/flatten
、Object.fromEntries
、String.trimStart/End
、可选的 catch 绑定以及 Symbol.description 等特性,简化了代码编写。
- ES2020(ES11):引入了 BigInt 数据类型、空值合并运算符(??)、可选链操作符(?.)、
Promise.allSettled
、globalThis
以及模块动态导入等功能,提升了语言的表达能力。
- ES2021(ES12):包含逻辑赋值运算符(&&=、||=、??=)、数字分隔符(_)、Promise.any 和 WeakRefs 等特性,进一步完善了语言功能。
- ES2022(ES13):新增了类字段声明、静态类字段和私有方法、Top-level await 以及 Error Cause 等特性,使类的定义更加简洁和强大。
- ES2023(ES14):引入了 Array find from last、Hashbang 语法、WeakMap 和 WeakSet 的新方法以及 Symbol.dispose 和 Disposable Objects 等特性,增强了语言的实用性。
- ES2024(ES15):预计会增加 Decorators(装饰器)、Record & Tuple(不可变数据结构)等特性,目前还在不断发展和完善中。
从 ES6 开始,ECMAScript 采用了每年一次的发布周期,版本号以年份命名,这种方式使得新特性能够更快地进入标准,满足开发者的需求。
ES 版本 |
Node.js 最小支持版本 |
Chrome 最小支持版本 |
Firefox 最小支持版本 |
ES6 (ES2015) |
v4.0.0 (部分) |
49 |
45 |
|
v6.0.0 (接近完整) |
|
|
ES2016 (ES7) |
v7.0.0 |
51 |
52 |
ES2017 (ES8) |
v8.0.0 |
58 |
52 |
ES2018 (ES9) |
v10.0.0 |
63 |
57 |
ES2019 (ES10) |
v12.0.0 |
73 |
67 |
ES2020 (ES11) |
v14.0.0 |
80 |
74 |
ES2021 (ES12) |
v16.0.0 |
91 |
90 |
ES2022 (ES13) |
v18.0.0 |
96 |
97 |
ES2023 (ES14) |
v20.0.0 |
110 |
111 |
ES2024 (ES15) |
v21.0.0 (部分) |
119 (部分) |
120 (部分) |
在生产环境中使用新特性时,建议搭配 Babel 等转译工具或 TypeScript 以确保兼容性。
参考资料与拓展阅读
SMTP
2025-06-30
2000/06,RFC 2852。
https://www.rfc-editor.org/search/rfc_search_detail.php?page=All&title=smtp
该扩展允许发送方在 RCPT TO
阶段声明期望的投递时限(如 RCPT TO:<user@example.com> DELIVERBY=3600
),要求接收方在指定秒数内完成投递,否则可触发退回或降级处理。
语法
RCPT TO:<forward-path> DELIVERBY=<duration>
例如:
S: 250 OK
C: RCPT TO:<user@example.com> DELIVERBY=1800
S: 250 Accepted with DELIVERBY=1800
ABNF
by-parameter = "BY="by-value
by-value = by-time";"by-mode[by-trace]
by-time = ["-" / "+"]1*9digit ; a negative or zero value is not
; allowed with a by-mode of "R"
by-mode = "N" / "R" ; "Notify" or "Return"
by-trace = "T" ; "Trace"
- by-mode(可选):
- N(Notify):超时后 通知发送方(DSN 报告)
- R(Return):超时后 直接退回邮件
- by-trace(可选):
- T 表示需(在邮件服务器日志中)记录投递路径追踪信息 (例如超时事件的时间戳、目标服务器等)
记录详细信息通过 DSN 报告给发送方?
政治
2025-06-17
-
尼日尔,非洲西部,讲法语,原法国殖民地(1904 年成为法属西非领地),1960 年独立。
- 已探明铀储量 42 万吨。(被法国公司以极低价格购买)
- 磷酸盐储量 12.54 亿吨,但尚未开发。
- 煤储量 600 万吨。
- 初步探明石油储量约 4.99 亿吨。(石油收入占 GDP 20%,主要由中石油控制)
- 还有锡、铁、石膏、黄金等矿藏。
尼日尔 1963 年 7 月 7 日与中华民国政府建交,1974 年 7 月 20 日改同中华人民共和国政府建交,1992 年 7 月 30 日尼日尔再同中华民国政府复交四年,直至 1996 年 8 月 19 日尼日尔同中华人民共和国政府二度复交,并与中华民国断交。
2024 年 1 月 2 日法国关闭驻尼日尔使馆,直至“另行通知”为止。
尼日尔 2024 年 8 月 6 日宣布与乌克兰断交。
-
2023 年,军政府政变上台,执行民族主义政策(努力摆脱法国控制,逐步收回国内矿场控制权)。
- 2023 年 7 月 26 日,尼日尔军人扣押巴祖姆总统,宣布成立“保卫祖国国家委员会”接管权力,总统卫队司令奇亚尼出任委员会主席、国家元首,并成立过渡政府。
- 2023 年 7 月下旬,尼日尔“保卫祖国国家委员会”接管权力,宣布承认和延续尼政府此前同外国签订的所有合作协议,但同美西方关系紧张,反对西非国家经济共同体制裁干预。
- 2023 年 9 月,马里、布基纳法索、尼日尔宣布成立萨赫勒国家联盟。
- 2024 年 1 月,三国宣布退出西共体。同月,西共体召开特别峰会,决定解除对尼经济制裁。2024 年 7 月,三国宣布成立“萨赫勒国家邦联”。
- 2025 年 1 月,西共体发布公报正式宣布三国退出生效,但保留对三国人员流通、贸易和服务等方面优惠政策。
- 2025 年 3 月,三国宣布退出法语国家与地区组织。
- 2025 年 3 月,奇亚尼正式宣誓就任尼日尔共和国总统。
-
2024 年,中国还向尼日尔军政府提供了一笔 4 亿美元的贷款,用于尼日尔建设石油输送管道、偿还其他债务等。
据说,今年到期,但是没有钱偿还,企图赖账。
-
今年 3 月,尼日尔军政府以薪酬不公平、税务违规等理由,驱逐了中国石油天然气集团的三名高层管理人员,冻结了炼油厂的银行账户,还撤销了中资酒店的营业执照。
军政府诉求:
- 将原油分成比例从 15% 提高至 30%;
- 追缴炼油厂“欠税”1.3 亿美元;
- 强制要求中企高管本土化。
同时:
- 撕毁与美国和法国的国防协议,驱逐法国驻军,控制铀矿
- 与乌克兰断交(可以看到俄罗斯对新政权的影响)
- 俄罗斯瓦格纳雇佣兵公司接管了尼日尔首都包围工作
-
今年 5 月,局势进一步升级,尼日尔方面计划削减石油工人人数,要求一些中国员工在 5 月 31 日之前离开该国,人数可能多达数十人。给出的理由是外籍员工在当地工作时间超过其法律规定时长。
- 今年 6 月,尼日尔外长访华,并在与中方的谈话中表示,希望加强与中方之间的经贸合作。
尼日尔的问题
- 长期以来经济不发达,在摆脱法国殖民影响后,经济发展缺乏稳定支撑。
- 虽然拥有丰富的矿产资源(铀矿储量位居世界前列),但是没有开采技术,需要外资的帮助。
- 资源开采中获得的资金收入没有能够用于发展经济和改善民生,还承担了环境破坏的后果。
现状
- 尼日尔国内安全局势不佳,武装冲突频发,中国铺设的石油管道多次被炸断
- 尼日尔石油产能下降了 70%
本国油价上涨 4 倍
- 营商环境恶化导致的国际舆论压力
主权信用评级下调到 CCC
- 中国对尼日尔军政府的不信任
对中国的影响
- 过去数十年,中国对尼日尔大量援助和支持,广泛参与当地的基础设施建设,帮助其构建原油出口产业链。
- 西方媒体恶意抹黑中非合作(“新殖民主义”),中方的应对是非常无力的。
- 为了避免类似情况再次发生,必须对尼日尔采取严厉的处罚措施。
此次事件暴露了中企在非投资的三大风险:
- 政权更迭风险:非洲 54 国中,23 国近十年发生过政变;
- 资源民族主义:刚果(金)、津巴布韦等国频繁以环保、劳工权益为名强制外资股权转让;
- 地缘政治裹挟:美西方通过舆论战将中非合作污名化为“新殖民主义”。
参考资料与拓展阅读
K8S
2025-06-09
Kubernetes 学习环境搭建手册 (Ubuntu 25.04)
架构

Kubernetes (K8S) 是一个开源的容器编排系统,采用主从架构,主要组件包括:
控制平面 (Control Plane):
- API Server: 集群的统一入口,提供 RESTful API 接口,所有组件都通过它与集群交互
- etcd: 高可用的分布式键值存储,持久化保存所有集群数据(唯一有状态组件)
- Scheduler: 负责资源调度,根据策略将 Pod 绑定到合适的工作节点
- Controller Manager: 运行各种控制器的主进程(如 Deployment 控制器、Node 控制器等),确保集群状态符合预期声明
工作节点 (Worker Nodes):
- Kubelet: 节点上的核心代理,负责与 API Server 通信并管理本节点容器的生命周期
- Kube-proxy: 实现 Service 抽象,通过 iptables/IPVS 维护网络规则,实现服务发现和负载均衡
- 容器运行时: 负责镜像管理和容器运行(推荐 containerd,Docker 已被弃用)
步骤
-
环境准备
# 更新系统
sudo apt update && sudo apt upgrade -y
# 安装必要工具
sudo apt install -y curl apt-transport-https ca-certificates
-
安装容器运行时 (containerd)
# 安装containerd
sudo apt install -y containerd
# 配置 containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd
-
安装 kubeadm, kubelet 和 kubectl
# 添加Kubernetes仓库
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
# 安装组件
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
-
初始化集群
# 初始化控制平面
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
# 配置kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown (id -u):(id -g) $HOME/.kube/config
-
安装网络插件 (Flannel)
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
-
允许主节点调度 Pod (单节点集群)
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
配置
-
日志管理
# 查看Pod日志
kubectl logs <pod-name>
-
存储配置
创建 PersistentVolume (PV):
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-local
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
persistentVolumeReclaimPolicy: Retain
创建 PersistentVolumeClaim (PVC):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-local
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
kubectl get pv
kubectl get pvc
kubectl describe pvc pvc-local
数据库部署 (MySQL 示例)
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
replicas: 1
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: pvc-local
动态伸缩
手动伸缩:
kubectl scale deployment <deployment-name> --replicas=3 -n <namespace>
# 不带命名空间的话,就用 default
自动伸缩 (HPA):
# 1. 部署服务(资源限制)
# resources:
# requests:
# cpu: "100m"
# 2. 安装 metrics-server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# 如果遇到证书错误
kubectl patch deployment metrics-server -n kube-system --type='json' -p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'
# 3. 创建 HPA
kubectl autoscale deployment <deployment-name> --cpu-percent=50 --min=1 --max=5
# 4. 生成负载测试(新终端)
kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh -c "while true; do wget -q -O- http://hpa-test; done"
# 5. 观察HPA
watch kubectl get hpa
常用命令速查
- 查看节点状态
kubectl get nodes
- 查看所有 Pod
kubectl get pods -A
- 查看服务
kubectl get services
- 查看部署
kubectl get deployments
- 进入 Pod 容器
kubectl exec -it -- /bin/bash
- 删除资源
kubectl delete
Shell
2025-06-01
https://heitorpb.github.io/bla/timeout/
until 是 Shell 控制结构,表示直到命令执行成功,一直循环。
加上 timeout 超时控制,在一分钟内重复尝试访问服务。一旦访问成功,命令立即结束;如果在 60 秒内仍未成功,timeout 会强制终止该命令,并返回错误码。
until curl --silent --fail-with-body 10.0.0.1:8080/health; do sleep 1; done
timeout 1m bash -c "until curl --silent --fail-with-body 10.0.0.1:8080/health; do sleep 1; done"
SMTP
2025-05-31
stateDiagram-v2
[*] --> Connected
Connected --> AwaitingGreeting: TCP连接建立
# 协议握手阶段
AwaitingGreeting --> HelloCommand: 收到220后发送EHLO
HelloCommand --> TLS_Decision: 解析250扩展
# 加密与认证决策
TLS_Decision --> TLS_Handshake: 需要STARTTLS
TLS_Handshake --> HelloCommand: 加密后重发EHLO
TLS_Decision --> Auth_Decision: 无需TLS
Auth_Decision --> AUTH_Login: 需要认证
AUTH_Login --> MailFromCommand: 认证成功
Auth_Decision --> MailFromCommand: 无需认证
# 邮件传输流程
MailFromCommand --> RcptToCommand: 收到250后发送RCPT TO
RcptToCommand --> DataCommand: 收到250(最终收件人)后发送DATA
DataCommand --> Data: 收到354后发送邮件内容
Data --> QuitCommand: 收到250后发送QUIT
QuitCommand --> Disconnected: 收到221断开连接
Disconnected --> [*]
# 统一错误处理
state ErrorHandler <<choice>>
HelloCommand --> ErrorHandler: 错误响应
MailFromCommand --> ErrorHandler: 错误响应
RcptToCommand --> ErrorHandler: 错误响应
DataCommand --> ErrorHandler: 错误响应
Data --> ErrorHandler: 错误响应
ErrorHandler --> RSETCommand: 可恢复错误
RSETCommand --> MailFromCommand: 重置到发件人状态
ErrorHandler --> Disconnected: 致命错误
Git
2025-05-26
看了 《How Core Git Developers Configure Git》,作者建议配置应该尽可能简单一些,不要使用 alias 定义别名。
最后作者也提供了一些他建议配置的条目,我在这个基础上做了一点调整(想要原版去上面的链接里面找),如下:
# clearly makes git better
[column]
# 自动分栏(比如列出分支的时候,会按照屏幕宽度自动分栏显示)
ui = auto
[branch]
# 按照最新提交时间排序
sort = -committerdate
[tag]
# 默认按字母排序不是好的选择,比如:
# v0.1
# v0.10
# v0.2
sort = version:refname
[init]
defaultBranch = master
[diff]
algorithm = histogram
colorMoved = plain
mnemonicPrefix = true
renames = true
[push]
default = simple
autoSetupRemote = true
followTags = true
[fetch]
prune = true
pruneTags = true
all = true
# why the hell not?
[help]
autocorrect = prompt
[commit]
verbose = true
[rerere]
enabled = true
autoupdate = true
[core]
excludesfile = ~/.gitignore
[rebase]
autoSquash = true
autoStash = true
updateRefs = true
# a matter of taste (uncomment if you dare)
[core]
# fsmonitor = true
# untrackedCache = true
[merge]
# (just 'diff3' if git version < 2.3)
# conflictstyle = zdiff3
[pull]
# rebase = true