#1064 周末流水账

2025-07-20

给女儿打样...

7/19 周六

上午爸爸带我和图图出门吃早餐,妈妈说她什么都不想吃,不要给她买。我们吃完回家的时候碰到妈妈,出门吃早餐 + 买菜。
妈妈不愿意出门,说是带孩子太累,要好好休息。爸爸带我和图图出门去附近的商场 “巡逻”,走 “百捷国际广场 - 友邻天地 - 世达广场” 路线。
百捷国际广场 和 友邻天地都是去看名创优品,常规操作,“不买只看看,名创也高兴”。世达广场就是去超市里面逛逛,图图在里面推着一个小车子跑来跑去都不愿回家。

中午吃饭之后,图图很早就去睡觉了,可能是上午一起出去消耗了太多体力。
妈妈陪图图在睡觉,爸爸说等他休息十分钟,然后带我去九凤头(徒步走过去,往返大概一小时路程),然后等图图一两个小时之后睡醒,再一起去武汉大学玩。
结果爸爸自己在床上玩手机睡着了,我只好一个人在看书、玩游戏。最后爸爸睡到图图都醒了,才被妈妈叫醒。我们只好跳过 Step1 九凤头,直接去 Step2 武汉大学。

我们一家四口(妈妈这个时候又愿意一起玩了),坐地铁到广埠屯,步行到武汉大学三门。没有带身份证,但是保安叔叔让我们填写表单,就放行了。
三门进入走的不是我和爸爸之前走的线路,爸爸要靠导航。因为已经五点四十了,爸爸直接导航到梅园教工食堂吃完饭。
墙上贴了一个不能使用支付宝微信的提醒,但实际上工作人员说可以用支付宝和微信。
爸爸选了好些食物,我记得有一个鸡腿,蒸蛋,小炒黄牛肉(可能),鹌鹑蛋,一碟炸虾(三个),还有一瓶百事可乐(玻璃瓶)和两个小盒装的蒙牛酸奶,一共三十几块钱。我和图图吃的很开心。
然后妈妈说挺好的,也去加了一些饭菜。
爸爸打菜时食堂几乎没有人,我们吃饭的时候陆陆续续来了不少人,等这个时候妈妈再去,她想要的鸡腿、牛肉都已经没有了。😂
里面还有两块腐乳,爸爸说不是老家的风味,倒像是 “炕豆腐”,非常咸。

吃完饭之后,我们四个一起去爬山。现在是夏天,虽然已经六点半了,但天还是非常亮。
我和妈妈一组,爸爸和图图一组,比赛谁先到山顶。
图图走的很慢,肯定是我们赢啊,就算爸爸抱,也肯定不如我和妈妈轻装上阵快。
爬了大概半个小时,爸爸指了一个石头,说这是最高的位置,确实也没有看到前面有继续往上的山坡。
我连忙冲过去,第一个站在石头上,正在高兴我们组赢了。但是爸爸抱着图图爬上来之后说他们组赢了,说如果是个人赛,那是我赢了,但是团队赛要看最后的那个人的成绩,这个时候妈妈还傻乎乎在后面慢慢走。
虽然不太服气,但是爸爸说的确实有道理,我只好承认他们赢了。
我继续提议,要比下山谁更快。有了前面的教训,我一直催妈妈快点,在我们的共同努力下,琪妈队终于获得胜利。

这个时候天色已经暗了下来,我们要回家了。
爸爸却带我们一起绕了一点远路到武汉大学牌楼那边拍照打卡。
因为背景有好些路灯,拍的效果总是不太好。而且还有不少可能是和我们一样来玩的人也在那里拍照。
总之,我们从牌楼旁边出武大(这是我们之前走的路线),然后走了大概十分钟到街道口站做地铁回家。
回到家的时候都十点半了。

7/20 周五

上午还是固定的行程,周三、周五、周日和第一医院医生约好的图图的语言康复课程,时间是 10:40 ~ 11:30。
出发之前,爸爸和妈妈规划了去两江游览粤汉码头坐船(上次在红巷码头体验非常好,我们都很开心)。

我们在地铁站旁边的蔡林记吃的早餐,我吃的是包子、妈妈吃的是糊米粉、爸爸吃的是热干面、图图吃了我的一个包子还有妈妈的糊米粉(他出门之前已经喝了牛奶)。
吃完早饭之后,我们坐地铁到汉正街站,然后走一小段路就到医院了(大约一个小时)。
到医院之后,妈妈陪图图上课,爸爸带我读英语(爸爸在网上买的三年级英语课本)(爸爸非说是收获满满的速速大王英语时光,我说是痛苦时光)。

中午我们步行到医院附近的恒隆广场四楼吃了西贝。
我吃了番茄挂面,很好吃,和奶奶做的味道差不多美味。还吃了奶牛慕斯、还有橙子沙棘汁(?),都不错。
妈妈还点了一盘牛肉,128 元,占总餐费的一大半(总共 230 的样子),这点牛肉还挺贵的。爸爸给我夹了几块,但是我吃的时候发现里面有一些不是瘦肉的部分,就把这部分留给爸爸吃了。
快吃完的时候,妈妈带图图去上厕所,可能半个小时才回来。我和爸爸就一直在西贝里面聊天等他们。

离开西贝之后,爸爸带我去了旁边的一鹿有你,这是一家抓娃娃店,之前妈妈带我来过一次,这里抓到娃娃的几率比较大。
爸爸付了 100 元,买了 130 个币。这次汲取上次的教训,没有在机器上购买,而是找老板扫码购买,可以多一次转盘抽奖活动,我抽到了一个直接选一个娃娃的机会,我选了一个可爱的小羊羔。
最后我一共搞到十几个娃娃。其中有一个乌龟形状的小玩具被爸爸摔破了,真实太虾了。
妈妈说我们要做地铁,带太多娃娃不好拿,最后找老板用其中的 5 个娃娃(包括那个可爱的小羊)换了几个好拿的玩具。

还有意见事情值得一说,在我抓娃娃的时候,爸爸发现图图要拉屎(闻到臭味),妈妈带图图去厕所。但是过一会儿,爸爸发现店门口有一坨屎,不知道是不是图图刚掉下来的。
爸爸说如果是图图刚拉的,他肯定要处理,如果不是,他就不管。
最后在厕所那边和妈妈确认,妈妈说肯定是刚才抱图图的时候,图图从衣服里面掉出来的。爸爸就跑回去把这个粑粑用纸捡起来,并把地上擦干净了。
幸好,幸好还没有人踩到,我都不敢想象有人踩到的样子 😖。

图图拉完屎之后变得活力四射,不像刚才有点没精神。但是没有持续多久,我们在去地铁的路上,他就在推车中睡着了。
爸爸查了两江游览最早在七点钟开始,现在才两点多,爸爸和妈妈决定去坐地铁去粤汉码头,主要是地铁站比较凉快,适合图图睡觉。

图图大概没有睡一个小时就醒了,我们就离开了大智路地铁站,走路去码头。
路上看到一个蜜雪冰城买水喝,我们每人一杯,我依然是棒打鲜橙(常温三分糖),图图是柠檬水(常温无糖,后来爸爸妈妈喝了他剩下的一点点,发现没有糖的好酸)。
正在喝水的时候,妈妈说图图要拉尿了,于是爸爸就抱着图图拉尿,但是好久了都没有拉出来,图图都要哭了。爸爸就说算了,妈妈却怪爸爸不一鼓作气,最后又怪到奶奶,他们吵了起来。
最后我们没人说话一直走到码头那边,妈妈带我和图图在江边玩了一会儿才好。

这次坐的船是两江盘龙号,比上次坐的钟子期号大太多了,爸爸说有钟子期号两倍大(发船的时候,爸爸发现江边有一艘船是俞伯牙号,正好和钟子期号是一对,爸爸讲的那个知音的故事)。
船有三层,一楼是餐厅、二楼是客房、三楼是观景台。几乎所有乘客都坐在三楼看江景,爸爸也在最靠边上的一排选了四个位置。
我们在船上看风景,吃零食,非常开心。船一直从码头(大圆球)那个位置,穿过长江大桥,到鹦鹉洲长江大桥附近才返航。返航明显要快很多,可能着就是所谓 “归心似箭” 吧!
看到大桥下面有火车一直在通行,而且大桥看起来像是几个大墩子上搞的一个复杂的钢结构桥体。
对了,水里面有人在游泳,每个人身后都有一个橙色的球球,爸爸说这是跟屁虫,里面放水和食物、干衣服,也不知道是不是真的是这样。

船靠岸之后,我们为了节约时间,先打车到循礼门站,这样可以直接坐二号线直达友邻天地(坐出门的时候骑过来的电动车和自行车回家),不用换乘。
图图在地铁上又拉尿了,几乎每次坐地铁都拉尿。确实做地铁的时间有点长,图图又不会说话。怕捂出痱子来,天气太热就没有给图图穿尿不湿,可能坐公共交通还是得穿上,总是搞得地上很长的“尿流”,容易招人嫌弃,我们自己也尴尬。
PS:在船上,图图也拉了尿,在楼梯上。

到家很晚了,我们都很累,和昨天一样,洗了澡就睡觉了。

#1063 客户分级

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/1、4/1、7/1、10/1)根据上个季度的消费金额,系统自动计算客户等级。
  2. 商务部门可以手动指定客户等级(申请流程),优先级高于系统自动计算结果。
  3. 系统自动创建客户群,按照标准拉指定人员进群提供支持。
    如果客户等级下调,不符合建群标准,保留原权益一个月,然后通知客户,并在两周后将客户群冻结。
  4. 黄金、铂金、钻石客户问题专项跟进,每周总结,每月总结,季度总结,年度总结。

权益:

  • 知识库
  • 产品简报
  • 线上培训
  • 线下活动
  • 优惠券
  • 定制开发

Diamond
Platinum
Gold
Silver
Bronze
Iron
Basic

#1061 ES2025 新特性

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 各主要版本及其核心变化:

  1. ES1(1997 年):这是 ECMAScript 的首个版本,它的制定参考了 JavaScript 1.1,是一个基础版本,为后续的发展奠定了基础。
  2. ES2(1998 年):此版本主要是为了使规范与 ISO/IEC 16262 国际标准保持一致,并没有对语言功能进行实质性的扩展。
  3. ES3(1999 年):这是一个具有重要意义的版本,引入了众多核心特性,包括正则表达式、try/catch 异常处理、do-while 循环以及更完善的字符串处理功能等,极大地丰富了 ECMAScript 的功能。
  4. ES4(未发布):该版本计划进行大幅更新,但由于各方在设计理念上存在较大分歧,最终未能正式发布。
  5. ES5(2009 年):引入了严格模式(strict mode),对 JSON 对象进行了标准化,还新增了数组方法(如 forEach、map、filter)和 Object.defineProperty 等特性,提升了代码的规范性和可维护性。
  6. ES5.1(2011 年):这是一个修正版本,主要是对 ES5 的规范进行了澄清和完善,使其更加严谨。
  7. ES6(ES2015):带来了众多革命性的特性,如箭头函数、let/const 块级作用域、Promise 异步编程、class 类和继承、模块系统(import/export)以及解构赋值等,使 ECMAScript 的语法更加现代化。
  8. ES2016(ES7):新增了数组 includes 方法和指数运算符(**),进一步扩展了 ECMAScript 的功能。
  9. ES2017(ES8):引入了 async/await 异步编程模式、Object.values/entries、字符串填充(padStart/padEnd)以及共享内存和原子操作等特性,提升了异步编程的便利性。
  10. ES2018(ES9):支持异步迭代器、Rest/Spread 属性、Promise.finally 以及正则表达式的一些增强功能,如后行断言等,增强了语言的灵活性。
  11. ES2019(ES10):新增了 Array.flat/flattenObject.fromEntriesString.trimStart/End、可选的 catch 绑定以及 Symbol.description 等特性,简化了代码编写。
  12. ES2020(ES11):引入了 BigInt 数据类型、空值合并运算符(??)、可选链操作符(?.)、Promise.allSettledglobalThis 以及模块动态导入等功能,提升了语言的表达能力。
  13. ES2021(ES12):包含逻辑赋值运算符(&&=、||=、??=)、数字分隔符(_)、Promise.any 和 WeakRefs 等特性,进一步完善了语言功能。
  14. ES2022(ES13):新增了类字段声明、静态类字段和私有方法、Top-level await 以及 Error Cause 等特性,使类的定义更加简洁和强大。
  15. ES2023(ES14):引入了 Array find from last、Hashbang 语法、WeakMap 和 WeakSet 的新方法以及 Symbol.dispose 和 Disposable Objects 等特性,增强了语言的实用性。
  16. 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 以确保兼容性。

参考资料与拓展阅读

#1060 SMTP RCPTTO 命令 DELIVERBY 拓展

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 报告给发送方?

#1059 尼日尔对华政策

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 月,尼日尔军政府以薪酬不公平、税务违规等理由,驱逐了中国石油天然气集团的三名高层管理人员,冻结了炼油厂的银行账户,还撤销了中资酒店的营业执照。

    军政府诉求:

    1. 将原油分成比例从 15% 提高至 30%;
    2. 追缴炼油厂“欠税”1.3 亿美元;
    3. 强制要求中企高管本土化。

    同时:

    1. 撕毁与美国和法国的国防协议,驱逐法国驻军,控制铀矿
    2. 与乌克兰断交(可以看到俄罗斯对新政权的影响)
    3. 俄罗斯瓦格纳雇佣兵公司接管了尼日尔首都包围工作
  • 今年 5 月,局势进一步升级,尼日尔方面计划削减石油工人人数,要求一些中国员工在 5 月 31 日之前离开该国,人数可能多达数十人。给出的理由是外籍员工在当地工作时间超过其法律规定时长。

    • 五月底,尼日尔政府又在阻拦中石油员工离境。
  • 今年 6 月,尼日尔外长访华,并在与中方的谈话中表示,希望加强与中方之间的经贸合作。

尼日尔的问题

  1. 长期以来经济不发达,在摆脱法国殖民影响后,经济发展缺乏稳定支撑。
  2. 虽然拥有丰富的矿产资源(铀矿储量位居世界前列),但是没有开采技术,需要外资的帮助。
  3. 资源开采中获得的资金收入没有能够用于发展经济和改善民生,还承担了环境破坏的后果。

现状

  1. 尼日尔国内安全局势不佳,武装冲突频发,中国铺设的石油管道多次被炸断
  2. 尼日尔石油产能下降了 70%
    本国油价上涨 4 倍
  3. 营商环境恶化导致的国际舆论压力
    主权信用评级下调到 CCC
  4. 中国对尼日尔军政府的不信任

对中国的影响

  1. 过去数十年,中国对尼日尔大量援助和支持,广泛参与当地的基础设施建设,帮助其构建原油出口产业链。
  2. 西方媒体恶意抹黑中非合作(“新殖民主义”),中方的应对是非常无力的。
  3. 为了避免类似情况再次发生,必须对尼日尔采取严厉的处罚措施。

此次事件暴露了中企在非投资的三大风险:

  • 政权更迭风险:非洲 54 国中,23 国近十年发生过政变;
  • 资源民族主义:刚果(金)、津巴布韦等国频繁以环保、劳工权益为名强制外资股权转让;
  • 地缘政治裹挟:美西方通过舆论战将中非合作污名化为“新殖民主义”。

参考资料与拓展阅读

#1058 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 已被弃用)

步骤

  1. 环境准备

    # 更新系统
    sudo apt update && sudo apt upgrade -y
    # 安装必要工具
    sudo apt install -y curl apt-transport-https ca-certificates
    
  2. 安装容器运行时 (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
    
  3. 安装 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
    
  4. 初始化集群

    # 初始化控制平面
    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
    
  5. 安装网络插件 (Flannel)

    kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
    
  6. 允许主节点调度 Pod (单节点集群)

    kubectl taint nodes --all node-role.kubernetes.io/control-plane-
    

配置

  1. 日志管理

    # 查看Pod日志
    kubectl logs <pod-name>
    
  2. 存储配置

    创建 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

#1057 Bash timeout

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"

#1056 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: 致命错误

#1055 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