博客

  • OpenClaw与WordPress集成指南:自动化博客发布工作流

    OpenClaw 与 WordPress 集成指南:自动化博客发布工作流

    引言

    在当今内容创作自动化的时代,将智能助手与内容管理系统(CMS)集成已成为提升效率的关键。OpenClaw 作为一款强大的自托管 AI 助手网关,通过与 WordPress 的集成,实现了从内容创作到发布的完整自动化流程。

    本文将详细介绍如何利用 publish_blog_post 工具,构建一个高效的博客自动化发布系统。

    publish_blog_post 工具概述

    publish_blog_post 是一个用于通过 OpenClaw Manager API 向 WordPress 站点发布博客文章的自定义工具。该工具将本地内容通过 REST API 直接发布到指定的 WordPress 网站,实现博客发布的自动化。

    技术规格

    API 接口

    • API Endpoint: https://www.tmser.com/wp-json/openclaw-manager/v1/post
    • HTTP 方法: POST
    • 内容类型: application/json

    请求参数

    参数 类型 必需 说明
    title string 博客文章标题
    content string 博客文章内容(支持 HTML 格式)
    status string 发布状态:publish(立即发布)或 draft(草稿),默认 publish
    categories array 分类 ID 数组
    tags array 标签数组

    认证机制

    • 认证方式: HTTP Header 认证
    • Header 名称: X-OpenClaw-API-Key
    • 当前 API Key: axAbQgwY2BlNDnPkl0XWiVk3ss9iyWfnSvAfmBfAVCOS2X2eJXgNhaExNC6MPJS2

    调用方式详解

    1. cURL 命令行调用

    curl -X POST https://www.tmser.com/wp-json/openclaw-manager/v1/post 
      -H "Content-Type: application/json" 
      -H "X-OpenClaw-API-Key: axAbQgwY2BlNDnPkl0XWiVk3ss9iyWfnSvAfmBfAVCOS2X2eJXgNhaExNC6MPJS2" 
      -d '{
        "title": "使用 OpenClaw 自动化博客发布",
        "content": "<p>这是一篇通过 API 自动发布的文章。</p>",
        "status": "publish"
      }'
    

    2. Node.js 程序化调用

    const https = require('https');
    
    const API_URL = 'https://www.tmser.com/wp-json/openclaw-manager/v1/post';
    const API_KEY = 'axAbQgwY2BlNDnPkl0XWiVk3ss9iyWfnSvAfmBfAVCOS2X2eJXgNhaExNC6MPJS2';
    
    const postData = JSON.stringify({
        title: '文章标题',
        content: '<p>HTML 格式内容</p>',
        status: 'publish'
    });
    
    const options = {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-OpenClaw-API-Key': API_KEY,
            'Content-Length': Buffer.byteLength(postData)
        }
    };
    
    const req = https.request(API_URL, options, (res) => {
        console.log(`状态码: ${res.statusCode}`);
        let responseData = '';
        res.on('data', (chunk) => responseData += chunk);
        res.on('end', () => console.log('响应:', responseData));
    });
    
    req.write(postData);
    req.end();
    

    3. 集成到 OpenClaw 工作流

    该工具可以作为 OpenClaw 自动化工作流的一部分:

    1. 内容生成: 使用 AI 助手生成博客内容
    2. 格式转换: 将 Markdown 转换为 HTML
    3. 自动发布: 调用 API 发布到 WordPress
    4. 链接分享: 将发布后的文章链接发送到聊天应用

    实际使用案例展示

    案例一:OpenClaw 介绍文章发布

    我们在实际测试中成功发布了 OpenClaw 介绍文章:

    案例二:工具功能测试文章

    为了验证工具功能,我们发布了测试文章:

    安全注意事项

    1. API Key 保护: 当前 API Key 存储在 TOOLS.md 中,应考虑加密存储
    2. 请求验证: 建议实现输入验证,确保发布内容的合规性
    3. 权限控制: WordPress 端应对 API 调用进行权限限制
    4. HTTPS 传输: 所有通信必须通过 HTTPS 加密

    扩展可能性与未来展望

    1. 功能增强方向

    • 媒体上传: 扩展支持图片、文件附件上传
    • 批量发布: 支持多篇文章批量发布
    • 定时发布: 添加定时发布功能
    • 草稿管理: 支持草稿的编辑和更新
    • 分类标签: 完善分类和标签支持

    2. 集成方案优化

    • GitHub Actions: 结合 CI/CD 自动化发布流程
    • 本地脚本: 创建命令行工具简化调用
    • OpenClaw Skill: 开发专门的技能文件,提供更友好的交互界面

    3. 监控与日志系统

    • 发布状态跟踪与通知
    • 错误处理和自动重试机制
    • 发布历史记录和统计

    4. 企业级功能

    • 多用户权限管理
    • 内容审核工作流
    • 发布排期和协作

    完整工作流示例

    以下是一个完整的自动化博客发布工作流程:

    graph LR
        A[内容创意] --> B[AI助手生成内容]
        B --> C[Markdown格式]
        C --> D[格式转换为HTML]
        D --> E[调用发布API]
        E --> F[WordPress接收]
        F --> G[自动发布]
        G --> H[链接分享]
        H --> I[社交媒体推广]
    

    技术实现细节

    HTML 转换处理

    由于 WordPress 需要 HTML 格式内容,我们需要将 Markdown 转换为 HTML。推荐使用 marked 库:

    const { marked } = require('marked');
    const markdown = '# 标题nn内容';
    const html = marked.parse(markdown);
    

    错误处理机制

    完善的错误处理是生产环境的关键:

    try {
        // API 调用
    } catch (error) {
        console.error('发布失败:', error);
        // 重试逻辑
        // 通知机制
    }
    

    状态监控

    建议实现发布状态监控:

    function monitorPostStatus(postId) {
        // 定期检查文章状态
        // 发送成功/失败通知
    }
    

    最佳实践建议

    1. 版本控制: 将博客内容纳入 Git 版本控制
    2. 备份策略: 定期备份发布的文章
    3. 测试环境: 建立测试 WordPress 站点进行预发布验证
    4. 文档维护: 保持 API 文档和工具说明的更新
    5. 安全审计: 定期进行安全审计和密钥轮换

    结语

    OpenClaw 与 WordPress 的集成代表了 AI 助手与内容管理系统的完美结合。通过 publish_blog_post 工具,我们可以实现从内容创作到发布的端到端自动化,大大提升了内容生产的效率和一致性。

    随着技术的不断发展,这种集成模式将为内容创作者带来更多的可能性。无论是个人博客还是企业级内容平台,OpenClaw 的自动化发布能力都将成为提升竞争力的重要工具。

    开始您的自动化博客发布之旅,体验智能内容创作的无限可能!


    相关资源:

  • 测试 publish_blog_post 工具功能

    测试 publish_blog_post 工具

    这是通过 OpenClaw Manager API 发布的测试文章,用于验证 publish_blog_post 工具的功能。

    工具功能测试

    API 调用验证

    • ✅ REST API 端点访问正常
    • ✅ 认证头(X-OpenClaw-API-Key)验证通过
    • ✅ JSON 数据格式正确解析
    • ✅ HTML 内容支持正常

    发布状态检查

    • 当前时间:2026/02/24 19:28:46
    • 发布状态:publish(立即发布)
    • 内容格式:HTML

    自动发布流程

    1. 内容生成: 通过 AI 生成或编写 markdown
    2. 格式转换: markdown → HTML
    3. API 调用: 调用 WordPress REST API
    4. 状态确认: 验证发布成功

    技术实现

    curl -X POST https://www.tmser.com/wp-json/openclaw-manager/v1/post 
      -H "Content-Type: application/json" 
      -H "X-OpenClaw-API-Key: API_KEY_HERE" 
      -d '{
        "title": "测试文章标题",
        "content": "<p>测试内容</p>",
        "status": "publish"
      }'
    

    下一步计划

    1. 扩展功能: 添加分类和标签支持
    2. 错误处理: 完善异常情况处理
    3. 批量操作: 支持多篇文章批量发布
    4. 定时发布: 支持预定发布时间

    本文为自动生成的测试内容,用于验证发布工具功能。

  • OpenClaw:自托管的多渠道AI助手网关

    引言

    在AI助手日益普及的今天,我们常常面临一个选择:是使用云端服务商的封闭式助手,还是寻找一种能够完全自主控制、保护隐私的替代方案?OpenClaw 应运而生,它是一款开源的自托管网关,能够将您喜爱的聊天应用(WhatsApp、Telegram、Discord、iMessage等)与强大的AI编码助手(如Pi)无缝连接。

    OpenClaw 的核心理念是 “你的数据,你的规则”。您可以在自己的硬件上运行一个Gateway进程,让它成为您与AI助手之间的桥梁,无需依赖任何第三方托管服务,彻底掌握数据主权。

    什么是OpenClaw?

    OpenClaw 是一个 多通道AI代理网关,专为开发者和高级用户设计。它允许您通过熟悉的聊天应用与AI助手进行交互,同时保持对数据和系统的完全控制。

    核心特性

    1. 多渠道支持:单一Gateway进程同时服务WhatsApp、Telegram、Discord、iMessage等多个平台
    2. 完全自托管:运行在您自己的机器或服务器上,数据永不离开您的控制
    3. 多代理路由:支持为不同工作区或发送者创建隔离会话
    4. 丰富的媒体支持:可以发送和接收图片、音频、文档等多种媒体格式
    5. 插件化扩展:通过扩展包轻松添加Mattermost等更多平台支持
    6. 移动节点支持:可与iOS和Android设备配对,支持Canvas表面交互
    7. Web控制界面:提供浏览器仪表板,方便管理聊天、配置、会话和节点

    架构概述

    OpenClaw 采用中心化的Gateway架构,所有聊天应用和插件都连接到这个统一的网关:

    聊天应用 + 插件 → Gateway → AI代理 (Pi)
                        ↓
                    CLI / Web控制界面 / macOS应用 / 移动节点
    

    Gateway 作为会话、路由和通道连接的单一事实来源,确保了系统的稳定性和一致性。

    为什么选择OpenClaw?

    1. 数据隐私与安全

    与使用云服务的AI助手不同,OpenClaw完全运行在您的硬件上。您的对话数据、文件、配置全都留在您的控制范围内,不会被第三方收集或分析。

    2. 灵活的集成方式

    无论是通过WhatsApp与家人聊天时顺便咨询AI,还是在Telegram群组中与团队协作时获取技术支持,OpenClaw都能无缝集成到您现有的沟通流程中。

    3. 可定制的工作流

    开发者可以基于OpenClaw构建自定义的工具和扩展,创建符合特定需求的AI助手工作流。开放的API和插件系统为此提供了无限可能。

    4. 成本控制

    自托管意味着您只支付基础架构成本(如果有的话),无需为API调用支付额外费用(取决于您使用的AI模型供应商)。

    快速开始

    系统要求

    • Node.js 22+
    • AI API密钥(推荐Anthropic)
    • 5分钟时间

    安装步骤

    # 1. 安装OpenClaw
    npm install -g openclaw@latest
    
    # 2. 运行引导程序并安装服务
    openclaw onboard --install-daemon
    
    # 3. 登录聊天渠道并启动Gateway
    openclaw channels login
    openclaw gateway --port 18789
    

    访问控制界面

    启动Gateway后,您可以通过浏览器访问控制界面:

    配置示例

    OpenClaw的配置文件位于 ~/.openclaw/openclaw.json。以下是一个简单的配置示例:

    {
      "channels": {
        "whatsapp": {
          "allowFrom": ["+8612345678901"],
          "groups": {
            "*": {
              "requireMention": true
            }
          }
        }
      },
      "messages": {
        "groupChat": {
          "mentionPatterns": ["@openclaw"]
        }
      }
    }
    

    如果您不做任何配置,OpenClaw会使用内置的Pi二进制文件,并默认为每个发送者创建独立会话。

    使用场景

    个人生产力助手

    • 通过WhatsApp快速查询信息、设定提醒
    • 在Telegram中获取代码片段和技术解答
    • 通过iMessage管理日程和待办事项

    团队协作增强

    • 在Discord服务器中添加AI助手,为社区成员提供技术支持
    • 在Mattermost工作区中集成AI代码审查助手
    • 创建专门的AI助手处理常见问题解答

    开发工作流优化

    • 通过CLI与AI助手交互,快速生成代码
    • 使用Canvas功能在移动设备上展示开发进度
    • 构建自定义工具扩展OpenClaw的功能

    未来展望

    OpenClaw 作为一个活跃的开源项目,正在不断进化中:

    1. 更多渠道支持:计划添加更多即时通讯平台的集成
    2. 增强的AI模型支持:除了Pi之外,支持更多的AI代理
    3. 企业级功能:审计日志、角色权限管理、多租户支持等
    4. 生态系统建设:鼓励社区贡献插件、工具和扩展

    结语

    OpenClaw 代表了一种新的AI助手使用范式:不再是让用户适应AI服务的限制,而是让AI适应用户的习惯和环境。它巧妙地将AI能力融入到我们日常的沟通工具中,同时尊重用户对数据和隐私的控制权。

    无论您是一名希望提升个人效率的开发者,还是一个需要为团队部署AI助手的组织领导者,OpenClaw都值得您尝试。它的自托管特性、开源精神和活跃的社区支持,为构建真正个性化的AI助手体验提供了坚实的基础。

    开始您的OpenClaw之旅,体验完全自主的AI助手生活!


    了解更多

  • 基于架构的软件设计(ABSD)简介

    基于架构的软件设计(Architecture-Based Software Design,ABSD) 是一种架构驱动的设计方法,强调通过功能分解、选择架构风格和使用软件模板来实现质量和业务需求。

    功能分解

    功能分解是ABSD方法的基础之一。在功能分解中,ABSD方法使用已有的基于模块的内聚和耦合技术。通过这种方式,可以将复杂的软件系统分解为更小、更易管理的模块,从而提高系统的可维护性和可扩展性。常见的方法包括:

    领域驱动设计(DDD):通过领域建模拆分功能。
    模块化设计:将系统拆解为多个独立模块,以降低耦合度,提高可维护性。

    选择架构风格

    选择合适的架构风格是实现质量和业务需求的关键。不同的架构风格可以满足不同的需求,例如分层架构、微服务架构等。在架构设计阶段,通过选择合适的架构风格,可以确保系统在满足功能需求的同时,也能满足性能、可扩展性等非功能需求。

    使用软件模板

    软件模板是ABSD方法的另一个基础。软件模板是一种特殊类型的软件元素,描述了这种类型的元素在共享服务和底层构造的基础上如何进行交互。在软件产品线系统中,软件模板显得格外重要,因为新元素的引入是一个通用的技术,用来使产品线架构适应一个特定的产品。如选择合适的设计模式:

    • 工厂模式(Factory Pattern):用于创建对象,提高代码复用性。
    • 观察者模式(Observer Pattern):适用于事件驱动系统,提高解耦性。
    • MVC 模式(Model-View-Controller):适用于前端和后端分离的 Web 应用。

    基于架构的软件开发模型

    ABSD模型把整个软件开发过程划分为六个主要阶段:架构需求、架构设计、架构文档化、架构复审、架构实现和架构演化

  • 评审是不是在浪费时间?

    项目实施流程中,评审是很重要的一环,并且复杂的流程会有各种评审,比如需求评审,概要设计评审,详细设计评审, 用例评审等。 为什么需要有这么多评审? 不评审会有什么影响? 为什么很多开发人员反感评审,认为很多评审浪费时间? 原因是对评审的目的和收益不理解,或其参与的评审已变质。 评审核心目的形成共识, 好的评审可以大大降低项目延期风险。

    项目延期是工程研发过程中经常遇到的问题, 也是过程管理的一大难点,是体现项目经理管理能力的一大指标。 项目延期的原因有很多,根据个人几十个项目经验分析, 大部分原因是评审执行不到位。有的是评审退化为宣贯,有的是评审变成了批斗会, 还有的是根本取消了评审,其后果就是很多时候它就会在延期项目的反思会上会被拿来作为根因(很多时候再下一层的根因是不会去反思的)。个人遇到过的与评审有关延期理由有:

    • 与产品理解不一致,导致开发返工。
    • 产品逻辑不严谨,需要加需求。
    • 测试回归发现,与前产品产生兼容性或逻辑性问题。
    • 第三方原因导致。

    以上几种或多或少都是因为没有共识,而一边项目中主要形成共识方式就是评审,因此这类延期大部分是与评审有关的, 有可能是没有评审(一般是小需求),或评审只是走形式退化为宣贯, 或评审组织出问题没有达到应用的目的。 那么什么时候该有评审,又如何组织评审呢。

    我们都知道开发过程中很多阶段都是可以有评审的, 严格执行的话会导致评审形式化,评审成本增加,所以项目实际实施的时候确实很多评审会精简掉,到底哪些是需要保留呢?根据个人经验来看,存在以下情况需要保留对应的评审:

    • 需求涉及多人或多方式时,必须有需求评审, 除非连专门测试都不需要的小需求外,因为需求评审是达成需求共识的最佳方式。
    • 技术方案里涉及三方(调用或输出接口),或做了特殊解决方案时,必须要有技术方案评审。核心目的在于确认研发验证对需求理解
    • 新项目需要有独立概要设计评审, 这对共识技术架构方案, 规范的统一有重要作用。
    • 测试用例评审。 如果有测试接入,则用例评审是不可缺少。核心目的达成需求理解共识,确认测试的覆盖度。

    个人认为开发过程中的评审不是能省则省的,而是要有尽有。 我们会发现项目里该有的评审都有,但还是经常出现理解偏差; 另外,是否项目里除了Leader 都方案评审。 这其实都评审实时问题, 为了让评审目的能够实现, 有几个方面是容易忽略却对评审目标达成有关键作用的。

    • 大范围的评审,评审资料需先进行组内,或组织相干专家先进行小范围讨论,确认无颠覆性问题。
    • 评审需要安排在整体项目开发计划中。 不是临时找时间,特别找非工作时间来安排, 评审的目的是发现问题达成共识,类似头脑风暴,是需要消耗参与的相干人员大量精力的。一般需要提前安排,且安排到上午,或下午上班1小时后。
    • 评审资料要提前将资料发送到参与评审的相干人,且要求核心相干人员(如明确的关联研发,产品,测试等)充分了解。 可以采用协同编辑的问题收集列表方式,即使没有问题的也需要填写”无相关问题“,被评审人不用评审前去核对问题列表,以免造成干扰。被评审人讲解完,需标记问题列表的问题是否还存在,且记录新产生的问题。需要避免相干人临时进会, 导致对于相干人来讲评审会变成宣贯会。
    • 评审会议不要变为问题解决会。 被评审人需要把握节奏,只做宣贯方案,解决理解偏差导致共识问题,其他问题如逻辑问题,遗漏问题等只做记录,避免直接讨论解决方案或修改方案。后续可小范围讨论解决, 解决方案通知各项目参与人,特别注意不要只解决不通知, 避免解决方案导致关联方出新问题。
    • 参与评审人员应关注实质性问题。 即提问题要核心关注当前评审内容, 不要关注一些非实质问题,如文档格式,措辞等等, 也不要提自己联想到的与当前评审内容无实质关系的问题。
    • 重视评审的组织。 首先相关负责人需要重视起来,注意组织工程,会议时间, 相干人选择, 通知, 场所都要有要求。 另外,除被评审人外,有一个主持人,主要把控会议流程,及时组织偏离目标的讨论。

    总的来说,核心的问题还是要重视评审,特别是相关负责人,需要起到带头作用,带领并督促组员形成对评审重视的风气,不要让评审形式化,也不要评审变宣贯。

  • 如何理解设计模式

    不论是编码还是架构设计都逃不过设计模式, 因为合理使用一些设计模式可以怎么我们地图的扩展性,可维护性等,另外也简化了设计实现难度,有大量文章或代码可参考。然而很多开发发费了很多时间与经历去学习记忆GoF 23种设计模式, 但很少人在自己的实际项目中去应用这些设计模式,推脱的理由能找到很多,但大部分根本理由多设计模式只是学而没真正理解。 这部分人在学习设计模式的目的是不正确的, 常见有以下几种:

    • 考试或面试需要。 很多技术考试或面试会问到,需要应付考试或面试。
    • 增加知识面。 设计模式当知识点学习。
    • 跟风或被迫学习。 很多公司技术组有专题学习。

    因为学习目的本就不是用的, 自然在实际编码过程中要嘛“忘了” 可以用,或“没想到” 能用,相信这种情况很多技术Leader在代码review是司空见惯的。 另外因为学习的目的与设计模式提出的目的不一致, 学习过程也是很痛苦的,需要记忆那么多类结构图。那么我们应该带什么样目的去学习设计模式呢?根据上文也可以猜出,个人认为最好目的是“用”,而要用好的前提是理解,知道什么时候适合用,什么时候不适合, 适合的是哪种或哪几种模式, 是否改变形或是否多模式组合使用等等。哪我们怎么去理解呢? 我觉得有两个方面: 什么是设计模式和设计模式起作用的原理是什么。

    什么是设计模式?

    都知道设计模式并不是软件开发工程专有的,各行特别是工程领域都有自己的设计模式。具体软件工程领域什么时候应用设计模式,不可知,但20世纪70年代GoF受建筑领域设计模式影响, 通过总结之前软件里的经验,写的一本著名的参考书《设计模式:可复用面向对象软件的基础》,极大的推动了设计模式被大家熟知并应用。GoF将设计模式定义为: 对被用来在特定场景下解决一般设计问题的类和相互对象的描述。我们可以适当泛化,理解为对某一类问题的通用解决方案。 明显,设计模式是来源于实践经验,是对之前最佳实践的提炼总结,是用来解决实际中特定问题的方案,而不是非常抽象的概念,是不能死记硬背,也不需要实际硬背的。如学习GoF 23种设计模式,我们应该深入理解各模式解决能解决问题是什么,了解使用该方案的好处是什么,而不是背诵概念与类图。

    设计模式起作用的原理是什么?

    我们在实际开发中经常遇到某些问题可以用设计模型,但是有好几种模式都可以,该如何选择;或者看着能用某种设计模式,但用了后又不能完全解决问题。这时候需要我们队设计模式原理有充分的了解,知道模式起作用的原理及代理优点和缺点,能通过灵活组合或变形模式来解决现有问题。 比如简单工厂模式,就是通过将对象创建与核心业务分离方式,降低核心业务的耦合度,是核心业务满足开闭原则,具有更好的扩展性并且实现简单,易理解等都是其优势。但也要认识到对整个系统来说其并未完全解决开闭问题, 扩展仍涉及到原有代码的修改。 如果系统对扩展有更高要求,比如需要指出第三方扩展,则应当适当扩展, 比如引入SPI。 其实,仔细分析下GoF各模式原理及其优劣,会发现没有完美的模式,只有适合的模式, 这些模式只是前人帮我们总结好的问题解决方案之一,不是唯一, 我们要学习不禁是这个答案,更多的是解决问题的思维方式。 相较来说,几大设计原则是更具通用性的, 我们在GoF 里的很多模式上都可以看到设计原则的体现。

    总结来说, 个人认为学习设计模式的重点是理解原理, 各模式解决的问题有个印象,在遇到类似问题,能想起来有这样的模式, 能快速查找相关资料,并确定是否直接使用模式或变形使用。 对相关类图更是没有必要死记,现实工作中完全可以现查,并且往往现实业务中不能完全套用,而需在符合设计原则情况下优化调整。

  • 如何理解高内聚、低耦合

    首先需要理解高内聚、低耦合各自的意义。注意在不同的领域它们的意义是不同的。本文中主要描述的是它们在软件工程领域中的意义。

    耦合:简单来讲可以理解为元素之间的依赖度。 这个依赖度往往决定于元素间进行依赖的方式。 如: 排课服务,排课时需要依赖老师的一些信息(职级,育龄等), 是通过教师服务接口依赖,还是公用库依赖,其耦合度是不一样的。

    耦合越强,说明元素间关系越紧密, 元素之间越不能离开其依赖元素而存在或运行, 且替换其依赖越困难。另外耦合也是因存在依赖而存在, 所以软件工程中会说降低耦合,而不是去耦合。这里的元素可以是系统,服务、 组件, 模块,类,甚至是方法。软件工程中不同角色关注的元素不一样。如架构师主要关心系统、组件间耦合度、 初级开发主要关心类、方法的耦合。因此,耦合情况可以是评价软件工程各个角色工作质量的一个重要指标。耦合按从弱到强的顺序可分为以下几种类型

    • 非直接耦合:两模块间没有直接依赖关系,依赖完全是通过主控制模块对依赖模块调用来实现的。面向抽象编程, 能做到具体实现的变更,不影响主模块。
    • 数据耦合:一个模块访问另一模块,彼此间通过简单数据参数来交换输入、输出信息。这里的简单数据参数不同于控制参数、公共数据结构或外部变量。如Java 中方法参数为值时
    • 标记耦合:如一组模块通过参数表传递记录信息,就是标记耦合。这个记录是某一数据结构的子结构,不是简单变量。 如Java 中方法参数为类引用时。 
    • 控制耦合:一个模块通过传递开关、标志、名字等控制信息,明显的控制选择另一模块的功能。常见的有直接使用其他模块标志字段做逻辑控制。
    • 外部耦合:一组模块都访问同一全局简单变量而不是同一全局数据结构,而且不是通过参数传递该全局变量的信息。
    • 公共耦合:一组模块都访问同一个公共数据环境。该公共数据环境可以是全局数据结构、共享的通信区、内存的公共覆盖区等。 公共配置就是常见的公共耦合。 如Nacos 公共配置, 这个配置建立目的就是建设重复配置,简化各项目配置项,但当多个模块或多个服务都使用到该配置时,配置变更就需要关注各使用模块。如默认的数据库连接池配置,默认的注册中心配置等。
    • 内容耦合:一个模块直接修改另一个模块的数据,或直接转入另一个模块。最常见的就数据库表共用,如排课服务直接调用教师服务库中教师信息表来获取教师职级信息。这会导致教师服务变更需要考虑到排课服务,排课服务也可能要因为教师服务变更而变更。

    在设计或编码过程,会发现要降低耦合,经常会增加实现的复杂度。如内容耦合,要降低耦合,就需要在模块A中提供符合模块B的业务能力的接口。所以在实际的编码和设计过程中,还是需要更加项目实际情况,选择适当耦合方式。

    内聚: 可以简单理解为模块内各元素间是强耦合的, 其对外提供的能力是单一的,即职责单一。

    单一,不是说一定是只有一个功能,也可以是一类。如: 一个排课服务,其提供排课申请,排查查询,排课变更等一类功能接口。

    与耦合不同,内聚有“模块内”这个前提。内聚程度越高,说明模块内各元素关联度越高,元素间关系越强,说明模块划分的越合理,这里的模块同样可以是系统,服务、 组件, 模块,类,甚至是方法。内聚也有按程度低到高几种分类:

    • 偶然内聚: 指一个模块内的各处理元素之间没有任何联系。
    • 逻辑内聚: 指模块内执行几个逻辑上相似的功能,通过参数确定该模块完成哪一个功能。
    • 时间内聚: 把需要同时执行的动作组合在一起形成的模块为时间内聚模块。
    • 通信内聚: 指模块内所有处理元素都在同一个数据结构上操作(有时称之为信息内聚),或者指各处理使用相同的输入数据或者产生相同的输出数据。
    • 顺序内聚: 指一个模块中各个处理元素都密切相关于同一功能且必须顺序执行,前一功能元素输出就是下一功能元素的输入。
    • 功能内聚: 最强的内聚,指模块内所有元素共同完成一个功能,缺一不可。与其他模块的耦合是最弱的。

    从分类可以看出,内聚是评估我们划分服务,模块,类甚至方法是否合理的重要指标。高内聚可以提升模块的鲁棒性,可靠性,可重用性,可读性等优点。

    所以我们在说高内聚低耦合时,实际指的是模块间耦合性低, 但模块内的内聚度高。从软件生命周期可知,很多软件的维护期是远远高于其他周期的,而系统的维护的难易程度很大程度决定于系统的可扩展性,可重用性,及可测试性。而符合高内聚低耦合的系统,直观表现上有模块划分合理,模块本地的重用性好, 模块间耦合度低,替换难度低, 易扩展,易测试。

    另外,需注意的一点从耦合、内聚定义可知,做好系统的高内聚低耦合,不是仅取决于系统架构师, 而是所有参与系统设计、研发编码的所有人员有关, 只是架构师或系统设计人员的影响会更大点而已。 那如何做好高内聚低耦合呢, 就技术本身没有固定方法,往往需要根据实际需求将高内聚低耦合作为目标,选择或组合适当的设计模式来实现。 对于开发来说,学习设计模式比较重要,但熟悉设计模式六大原则,然后根据设计原则灵活组合设计模式更重要。另外对于实际项目来说,内聚耦合不仅依赖于开发或架构技术水平, 还于项目的周期长短,可投入资源多少,项目性质有关系, 这也是为什么要求设计人员有实际项目经验的原因。

  • 基于SpringBoot Actuator存活就绪检查

    什么是存活就绪检查?

    存活检查: 检查一个服务是否存活, 如果不存活,需要启动新的服务进行补充替换。对于JAVA 服务,如在Java 进程异常退出、 Java 进程假死等情况等不可自动恢复的情况,就任务是不存活的。

    就绪检查: 检查一个服务是否准备好,对外提供服务。 主要应用在新应用启动后,不立刻提供对外服务,而需要通过就绪检查确定提供的服务的资源都准备好后才提供对外的服务。

    为什么需要存活、就绪检查?

    对于一个被线上使用的服务来说,降低服务的可用性的原因(不考虑编码层面问题)主要有:

    • 发布不平滑。 发布时不能平滑替换服务,导致部分请求报错,降低可用性。
    • 服务故障修复不及时。 一般是服务过载情况下, 服务缺失故障自动修复能力,或自动扩展能力不足,导致服务不可用。
    • 没有备份。 单机或单区运行,在服务器异常或区域性依赖异常时,导致服务不可用。

    就绪检查主要会用在保障发布时保障服务可用时再提供对外服务使用,是平滑发布保障的关键一环。

    存活检查主要用在服务过程中,服务发生不可恢复故障时,发布工具能够自动及时的进行补救。

    如何实现存活就绪检查?

    根据存活就绪检查目的, 实现方法一般会对应用依赖重要组件进行检查,汇总后提供检查结果输出。 可以看出来这是比较适合进行封装的动作,SpringBoot Actuator 就这样一个包,虽然存活就绪只是其功能之一。如果需要自己实现,SpringBoot Actuator 是一个很好的参考。

    SpringBoot Actuator 做为存活就绪检查步骤

    SpringBoot Actuator提供的健康检查端点 /actuator/health ,虽然也可以做为存活和就绪检查使用,通过对存活和就绪作用及原理的了解,知道其满足不了存活就绪分离检测。 不过在Spring Boot 2.3及以上版本,Actuator新增了分组功能,通过对健康端点的各组件进行分组,通过分组自定义组内包含的检测组件,实现不同作用的检测。如可以设置liveness和readiness 两个分组, 然后通过/actuator/health/liveness和/actuator/health/readiness来作为检测接口。

    使用SpringBoot Actuator 基本上包含大部分组件的检查端点实现, 通过配置可以灵活的配置需要使用的端点。配置示例如下:

    management:
      endpoints:
        web:
          exposure:
            include: "health,info,env"  #开放访问的接口
          base-path: /actuator     #自定义基础路径, 默认/actuator
      endpoint:
        health:
          enabled: true            #是否开启,默认true
          show-details: ALWAYS     #health 接口是否返回详情信息,方便排查一般返回
          group:
            readiness:               #就绪检查组,访问地址 /health/readiness
              include: "ping"   #就绪组检查的组件
            liveness:                #存活检查组,访问地址 /health/liveness
              include: "ping"        #存活组要检查的组件
      health:
        defaults.enabled: false      #关闭自动启用组件检查,改由手动启用
        ping.enabled: true           #defaults.enabled 为false 情况下, 手动指定开启的检查端点
        mysql.enabled: true          

    如何确定哪些组件需要加入存活或就绪检测

    一般项目不复杂,引入组件很少或没有重要影响系统运行的三方组件情况下,可以使用

    Spring Boot Actuator提供的默认设置即可满足需求。但因为默认设置会默认加载所有引入组件包中带的Actuator 健康监测端点,而不管这个端点检测的组件是否使用,是否重要。为防止一些无效的包或不重要的组件检测故障导致存活或就绪检查失败,推荐自定义配置来定义设置线上项目的health 端点, 即把defaults.enabled 设置为false, 然后手工开启需要进行检测的组件。

    具体项目中包含哪些可用端点呢, 可以通过设置defaults.enabled 设置为true,

    开启actuator 健康检查,将health.defaults.enabled 设置为true的情况下,访问/actuator/health 就能查看到当前项目所有检查的端点。

    如果项目没有需要检测的组件,或组件不适合作为就绪或存活检查项, 可以启用ping 组件做空白验证。对于有重要组件,但没有自带的检测端点,也可以自实现端点接口HealthIndicator。 示例:

    public class MemHealthIndicator implements HealthIndicator {
        private final Logger LOGGER = LoggerFactory.getLogger(MemHealthIndicator.class);
        @Override
        public Health health() {
            MemoryMXBean memoryMbean = ManagementFactory.getMemoryMXBean();
            MemoryUsage usage = memoryMbean.getHeapMemoryUsage();
            Long max = usage.getMax();
            Long used = usage.getUsed();
            double useRate = used.doubleValue()/max.doubleValue();
            String useInfo = toString(usage);
            if(useRate > 0.9){
                LOGGER.info("jvm 内存使用超过90%,使用率{}",useInfo);
                return Health.down().withDetail("内存使用率",usage).build();
            }
            LOGGER.info("jvm 内存使用{}",useInfo);
            return Health.up().withDetail("内存使用率",usage).build();
        }
    }
    //其他配置类中
    ...
        @Bean
        @ConditionalOnEnabledHealthIndicator("mem") // 定义端点名称,配置中可以使用mem.enable:true 启用
        public HealthIndicator memHealthIndicator(){
            return new MemHealthIndicator();
        }
    ....