微信开发之初体验
缘起2017 年下半年,微信生态正处于高速发展的黄金期。公众号、小程序、企业微信,每一个方向都蕴含着巨大的商业机会。公司决定开拓微信端的业务,而我作为技术负责人之一,承担起了微信开发的技术预研工作。 那段时间,我几乎把所有的业余时间都花在了阅读微信官方文档上。微信的开发文档以详尽著称,但也因为其庞大的体系而让新手望而生畏。企业号、服务号、订阅号、小程序、开放平台、公众平台……光是理清这些概念之间的关系,就花了我整整一个周末。 这篇博客记录的,就是我在微信开发入门阶段整理的一些核心知识点。希望对于后来者,能够少走一些弯路。 微信号区别在微信生态中,有四种主要的账号类型。很多人一开始分不清它们的区别,这完全可以理解——因为微信自己在不同的时期对这些账号的定位也在不断调整。 1. 企业号(后升级为企业微信)企业号的核心定位是企业内部通信与协作: 微信企业号只有企业通信录成员才能关注,外部人员无法看到。 同一个微信企业号可配置多个类似服务号的应用,发送信息条数无限制。 旨在通过微信连接企业应用,为企业提供移动端办公入口。 后来企业号升级为”企业微信”,成为一个独立的产品。它在保留...
Redis Cluster FlushAll失败
问题背景FLUSHALL 是一个在生产环境中极少用到的危险操作。它的功能是把 Redis 实例中的所有数据库数据全部清空——这意味着所有 Key-Value 都会被永久删除,不可恢复。正因为它的破坏性极强,我们在日常运维中几乎不会主动去触发它。 然而,”极少用到”并不等于”不会用到”。2017 年下半年的一次例行维护中,我们碰到了一个诡异的现象:在 Redis Cluster 中向主节点发送 FLUSHALL 命令后,预期所有主从节点都应该清空数据库,但实际结果却是——主从节点发生了切换,并且数据并没有被清空。 这个现象让我困惑了很久。直觉上,FLUSHALL 应该是一个”一发入魂”的操作,命令发出,数据清空,结束。但分布式系统的复杂性远超我们的想象,这个看似简单的操作背后,隐藏着 Redis Cluster 运行机制中一个容易被忽视的盲区。 问题复现让我们还原当时的操作场景: 我们有一个 Redis Cluster,采用主从模式运行。 主节点上有大量业务数据。 运维人员通过 redis-cli 向主节点发送了 FLUSHALL 命令。 预期结果:主节点和从节点的数据都被清空...
MyBatis Mapper变量引用方式#{}与${}差别
前言在 Java 开发中,SQL 注入是一个永远不能忽视的安全问题。每一个有经验的开发者都知道,用户输入的数据永远不能被信任——它可能包含恶意代码,试图绕过你的安全检查,直接操作你的数据库。 MyBatis 作为一款优秀的 ORM 框架,在设计之初就充分考虑了 SQL 注入的防护。默认情况下,MyBatis 会使用预编译的方式处理参数,并设置 PreparedStatement 参数,同时进行必要的安全检查和字符转义。 但在实际开发中,我们经常会在 Mapper 文件中看到两种变量引用方式:#{} 和 ${}。它们看起来很像,但背后的运行机制却截然不同。理解它们的区别,是每一个 MyBatis 使用者的必修课。 PreparedStatement 预编译(#{} 方式)1. Mapper 配置在 MyBatis 中,默认使用预编译方式。以下是一个典型的 Mapper 配置: 123<select id="getList" resultType="Map"> select * fro...
企业级Redis环境部署
背景与动机2016 年,随着公司业务的快速发展,单机 Redis 已经无法满足我们对高可用性的要求。一次深夜的 Redis 宕机事故,导致核心服务不可用长达 20 分钟,那 20 分钟里,客服投诉电话此起彼伏,运维团队紧急排查问题,最终确认是 Redis 单点故障导致的。这次事故成为了推动我们部署 Redis 高可用架构的直接动力。 经过调研和评估,我们决定采用 Redis Sentinel(哨兵) 方案来实现主从自动故障转移。这篇博客记录的,就是那次企业级 Redis 高可用环境部署的完整过程,包括配置、测试和运维注意事项。 Redis Sentinel 架构概述Redis Sentinel 是 Redis 官方推荐的高可用性解决方案。它的核心功能包括: 监控:Sentinel 会持续监控 Redis 主从节点是否正常工作。 通知:当被监控的 Redis 节点出现问题时,Sentinel 可以通过 API 向管理员或其他应用程序发送通知。 自动故障转移:当主节点不可用时,Sentinel 会发起故障转移,将从节点提升为新的主节点。 配置提供者:客户端可以向 Sentinel...
监控系统工具对比
背景与动机2016 年,随着公司业务规模的快速增长,日志量和监控需求呈指数级上升。我们面临着这样一个问题:如何在海量的日志数据中,高效地收集、传输、存储和分析日志信息? 当时,团队内部对日志收集方案产生了分歧。一部分同事推荐 Apache Flume,另一部分则倾向于 ELK 技术栈中的 Logstash。为了做出科学的决策,我决定对这两个工具进行系统的性能对比测试。这篇博客记录的,就是那段日子里我做的三组测试的完整过程和结论。 测试环境说明在开始测试之前,先交代一下测试环境的基本情况: 服务器配置:4核 CPU,8GB 内存,千兆网卡 日志来源:Nginx access.log 测试工具:ab(Apache Benchmark) 监控指标:CPU 负载、请求延时、数据收集效率 测试一:CPU 负载对比第一个测试的目标是观察两种工具在端口监控场景下对系统资源的占用情况。毕竟,一个日志收集工具如果本身就吃掉了大量的 CPU 资源,那它就没有资格被部署到生产环境中。 Flume端口监控时,Java 进程的 CPU 负载在 10%~13% 左右。 从监控图表可以看出,Flume...
PHP类的自动加载
在学习和开发PHP项目的过程中,类的自动加载是一个绕不开的话题。从最初的 require、include 手动引入,到后来的 __autoload 魔术方法,再到 spl_autoload_register 注册函数,最后到 Composer 的 PSR 规范,PHP 的类加载机制经历了漫长而精彩的演进。这篇文章,我想系统地梳理一下这段技术演变的历史,以及每一步背后的设计思想和实际应用场景。 类的加载:最原始的方式在 PHP 的早期版本中,加载类文件最直接的方式就是使用 require() 和 include() 语句。这两者都是语言结构,不是真正的函数,所以它们也可以不加圆括号而直接加参数。虽然看起来简单,但其中蕴含了不少值得注意的细节。 12345// 四种常见的文件引入方式require 'config.php'; // 找不到文件时致命错误,停止执行include 'config.php'; // 找不到文件时警告,继续执行require_once 'config.php'; // ...







