refactor: Complete vault remediation - fix duplicates, broken links, and add frontmatter
Resolved 48 identified issues across 5 remediation batches: Critical Fixes (2/2 = 100%): - Removed duplicate "System Architec" directory with 4 archived files - Fixed broken PARA Notes wikilinks in 2 Outline.md files High Priority (14/15 = 93%): - Consolidated 10+ duplicate file pairs to canonical locations - Added frontmatter to 30 files in 200-area (now 100% coverage) - Relocated orphaned image with updated reference - Removed security-sensitive file duplicates Medium Priority (32/41 = 78%): - Deleted 4 empty files (0-15 bytes each) - Relocated misplaced files to proper PARA categories - Improved archive organization structure File Changes: - Modified: 33 files (frontmatter + wikilink fixes) - Moved: 16 files (to archive or new locations) - Deleted: 6 files (duplicates after archival) - Created: 25 files (archived copies + documentation) Vault Health Improvement: - Frontmatter coverage: 43% → 75% - Broken wikilinks: 2 → 0 - Duplicate files: 10+ → 0 - Empty files: 4 → 0 - Overall health score: 6.5/10 → 8.5/10 Documentation: - Created comprehensive remediation plan and batch reports in copilot/ - All changes tracked with detailed change reports - No data loss - duplicates archived, not deleted 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.5
parent
5881ca5c80
commit
9f6e62676e
Executable
+493
@@ -0,0 +1,493 @@
|
||||
|
||||
|
||||
# 冯志强
|
||||
|
||||
男 | 50 岁(1975-08)| 27 年工作经验 | 现居广州
|
||||
|
||||
- 手机:13822217956
|
||||
- 邮箱:zhiqiang@windy.me
|
||||
|
||||
---
|
||||
|
||||
## 求职意向
|
||||
|
||||
- 期望职位:系统架构师 / 技术负责人
|
||||
- 工作性质:全职
|
||||
- 求职状态:希望有更大的舞台
|
||||
|
||||
---
|
||||
|
||||
## 个人优势
|
||||
|
||||
- 长期从事 J2EE 企业级应用系统架构与实现,具有丰富的架构设计经验
|
||||
- 超过 20 年的软件开发、项目实施与现场运维经验
|
||||
- 熟悉机场信息系统、智慧城市平台、大型赛事指挥中心、政务办公等行业应用
|
||||
- 精通 Java、Oracle、AIX / Linux 等企业级技术环境
|
||||
- 具备从需求分析、架构设计、开发管理到上线运维的完整项目生命周期经验
|
||||
|
||||
---
|
||||
|
||||
## 工作经历
|
||||
|
||||
### 广州智能科技发展有限公司(民营)
|
||||
|
||||
**架构师|2003/03 – 至今|广州**
|
||||
|
||||
**主要职责:**
|
||||
|
||||
- 负责公司核心项目的系统架构设计与技术路线规划
|
||||
- 搭建应用系统框架及开发 / 测试 / 生产环境
|
||||
- 解决开发过程中的关键技术与性能问题
|
||||
- 组织项目实施、上线部署及现场运行保障
|
||||
- 持续为重点客户(机场、政府、运营机构等)提供技术支持与系统优化
|
||||
|
||||
**涉及领域:**
|
||||
|
||||
- 机场信息系统集成(航班管理、资源分配、电报系统、中央信息集成等)
|
||||
- 智慧城市平台及大屏幕展示系统
|
||||
- 大型赛事(广州亚运会、亚残运会、深圳大运会)信息中心和应急处理系统
|
||||
- 政府公文归档、培训管理及内部业务管理系统
|
||||
|
||||
---
|
||||
|
||||
### 广东泰信实业有限公司(国企)
|
||||
|
||||
**软件工程师|2001/09 – 2003/03|广州**
|
||||
|
||||
**主要职责:**
|
||||
|
||||
- 参与软件系统架构设计与技术方案讨论
|
||||
- 制定并执行项目开发计划
|
||||
- 负责短信接口及相关业务功能开发
|
||||
- 参与企业门户、会员管理等系统的实现与维护
|
||||
|
||||
---
|
||||
|
||||
### 点石资讯有限公司(合资)
|
||||
|
||||
**软件工程师|2000/04 – 2001/08|中山**
|
||||
|
||||
**主要职责:**
|
||||
|
||||
- 参与 B2B / B2C 商业平台及信息平台的需求分析与系统设计
|
||||
- 搭建开发、测试环境,编写核心业务代码
|
||||
- 编写技术文档和用户使用文档,支持系统上线及日常维护
|
||||
|
||||
---
|
||||
|
||||
### 昆明博通信息网络技术有限公司(民营)
|
||||
|
||||
**软件工程师|1999/10 – 2000/03|昆明**
|
||||
|
||||
- 参与公司网站及相关应用系统的设计与开发
|
||||
- 协助完成整体技术方案和实现
|
||||
|
||||
---
|
||||
|
||||
### 云南百姓服务网有限公司(国企)
|
||||
|
||||
**硬件工程师|1999/01 – 1999/08|昆明**
|
||||
|
||||
- 担任网络管理员及系统软硬件管理员
|
||||
- 负责一套呼叫中心系统的日常运行维护及软硬件故障排查
|
||||
|
||||
---
|
||||
|
||||
### 云南汇友系统集成有限公司(民营)
|
||||
|
||||
**售后技术支持主管|1998/10 – 1999/01|昆明**
|
||||
|
||||
- 负责家用电脑硬件组装与测试
|
||||
- 提供家用电脑售后软硬件服务及现场技术支持
|
||||
|
||||
---
|
||||
|
||||
## 项目经验(节选)
|
||||
|
||||
> 以下为从原始简历整理后的主要项目,去除重复的“开发工具 / 硬件环境”描述,仅保留项目内容与职责。
|
||||
|
||||
### 南京智慧城市项目
|
||||
|
||||
**时间:** 2012/03 – 至今(按阶段参与建设与运维支持)
|
||||
|
||||
**项目简介:**
|
||||
|
||||
- 参与南京智慧城市项目中分包部分,包括大屏幕控制、城市指标展示等模块
|
||||
- 总承包商为南京邮电设计院
|
||||
|
||||
**个人职责:**
|
||||
|
||||
- 参与系统架构设计与技术方案制定
|
||||
- 负责城市指标展示及大屏控制相关模块的设计与实现
|
||||
- 协调与总包方及其他系统的技术接口与联调
|
||||
|
||||
---
|
||||
|
||||
### 深圳大运会软件系统
|
||||
|
||||
**时间:** 2010/06 – 2012/12(大运会期间及后续维护周期内)
|
||||
|
||||
**项目简介:**
|
||||
|
||||
- 软件包含:事件上报系统、应急处理系统、大屏幕显示系统等
|
||||
|
||||
**个人职责:**
|
||||
|
||||
- 参与系统技术架构和关键模块设计
|
||||
- 编写核心业务代码并负责系统联调
|
||||
- 大运会期间提供现场技术支持与故障处理
|
||||
|
||||
---
|
||||
|
||||
### 广州亚运会 / 亚残运信息中心软件
|
||||
|
||||
**时间:** 2009/06 – 2010/11
|
||||
|
||||
**项目简介:**
|
||||
|
||||
- 信息中心软件包括事件上报系统、应急处理系统、大屏幕显示系统等
|
||||
|
||||
**个人职责:**
|
||||
|
||||
- 负责关键模块设计与开发
|
||||
- 赛事期间保障系统稳定运行,提供应急响应支持
|
||||
|
||||
---
|
||||
|
||||
### 沈阳机场二期改造
|
||||
|
||||
**时间:** 2007/05 – 2015/12(建设及后续维护阶段)
|
||||
|
||||
**项目简介:**
|
||||
|
||||
- 沈阳机场二期扩建信息系统
|
||||
- 软件包括:航班管理系统、资源分配系统、中央信息集成、电报系统等
|
||||
|
||||
**个人职责:**
|
||||
|
||||
- 参与项目总体设计与模块划分
|
||||
- 负责核心业务系统开发及数据库逻辑实现
|
||||
- 在建设期及后续维护期内持续进行系统优化与技术支持
|
||||
|
||||
---
|
||||
|
||||
### 天津滨海国际机场系统集成
|
||||
|
||||
**时间:** 2006/10 – 2010/05
|
||||
|
||||
**项目简介:**
|
||||
|
||||
- 天津滨海国际机场信息系统集成项目
|
||||
- 包括:航班管理系统、资源分配系统、内部查询系统、中央信息总线、电报处理系统、机场核心网络建设等
|
||||
|
||||
**个人职责:**
|
||||
|
||||
- 参与系统集成方案设计与实现
|
||||
- 负责电报处理、中央信息总线等模块的开发与维护
|
||||
- 参与部分系统的现场部署与调试
|
||||
|
||||
---
|
||||
|
||||
### 番禺政府公文归档 / 广州软件蓝领施训系统 / 广州市委秘书处公文分发系统
|
||||
|
||||
**时间:** 2005/01 – 2006/02
|
||||
|
||||
**项目简介与职责:**
|
||||
|
||||
- **番禺政府公文归档系**
|
||||
|
||||
--------
|
||||
|
||||
# 冯志强
|
||||
|
||||
**系统架构师 / 高级技术负责人**
|
||||
📍 广州 | 📞 138****7956 | 📧 wind****@gmail.com
|
||||
🎂 1975年生 | 💼 27年 IT从业经验(20年+核心开发与实施,15年架构设计)
|
||||
|
||||
---
|
||||
|
||||
## 📝 职业综述
|
||||
|
||||
- **资深架构背景**:拥有超过 20 年企业级应用开发与实施经验,长期服务于**机场、大型赛事、智慧城市**等对稳定性要求极高的领域。
|
||||
- **全栈交付能力**:具备从需求调研、架构规划、核心代码编写、环境搭建到现场运维的软件全生命周期(SDLC)掌控力。
|
||||
- **高可靠性专家**:擅长构建基于 Java/Oracle/Unix 体系的高可用系统,在广州新白云机场、广州亚运会等**零故障**要求的项目中担任核心技术骨干。
|
||||
- **持续技术演进**:在深耕传统稳态架构(Monolithic/SOA)的同时,保持对云原生、Go 语言及现代监控体系的学习与实践。
|
||||
|
||||
---
|
||||
|
||||
## 🛠 核心技术栈
|
||||
|
||||
**✅ 企业级应用开发 (Expert)**
|
||||
|
||||
- **语言**:Java (J2EE, Servlet, JSP, JDBC), Shell Scripting
|
||||
- **框架**:传统企业级架构设计,熟悉 MVC 模式及各类各类内部集成总线设计
|
||||
- **中间件**:JBoss, Tomcat, WebLogic, IBM MQ (Series)
|
||||
|
||||
**✅ 数据库与存储 (Expert)**
|
||||
|
||||
- **Oracle**:精通 Oracle 10g/11g/12c 体系,擅长 PL/SQL 开发、存储过程编写及复杂 SQL 性能调优
|
||||
- **数据处理**:具备海量数据归档、报表统计及高并发写入场景的设计经验
|
||||
|
||||
**✅ 系统与运维 (Proficient)**
|
||||
|
||||
- **OS**:精通 AIX, Linux (RHEL/CentOS), Windows Server, 熟悉 IBM Mainframe (MVS/Z-OS环境)
|
||||
- **工具**:Eclipse, PL/SQL Developer, PowerDesigner, CVS/SVN
|
||||
|
||||
**🚀 近期技术拓展 (Modern Stack)**
|
||||
|
||||
- _说明:以下为近期自研项目或实验环境中的技术实践,由于具备深厚底层基础,可快速转化为生产力_
|
||||
- **Go 生态**:Go 语言开发,NATS 消息中间件
|
||||
- **云原生**:Docker 容器化部署,Prometheus + Grafana 监控体系
|
||||
- **时序数据库**:TimescaleDB 应用
|
||||
|
||||
---
|
||||
|
||||
## 💼 工作经历
|
||||
|
||||
### **广州智能科技发展有限公司** | 架构师 / 技术负责人
|
||||
|
||||
📅 _2003.03 – 至今 | 广州_
|
||||
|
||||
> 该公司专注于机场信息系统集成、大型赛事及智慧城市解决方案。
|
||||
|
||||
- **架构规划与设计**:主导公司核心产品线(机场集成系统、赛事指挥系统)的技术选型与架构设计,确保系统在 UNIX/Linux + Oracle 环境下的长期稳定运行。
|
||||
- **技术攻坚与故障排除**:解决项目实施过程中的底层技术难题(如内存泄漏、数据库锁表、网络延迟等),作为“最后一道防线”保障系统上线。
|
||||
- **多环境管理**:负责搭建并维护开发、测试、预发布及生产环境(AIX/Linux),制定自动化部署脚本与运维规范。
|
||||
- **项目交付管理**:带领团队完成从需求分析到最终验收的全过程,协调与外部总包方(如 Unisys)的技术接口对接。
|
||||
|
||||
---
|
||||
|
||||
### **广东泰信实业有限公司** | 软件工程师
|
||||
|
||||
📅 _2001.09 – 2003.03 | 广州_
|
||||
|
||||
- 负责企业门户网站及会员管理系统的后端开发。
|
||||
- 设计并实现了短信网关接口,解决了早期短信大规模并发发送的稳定性问题。
|
||||
- 参与公司内部业务流程的数字化改造与系统实现。
|
||||
|
||||
---
|
||||
|
||||
### **点石资讯有限公司** | 软件工程师
|
||||
|
||||
📅 _2000.04 – 2001.08 | 中山_
|
||||
|
||||
- 参与 B2B/B2C 电商交易平台的核心模块开发,负责订单处理与数据库逻辑实现。
|
||||
- 编写系统详细设计文档及用户操作手册,协助 QA 部门进行功能测试。
|
||||
|
||||
---
|
||||
|
||||
### **早期职业经历 (1998-2000)**
|
||||
|
||||
- **昆明博通信息** (1999.10-2000.03):软件工程师,Web 应用开发。
|
||||
- **云南百姓服务网** (1999.01-1999.08):硬件工程师/网管,负责呼叫中心硬件及网络维护。
|
||||
- **云南汇友系统集成** (1998.10-1999.01):技术支持,PC 软硬件维护。
|
||||
|
||||
---
|
||||
|
||||
## 🏆 代表性项目 (Project Highlights)
|
||||
|
||||
> **核心亮点:** 长期服务于国家级大型项目,所负责系统均达到“关键任务级”稳定性要求。
|
||||
|
||||
### **1. 广州新白云机场信息系统集成 (AODB/集成)**
|
||||
|
||||
- **角色**:核心开发 / 现场技术负责人
|
||||
- **内容**:参与 Unisys 总包的机场核心系统建设,负责 AMS(资源分配)、IMG(信息网关)、IIS(信息查询)子系统的落地与本地化开发。
|
||||
- **难点**:系统需 24x7 不间断运行,且涉及与全球主要航空系统的数据交换。
|
||||
- **成果**:成功完成了系统在新机场的顺利转场与上线,保障了开航初期的平稳运行,建立了一套完善的系统日志与监控机制。
|
||||
|
||||
### **2. 广州亚运会 / 深圳大运会 信息中心系统**
|
||||
|
||||
- **角色**:系统架构师
|
||||
- **内容**:为大型赛事提供事件上报、应急联动指挥、大屏展示控制等核心软件。
|
||||
- **难点**:赛事期间**绝对不可中断**,对实时性要求极高。
|
||||
- **成果**:系统在亚运会及大运会期间实现“零重大故障”,高效支撑了指挥中心对突发事件的决策调度。
|
||||
|
||||
### **3. 天津/沈阳 机场二期扩建工程**
|
||||
|
||||
- **角色**:技术架构主导
|
||||
- **内容**:负责异地机场的航班显示与集成系统部署。
|
||||
- **成果**:设计了适应不同机场硬件环境的通用适配层,降低了异地实施的二次开发成本,实现了多地系统的统一维护标准。
|
||||
|
||||
### **4. 南京智慧城市展示与控制系统**
|
||||
|
||||
- **角色**:后端架构与接口负责人
|
||||
- **内容**:负责智慧城市各项民生/政务指标的数据采集、清洗与大屏可视化后端支撑。
|
||||
- **成果**:解决了多源异构数据(数据库、文件、API)的统一接入问题,提升了数据展示的实时性。
|
||||
|
||||
---
|
||||
|
||||
## 🎓 教育背景
|
||||
|
||||
**华南理工大学 (985 / 211)** | 本科
|
||||
📅 _1994.09 – 1998.07_
|
||||
|
||||
- **主修**:土木工程
|
||||
- **辅修**:计算机科学与技术(系统学习数据结构、操作系统、数据库原理等核心课程)
|
||||
|
||||
---
|
||||
|
||||
## 🗣 语言与兴趣
|
||||
|
||||
- **语言**:普通话(精通)、粤语(熟练)、英语(可熟练阅读各类技术文档与原版书籍)
|
||||
- **兴趣**:摄影、电影、音乐、旅游
|
||||
|
||||
---
|
||||
|
||||
### 💡 给你的修改说明:
|
||||
|
||||
1. **学历已修正**:改回了华南理工,保留了双专业背景,这其实是加分项(说明数理逻辑好,且复合背景)。
|
||||
2. **技术栈分层**:
|
||||
- 我特意加了一个**"近期技术拓展 (Modern Stack)"**。这样既诚实地表明你原来的工作是用 Java/Oracle,又展示了你现在正在学 Go/Docker 等新技术。这在面试中非常重要:**“老架构”意味着稳,“新探索”意味着你没有被时代抛弃。**
|
||||
3. **去掉了虚假指标**:
|
||||
- 把“RTO<50ms”这种如果不测就不准的数据,改成了更定性的描述,如“保障了开航初期的平稳运行”、“零重大故障”。这对于架构师来说,比编造一个数字更有说服力。
|
||||
4. **工作经历拆解**:
|
||||
- 把你 2003 年至今的这家公司,用“项目”来撑起来。因为在一家公司呆 20 年,面试官最怕的是通过“混日子”。通过列举不同年代的国家级重点项目,证明你在持续产出价值。
|
||||
|
||||
你可以基于这个版本进行微调(比如项目的具体时间点如果记得更清楚可以改一下),然后就可以生成 PDF 了。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 冯志强
|
||||
|
||||
**系统架构师 / 高级技术负责人**
|
||||
📍 广州 | 📞 13822217956 | 📧 zhiqiang@windy.me
|
||||
🎂 1975年8月生 | 💼 27年 IT从业经验(20年+核心开发与实施,15年+架构设计)
|
||||
|
||||
---
|
||||
|
||||
## 📝 职业综述
|
||||
|
||||
- **资深架构背景**:拥有超过20年企业级应用开发与实施经验,长期服务于**机场、大型赛事、智慧城市**等对稳定性要求极高的关键业务领域。
|
||||
- **全栈交付能力**:具备从需求调研、架构规划、核心代码编写、环境搭建到现场运维的**完整软件生命周期(SDLC)**掌控力。
|
||||
- **高可靠性专家**:擅长构建基于 Java/Oracle/Unix 体系的高可用系统,在广州新白云机场、广州亚运会等**零故障**要求的项目中担任核心技术骨干。
|
||||
- **持续技术演进**:在深耕传统稳态架构的同时,保持对云原生、Go 语言及现代监控体系的学习与实践,具备快速将新技术转化为生产力的能力。
|
||||
|
||||
---
|
||||
|
||||
## 🛠 核心技术栈
|
||||
|
||||
**✅ 企业级应用开发 (Expert)**
|
||||
|
||||
- **语言**:Java (J2EE, Servlet, JSP, JDBC), Shell Scripting
|
||||
- **架构**:传统企业级架构设计,精通 MVC 模式及各类内部集成总线设计
|
||||
- **中间件**:JBoss, Tomcat, WebLogic, IBM MQ (Series)
|
||||
|
||||
**✅ 数据库与存储 (Expert)**
|
||||
|
||||
- **Oracle**:精通 Oracle 10g/11g/12c 体系,擅长 PL/SQL 开发、存储过程编写及复杂 SQL 性能调优
|
||||
- **数据处理**:具备海量数据归档、报表统计及高并发写入场景的设计经验
|
||||
|
||||
**✅ 系统与运维 (Proficient)**
|
||||
|
||||
- **OS**:精通 AIX, Linux (RHEL/CentOS), Windows Server, 熟悉 IBM Mainframe (MVS/Z-OS环境)
|
||||
- **工具**:Eclipse, PL/SQL Developer, PowerDesigner, CVS/SVN
|
||||
|
||||
**🚀 近期技术拓展 (Modern Stack)**
|
||||
|
||||
- **Go 生态**:Go 语言开发,NATS 消息中间件
|
||||
- **云原生**:Docker 容器化部署,Prometheus + Grafana 监控体系
|
||||
- **时序数据库**:TimescaleDB 应用
|
||||
|
||||
---
|
||||
|
||||
## 💼 工作经历
|
||||
|
||||
### **广州智能科技发展有限公司** | 架构师 / 技术负责人
|
||||
|
||||
📅 *2003.03 – 至今 | 广州*
|
||||
|
||||
> 该公司专注于机场信息系统集成、大型赛事及智慧城市解决方案。
|
||||
|
||||
- **架构规划与设计**:主导公司核心产品线(机场集成系统、赛事指挥系统)的技术选型与架构设计,确保系统在 UNIX/Linux + Oracle 环境下的长期稳定运行。
|
||||
- **技术攻坚与故障排除**:解决项目实施过程中的底层技术难题(如内存泄漏、数据库锁表、网络延迟等),作为"最后一道防线"保障系统上线。
|
||||
- **多环境管理**:负责搭建并维护开发、测试、预发布及生产环境(AIX/Linux),制定自动化部署脚本与运维规范。
|
||||
- **项目交付管理**:带领团队完成从需求分析到最终验收的全过程,协调与外部总包方(如 Unisys、南京邮电设计院)的技术接口对接。
|
||||
|
||||
---
|
||||
|
||||
### **广东泰信实业有限公司** | 软件工程师
|
||||
|
||||
📅 *2001.09 – 2003.03 | 广州*
|
||||
|
||||
- 负责企业门户网站及会员管理系统的后端开发。
|
||||
- 设计并实现了短信网关接口,解决了早期短信大规模并发发送的稳定性问题。
|
||||
- 参与公司内部业务流程的数字化改造与系统实现。
|
||||
|
||||
---
|
||||
|
||||
### **点石资讯有限公司** | 软件工程师
|
||||
|
||||
📅 *2000.04 – 2001.08 | 中山*
|
||||
|
||||
- 参与 B2B/B2C 电商交易平台的核心模块开发,负责订单处理与数据库逻辑实现。
|
||||
- 编写系统详细设计文档及用户操作手册,协助 QA 部门进行功能测试。
|
||||
|
||||
---
|
||||
|
||||
### **早期职业经历 (1998-2000)**
|
||||
|
||||
- **昆明博通信息网络技术有限公司** (1999.10-2000.03):软件工程师,Web 应用开发
|
||||
- **云南百姓服务网有限公司** (1999.01-1999.08):硬件工程师/网管,负责呼叫中心硬件及网络维护
|
||||
- **云南汇友系统集成有限公司** (1998.10-1999.01):技术支持,PC 软硬件维护
|
||||
|
||||
---
|
||||
|
||||
## 🏆 代表性项目
|
||||
|
||||
> **核心亮点:** 长期服务于国家级大型项目,所负责系统均达到"关键任务级"稳定性要求。
|
||||
|
||||
### **1. 广州新白云机场信息系统集成 (AODB/集成)**
|
||||
|
||||
- **角色**:核心开发 / 现场技术负责人
|
||||
- **时间**:2003-2007(建设期),2007-至今(运维支持)
|
||||
- **内容**:参与 Unisys 总包的机场核心系统建设,负责 AMS(资源分配)、IMG(信息网关)、IIS(信息查询)子系统的落地与本地化开发。
|
||||
- **难点**:系统需 24x7 不间断运行,且涉及与全球主要航空系统的数据交换。
|
||||
- **成果**:成功完成了系统在新机场的顺利转场与上线,保障了开航初期的平稳运行,建立了一套完善的系统日志与监控机制。
|
||||
|
||||
---
|
||||
|
||||
### **2. 广州亚运会 / 深圳大运会 信息中心系统**
|
||||
|
||||
- **角色**:系统架构师
|
||||
- **时间**:2009.06 – 2010.11(亚运会),2010.06 – 2012.12(大运会)
|
||||
- **内容**:为大型赛事提供事件上报、应急联动指挥、大屏展示控制等核心软件。
|
||||
- **难点**:赛事期间**绝对不可中断**,对实时性要求极高。
|
||||
- **成果**:系统在亚运会及大运会期间实现"零重大故障",高效支撑了指挥中心对突发事件的决策调度。
|
||||
|
||||
---
|
||||
|
||||
### **3. 天津/沈阳 机场二期扩建工程**
|
||||
|
||||
- **角色**:技术架构主导
|
||||
- **时间**:2006.10 – 2010.05(天津),2007.05 – 2015.12(沈阳)
|
||||
- **内容**:负责异地机场的航班显示与集成系统部署。
|
||||
- **成果**:设计了适应不同机场硬件环境的通用适配层,降低了异地实施的二次开发成本,实现了多地系统的统一维护标准。
|
||||
|
||||
---
|
||||
|
||||
### **4. 南京智慧城市展示与控制系统**
|
||||
|
||||
- **角色**:后端架构与接口负责人
|
||||
- **时间**:2012.03 – 至今(按阶段参与建设与运维支持)
|
||||
- **内容**:负责智慧城市各项民生/政务指标的数据采集、清洗与大屏可视化后端支撑。
|
||||
- **成果**:解决了多源异构数据(数据库、文件、API)的统一接入问题,提升了数据展示的实时性。
|
||||
|
||||
---
|
||||
|
||||
## 🎓 教育背景
|
||||
|
||||
**华南理工大学 (985/211)** | 本科
|
||||
📅 *1994.09 – 1998.07*
|
||||
|
||||
- **主修**:土木工程
|
||||
- **辅修**:计算机科学与技术(系统学习数据结构、操作系统、数据库原理等核心课程)
|
||||
|
||||
---
|
||||
|
||||
## 🗣 语言与兴趣
|
||||
|
||||
- **语言**:普通话(精通)、粤语(熟练)、英语(可熟练阅读各类技术文档与原版书籍)
|
||||
- **兴趣**:摄影、电影、音乐、旅游
|
||||
@@ -0,0 +1,37 @@
|
||||
Title: "\[Better Developers\] Using 'From X Import Y' in Python"
|
||||
Author: [[Reuven Lerner]]
|
||||
From:
|
||||
|
||||
## Highlights:
|
||||
|
||||
Is a variation on "import" that is commonly used, which looks like this:
|
||||
from X import Y
|
||||
|
||||
The idea is pretty simple: When you say
|
||||
import foobar
|
||||
|
||||
you're creating a variable "foobar" in the current namespace. That variable is a module, whose attributes are the global variables created in the module's file
|
||||
|
||||
Whether you find it aesthetically ugly, or annoying to type, or confusing, or if you just want to put it in the current namespace, you can do that with:
|
||||
from foobar import hello
|
||||
|
||||
Or if you want both of them, you can say
|
||||
from foobar import hello, x
|
||||
|
||||
Once you have done this, the names "hello" and "x" are defined in your current namespace, and you can use them to access the module's attributes
|
||||
|
||||
Note that I keep saying, "the current namespace." That's because "import", like "def", is a way to define a variable. When you use "def", you're both creating a function object and setting a variable (the function name) to point to that function object. And when you use "import", you're both creating a module object, and setting a variable (the module name) to point to that module object.
|
||||
|
||||
But all variables can be global or local -- and modules are no different.
|
||||
|
||||
I should note that while you can use an "import" statement anywhere, it's pretty rare in my experience to have it anywhere but at the global scope
|
||||
|
||||
So: "from-import" loads the entire module, and puts the module in sys.modules. It then creates aliases to the specified names in the local namespace.
|
||||
|
||||
And if you're using "from-import" because you want to save memory, or don't want to load an entire module, that's obviously bad news.
|
||||
|
||||
When you say "from import *", you're saying that it would be totally OK for the module's variables to overwrite the variables that you have defined in the current namespace
|
||||
|
||||
For starters, "from-import" ignores names that start with an underscore (_) character
|
||||
|
||||
If I want, I can also define the variable __all__, a list of strings indicating which names should be exported when you use a wildcard
|
||||
Executable
+649
@@ -0,0 +1,649 @@
|
||||
|
||||
|
||||
### Powerdns
|
||||
|
||||
ns1
|
||||
hk2.chans.xyz
|
||||
|
||||
with docker compose:
|
||||
好的,按你要的思路来:**仍然用“官方 schema 自动建表”的 Compose 方案**(PostgreSQL 16 + PowerDNS Authoritative),**另外提供一个“手动恢复数据”的脚本**,支持恢复纯 SQL dump 和 `pg_dump -Fc` 自定义格式 dump。
|
||||
|
||||
---
|
||||
|
||||
# 目录结构(建议)
|
||||
|
||||
```
|
||||
pdns/
|
||||
├─ docker-compose.yml
|
||||
├─ auth/
|
||||
│ └─ pdns.conf
|
||||
├─ db-init/
|
||||
│ └─ 01-pdns-schema.sql # 官方 gpgsql schema(见下文获取方式)
|
||||
├─ backup/
|
||||
│ └─ pdns.dump # 你的备份文件(.sql 或 -Fc)
|
||||
└─ scripts/
|
||||
└─ restore-pdns.sh # 手动恢复脚本
|
||||
```
|
||||
|
||||
## 1) 获取 PowerDNS 官方 PostgreSQL schema
|
||||
|
||||
> **重要**:请下载与你将使用的 `powerdns/pdns-auth-49` **相同小版本**的 schema(例如 4.9.x 对应的 tag),保存为 `db-init/01-pdns-schema.sql`。
|
||||
> (官方路径通常在 `modules/gpgsqlbackend/schema.pgsql.sql` 对应版本的 tag 下。)
|
||||
|
||||
---
|
||||
|
||||
## 2) `docker-compose.yml`(保持“官方 schema 建表”的方案)
|
||||
|
||||
```yaml
|
||||
version: "3.9"
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgres:16
|
||||
container_name: pdns-db
|
||||
environment:
|
||||
POSTGRES_DB: powerdns
|
||||
POSTGRES_USER: powerdns
|
||||
POSTGRES_PASSWORD: ${PDNS_DB_PASSWORD:-changeme_db}
|
||||
volumes:
|
||||
- dbdata:/var/lib/postgresql/data
|
||||
- ./db-init:/docker-entrypoint-initdb.d:ro # 首启时自动导入 schema
|
||||
- ./backup:/backup:ro # 供手动恢复脚本读取 dump
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U powerdns -d powerdns"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
restart: unless-stopped
|
||||
networks: [dnsnet]
|
||||
|
||||
auth:
|
||||
# 固定到你要用的 4.9.x 小版本,例如 4.9.4
|
||||
image: powerdns/pdns-auth-49:4.9.4
|
||||
container_name: pdns-auth
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "53:53/udp"
|
||||
- "53:53/tcp"
|
||||
- "8081:8081" # REST API / 内置 webserver
|
||||
volumes:
|
||||
- ./auth/pdns.conf:/etc/powerdns/pdns.conf:ro
|
||||
environment:
|
||||
PDNS_API_KEY: ${PDNS_API_KEY:-changeme_api}
|
||||
healthcheck:
|
||||
test: ["CMD", "sh", "-c",
|
||||
"wget -qO- --header='X-API-Key: ${PDNS_API_KEY:-changeme_api}' http://127.0.0.1:8081/api/v1/servers/localhost | grep -q 'version'"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
restart: unless-stopped
|
||||
networks: [dnsnet]
|
||||
|
||||
networks:
|
||||
dnsnet:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
dbdata: {}
|
||||
```
|
||||
|
||||
## 3) `auth/pdns.conf`(PostgreSQL 后端示例)
|
||||
|
||||
```ini
|
||||
local-address=0.0.0.0
|
||||
local-port=53
|
||||
|
||||
launch=gpgsql
|
||||
gpgsql-host=pdns-db
|
||||
gpgsql-port=5432
|
||||
gpgsql-dbname=powerdns
|
||||
gpgsql-user=powerdns
|
||||
gpgsql-password=changeme_db
|
||||
|
||||
api=yes
|
||||
api-key=changeme_api
|
||||
webserver=yes
|
||||
webserver-address=0.0.0.0
|
||||
webserver-port=8081
|
||||
webserver-allow-from=127.0.0.1,10.0.0.0/8,192.168.0.0/16
|
||||
|
||||
version-string=anonymous
|
||||
disable-syslog=yes
|
||||
loglevel=4
|
||||
```
|
||||
|
||||
## 4) 启动
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
# 等 db 健康检查 OK 后,auth 会启动并可通过 8081 API 访问
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 手动恢复脚本(支持 .sql 与 -Fc)
|
||||
|
||||
`scripts/restore-pdns.sh`:默认**安全模式**是恢复到一个**新数据库**(避免与你现有 schema 冲突),完成后你只需把 `pdns.conf` 的 `gpgsql-dbname` 改成新库名并 `docker compose restart auth` 即可。也提供 `--inplace` 选项可“原地覆盖”(会清空原库 `public` 模式)——谨慎使用。
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# 用法:
|
||||
# scripts/restore-pdns.sh /absolute/or/relative/path/to/backup/pdns.dump
|
||||
# 可选: --inplace # 原地覆盖到 powerdns 库(会清空 public schema)
|
||||
#
|
||||
# 说明:
|
||||
# - 支持两类 dump:
|
||||
# 1) 纯 SQL
|
||||
# 2) pg_dump -Fc 自定义格式
|
||||
# - 默认行为: 恢复到新库 powerdns_restore_YYYYmmddHHMMSS
|
||||
# - 容器/数据库参数需与 docker-compose.yml 一致
|
||||
|
||||
DB_SVC="db" # Compose 中的服务名
|
||||
DB_NAME="powerdns"
|
||||
DB_USER="powerdns"
|
||||
|
||||
INPLACE=0
|
||||
if [[ "${1:-}" == "--inplace" ]]; then
|
||||
INPLACE=1
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ $# -lt 1 ]]; then
|
||||
echo "Usage: $0 [--inplace] <path-to-dump>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DUMP_PATH="$1"
|
||||
if [[ ! -f "$DUMP_PATH" ]]; then
|
||||
echo "Dump file not found: $DUMP_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 统一让容器内能看到该文件(compose 已挂载 ./backup -> /backup:ro)
|
||||
# 若传入的不是 ./backup 下的文件,临时 cp 进去容器使用
|
||||
IN_CONTAINER_DUMP=""
|
||||
if [[ "$DUMP_PATH" == ./backup/* || "$DUMP_PATH" == backup/* ]]; then
|
||||
# 剥离前缀,映射到 /backup
|
||||
BN="${DUMP_PATH##*/}"
|
||||
IN_CONTAINER_DUMP="/backup/${BN}"
|
||||
else
|
||||
# 复制到容器临时路径
|
||||
BN="$(basename "$DUMP_PATH")"
|
||||
echo "Copying dump into container..."
|
||||
docker compose cp "$DUMP_PATH" "${DB_SVC}:/tmp/${BN}"
|
||||
IN_CONTAINER_DUMP="/tmp/${BN}"
|
||||
fi
|
||||
|
||||
# 检测 dump 类型(在容器内使用 'file')
|
||||
FILE_OUT="$(docker compose exec -T ${DB_SVC} sh -lc "file -b ${IN_CONTAINER_DUMP} || true")"
|
||||
echo "Detected: ${FILE_OUT}"
|
||||
|
||||
IS_FC=0
|
||||
if echo "$FILE_OUT" | grep -qi 'PostgreSQL custom database dump'; then
|
||||
IS_FC=1
|
||||
fi
|
||||
|
||||
if [[ $INPLACE -eq 1 ]]; then
|
||||
echo ">>> INPLACE mode: dropping and recreating schema 'public' in ${DB_NAME}"
|
||||
docker compose exec -T ${DB_SVC} psql -U "${DB_USER}" -d "${DB_NAME}" -v ON_ERROR_STOP=1 <<'SQL'
|
||||
DO $$
|
||||
BEGIN
|
||||
EXECUTE 'DROP SCHEMA IF EXISTS public CASCADE';
|
||||
EXECUTE 'CREATE SCHEMA public AUTHORIZATION powerdns';
|
||||
EXECUTE 'GRANT ALL ON SCHEMA public TO powerdns';
|
||||
END$$;
|
||||
SQL
|
||||
if [[ $IS_FC -eq 1 ]]; then
|
||||
echo ">>> Restoring (-Fc) into ${DB_NAME} ..."
|
||||
docker compose exec -T ${DB_SVC} sh -lc \
|
||||
"pg_restore --clean --if-exists --no-owner -U ${DB_USER} -d ${DB_NAME} ${IN_CONTAINER_DUMP}"
|
||||
else
|
||||
echo ">>> Restoring (SQL) into ${DB_NAME} ..."
|
||||
docker compose exec -T ${DB_SVC} sh -lc \
|
||||
"psql -v ON_ERROR_STOP=1 -U ${DB_USER} -d ${DB_NAME} -f ${IN_CONTAINER_DUMP}"
|
||||
fi
|
||||
echo ">>> Done. INPLACE restore finished for DB: ${DB_NAME}"
|
||||
else
|
||||
NEWDB="powerdns_restore_$(date +%Y%m%d%H%M%S)"
|
||||
echo ">>> Creating new database: ${NEWDB}"
|
||||
docker compose exec -T ${DB_SVC} sh -lc \
|
||||
"psql -U ${DB_USER} -d postgres -v ON_ERROR_STOP=1 -c 'CREATE DATABASE ${NEWDB} OWNER ${DB_USER};'"
|
||||
|
||||
if [[ $IS_FC -eq 1 ]]; then
|
||||
echo ">>> Restoring (-Fc) into ${NEWDB} ..."
|
||||
docker compose exec -T ${DB_SVC} sh -lc \
|
||||
"pg_restore --clean --if-exists --no-owner -U ${DB_USER} -d ${NEWDB} ${IN_CONTAINER_DUMP}"
|
||||
else
|
||||
echo ">>> Restoring (SQL) into ${NEWDB} ..."
|
||||
docker compose exec -T ${DB_SVC} sh -lc \
|
||||
"psql -v ON_ERROR_STOP=1 -U ${DB_USER} -d ${NEWDB} -f ${IN_CONTAINER_DUMP}"
|
||||
fi
|
||||
|
||||
echo ">>> Done. Now edit ./auth/pdns.conf:"
|
||||
echo " gpgsql-dbname=${NEWDB}"
|
||||
echo ">>> Then restart PDNS:"
|
||||
echo " docker compose restart auth"
|
||||
fi
|
||||
```
|
||||
|
||||
给执行权限:
|
||||
|
||||
```bash
|
||||
chmod +x scripts/restore-pdns.sh
|
||||
```
|
||||
|
||||
### 使用示例
|
||||
|
||||
1. **默认安全模式(恢复到新库,不影响当前运行):**
|
||||
|
||||
|
||||
```bash
|
||||
./scripts/restore-pdns.sh ./backup/pdns.dump
|
||||
# 按提示把 auth/pdns.conf 的 gpgsql-dbname 改为脚本输出的新库名
|
||||
docker compose restart auth
|
||||
```
|
||||
|
||||
2. **原地覆盖(会清空当前库的 public schema):**
|
||||
|
||||
|
||||
```bash
|
||||
./scripts/restore-pdns.sh --inplace ./backup/pdns.dump
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 小结 / 注意点
|
||||
|
||||
- **官方 schema 自动建表**:通过 `db-init/01-pdns-schema.sql` 在首次初始化时创建所需表结构,之后你随时可以用上面的脚本**手动恢复**。
|
||||
|
||||
- **避免冲突**:若你的 dump 是“包含 schema 的完整备份”,默认脚本会恢复到**新库**,避免与已存在的官方 schema 冲突;你也可以用 `--inplace` 覆盖恢复。
|
||||
|
||||
- **版本匹配**:尽量让 dump 的来源 PostgreSQL 版本 ≤ 目标版本(例如从 13/14/15 恢复到 16 一般可行);PowerDNS 版本与 schema 文件要匹配同一小版本。
|
||||
|
||||
- **安全回滚**:新库恢复方式便于回滚——只需把 `pdns.conf` 切回旧库名并 `restart auth`。
|
||||
|
||||
|
||||
需要我把「下载 schema 的命令」按你的目标 `pdns-auth` 版本具体写死(例如 4.9.4)吗?我可以直接给出一条 `curl` 命令放到 README 里。
|
||||
|
||||
|
||||
## 4.9.8:
|
||||
|
||||
#### db init
|
||||
```
|
||||
curl -L \
|
||||
https://raw.githubusercontent.com/PowerDNS/pdns/master/modules/gpgsqlbackend/schema.pgsql.sql \
|
||||
-o db-init/01-pdns-schema.sql
|
||||
```
|
||||
|
||||
|
||||
|
||||
```
|
||||
docker compose exec -T db \
|
||||
pg_restore --clean --if-exists --no-owner \
|
||||
-U pdns -d pdns /backup/pdns.dump
|
||||
|
||||
|
||||
```
|
||||
```
|
||||
docker compose exec -e PGPASSWORD=windyboy2006 -T db \
|
||||
pg_restore --jobs=4 --clean --if-exists --no-owner --no-acl \
|
||||
-U pdns -d pdns /backup/pdns.dump
|
||||
```
|
||||
|
||||
```
|
||||
docker compose exec -T db psql -U pdns -d pdns -c "SELECT count(*) FROM domains;"
|
||||
```
|
||||
|
||||
|
||||
|
||||
db-init/02-pda.sql
|
||||
```sql
|
||||
-- 创建 PowerDNS-Admin 的数据库与用户(与 PDNS 库隔离)
|
||||
CREATE USER pdnsadmin WITH PASSWORD 'windyboy2006';
|
||||
CREATE DATABASE pdnsadmin OWNER pdnsadmin ENCODING 'UTF8';
|
||||
GRANT ALL PRIVILEGES ON DATABASE pdnsadmin TO pdnsadmin;
|
||||
|
||||
```
|
||||
|
||||
```shell
|
||||
docker compose exec -T db psql -U ${PDNS_DB_USER:-pdns} -d postgres -v ON_ERROR_STOP=1 \
|
||||
-c "DO \$\$BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname='pdnsadmin') THEN CREATE ROLE pdnsadmin LOGIN PASSWORD 'changeme_pdapass'; END IF; END\$\$;"
|
||||
|
||||
docker compose exec -T db psql -U ${PDNS_DB_USER:-pdns} -d postgres -v ON_ERROR_STOP=1 \
|
||||
-c "CREATE DATABASE pdnsadmin OWNER pdnsadmin;" || true
|
||||
|
||||
```
|
||||
|
||||
|
||||
```shell
|
||||
docker compose exec -T db psql \
|
||||
-U "${PDNS_DB_USER:-powerdns}" -d postgres -v ON_ERROR_STOP=1 \
|
||||
-c "ALTER ROLE \"${PDNSADMIN_DB_USER:-pdns}\" WITH PASSWORD '${PDNSADMIN_DB_PASSWORD}';"
|
||||
```
|
||||
|
||||
```
|
||||
pda:
|
||||
image: powerdnsadmin/pda-legacy:latest
|
||||
container_name: powerdns-admin
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
auth:
|
||||
condition: service_started
|
||||
ports:
|
||||
- "${PDA_HTTP_PORT:-9191}:80"
|
||||
environment:
|
||||
SECRET_KEY: ${PDA_SECRET_KEY:-changeme_pda_secret}
|
||||
SQLALCHEMY_DATABASE_URI: >-
|
||||
postgresql://${PDNSADMIN_DB_USER:-pdnsadmin}:${PDNSADMIN_DB_PASSWORD:-changeme_pdapass}@db:5432/${PDNSADMIN_DB:-pdnsadmin}
|
||||
restart: unless-stopped
|
||||
networks: [dnsnet]
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
docker compose exec -T db psql -U pdns -d postgres -v ON_ERROR_STOP=1
|
||||
-c "ALTER ROLE pdnsadmin WITH PASSWORD 'windyboy2006';"
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
docker compose exec -e PGPASSWORD="$PDNSADMIN_DB_PASSWORD" -T db \
|
||||
psql -U "${PDNSADMIN_DB_USER:-pdnsadmin}" -d "${PDNSADMIN_DB:-pdnsadmin}" \
|
||||
-c "select current_user, current_database();"
|
||||
```
|
||||
|
||||
```shell
|
||||
docker compose exec auth pdnsutil list-zone chans.xyz
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
docker compose exec auth pdnsutil add-record chans.xyz hk2 A 154.36.174.161
|
||||
```
|
||||
|
||||
```
|
||||
docker compose exec auth pdnsutil delete-rrset example.test www AAAA
|
||||
|
||||
```
|
||||
|
||||
|
||||
# PowerDNS Auth 变更 IP — 简版操作手册(按本次实际操作)
|
||||
|
||||
> 场景回顾:主节点(Docker,**154.36.174.161**)更换/确认公网 IP;二级节点 **us1.wsvc.info** 为二进制安装(非 Docker)。前端用 **Nginx Proxy Manager (NPM)** 代理 **PowerDNS-Admin (PDA)** 与 **PDNS API**。
|
||||
|
||||
---
|
||||
|
||||
## 1) 现状与目标
|
||||
|
||||
- **主节点(Docker)**:`pdns-auth-49:4.9.8` + `postgres:16` + `powerdnsadmin/pda-legacy`。
|
||||
|
||||
- **从节点(us1)**:二进制 `pdns-server`,数据库 `domains` 使用老式字段 `type/master`。
|
||||
|
||||
- **NPM 单独 compose**,与 PDNS/PDA 通过 **共享外部网络 `npm_proxy`** 互通。
|
||||
|
||||
- 对外 **只开放 53/tcp, 53/udp**;PDA 与 PDNS API 仅在容器网络内,由 NPM 反代并做 IP 白名单。
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 2) 主节点(Docker)操作
|
||||
|
||||
### 2.1 网络与 Compose
|
||||
|
||||
```bash
|
||||
docker network create npm_proxy || true
|
||||
```
|
||||
|
||||
**pdns compose 关键点:**
|
||||
|
||||
- `auth`:
|
||||
|
||||
- `ports`: 只保留 `53:53/udp`、`53:53/tcp`。
|
||||
|
||||
- `expose`: `8081`(API 仅在容器网络可见)。
|
||||
|
||||
- `networks`: 加入 `default` + `npm_proxy`。
|
||||
|
||||
- **挂载目录**:`./auth:/etc/powerdns:ro`(避免 pdns.conf 丢失)。
|
||||
|
||||
- 健康检查可用 `curl`:`curl -fsS -H 'X-API-Key: ${PDNS_API_KEY}' http://127.0.0.1:${PDNS_API_PORT}/api/v1/servers/localhost`。
|
||||
|
||||
- `pda`:
|
||||
|
||||
- **移除** `9191:80` 的对外发布;仅 `expose: 80`,加入 `npm_proxy` 网络。
|
||||
|
||||
|
||||
### 2.2 `auth/pdns.conf` 关键参数
|
||||
|
||||
```ini
|
||||
api=yes
|
||||
api-key=<你的长随机值>
|
||||
webserver=yes
|
||||
webserver-address=0.0.0.0
|
||||
webserver-port=8081
|
||||
webserver-allow-from=127.0.0.1,::1,172.16.0.0/12
|
||||
launch=gpgsql
|
||||
# gpgsql-* 与 Postgres 账户一致
|
||||
```
|
||||
|
||||
> **提示**:若本机 `curl http://localhost:8081` 空回应,多半命中 IPv6 `::1`;用 `curl -4` 或把 `::1` 加入 `webserver-allow-from`。
|
||||
|
||||
### 2.3 通过 NPM 反代
|
||||
|
||||
- NPM `app` 服务加入 `npm_proxy`;发布 `80/443`。
|
||||
|
||||
- 新建 Proxy Host:
|
||||
|
||||
- **PDA** → `pda:80`(绑定域名,Access List 白名单)。
|
||||
|
||||
- **PDNS API** → `auth:8081`(同上)。
|
||||
|
||||
|
||||
> 在 NPM 容器内自检:
|
||||
|
||||
```bash
|
||||
docker compose exec app curl -sI http://pda:80/ | head
|
||||
docker compose exec app curl -sI http://auth:8081/api/v1/servers/localhost | head
|
||||
```
|
||||
|
||||
### 2.4 记录修改(本次实际)
|
||||
|
||||
- **ns1.wsvc.info A** 改为 `154.36.174.161`:
|
||||
|
||||
|
||||
```bash
|
||||
curl -s -X PATCH -H "X-API-Key: $PDNS_API_KEY" -H 'Content-Type: application/json' \
|
||||
http://127.0.0.1:8081/api/v1/servers/localhost/zones/wsvc.info. \
|
||||
-d '{"rrsets":[{"name":"ns1.wsvc.info.","type":"A","changetype":"REPLACE","ttl":86400,"records":[{"content":"154.36.174.161","disabled":false}]}]}'
|
||||
```
|
||||
|
||||
- **hk2.chans.xyz A** 移除 `.101`,保留 `.161`:
|
||||
|
||||
|
||||
```bash
|
||||
curl -s -X PATCH -H "X-API-Key: $PDNS_API_KEY" -H 'Content-Type: application/json' \
|
||||
http://127.0.0.1:8081/api/v1/servers/localhost/zones/chans.xyz. \
|
||||
-d '{"rrsets":[{"name":"hk2.chans.xyz.","type":"A","changetype":"REPLACE","ttl":3600,"records":[{"content":"154.36.174.161","disabled":false}]}]}'
|
||||
```
|
||||
|
||||
- 验证:`dig @127.0.0.1 ns1.wsvc.info A +short`、`dig @127.0.0.1 hk2.chans.xyz A +short`。
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 3) us1(二进制从节点)操作(本次实际)
|
||||
|
||||
> us1 使用二进制 `pdns-server`,数据库 `domains` 为旧 schema(`type/master`)。本次已验证以下两种方式皆可;**推荐优先使用 pdnsutil 命令**。
|
||||
|
||||
### 3.1 推荐:用 `pdnsutil` 指向新主并拉取
|
||||
|
||||
确保允许从区:
|
||||
|
||||
```
|
||||
# /etc/powerdns/pdns.conf
|
||||
secondary=yes # 旧版本为 slave=yes
|
||||
```
|
||||
|
||||
把各区改为 Secondary,并设置新的主(**154.36.174.161**),然后触发 AXFR:
|
||||
|
||||
```bash
|
||||
sudo pdnsutil set-kind wsvc.info secondary
|
||||
sudo pdnsutil set-kind chans.xyz secondary
|
||||
sudo pdnsutil set-kind windy.me secondary
|
||||
|
||||
# 你的 pdnsutil 支持:change-secondary-zone-primary
|
||||
sudo pdnsutil change-secondary-zone-primary wsvc.info 154.36.174.161
|
||||
sudo pdnsutil change-secondary-zone-primary chans.xyz 154.36.174.161
|
||||
sudo pdnsutil change-secondary-zone-primary windy.me 154.36.174.161
|
||||
|
||||
# 立即拉取(若无此命令可重启 pdns 替代)
|
||||
sudo pdnsutil retrieve-secondary wsvc.info
|
||||
sudo pdnsutil retrieve-secondary chans.xyz
|
||||
sudo pdnsutil retrieve-secondary windy.me
|
||||
```
|
||||
|
||||
日志与连通性:
|
||||
|
||||
```bash
|
||||
journalctl -u pdns -e | egrep -i 'SOA|AXFR|IXFR|NOTIFY'
|
||||
dig @154.36.174.161 wsvc.info SOA +tcp +time=2 +tries=1
|
||||
```
|
||||
|
||||
> 失败多为 **TCP/53 未通** 或主节点未监听 TCP/53。
|
||||
|
||||
### 3.2 备选 A:没有该子命令时,用“重建从区”
|
||||
|
||||
```bash
|
||||
sudo pdnsutil delete-zone wsvc.info && sudo pdnsutil create-secondary-zone wsvc.info 154.36.174.161
|
||||
sudo pdnsutil delete-zone chans.xyz && sudo pdnsutil create-secondary-zone chans.xyz 154.36.174.161
|
||||
sudo pdnsutil delete-zone windy.me && sudo pdnsutil create-secondary-zone windy.me 154.36.174.161
|
||||
```
|
||||
|
||||
### 3.3 备选 B:直接改数据库后补拉取(你本次已用)
|
||||
|
||||
```sql
|
||||
-- 在 us1 上
|
||||
UPDATE domains SET type='SLAVE', master='154.36.174.161'
|
||||
WHERE name IN ('wsvc.info','chans.xyz','windy.me');
|
||||
```
|
||||
|
||||
然后:
|
||||
|
||||
```bash
|
||||
sudo pdnsutil retrieve-secondary wsvc.info || sudo systemctl restart pdns
|
||||
sudo pdnsutil retrieve-secondary chans.xyz || sudo systemctl restart pdns
|
||||
sudo pdnsutil retrieve-secondary windy.me || sudo systemctl restart pdns
|
||||
```
|
||||
|
||||
### 3.4 主节点授权(在 161 的容器上执行)
|
||||
|
||||
```bash
|
||||
US1_IP=<us1 公网 IP>
|
||||
docker compose exec auth pdnsutil set-meta wsvc.info ALLOW-AXFR-FROM $US1_IP
|
||||
docker compose exec auth pdnsutil set-meta chans.xyz ALLOW-AXFR-FROM $US1_IP
|
||||
docker compose exec auth pdnsutil set-meta windy.me ALLOW-AXFR-FROM $US1_IP
|
||||
# 可选:
|
||||
docker compose exec auth pdnsutil set-meta wsvc.info ALSO-NOTIFY $US1_IP
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4) 常见问题(按本次排障)
|
||||
|
||||
- **PDA 看不到 zone**:PDA 不读数据库,需连 PDNS API。PDA 服务器配置:`API URL=http://auth:8081`、`API Key` 与 `pdns.conf` 一致、`Server ID=localhost`。从 `pda` 容器内 `curl http://auth:8081/...` 验证。
|
||||
|
||||
- **`Empty reply from server`**:`curl` 命中 IPv6 `::1`;改 `curl -4` 或在 `webserver-allow-from` 加 `::1`。
|
||||
|
||||
- **`auth` Unhealthy**:多数是 API Key 不一致或健康检查命令在镜像中不可用;改用 `curl` 并确保 key 一致。
|
||||
|
||||
- **`Received NOTIFY ... not a primary (Refused)`**:从节点仍为 `MASTER`;将其改为 `SLAVE` 并正确设置 `master`。
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 5) 验收清单(简版)
|
||||
|
||||
- 主节点:`db` healthy、`auth` API 可返回版本、PDA 通过 NPM 可访问。
|
||||
|
||||
- us1:`domains` 中 `type=SLAVE`、`master=154.36.174.161`;`retrieve-secondary` 成功;日志有 AXFR/IXFR 记录。
|
||||
|
||||
- 主节点对 `US1_IP` 设置了 `ALLOW-AXFR-FROM`(必要时 `ALSO-NOTIFY`)。
|
||||
|
||||
- 关键记录变更已生效(`dig` 结果正确,考虑 TTL 缓存)。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
export PGHOST=127.0.0.1
|
||||
export PGPORT=5432
|
||||
export PGUSER=pdns
|
||||
export PGPASSWORD='windyboy2006'
|
||||
export PGDATABASE=pdns
|
||||
```
|
||||
|
||||
```
|
||||
pg_dump --no-owner --no-acl --format=p --file=~/pdns_backup_$(date +%F).sql \
|
||||
--single-transaction
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
docker compose exec -T db psql -U pdns -c "DROP DATABASE IF EXISTS pdns;"
|
||||
docker compose exec -T db psql -U pdns -c "CREATE DATABASE pdns OWNER pdns;"
|
||||
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
docker compose exec -T db psql -U pdns -d template1 -c "DROP DATABASE IF EXISTS pdns;"
|
||||
docker compose exec -T db psql -U pdns -d template1 -c "CREATE DATABASE pdns OWNER pdns;"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
docker compose exec -T db psql -U pdns -d pdns < backup/pdns_backup_2025-11-03.sql
|
||||
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
docker compose exec -T db psql -U pdns -d pdns -c "UPDATE domains SET type='MASTER';"
|
||||
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
docker compose exec -T db psql -U pdns -d pdns -c "DELETE FROM domainmetadata WHERE kind='AXFR-MASTER-TSIG';"
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
docker compose exec -T db psql -U pdns -d pdns -c "TRUNCATE TABLE supermasters;"
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
docker compose exec auth pdnsutil list-all-zones
|
||||
docker compose exec auth pdnsutil check-all-zones
|
||||
docker compose exec auth pdnsutil list-zone windy.me
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
```
|
||||
docker compose exec -e PGPASSWORD=windyboy2006 backup psql -h db -U pdns -d pdns -c "\l"
|
||||
|
||||
```
|
||||
File diff suppressed because it is too large
Load Diff
Executable
+1037
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
## Highlights:
|
||||
`Mock.patch ` will intercept import statements identified by a string, and return a Mock instance you can preconfigure using the techniques we discussed above.
|
||||
|
||||
we need to supply `Mock.patch ` with a string representing our specific import. We do not want to supply simply `os.getcwd ` since that would patch it for all modules, instead we want to supply the module under test’s import of os , i.e. work.os . When the module is imported patch will work its magic and return a Mock instead.
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: Batch 2 - Archived Duplicate Files
|
||||
archived: 2025-12-30
|
||||
reason: Duplicate files consolidated during vault remediation
|
||||
---
|
||||
|
||||
# Archived Duplicates - Batch 2
|
||||
|
||||
These files were duplicates of canonical versions kept elsewhere in the vault.
|
||||
|
||||
## Files Archived
|
||||
|
||||
### 1. Giffgaff ESIM Guide
|
||||
- **Archived:** `在非原生ESIM设备上申请Giffgaff ESIM.md`
|
||||
- **From:** `100-project/Personal/Phone/`
|
||||
- **Canonical:** `200-area/Lifestyle/Mobile/在非原生ESIM设备上申请Giffgaff ESIM.md`
|
||||
- **Reason:** Reference guide belongs in Area (ongoing), not Project (temporary)
|
||||
|
||||
### 2. Database Configuration
|
||||
- **Archived:** `Database.md`
|
||||
- **From:** `100-project/Personal/Software/Home Assistant/`
|
||||
- **Canonical:** `100-project/Home-Automation/Config/Database.md`
|
||||
- **Reason:** Keep in project-specific location (Home-Automation)
|
||||
|
||||
### 3. ER-X Router Documentation
|
||||
- **Archived:** `ER-X.md`
|
||||
- **From:** `100-project/Personal/Hardware/`
|
||||
- **Canonical:** `100-project/Infrastructure/Network/ER-X.md`
|
||||
- **Reason:** Keep in Infrastructure project (more organized structure)
|
||||
|
||||
### 4. DNS Documentation
|
||||
- **Archived:** `DNS.md`
|
||||
- **From:** `100-project/Personal/VPS/`
|
||||
- **Canonical:** `100-project/Infrastructure/VPS/DNS.md`
|
||||
- **Reason:** Keep in Infrastructure project (consolidated location)
|
||||
|
||||
### 5. arc42 Template
|
||||
- **Archived:** `arc42-template-EN.md`
|
||||
- **From:** `300-resources/Development/Architecture/arc42/`
|
||||
- **Canonical:** `300-resources/Personal Knowledge Management/arc42/arc42-template-EN.md`
|
||||
- **Reason:** Keep in PKM resources (primary template location)
|
||||
|
||||
### 6. Mock Patching Guide
|
||||
- **Archived:** `Mock Patching.md`
|
||||
- **From:** `300-resources/Development/`
|
||||
- **Canonical:** `300-resources/Development/Languages/Python/Mock Patching.md`
|
||||
- **Reason:** Keep in more specific location (Python subfolder)
|
||||
|
||||
### 7. Development Philosophy Article
|
||||
- **Archived:** `better developers computers are cheap people are expensive.md`
|
||||
- **From:** `300-resources/Development/`
|
||||
- **Canonical:** `300-resources/Development/Philosophy/better developers computers are cheap people are expensive.md`
|
||||
- **Reason:** Keep in more specific location (Philosophy subfolder)
|
||||
|
||||
### 8. Python Import Best Practices
|
||||
- **Archived:** `Better developers Using from X import Y in Python.md`
|
||||
- **From:** `300-resources/Development/`
|
||||
- **Canonical:** `300-resources/Development/Languages/Python/Better developers Using from X import Y in Python.md`
|
||||
- **Reason:** Keep in more specific location (Python subfolder)
|
||||
|
||||
### 9. 2025 Resume
|
||||
- **Archived:** `2025.md`
|
||||
- **From:** `200-area/Career/`
|
||||
- **Canonical:** `100-project/Personal/resume/2025.md`
|
||||
- **Reason:** Active resume belongs in project folder (job search)
|
||||
|
||||
## Security-Sensitive Files (Deleted from Active Areas)
|
||||
|
||||
These duplicates were removed because canonical versions already exist in `400-archive/security-sensitive/`:
|
||||
|
||||
1. **Apple App Password.md** - Removed from `300-resources/`
|
||||
2. **Cookies.md** - Removed from `300-resources/Network/`
|
||||
3. **Domains.md** - Removed from `300-resources/Network/`
|
||||
|
||||
**Reason:** Sensitive credentials should not be in active resource folders. Canonical versions preserved in secure archive.
|
||||
|
||||
---
|
||||
|
||||
**Total Files Archived:** 9
|
||||
**Total Security Files Removed:** 3
|
||||
**Date:** 2025-12-30
|
||||
**Batch:** 2
|
||||
@@ -0,0 +1,989 @@
|
||||
#
|
||||
|
||||
**About arc42**
|
||||
|
||||
arc42, the template for documentation of software and system
|
||||
architecture.
|
||||
|
||||
Template Version 8.2 EN. (based upon AsciiDoc version), January 2023
|
||||
|
||||
Created, maintained and © by Dr. Peter Hruschka, Dr. Gernot Starke and
|
||||
contributors. See <https://arc42.org>.
|
||||
|
||||
::: note
|
||||
This version of the template contains some help and explanations. It is
|
||||
used for familiarization with arc42 and the understanding of the
|
||||
concepts. For documentation of your own system you use better the
|
||||
*plain* version.
|
||||
:::
|
||||
|
||||
# Introduction and Goals {#section-introduction-and-goals}
|
||||
|
||||
Describes the relevant requirements and the driving forces that software
|
||||
architects and development team must consider. These include
|
||||
|
||||
- underlying business goals,
|
||||
|
||||
- essential features,
|
||||
|
||||
- essential functional requirements,
|
||||
|
||||
- quality goals for the architecture and
|
||||
|
||||
- relevant stakeholders and their expectations
|
||||
|
||||
## Requirements Overview {#_requirements_overview}
|
||||
|
||||
::: formalpara-title
|
||||
**Contents**
|
||||
:::
|
||||
|
||||
Short description of the functional requirements, driving forces,
|
||||
extract (or abstract) of requirements. Link to (hopefully existing)
|
||||
requirements documents (with version number and information where to
|
||||
find it).
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
From the point of view of the end users a system is created or modified
|
||||
to improve support of a business activity and/or improve the quality.
|
||||
|
||||
::: formalpara-title
|
||||
**Form**
|
||||
:::
|
||||
|
||||
Short textual description, probably in tabular use-case format. If
|
||||
requirements documents exist this overview should refer to these
|
||||
documents.
|
||||
|
||||
Keep these excerpts as short as possible. Balance readability of this
|
||||
document with potential redundancy w.r.t to requirements documents.
|
||||
|
||||
See [Introduction and Goals](https://docs.arc42.org/section-1/) in the
|
||||
arc42 documentation.
|
||||
|
||||
## Quality Goals {#_quality_goals}
|
||||
|
||||
::: formalpara-title
|
||||
**Contents**
|
||||
:::
|
||||
|
||||
The top three (max five) quality goals for the architecture whose
|
||||
fulfillment is of highest importance to the major stakeholders. We
|
||||
really mean quality goals for the architecture. Don't confuse them with
|
||||
project goals. They are not necessarily identical.
|
||||
|
||||
Consider this overview of potential topics (based upon the ISO 25010
|
||||
standard):
|
||||
|
||||

|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
You should know the quality goals of your most important stakeholders,
|
||||
since they will influence fundamental architectural decisions. Make sure
|
||||
to be very concrete about these qualities, avoid buzzwords. If you as an
|
||||
architect do not know how the quality of your work will be judged...
|
||||
|
||||
::: formalpara-title
|
||||
**Form**
|
||||
:::
|
||||
|
||||
A table with quality goals and concrete scenarios, ordered by priorities
|
||||
|
||||
## Stakeholders {#_stakeholders}
|
||||
|
||||
::: formalpara-title
|
||||
**Contents**
|
||||
:::
|
||||
|
||||
Explicit overview of stakeholders of the system, i.e. all person, roles
|
||||
or organizations that
|
||||
|
||||
- should know the architecture
|
||||
|
||||
- have to be convinced of the architecture
|
||||
|
||||
- have to work with the architecture or with code
|
||||
|
||||
- need the documentation of the architecture for their work
|
||||
|
||||
- have to come up with decisions about the system or its development
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
You should know all parties involved in development of the system or
|
||||
affected by the system. Otherwise, you may get nasty surprises later in
|
||||
the development process. These stakeholders determine the extent and the
|
||||
level of detail of your work and its results.
|
||||
|
||||
::: formalpara-title
|
||||
**Form**
|
||||
:::
|
||||
|
||||
Table with role names, person names, and their expectations with respect
|
||||
to the architecture and its documentation.
|
||||
|
||||
+-------------+---------------------------+---------------------------+
|
||||
| Role/Name | Contact | Expectations |
|
||||
+=============+===========================+===========================+
|
||||
| *\<Role-1>* | *\<Contact-1>* | *\<Expectation-1>* |
|
||||
+-------------+---------------------------+---------------------------+
|
||||
| *\<Role-2>* | *\<Contact-2>* | *\<Expectation-2>* |
|
||||
+-------------+---------------------------+---------------------------+
|
||||
|
||||
# Architecture Constraints {#section-architecture-constraints}
|
||||
|
||||
::: formalpara-title
|
||||
**Contents**
|
||||
:::
|
||||
|
||||
Any requirement that constraints software architects in their freedom of
|
||||
design and implementation decisions or decision about the development
|
||||
process. These constraints sometimes go beyond individual systems and
|
||||
are valid for whole organizations and companies.
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
Architects should know exactly where they are free in their design
|
||||
decisions and where they must adhere to constraints. Constraints must
|
||||
always be dealt with; they may be negotiable, though.
|
||||
|
||||
::: formalpara-title
|
||||
**Form**
|
||||
:::
|
||||
|
||||
Simple tables of constraints with explanations. If needed you can
|
||||
subdivide them into technical constraints, organizational and political
|
||||
constraints and conventions (e.g. programming or versioning guidelines,
|
||||
documentation or naming conventions)
|
||||
|
||||
See [Architecture Constraints](https://docs.arc42.org/section-2/) in the
|
||||
arc42 documentation.
|
||||
|
||||
# System Scope and Context {#section-system-scope-and-context}
|
||||
|
||||
::: formalpara-title
|
||||
**Contents**
|
||||
:::
|
||||
|
||||
System scope and context - as the name suggests - delimits your system
|
||||
(i.e. your scope) from all its communication partners (neighboring
|
||||
systems and users, i.e. the context of your system). It thereby
|
||||
specifies the external interfaces.
|
||||
|
||||
If necessary, differentiate the business context (domain specific inputs
|
||||
and outputs) from the technical context (channels, protocols, hardware).
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
The domain interfaces and technical interfaces to communication partners
|
||||
are among your system's most critical aspects. Make sure that you
|
||||
completely understand them.
|
||||
|
||||
::: formalpara-title
|
||||
**Form**
|
||||
:::
|
||||
|
||||
Various options:
|
||||
|
||||
- Context diagrams
|
||||
|
||||
- Lists of communication partners and their interfaces.
|
||||
|
||||
See [Context and Scope](https://docs.arc42.org/section-3/) in the arc42
|
||||
documentation.
|
||||
|
||||
## Business Context {#_business_context}
|
||||
|
||||
::: formalpara-title
|
||||
**Contents**
|
||||
:::
|
||||
|
||||
Specification of **all** communication partners (users, IT-systems, ...)
|
||||
with explanations of domain specific inputs and outputs or interfaces.
|
||||
Optionally you can add domain specific formats or communication
|
||||
protocols.
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
All stakeholders should understand which data are exchanged with the
|
||||
environment of the system.
|
||||
|
||||
::: formalpara-title
|
||||
**Form**
|
||||
:::
|
||||
|
||||
All kinds of diagrams that show the system as a black box and specify
|
||||
the domain interfaces to communication partners.
|
||||
|
||||
Alternatively (or additionally) you can use a table. The title of the
|
||||
table is the name of your system, the three columns contain the name of
|
||||
the communication partner, the inputs, and the outputs.
|
||||
|
||||
**\<Diagram or Table>**
|
||||
|
||||
**\<optionally: Explanation of external domain interfaces>**
|
||||
|
||||
## Technical Context {#_technical_context}
|
||||
|
||||
::: formalpara-title
|
||||
**Contents**
|
||||
:::
|
||||
|
||||
Technical interfaces (channels and transmission media) linking your
|
||||
system to its environment. In addition a mapping of domain specific
|
||||
input/output to the channels, i.e. an explanation which I/O uses which
|
||||
channel.
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
Many stakeholders make architectural decision based on the technical
|
||||
interfaces between the system and its context. Especially infrastructure
|
||||
or hardware designers decide these technical interfaces.
|
||||
|
||||
::: formalpara-title
|
||||
**Form**
|
||||
:::
|
||||
|
||||
E.g. UML deployment diagram describing channels to neighboring systems,
|
||||
together with a mapping table showing the relationships between channels
|
||||
and input/output.
|
||||
|
||||
**\<Diagram or Table>**
|
||||
|
||||
**\<optionally: Explanation of technical interfaces>**
|
||||
|
||||
**\<Mapping Input/Output to Channels>**
|
||||
|
||||
# Solution Strategy {#section-solution-strategy}
|
||||
|
||||
::: formalpara-title
|
||||
**Contents**
|
||||
:::
|
||||
|
||||
A short summary and explanation of the fundamental decisions and
|
||||
solution strategies, that shape system architecture. It includes
|
||||
|
||||
- technology decisions
|
||||
|
||||
- decisions about the top-level decomposition of the system, e.g.
|
||||
usage of an architectural pattern or design pattern
|
||||
|
||||
- decisions on how to achieve key quality goals
|
||||
|
||||
- relevant organizational decisions, e.g. selecting a development
|
||||
process or delegating certain tasks to third parties.
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
These decisions form the cornerstones for your architecture. They are
|
||||
the foundation for many other detailed decisions or implementation
|
||||
rules.
|
||||
|
||||
::: formalpara-title
|
||||
**Form**
|
||||
:::
|
||||
|
||||
Keep the explanations of such key decisions short.
|
||||
|
||||
Motivate what was decided and why it was decided that way, based upon
|
||||
problem statement, quality goals and key constraints. Refer to details
|
||||
in the following sections.
|
||||
|
||||
See [Solution Strategy](https://docs.arc42.org/section-4/) in the arc42
|
||||
documentation.
|
||||
|
||||
# Building Block View {#section-building-block-view}
|
||||
|
||||
::: formalpara-title
|
||||
**Content**
|
||||
:::
|
||||
|
||||
The building block view shows the static decomposition of the system
|
||||
into building blocks (modules, components, subsystems, classes,
|
||||
interfaces, packages, libraries, frameworks, layers, partitions, tiers,
|
||||
functions, macros, operations, data structures, ...) as well as their
|
||||
dependencies (relationships, associations, ...)
|
||||
|
||||
This view is mandatory for every architecture documentation. In analogy
|
||||
to a house this is the *floor plan*.
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
Maintain an overview of your source code by making its structure
|
||||
understandable through abstraction.
|
||||
|
||||
This allows you to communicate with your stakeholder on an abstract
|
||||
level without disclosing implementation details.
|
||||
|
||||
::: formalpara-title
|
||||
**Form**
|
||||
:::
|
||||
|
||||
The building block view is a hierarchical collection of black boxes and
|
||||
white boxes (see figure below) and their descriptions.
|
||||
|
||||

|
||||
|
||||
**Level 1** is the white box description of the overall system together
|
||||
with black box descriptions of all contained building blocks.
|
||||
|
||||
**Level 2** zooms into some building blocks of level 1. Thus it contains
|
||||
the white box description of selected building blocks of level 1,
|
||||
together with black box descriptions of their internal building blocks.
|
||||
|
||||
**Level 3** zooms into selected building blocks of level 2, and so on.
|
||||
|
||||
See [Building Block View](https://docs.arc42.org/section-5/) in the
|
||||
arc42 documentation.
|
||||
|
||||
## Whitebox Overall System {#_whitebox_overall_system}
|
||||
|
||||
Here you describe the decomposition of the overall system using the
|
||||
following white box template. It contains
|
||||
|
||||
- an overview diagram
|
||||
|
||||
- a motivation for the decomposition
|
||||
|
||||
- black box descriptions of the contained building blocks. For these
|
||||
we offer you alternatives:
|
||||
|
||||
- use *one* table for a short and pragmatic overview of all
|
||||
contained building blocks and their interfaces
|
||||
|
||||
- use a list of black box descriptions of the building blocks
|
||||
according to the black box template (see below). Depending on
|
||||
your choice of tool this list could be sub-chapters (in text
|
||||
files), sub-pages (in a Wiki) or nested elements (in a modeling
|
||||
tool).
|
||||
|
||||
- (optional:) important interfaces, that are not explained in the
|
||||
black box templates of a building block, but are very important for
|
||||
understanding the white box. Since there are so many ways to specify
|
||||
interfaces why do not provide a specific template for them. In the
|
||||
worst case you have to specify and describe syntax, semantics,
|
||||
protocols, error handling, restrictions, versions, qualities,
|
||||
necessary compatibilities and many things more. In the best case you
|
||||
will get away with examples or simple signatures.
|
||||
|
||||
***\<Overview Diagram>***
|
||||
|
||||
Motivation
|
||||
|
||||
: *\<text explanation>*
|
||||
|
||||
Contained Building Blocks
|
||||
|
||||
: *\<Description of contained building block (black boxes)>*
|
||||
|
||||
Important Interfaces
|
||||
|
||||
: *\<Description of important interfaces>*
|
||||
|
||||
Insert your explanations of black boxes from level 1:
|
||||
|
||||
If you use tabular form you will only describe your black boxes with
|
||||
name and responsibility according to the following schema:
|
||||
|
||||
+-----------------------+-----------------------------------------------+
|
||||
| **Name** | **Responsibility** |
|
||||
+=======================+===============================================+
|
||||
| *\<black box 1>* | *\<Text>* |
|
||||
+-----------------------+-----------------------------------------------+
|
||||
| *\<black box 2>* | *\<Text>* |
|
||||
+-----------------------+-----------------------------------------------+
|
||||
|
||||
If you use a list of black box descriptions then you fill in a separate
|
||||
black box template for every important building block . Its headline is
|
||||
the name of the black box.
|
||||
|
||||
### \<Name black box 1> {#__name_black_box_1}
|
||||
|
||||
Here you describe \<black box 1> according the the following black box
|
||||
template:
|
||||
|
||||
- Purpose/Responsibility
|
||||
|
||||
- Interface(s), when they are not extracted as separate paragraphs.
|
||||
This interfaces may include qualities and performance
|
||||
characteristics.
|
||||
|
||||
- (Optional) Quality-/Performance characteristics of the black box,
|
||||
e.g.availability, run time behavior, ....
|
||||
|
||||
- (Optional) directory/file location
|
||||
|
||||
- (Optional) Fulfilled requirements (if you need traceability to
|
||||
requirements).
|
||||
|
||||
- (Optional) Open issues/problems/risks
|
||||
|
||||
*\<Purpose/Responsibility>*
|
||||
|
||||
*\<Interface(s)>*
|
||||
|
||||
*\<(Optional) Quality/Performance Characteristics>*
|
||||
|
||||
*\<(Optional) Directory/File Location>*
|
||||
|
||||
*\<(Optional) Fulfilled Requirements>*
|
||||
|
||||
*\<(optional) Open Issues/Problems/Risks>*
|
||||
|
||||
### \<Name black box 2> {#__name_black_box_2}
|
||||
|
||||
*\<black box template>*
|
||||
|
||||
### \<Name black box n> {#__name_black_box_n}
|
||||
|
||||
*\<black box template>*
|
||||
|
||||
### \<Name interface 1> {#__name_interface_1}
|
||||
|
||||
...
|
||||
|
||||
### \<Name interface m> {#__name_interface_m}
|
||||
|
||||
## Level 2 {#_level_2}
|
||||
|
||||
Here you can specify the inner structure of (some) building blocks from
|
||||
level 1 as white boxes.
|
||||
|
||||
You have to decide which building blocks of your system are important
|
||||
enough to justify such a detailed description. Please prefer relevance
|
||||
over completeness. Specify important, surprising, risky, complex or
|
||||
volatile building blocks. Leave out normal, simple, boring or
|
||||
standardized parts of your system
|
||||
|
||||
### White Box *\<building block 1>* {#_white_box_emphasis_building_block_1_emphasis}
|
||||
|
||||
...describes the internal structure of *building block 1*.
|
||||
|
||||
*\<white box template>*
|
||||
|
||||
### White Box *\<building block 2>* {#_white_box_emphasis_building_block_2_emphasis}
|
||||
|
||||
*\<white box template>*
|
||||
|
||||
...
|
||||
|
||||
### White Box *\<building block m>* {#_white_box_emphasis_building_block_m_emphasis}
|
||||
|
||||
*\<white box template>*
|
||||
|
||||
## Level 3 {#_level_3}
|
||||
|
||||
Here you can specify the inner structure of (some) building blocks from
|
||||
level 2 as white boxes.
|
||||
|
||||
When you need more detailed levels of your architecture please copy this
|
||||
part of arc42 for additional levels.
|
||||
|
||||
### White Box \<\_building block x.1\_\> {#_white_box_building_block_x_1}
|
||||
|
||||
Specifies the internal structure of *building block x.1*.
|
||||
|
||||
*\<white box template>*
|
||||
|
||||
### White Box \<\_building block x.2\_\> {#_white_box_building_block_x_2}
|
||||
|
||||
*\<white box template>*
|
||||
|
||||
### White Box \<\_building block y.1\_\> {#_white_box_building_block_y_1}
|
||||
|
||||
*\<white box template>*
|
||||
|
||||
# Runtime View {#section-runtime-view}
|
||||
|
||||
::: formalpara-title
|
||||
**Contents**
|
||||
:::
|
||||
|
||||
The runtime view describes concrete behavior and interactions of the
|
||||
system's building blocks in form of scenarios from the following areas:
|
||||
|
||||
- important use cases or features: how do building blocks execute
|
||||
them?
|
||||
|
||||
- interactions at critical external interfaces: how do building blocks
|
||||
cooperate with users and neighboring systems?
|
||||
|
||||
- operation and administration: launch, start-up, stop
|
||||
|
||||
- error and exception scenarios
|
||||
|
||||
Remark: The main criterion for the choice of possible scenarios
|
||||
(sequences, workflows) is their **architectural relevance**. It is
|
||||
**not** important to describe a large number of scenarios. You should
|
||||
rather document a representative selection.
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
You should understand how (instances of) building blocks of your system
|
||||
perform their job and communicate at runtime. You will mainly capture
|
||||
scenarios in your documentation to communicate your architecture to
|
||||
stakeholders that are less willing or able to read and understand the
|
||||
static models (building block view, deployment view).
|
||||
|
||||
::: formalpara-title
|
||||
**Form**
|
||||
:::
|
||||
|
||||
There are many notations for describing scenarios, e.g.
|
||||
|
||||
- numbered list of steps (in natural language)
|
||||
|
||||
- activity diagrams or flow charts
|
||||
|
||||
- sequence diagrams
|
||||
|
||||
- BPMN or EPCs (event process chains)
|
||||
|
||||
- state machines
|
||||
|
||||
- ...
|
||||
|
||||
See [Runtime View](https://docs.arc42.org/section-6/) in the arc42
|
||||
documentation.
|
||||
|
||||
## \<Runtime Scenario 1> {#__runtime_scenario_1}
|
||||
|
||||
- *\<insert runtime diagram or textual description of the scenario>*
|
||||
|
||||
- *\<insert description of the notable aspects of the interactions
|
||||
between the building block instances depicted in this diagram.\>*
|
||||
|
||||
## \<Runtime Scenario 2> {#__runtime_scenario_2}
|
||||
|
||||
## ... {#_}
|
||||
|
||||
## \<Runtime Scenario n> {#__runtime_scenario_n}
|
||||
|
||||
# Deployment View {#section-deployment-view}
|
||||
|
||||
::: formalpara-title
|
||||
**Content**
|
||||
:::
|
||||
|
||||
The deployment view describes:
|
||||
|
||||
1. technical infrastructure used to execute your system, with
|
||||
infrastructure elements like geographical locations, environments,
|
||||
computers, processors, channels and net topologies as well as other
|
||||
infrastructure elements and
|
||||
|
||||
2. mapping of (software) building blocks to that infrastructure
|
||||
elements.
|
||||
|
||||
Often systems are executed in different environments, e.g. development
|
||||
environment, test environment, production environment. In such cases you
|
||||
should document all relevant environments.
|
||||
|
||||
Especially document a deployment view if your software is executed as
|
||||
distributed system with more than one computer, processor, server or
|
||||
container or when you design and construct your own hardware processors
|
||||
and chips.
|
||||
|
||||
From a software perspective it is sufficient to capture only those
|
||||
elements of an infrastructure that are needed to show a deployment of
|
||||
your building blocks. Hardware architects can go beyond that and
|
||||
describe an infrastructure to any level of detail they need to capture.
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
Software does not run without hardware. This underlying infrastructure
|
||||
can and will influence a system and/or some cross-cutting concepts.
|
||||
Therefore, there is a need to know the infrastructure.
|
||||
|
||||
Maybe a highest level deployment diagram is already contained in section
|
||||
3.2. as technical context with your own infrastructure as ONE black box.
|
||||
In this section one can zoom into this black box using additional
|
||||
deployment diagrams:
|
||||
|
||||
- UML offers deployment diagrams to express that view. Use it,
|
||||
probably with nested diagrams, when your infrastructure is more
|
||||
complex.
|
||||
|
||||
- When your (hardware) stakeholders prefer other kinds of diagrams
|
||||
rather than a deployment diagram, let them use any kind that is able
|
||||
to show nodes and channels of the infrastructure.
|
||||
|
||||
See [Deployment View](https://docs.arc42.org/section-7/) in the arc42
|
||||
documentation.
|
||||
|
||||
## Infrastructure Level 1 {#_infrastructure_level_1}
|
||||
|
||||
Describe (usually in a combination of diagrams, tables, and text):
|
||||
|
||||
- distribution of a system to multiple locations, environments,
|
||||
computers, processors, .., as well as physical connections between
|
||||
them
|
||||
|
||||
- important justifications or motivations for this deployment
|
||||
structure
|
||||
|
||||
- quality and/or performance features of this infrastructure
|
||||
|
||||
- mapping of software artifacts to elements of this infrastructure
|
||||
|
||||
For multiple environments or alternative deployments please copy and
|
||||
adapt this section of arc42 for all relevant environments.
|
||||
|
||||
***\<Overview Diagram>***
|
||||
|
||||
Motivation
|
||||
|
||||
: *\<explanation in text form>*
|
||||
|
||||
Quality and/or Performance Features
|
||||
|
||||
: *\<explanation in text form>*
|
||||
|
||||
Mapping of Building Blocks to Infrastructure
|
||||
|
||||
: *\<description of the mapping>*
|
||||
|
||||
## Infrastructure Level 2 {#_infrastructure_level_2}
|
||||
|
||||
Here you can include the internal structure of (some) infrastructure
|
||||
elements from level 1.
|
||||
|
||||
Please copy the structure from level 1 for each selected element.
|
||||
|
||||
### *\<Infrastructure Element 1>* {#__emphasis_infrastructure_element_1_emphasis}
|
||||
|
||||
*\<diagram + explanation>*
|
||||
|
||||
### *\<Infrastructure Element 2>* {#__emphasis_infrastructure_element_2_emphasis}
|
||||
|
||||
*\<diagram + explanation>*
|
||||
|
||||
...
|
||||
|
||||
### *\<Infrastructure Element n>* {#__emphasis_infrastructure_element_n_emphasis}
|
||||
|
||||
*\<diagram + explanation>*
|
||||
|
||||
# Cross-cutting Concepts {#section-concepts}
|
||||
|
||||
::: formalpara-title
|
||||
**Content**
|
||||
:::
|
||||
|
||||
This section describes overall, principal regulations and solution ideas
|
||||
that are relevant in multiple parts (= cross-cutting) of your system.
|
||||
Such concepts are often related to multiple building blocks. They can
|
||||
include many different topics, such as
|
||||
|
||||
- models, especially domain models
|
||||
|
||||
- architecture or design patterns
|
||||
|
||||
- rules for using specific technology
|
||||
|
||||
- principal, often technical decisions of an overarching (=
|
||||
cross-cutting) nature
|
||||
|
||||
- implementation rules
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
Concepts form the basis for *conceptual integrity* (consistency,
|
||||
homogeneity) of the architecture. Thus, they are an important
|
||||
contribution to achieve inner qualities of your system.
|
||||
|
||||
Some of these concepts cannot be assigned to individual building blocks,
|
||||
e.g. security or safety.
|
||||
|
||||
::: formalpara-title
|
||||
**Form**
|
||||
:::
|
||||
|
||||
The form can be varied:
|
||||
|
||||
- concept papers with any kind of structure
|
||||
|
||||
- cross-cutting model excerpts or scenarios using notations of the
|
||||
architecture views
|
||||
|
||||
- sample implementations, especially for technical concepts
|
||||
|
||||
- reference to typical usage of standard frameworks (e.g. using
|
||||
Hibernate for object/relational mapping)
|
||||
|
||||
::: formalpara-title
|
||||
**Structure**
|
||||
:::
|
||||
|
||||
A potential (but not mandatory) structure for this section could be:
|
||||
|
||||
- Domain concepts
|
||||
|
||||
- User Experience concepts (UX)
|
||||
|
||||
- Safety and security concepts
|
||||
|
||||
- Architecture and design patterns
|
||||
|
||||
- \"Under-the-hood\"
|
||||
|
||||
- development concepts
|
||||
|
||||
- operational concepts
|
||||
|
||||
Note: it might be difficult to assign individual concepts to one
|
||||
specific topic on this list.
|
||||
|
||||

|
||||
|
||||
See [Concepts](https://docs.arc42.org/section-8/) in the arc42
|
||||
documentation.
|
||||
|
||||
## *\<Concept 1>* {#__emphasis_concept_1_emphasis}
|
||||
|
||||
*\<explanation>*
|
||||
|
||||
## *\<Concept 2>* {#__emphasis_concept_2_emphasis}
|
||||
|
||||
*\<explanation>*
|
||||
|
||||
...
|
||||
|
||||
## *\<Concept n>* {#__emphasis_concept_n_emphasis}
|
||||
|
||||
*\<explanation>*
|
||||
|
||||
# Architecture Decisions {#section-design-decisions}
|
||||
|
||||
::: formalpara-title
|
||||
**Contents**
|
||||
:::
|
||||
|
||||
Important, expensive, large scale or risky architecture decisions
|
||||
including rationales. With \"decisions\" we mean selecting one
|
||||
alternative based on given criteria.
|
||||
|
||||
Please use your judgement to decide whether an architectural decision
|
||||
should be documented here in this central section or whether you better
|
||||
document it locally (e.g. within the white box template of one building
|
||||
block).
|
||||
|
||||
Avoid redundancy. Refer to section 4, where you already captured the
|
||||
most important decisions of your architecture.
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
Stakeholders of your system should be able to comprehend and retrace
|
||||
your decisions.
|
||||
|
||||
::: formalpara-title
|
||||
**Form**
|
||||
:::
|
||||
|
||||
Various options:
|
||||
|
||||
- ADR ([Documenting Architecture
|
||||
Decisions](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions))
|
||||
for every important decision
|
||||
|
||||
- List or table, ordered by importance and consequences or:
|
||||
|
||||
- more detailed in form of separate sections per decision
|
||||
|
||||
See [Architecture Decisions](https://docs.arc42.org/section-9/) in the
|
||||
arc42 documentation. There you will find links and examples about ADR.
|
||||
|
||||
# Quality Requirements {#section-quality-scenarios}
|
||||
|
||||
::: formalpara-title
|
||||
**Content**
|
||||
:::
|
||||
|
||||
This section contains all quality requirements as quality tree with
|
||||
scenarios. The most important ones have already been described in
|
||||
section 1.2. (quality goals)
|
||||
|
||||
Here you can also capture quality requirements with lesser priority,
|
||||
which will not create high risks when they are not fully achieved.
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
Since quality requirements will have a lot of influence on architectural
|
||||
decisions you should know for every stakeholder what is really important
|
||||
to them, concrete and measurable.
|
||||
|
||||
See [Quality Requirements](https://docs.arc42.org/section-10/) in the
|
||||
arc42 documentation.
|
||||
|
||||
## Quality Tree {#_quality_tree}
|
||||
|
||||
::: formalpara-title
|
||||
**Content**
|
||||
:::
|
||||
|
||||
The quality tree (as defined in ATAM -- Architecture Tradeoff Analysis
|
||||
Method) with quality/evaluation scenarios as leafs.
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
The tree structure with priorities provides an overview for a sometimes
|
||||
large number of quality requirements.
|
||||
|
||||
::: formalpara-title
|
||||
**Form**
|
||||
:::
|
||||
|
||||
The quality tree is a high-level overview of the quality goals and
|
||||
requirements:
|
||||
|
||||
- tree-like refinement of the term \"quality\". Use \"quality\" or
|
||||
\"usefulness\" as a root
|
||||
|
||||
- a mind map with quality categories as main branches
|
||||
|
||||
In any case the tree should include links to the scenarios of the
|
||||
following section.
|
||||
|
||||
## Quality Scenarios {#_quality_scenarios}
|
||||
|
||||
::: formalpara-title
|
||||
**Contents**
|
||||
:::
|
||||
|
||||
Concretization of (sometimes vague or implicit) quality requirements
|
||||
using (quality) scenarios.
|
||||
|
||||
These scenarios describe what should happen when a stimulus arrives at
|
||||
the system.
|
||||
|
||||
For architects, two kinds of scenarios are important:
|
||||
|
||||
- Usage scenarios (also called application scenarios or use case
|
||||
scenarios) describe the system's runtime reaction to a certain
|
||||
stimulus. This also includes scenarios that describe the system's
|
||||
efficiency or performance. Example: The system reacts to a user's
|
||||
request within one second.
|
||||
|
||||
- Change scenarios describe a modification of the system or of its
|
||||
immediate environment. Example: Additional functionality is
|
||||
implemented or requirements for a quality attribute change.
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
Scenarios make quality requirements concrete and allow to more easily
|
||||
measure or decide whether they are fulfilled.
|
||||
|
||||
Especially when you want to assess your architecture using methods like
|
||||
ATAM you need to describe your quality goals (from section 1.2) more
|
||||
precisely down to a level of scenarios that can be discussed and
|
||||
evaluated.
|
||||
|
||||
::: formalpara-title
|
||||
**Form**
|
||||
:::
|
||||
|
||||
Tabular or free form text.
|
||||
|
||||
# Risks and Technical Debts {#section-technical-risks}
|
||||
|
||||
::: formalpara-title
|
||||
**Contents**
|
||||
:::
|
||||
|
||||
A list of identified technical risks or technical debts, ordered by
|
||||
priority
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
"Risk management is project management for grown-ups" (Tim Lister,
|
||||
Atlantic Systems Guild.)
|
||||
|
||||
This should be your motto for systematic detection and evaluation of
|
||||
risks and technical debts in the architecture, which will be needed by
|
||||
management stakeholders (e.g. project managers, product owners) as part
|
||||
of the overall risk analysis and measurement planning.
|
||||
|
||||
::: formalpara-title
|
||||
**Form**
|
||||
:::
|
||||
|
||||
List of risks and/or technical debts, probably including suggested
|
||||
measures to minimize, mitigate or avoid risks or reduce technical debts.
|
||||
|
||||
See [Risks and Technical Debt](https://docs.arc42.org/section-11/) in
|
||||
the arc42 documentation.
|
||||
|
||||
# Glossary {#section-glossary}
|
||||
|
||||
::: formalpara-title
|
||||
**Contents**
|
||||
:::
|
||||
|
||||
The most important domain and technical terms that your stakeholders use
|
||||
when discussing the system.
|
||||
|
||||
You can also see the glossary as source for translations if you work in
|
||||
multi-language teams.
|
||||
|
||||
::: formalpara-title
|
||||
**Motivation**
|
||||
:::
|
||||
|
||||
You should clearly define your terms, so that all stakeholders
|
||||
|
||||
- have an identical understanding of these terms
|
||||
|
||||
- do not use synonyms and homonyms
|
||||
|
||||
A table with columns \<Term> and \<Definition>.
|
||||
|
||||
Potentially more columns in case you need translations.
|
||||
|
||||
See [Glossary](https://docs.arc42.org/section-12/) in the arc42
|
||||
documentation.
|
||||
|
||||
+-----------------------+-----------------------------------------------+
|
||||
| Term | Definition |
|
||||
+=======================+===============================================+
|
||||
| *\<Term-1>* | *\<definition-1>* |
|
||||
+-----------------------+-----------------------------------------------+
|
||||
| *\<Term-2>* | *\<definition-2>* |
|
||||
+-----------------------+-----------------------------------------------+
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
Title: "[Better Developers] Computers Are Cheap. People Are Expensive."
|
||||
Author:
|
||||
From:
|
||||
|
||||
## Highlights:
|
||||
|
||||
My point is that it took a long time for people to realize that it was OK to work with a high-level language, and that doing so didn't make you a worse programmer. When you use a high-level language, your programs might run a bit more slowly, but that's often an acceptable compromise.
|
||||
|
||||
---
|
||||
|
||||
**==In today's world, computers are cheap, while people are expensive.==**
|
||||
|
||||
---
|
||||
|
||||
Let's assume that a Python program runs twice as slowly as the equivalent Java program, and thus requires two servers instead of one server. In today's world, that server difference will probably cost a few hundred dollars per month. If the programmer writing the software is 5x as productive, then that server is more than paid for by the increase in efficiency.
|
||||
|
||||
---
|
||||
|
||||
This doesn't mean, of course, that you don't need to worry about slow code, or that there's no need for C++ programmers in the world any more. But the need for speed is increasingly balanced by something even more important: The need for maintainable software.
|
||||
|
||||
---
|
||||
|
||||
One of the reasons I love Python is that the code is clear and readable, allowing me to join a new project and dive in, because the code is written similarly to all of the other Python code I've read and written over the years.
|
||||
|
||||
---
|
||||
|
||||
Better to save your colleagues (and company) money by making things more efficient for people, rather than for computers.
|
||||
|
||||
---
|
||||
|
||||
Your 1st comment on this article **Note:** Really interesting insight with the switch to a high level language to save people time and make debugging easier instead of saving server resources. It might not always be the right equation like in our case where the biggest expense are the servers but in many cases it would be true that human price > server price
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
---
|
||||
title: "在非原生ESIM设备上申请Giffgaff ESIM"
|
||||
source: "https://simonmy.com/posts/giffgaff-esim-apply-without-official-app.html#1-%E7%94%A8%E9%82%AE%E7%AE%B1%E6%B3%A8%E5%86%8C%E4%B8%80%E4%B8%AAgiffgaff%E8%B4%A6%E5%8F%B7"
|
||||
author:
|
||||
- "[[Simon (Yu Ma)]]"
|
||||
published: 2024-10-22
|
||||
created: 2025-09-25
|
||||
description: "Progress is the activity of today and the assurance of tomorrow."
|
||||
tags:
|
||||
- "clippings"
|
||||
---
|
||||
## 背景
|
||||
|
||||
Giffgaff是英国的一家虚拟运营商,其Giffgaff卡适合长期保号使用。Giffgaff原先只提供实体SIM卡,随后开始支持将实体SIM卡转换为esim或者直接购买新的esim。Giffgaff并不提供ESIM的二维码,而是通过Giffgaff APP直接将ESIM配置文件下载到手机中。Giffgaff在申请或更换ESIM时都会检测当前手机是否能够支持ESIM功能,由于国内设备或早期发行的设备不支持ESIM功能,客户端将无法进行申请。本文介绍如何使用抓包请求的方式,直接申请Giffgaff ESIM卡,并获取二维码进行绑定。ESTK/5ber/9esim等均可采用此方案。
|
||||
|
||||
## 操作步骤
|
||||
|
||||
### 1\. 用邮箱注册一个Giffgaff账号
|
||||
|
||||
打开官网注册链接([https://www.giffgaff.com/auth/register](https://www.giffgaff.com/auth/register)),进行常规注册。特别需要注意的地方我截图放在下面,没有提到的步骤就按照常规进行填写。
|
||||
|
||||
安全提醒
|
||||
|
||||
注意!这一步的邮箱是安全邮箱,一定要自己可信的邮箱来注册,后续经常要用来做验证,不要使用临时邮箱或不安全的邮箱。
|
||||
|
||||
1. 填写安全邮箱
|
||||
2. 邮箱收到验证码后,填写进行下一步
|
||||
3. 密码符合要求填写就好,一定要记住,后续要频繁使用
|
||||
4. 选择 `No Thanks` ,生日可不写
|
||||
5. 当你看到 `Welcome` 的时候,说明已经注册成功,点击按钮回到 `我的Giffgaff`
|
||||
6. 不要关闭这个窗口,后续要用!
|
||||
|
||||
[](https://image.simonmy.com/file/1729607150231_image.png) [](https://image.simonmy.com/file/1729607245363_image.png) [](https://image.simonmy.com/file/1729607267059_image.png)
|
||||
|
||||
特别提醒
|
||||
|
||||
后续登录都是使用 `我的Giffgaff` 中显示的用户名登录,不会使用邮箱。 邮箱是用来收验证码
|
||||
|
||||
### 2\. 下载Postman客户端
|
||||
|
||||
通过官方网站下载Postman客户端,首次运行会提示并注册并登录Postman,如果你自己有账号可直接登录。切记,这里一定要注册登录,因为后续要依赖Postman的高级功能,不登录无法使用。
|
||||
|
||||
特别提醒
|
||||
|
||||
如果你仅希望临时注册一个账号并不暴露自己的邮箱,可以使用下面的网站快速获得临时邮箱,完成接验证码或确认邮件。 [https://fakemail.ink/](https://fakemail.ink/) 和 [https://fakemail.chat/](https://fakemail.chat/)
|
||||
|
||||
下载地址:https://www.postman.com/downloads/
|
||||
|
||||
[](https://image.simonmy.com/file/1729606034895_image.png) [](https://image.simonmy.com/file/1729606121802_image.png) [](https://image.simonmy.com/file/1729606169022_image.png)
|
||||
|
||||
跳回软件后的部分,自己随便填写就好,没有什么要特别注意的了。
|
||||
|
||||
### 3\. 导入Postman脚本
|
||||
|
||||
打开软件后,直接点击Import按键,粘贴脚本地址到图示位置即可。
|
||||
|
||||
脚本地址:
|
||||
|
||||
```
|
||||
https://assets.simonmy.com/2025-02-25/pNpfad.json
|
||||
```
|
||||
|
||||
备用脚本地址:
|
||||
|
||||
```
|
||||
https://image.simonmy.com/file/1740496037998_Giffgaff-swap-esim_20250225a.json
|
||||
```
|
||||
|
||||
[](https://image.simonmy.com/file/1729606423680_image.png) [](https://image.simonmy.com/file/1729606546311_image.png)
|
||||
|
||||
### 4\. Postman登录账号获取Token
|
||||
|
||||
提示:这个步骤后续还要重复操作,下文中提到重新执行 `Postman登录账号`, 具体过程执行以下步骤即可
|
||||
|
||||
要通过HTTP请求的方式直接与Giffgaff服务器通讯,首先需要获取一个Access Token。向服务器发送的请求中需要包含这个Token来验证用户身份。 具体步骤如下:
|
||||
|
||||
1. 选中这一组脚本后,依次点击 `Authorization` - `滚动条划到最后` - `Clear cookies` - `Get New Access Token`
|
||||
2. 弹窗后输入用户名和密码,注意这里的用户名是 `我的Giffgaff` 中的用户名,并不是邮箱
|
||||
3. 邮箱接收验证码,提交登录
|
||||
4. 稍等一会,Postman有一个弹框,点击按钮 `Use Token`
|
||||
|
||||
[](https://image.simonmy.com/file/1729608044731_image.png) [](https://image.simonmy.com/file/1729608249229_image.png) [](https://image.simonmy.com/file/1729608325194_image.png)
|
||||
|
||||
### 5\. 执行脚本 - 邮箱二次确认,获取签名
|
||||
|
||||
脚本中的前三步骤我合并在一起描述,本步骤是为了二次验证,获取签名。 具体步骤如下:
|
||||
|
||||
1. 点击 `發送認證郵件 Send Email Verification` ,并发送请求
|
||||
2. 安全邮箱收到验证码后,填写到 `檢查郵件認證碼 Verify Email code` 的 `Body` ,并且发送请求
|
||||
3. 点击 `取得會員資訊 Get Member` ,并发送请求
|
||||
|
||||
[](https://image.simonmy.com/file/1729609371482_image.png) [](https://image.simonmy.com/file/1729609494858_image.png) [](https://image.simonmy.com/file/1729609604305_image.png)
|
||||
|
||||
### 6\. 执行脚本 - 申请ESIM卡
|
||||
|
||||
1. 点击 `申請 SIM卡 Reserve SIM` 发送请求
|
||||
2. 注意返回体里面的 `esim` 部分,这一块要复制保存下来
|
||||
[](https://image.simonmy.com/file/1729615482105_image.png)
|
||||
|
||||
### 7\. 通过官方APP - 激活ESIM卡并完成充值
|
||||
|
||||
1. 通过 `Play商店` 或 `App Store` 下载 Giffgaff
|
||||
2. 使用用户名(注意不是邮箱)和密码 登录官方App,同样邮箱会收到验证码,正常验证即可
|
||||
3. 登录后选择选择 `SIM Card` 下的 `Activate your SIM card`
|
||||
4. 输入上一步获取的 `activationCode` 6位激活码,提交激活
|
||||
5. 页面拉到最下面,选择 `I don't want a plan` 付费方案
|
||||
|
||||
[](https://image.simonmy.com/file/1734447150223_image.png) [](https://image.simonmy.com/file/1734447173642_image.png) [](https://image.simonmy.com/file/1734447218968_image.png)
|
||||
|
||||
1. 选择最小充值金额 €10, 再次提交继续。
|
||||
2. 新增一个付款方式,并选择 `Add Card`, 这里可以使用国内发行的Visa和Master Card。 并填写账单信息,用地址生成器弄一个英国的地址。或者你写中国自己的地址也可以,并没有非常强的要求。
|
||||
3. 勾选协议授权,并提交。
|
||||
4. 稍等片刻你应该就可以看到自己的手机号码了
|
||||
|
||||
[](https://image.simonmy.com/file/1734447264041_image.png) [](https://image.simonmy.com/file/1734447318908_image.png) [](https://image.simonmy.com/file/1734447381690_image.png)
|
||||
|
||||
注意:此时此刻你是无法进行安装ESIM的,回到电脑端Postman窗口
|
||||
|
||||
### 8\. 下载ESIM,生成二维码
|
||||
|
||||
由于我的卡是之前操作过的,所以就没有办法继续演示截图。后续就是顺序执行剩下的脚本,我把步骤列在这里。
|
||||
|
||||
特别提醒
|
||||
|
||||
不要去执行 `申請交換eSIM Swap SIM` ,这个步骤一定要跳过!!!
|
||||
|
||||
1. 执行脚本 `取得eSIM Get ESIMs` , 获取当前可以下载的ESIM信息
|
||||
2. 执行脚本 `取得eSIM下載碼 Get ESIM Token` , 获取ESIM LPA信息。如果你知道LPA怎么用,下面扫码的步骤可不执行。
|
||||
3. 执行脚本 `產生QRCode Get ESIM QRCode`
|
||||
|
||||
[](https://image.simonmy.com/file/1729611969794_image.png) [](https://image.simonmy.com/file/1729612014146_image.png) [](https://image.simonmy.com/file/1729612038215_image.png)
|
||||
|
||||
### 9\. 导入ESIM, 等待服务器激活
|
||||
|
||||
使用支持eSIM的手机、EasyUICC或者其他第三方的eSIM管理工具扫描这个二维码,即可下载并安装eSIM配置文件
|
||||
|
||||
### 10\. 更换ESIM卡(SIM换ESIM同理)
|
||||
|
||||
特别提醒
|
||||
|
||||
首次申请不需要关注这个过程,此过程是帮助有换卡需求的小伙伴
|
||||
|
||||
近期Giffgaff API更新,很多小伙伴在使用脚本时都出现了 `Required header 'X-GG-MFA-REF' is not present.`异常。 如果你也遇到了这个问题,请按照下面的步骤解决。
|
||||
|
||||
1. 执行上述步骤的 `1-6` ,你会在Postman中获得一个状态为 `RESERVED` 的ESIM卡, 请如图,暂时保存这个卡的所有信息,尤其是 `activationCode` 和 `ssn` ,Postman不要关闭,后续有用!!!
|
||||
2. 登录并打开官网个人信息页([https://www.giffgaff.com/profile/details](https://www.giffgaff.com/profile/details))
|
||||
3. 找到SIM Card - Replace my SIM 这个Tab, 点击Open - Activate your SIM, 如图
|
||||
4. 进入激活页面后,填写你上述的 `activationCode` ,点击 `Active`
|
||||
5. 点击下面的确认按钮,跳转页面后再次点击确认,网页会跳转到首页并提示成功。
|
||||
6. 回到Postman, 执行上述第8步
|
||||
|
||||
> 执行脚本 `取得eSIM Get ESIMs` , 获取当前可以下载的ESIM信息
|
||||
> 执行脚本 `取得eSIM下載碼 Get ESIM Token` , 获取ESIM LPA信息。如果你知道LPA怎么用,下面扫码的步骤可不执行。
|
||||
> 执行脚本 `產生QRCode Get ESIM QRCode`
|
||||
|
||||
[](https://image.simonmy.com/file/1753876221141_GvRPUJ.png) [](https://image.simonmy.com/file/1753876440224_J0BMEg.png) [](https://image.simonmy.com/file/1753876538880_vs8rh3.png) [](https://image.simonmy.com/file/1753876624730_gQ0myu.png)
|
||||
|
||||
### 11\. 其他
|
||||
|
||||
如果你在过程中遇到了问题,可以在下方留言或通过 [https://t.me/Charpati](https://t.me/Charpati) 寻求帮助
|
||||
寻求帮助前,请一定准备好下面材料和设备:
|
||||
|
||||
1. 一个可用的安全邮箱
|
||||
2. 一个可支付的银行卡
|
||||
3. 一个支持ESIM的设备(可以是estk、5ber、9esim等)
|
||||
4. 当前遇到的问题
|
||||
|
||||
## 参考文章
|
||||
|
||||
1. [如何将GiffGaff sim卡转换为esim](https://azhu.site/posts/1015/)
|
||||
Reference in New Issue
Block a user