作为前端,我从来没觉得自己“只会写页面”——但直到第一次完整把微信小程序从零推到上线,才意识到:小程序那层壳再漂亮,也只是一半。另一半在服务器上,在数据库里,在签名和加密的逻辑里,在那一堆 Java 代码里。
这篇内容围绕“微信小程序是前端,也需要 Java 开发的后端服务”展开,适合三类人看:一是准备独立做小程序全栈项目的前端同学,二是刚接触后端、想搞清楚小程序接口怎么设计的 Java 新人,三是准备面试时被问到“小程序登录流程怎么实现”“支付回调怎么验签”这类问题的开发者。我会从为什么需要后端开始,讲到 Spring Boot 如何承接小程序请求,再拆解登录、签名、支付回调这些核心链路,最后聊一聊联调排查和工程化经验。
1. 先说结论:小程序前端的边界到底在哪里
1.1 小程序的“前端”标签只描述了一半事实
小程序的形态上确实属于前端:WXML 写结构、WXSS 写样式、JS 写交互,跑在微信提供的 WebView 和 JS 引擎里。前端开发者上手小程序几乎没有门槛,这也是很多人习惯性把它归类为“前端活儿”的原因。
但小程序和传统 H5 页面有一个本质差异:它对后端接口的依赖程度极高。拿最常见的登录来说,H5 页面登录可以只调一个 /login 接口,用户名密码由后端校验;小程序端连密码都没有,它靠的是微信的 code 换 session_key,再拿 session_key 去换业务登录态。这整个链路里,如果没有人写后端逻辑,小程序端连“我是谁”都证明不了。
说“小程序是前端”不是错,但只说对了一半。另一半在服务器上,在数据库里,在签名和加密的逻辑里。
1.2 一个完整项目里,前端只占一半工作量
我见过不少团队做小程序,一开始只有两三个前端,产品原型出来之后,前端吭哧吭哧把页面写完了,数据全是 mock 的。等要联调时才发现:没有后端,所有页面都只是空壳。
一个完整的小程序项目,通常包含这些部分:
- 小程序前端:页面、组件、状态管理、请求封装
- 后端接口服务:登录、用户信息、业务数据、文件上传
- 数据库设计:用户表、订单表、商品表、日志表
- 运维与部署:服务器、HTTPS 域名、环境配置、日志排查
- 安全机制:签名校验、敏感数据加密、支付回调验签
前端负责“看得见”的部分,后端负责“看不见但必须正确”的部分。后者如果缺失,前者再漂亮也无法上线。
1.3 后端服务解决的三类核心问题
为什么不能用云开发或者纯前端方案硬扛?其实可以,但要看场景。后端服务在小程序体系里主要解决三类问题:
第一类是身份与权限问题。小程序的用户身份来自微信的 openid 和 unionid,这些信息不能直接暴露给前端,也不能由前端自己生成,必须通过服务端去微信接口换取,然后由服务端管理自己的 token 体系。
第二类是数据安全与业务隔离问题。前端代码打包在小程序包里,任何人用工具都能看到全部代码。把业务规则、密钥、统计逻辑放在后端,可以避免核心逻辑被直接扒走。
第三类是复杂业务与性能问题。支付、订单、消息推送、定时任务、权限控制,这些单靠小程序端无法完成。后端服务还可以做缓存、做消息队列,在流量上来时保护核心服务。
简单说:小程序是“门口的接待”,后端是“店里的仓库和会计”。接待再热情,仓库乱套、账目不清,生意照样做不下去。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 为什么需要后端:从三个真实场景说起
2.1 场景一:登录态与 openid 的安全传递
小程序的登录已经形成了标准流程,链路里每一步都依赖后端。
前端调用 wx.login() 拿到一个临时 code,这个 code 的有效期只有 5 分钟,一次性的,用完就废。前端把 code 传给后端,后端拿着 code、加上小程序的 appid 和 secret,调用微信的 jscode2session 接口,换取 openid、session_key 和 unionid。
后端拿到 openid 之后,会在自己的用户表里查这个用户是否存在,不存在就创建新用户,存在就更新登录时间。然后后端自己签发一个 token(可以是 JWT,也可以是自定义随机串),把 token 返回给小程序端。
小程序端后续所有请求,都在 header 里带上这个 token,后端每次校验 token 合法性,以此识别用户身份。
这里有几个关键安全点:
session_key绝对不能返回给前端,它主要用于后续解密手机号、解密用户信息的敏感数据secret绝对不能写在小程序前端代码里,一旦泄露,任何人都可以模拟你的服务端去请求微信接口- 后端签发的 token 要设置合理过期时间,并且服务端能主动失效
所以你看,登录这个看似“前端操作”的流程,其实骨架完全在后端。
2.2 场景二:微信支付 v3 的签名与回调
小程序支付是另一个“必须要后端”的典型场景。支付分为三步,每一步都有签名、验签逻辑。
第一步:后端统一下单。前端把商品信息、用户 openid、金额等传给后端,后端调用微信支付 v3 的下单接口,带上商户号、证书序列号、请求体,使用商户私钥生成签名。微信支付返回 prepay_id,后端拿这个 prepay_id 再生成小程序的支付参数,返回给前端。
第二步:前端拉起支付。小程序端拿到 paySign、timeStamp、nonceStr、package 这些参数后,调用 wx.requestPayment。这些参数必须由后端生成,因为 paySign 需要商户私钥签名。
第三步:回调验签。用户付完钱后,微信支付会向你的后端服务器发送一个支付结果通知。这个通知必须验签:后端要确认这个通知确实来自微信支付,而不是有人伪造的。验签用的是微信支付平台证书公钥。验签通过后,后端更新订单状态,再给微信返回一个成功的应答。如果后端不返回或者返回错误,微信会持续重试通知。
如果只靠前端完成支付,所有敏感信息都暴露在小程序包里,整个支付链路的信任基础就不存在了。这就是为什么支付场景下,后端服务完全是刚需。
2.3 场景三:数据不下前端,业务逻辑留在服务端
有些业务规则,不该让前端知道。比如优惠券的抵扣规则、运费计算逻辑、风控策略、价格体系,这些如果写在小程序里,懂技术的人反编译一下就把规则全看光了。
后端服务可以把这些规则收敛在服务端:
- 前端只传“我选了哪些商品”,后端返回“最终价格是多少”
- 前端只传“用户 ID 和优惠券 ID”,后端判断“这个券能不能用、用了之后多少钱”
- 前端只负责展示结果,不负责计算规则
这样做的另一个好处是,当你想要调整业务策略、修复严重的业务漏洞时,只需要改后端代码重启服务,不用发小程序版本。小程序每次发布都要审核,后端发布则立竿见影。
所以,后端不是“可有可无的配套”,而是小程序商业化、规范化运作的基础设施。
3. Java 后端怎么接小程序:以 Spring Boot 为例的完整链路
3.1 环境准备:JDK 安装与 Maven 配置
Java 后端最常见的技术栈就是 Spring Boot。先把基础环境准备好。
我用的是 JDK 1.8 或 JDK 17 都行,实际项目里 1.8 仍然占很大比例。安装完之后,必须配置环境变量。Windows 下要配三个:
JAVA_HOME:指向 JDK 安装目录,比如C:\Program Files\Java\jdk1.8.0_202Path:追加%JAVA_HOME%\binCLASSPATH:通常配成.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar
配完后在命令行敲 java -version,能正常输出版本号就说明配置成功。很多新手卡在“java 不是内部或外部命令”,九成是 Path 没配好,或者配置了没重启终端。
Maven 是 Java 项目的构建工具,负责下载依赖、打包。下载完解压后,同样配置 MAVEN_HOME 和 Path,然后在命令行执行 mvn -v 验证。
项目层面,推荐直接用 Spring Initializr(start.spring.io)生成基础工程,勾选 Spring Web、Validation、Lombok 这些模块,省去手动搭目录的时间。我一般还会引入这些依赖:
xml复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- HTTP 客户端:用于请求微信接口 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- JSON 处理 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.32</version>
</dependency>
3.2 后端核心接口:登录、业务数据、通用返回结构
以一个驾校模拟考试小程序为例,用户需要刷题、考试、查看错题。后端至少需要三个核心接口:登录、获取题目列表、提交答题记录。
先定义一个统一的返回结构,保证前端拿到数据格式一致:
java复制@Data
public class Result<T> {
private Integer code;
private String message;
private T data;
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.code = 200;
result.message = "success";
result.data = data;
return result;
}
public static <T> Result<T> error(Integer code, String message) {
Result<T> result = new Result<>();
result.code = code;
result.message = message;
return result;
}
}
登录接口的核心逻辑是:接收前端传来的 code,调用微信接口拿到 openid,再生成自己的 token。
java复制@RestController
@RequestMapping("/api/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/login")
public Result<LoginResponse> login(@RequestBody LoginRequest request) {
// 1. 调用微信 code2Session 接口
WxLoginResult wxResult = userService.code2Session(request.getCode());
// 2. 用 openid 查表或创建新用户
User user = userService.findOrCreateUser(wxResult.getOpenid());
// 3. 签发 token
String token = userService.generateToken(user.getId());
return Result.success(new LoginResponse(token, user));
}
}
code2Session 内部实际调用的是微信的 GET https://api.weixin.qq.com/sns/jscode2session,携带参数:
appid:小程序 appidsecret:小程序 secretjs_code:前端传过来的 codegrant_type:固定值authorization_code
微信返回的 JSON 里有 openid、session_key,如果 code 过期或错误,会返回 errcode。所以这里必须做错误处理,不能直接透传给前端。
3.3 小程序端如何对齐后端接口:请求封装与拦截器
后端接口写好了,小程序端需要封装 wx.request,统一处理 baseURL、token 注入和错误提示。
javascript复制const BASE_URL = 'https://yourdomain.com/api'
function request(url, method, data) {
return new Promise((resolve, reject) => {
wx.request({
url: BASE_URL + url,
method: method || 'GET',
data: data || {},
header: {
'Content-Type': 'application/json',
'Authorization': wx.getStorageSync('token') || ''
},
success(res) {
if (res.statusCode === 200 && res.data.code === 200) {
resolve(res.data.data)
} else if (res.statusCode === 401) {
// token 过期,重新登录
wx.removeStorageSync('token')
wx.navigateTo({ url: '/pages/login/login' })
} else {
wx.showToast({ title: res.data.message, icon: 'none' })
reject(res.data)
}
},
fail(err) {
wx.showToast({ title: '网络异常', icon: 'none' })
reject(err)
}
})
})
}
module.exports = { request }
前端只要保证登录成功后把 token 存起来,后续所有请求都会自动带上。而后端需要一个拦截器,统一校验每个请求的 token:
java复制public class TokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String token = request.getHeader("Authorization");
if (StringUtils.isBlank(token)) {
throw new BusinessException(401, "未登录");
}
// 校验 token 并放入 request 上下文
Integer userId = tokenService.verifyToken(token);
request.setAttribute("userId", userId);
return true;
}
}
这个交互方式,前端其实只需要懂“后端给我什么,我存什么;后端要什么,我传什么”,但理解后端为什么这么设计,联调会顺利很多。
4. 关键机制拆解:签名、加密与数据安全
4.1 小程序登录流程中的 code2Session 细节
前面提过 code2Session,这里把细节展开说清楚。
code 是一次性的,而且有效期极短。前端每次调用 wx.login() 都会生成新的 code,同一个 code 只能用一次,第二次再用微信会报 40163(code been used)。所以前端不能把 code 缓存,一定要在需要登录时现场获取。
session_key 是微信生成的会话密钥,它不会变吗?不是。用户主动退出、更换设备、修改微信密码、长时间未使用,都可能导致 session_key 失效。所以当后端发现 session_key 不对时,应该引导前端重新 wx.login()。
还有一个常见问题:openid 和 unionid 的区别。openid 是“同一个微信用户,在不同小程序下不同”,unionid 是“同一个微信用户,在同一个开放平台账号下的所有小程序、公众号下相同”。如果只是做单小程序,openid 就够了;如果想打通多个小程序和公众号的用户体系,才需要 unionid。
4.2 支付 v3 的签名机制为什么必须放在后端
微信支付 v3 的签名算法是 SHA256withRSA。大概过程是:拼接请求方法、请求路径、请求时间戳、请求随机数、请求体,得到待签名字符串,然后用商户私钥做 SHA256withRSA 签名,生成 Authorization 请求头。
这整套流程里有两个东西绝对不能暴露给前端:
- 商户私钥:一旦泄露,任何人都可以伪造支付请求、发起退款操作
- 商户号与证书序列号的对应关系:这是身份标识的一部分
所以支付签名必须在后端完成。前端唯一能涉及的部分,就是拿到后端生成好的支付参数后,调用 wx.requestPayment。前端不需要知道任何签名细节,也不应该知道。
回调通知的验签逻辑稍微复杂一些。微信支付的回调请求头里带有 Wechatpay-Signature、Wechatpay-Timestamp、Wechatpay-Nonce,body 是加密的支付结果数据。后端验签的大致步骤:
- 用平台证书公钥验证
Wechatpay-Signature是不是微信私钥签的 - 验签通过后,用 APIv3 密钥解密 body 中的
resource字段 - 解密得到订单状态、金额等实际数据
- 校验订单金额与本地订单是否一致
- 更新订单状态,返回
{"code":"SUCCESS"}给微信
很多同学在支付回调这里踩坑,最常见的错误就是验签不通过。排查时先看服务器时间是否准确,再看平台证书是否加载的是最新版本,最后确认解密用的 APIv3 密钥是否填对。
4.3 敏感数据解密:getPhoneNumber、encryptedData
小程序的手机号快速验证组件,前端在 bindgetphonenumber 事件中拿到的 code,是可以直接调后端接口换手机号的。但现在推荐的方案是:
前端把 code 传给后端,后端调用微信接口 phonenumber.getPhoneNumber,用 code 直接换取手机号,整个流程不需要 session_key 参与,更安全更简单。
还有一种老方案是拿 encryptedData 和 iv 给后端,后端用 session_key 解密。这个方案的问题在于 session_key 是动态的,如果前端拿到的 session_key 已经过期,解密必然失败。我当时做实际项目时,第一版用的老方案,线上频繁出现解密失败,排查到最后发现是 session_key 过期导致的。后来改成 code 换手机号方案,问题直接消失。
如果确实需要解密 encryptedData(比如 getUserInfo 里的敏感字段),后端处理时要注意:
- AES 解密,算法是 AES-128-CBC
- 密钥是 session_key,偏移量是 iv
- 解密后的数据是 JSON 字符串,里面包含 openid、unionid、nickname 等
- 解密前必须校验数据长度、session_key 是否有效
这块的逻辑属于典型的“前端拿到密文、后端负责解密”协作模式,双方约定好数据格式非常关键。
5. 联调与排查:前后端协作中的常见问题
5.1 域名校验与开发者工具配置
小程序正式环境要求所有请求域名必须是 HTTPS,并且在微信公众平台后台配置 request 合法域名。开发时可以勾选开发者工具右上角的“不校验合法域名”,但真机预览时必须配置好。
实际项目中,我建议即使开发阶段也尽量走 HTTPS,避免快上线时才暴露出证书和域名的问题。没有 HTTPS 域名的情况下,可以用内网穿透工具把本地服务映射到公网临时调试,但要注意把安全措施做足,毕竟内网穿透会把本地服务直接暴露出去。
后端配置 CORS 时也要注意,小程序请求不是浏览器请求,不受同源策略限制,所以后端不需要配置跨域。这一点和 H5 项目完全不一样,有些后端同学把 CORS 配了半天,发现小程序照样请求失败,其实是别的问题。
5.2 常见报错速查表
我在小程序和 Java 后端联调时,遇到过一堆报错,整理成表格方便对照排查。
| 报错信息 | 可能原因 | 解决方案 |
|---|---|---|
errcode: 40029 |
code 无效或已过期 | 前端重新 wx.login() |
errcode: 40163 |
code 重复使用 | 检查前端是否缓存了 code |
errcode: 41008 |
缺少 code 参数 | 检查后端接口入参 |
request:fail |
域名未配置或不在白名单 | 检查 request 合法域名配置 |
Error: System error. |
后端接口异常 | 查看后端日志,检查异常堆栈 |
statusCode 404 |
接口路径不对或服务未启动 | 确认 Spring Boot 启动成功,确认请求路径匹配 |
statusCode 401 |
token 缺失或已过期 | 重新登录,检查拦截器逻辑 |
statusCode 500 |
后端系统异常 | 查看日志,常见空指针、数据库连接问题 |
页面白屏或者数据出不来,先从 Network 面板看请求到底发出去了没有。小程序开发者工具的 Network 里能看到每个请求的状态码、耗时和响应体,这一层信息比啥排查都快。
还有一个高频问题:真机预览时接口正常,电脑模拟器上接口却挂了。多半是因为模拟器访问不了内网 IP,或者电脑和手机不在同一网络。这种情况把电脑防火墙临时关掉试试,或者直接用真机调试。
5.3 抓包与联调技巧
抓包是前后端联调时的重要技能。做小程序开发时,我常用的抓包方式有几种。
第一种是微信开发者工具自带的 Network 面板,可以看请求头、请求体、响应体,足够覆盖日常需求。唯一的问题是部分接口数据被加密时,看到的是密文,但那也要正常,说明加密逻辑生效了。
第二种是使用 Charles 或 Fiddler 抓 HTTPS 包。这些工具不仅可以看请求内容,还能断点修改请求,模拟异常场景。需要注意抓 HTTPS 包要在手机或电脑上安装并信任证书。我自己在移动端调试时喜欢用 Charles,因为它能清晰看到 SSL 握手、请求耗时这些细节。
抓包时有一个原则要保持:只抓自己开发的程序、自己参与的联调环境。用抓包工具去破解别人的接口、绕过验证,甚至获取未授权数据,属于越界行为,技术上也许能做到,但它既违反用户协议,也可能触犯法律,没有讨论空间。
5.4 后端日志与接口文档:联调的最后一公里
联调过程中,最怕前端说“接口报错了”,后端说“我这边没看到日志”。要减少这种互相踢皮球的情况,后端项目一定要做好日志输出。
我习惯在拦截器里记录每个请求的路径、参数、耗时,在 Controller 层记录业务结果和异常信息:
java复制@Component
public class AccessLogInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(AccessLogInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
long startTime = System.currentTimeMillis();
request.setAttribute("startTime", startTime);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
long startTime = (Long) request.getAttribute("startTime");
long cost = System.currentTimeMillis() - startTime;
logger.info("path={}, method={}, status={}, cost={}ms",
request.getRequestURI(), request.getMethod(), response.getStatus(), cost);
}
}
接口文档可以采用 Swagger(springdoc-openapi)或者 YApi 这类工具管理,但更实际的做法是:小项目直接约定一个 Markdown 文档,把每个接口的入参、出参、错误码写清楚,放在 Git 仓库里一起维护。
联调时前端要改字段名、后端要改返回结构,这很正常。但如果文档保持同步,很多争执其实可以避免。我自己的经验是:接口联调作为开发的一部分,而不是开完会后靠记忆干活。
6. 前端如何补后端知识:给前端同学的几条学习路线
6.1 Java 基础要掌握到什么程度
前端同学转 Java 后端,不需要把 Java 学到精通,但要掌握到“能写服务、能排查问题”的程度。
核心需要掌握的点:
- 基本语法、集合框架(List、Map)、异常处理
- 面向对象:类和对象、封装继承多态、接口
- 常用工具类:String、日期时间、JSON 解析
- 文件读写、HTTP 请求发送
- 数据库基础:SQL 增删改查、事务概念
- Spring Boot 的基本使用:Controller、Service、Mapper
Java 的 lambda、Stream 流、函数式接口,这些属于进阶内容,面试经常考,实际项目中也能提高效率。我记得刚开始学时,总觉得 lambda 语法很难记,后来发现它本质上就是“把一个函数作为参数传递”,多看几遍示例就顺了。
6.2 Spring Boot 入门路径
后端项目的落地,光会 Java 语法还不行,得理解 Spring Boot 的框架逻辑。
最简单的理解方式是:Spring Boot 是一个帮你把对象创建好、把依赖注入好、把 HTTP 请求路由到方法的框架。你只需要写 Controller 接收请求,写 Service 处理业务,写 Mapper 访问数据库,剩下的配置和容器管理,框架帮你搞定。
我建议前端同学按这个顺序来学:
- 先做一个最简单的接口:
@RestController+@GetMapping,返回一个 JSON - 学会接收前端参数:
@RequestBody、@PathVariable、@RequestParam - 连接数据库:引入 MyBatis-Plus 或 Spring Data JPA,做一个增删改查
- 做登录注册:学会用 JWT 或 Redis 管理会话
- 对接第三方接口:用 HttpClient 或 Hutool 的 HttpUtil 调微信接口
- 最后做支付回调、消息推送这种异步场景
每一步都能跑通、能调试,比只看书有效得多。
6.3 面试视角:小程序开发常问的后端问题
前端面试题和小程序面试题里,现在经常掺杂后端内容。我整理了面试中被问过或者听同行被问过的高频题:
| 问题 | 考察点 |
|---|---|
| 小程序登录流程讲一下 | 是否理解 code、openid、session_key、token 的关系 |
| 支付回调怎么保证安全性 | 验签逻辑、幂等处理、金额比对 |
| 为什么 session_key 不能给前端 | 敏感数据解密密钥,泄露等于数据裸奔 |
| 多个小程序之间如何识别同一用户 | unionid 与开放平台账号体系 |
| token 和 session 有什么区别 | 状态管理方案、分布式场景、过期策略 |
| 接口返回数据加密和不加密怎么选 | 性能与安全性的平衡,业务区分 |
回答这些题,核心不是背答案,而是理解链路。能画出小程序、后端、微信服务三者之间的交互时序,再配合一两个踩坑经验,面试官基本就认可了。
7. 项目工程化与部署上线:后端服务如何真正跑起来
7.1 从开发环境到生产环境的差异
本地用 IDEA 跑 Spring Boot 只算“能跑”,真正上线是另一套工程问题。
生产环境的配置项至少要考虑这些:
- 数据库连接信息通过环境变量或配置中心管理,不写死在代码里
- 日志要落盘,且按天滚动切割,方便保留和排查
- 部署方式:用
mvn clean package -DskipTests打成 jar 包,通过 systemd 或容器方式运行 - 上线前跑一遍敏感信息扫描,确认没有把 secret、密码提交到仓库
我在第一次上线时犯过的错误是,把微信小程序的 secret 直接写在了 application.yml 里,然后提交到了 Git 仓库。虽然不是公开仓库,但这个习惯非常危险。后来改成了从环境变量读取,配置文件里只保留占位符:
yaml复制wx:
appid: ${WX_APPID}
secret: ${WX_SECRET}
部署时在服务器的环境变量里注入真实值。这样即使代码泄露,敏感信息也不会跟着泄露。
7.2 HTTPS 域名与小程序后台配置
小程序生产环境强制要求 HTTPS。域名证书可以买,也可以用一些免费的证书服务,但要注意证书有效期,定时替换。
在小程序后台需要配置 request 合法域名和 uploadFile 合法域名。配置生效不是即时的,保存后通常需要一段时间,真机调试时如果提示“不在以下 request 合法域名列表中”,多半是这个配置还没生效。
还有一点容易忽略:小程序后台还需要配置服务器 IP 白名单。如果后端调用了 code2Session 这类微信接口,微信会校验来源 IP。生产环境的出口 IP 必须加到白名单里,否则线上会报 errcode: 40164。
7.3 上线后的监控与告警
前端上线后看不见报错,问题会更隐蔽。后端要具备基本的可观测性。
我的最低配置是:
- 健康检查接口:
/actuator/health,配合运维做存活探针 - 错误日志告警:关键词监控,比如出现
Exception、Error、验签失败就触发通知 - 接口耗时统计:超过 1 秒的接口单独输出慢日志
- 数据库慢查询日志开启
这些能力不需要一开始就引入全套微服务监控系统,先把日志和健康检查做好,能解决大部分线上问题。等业务量上来了,再考虑链路追踪、性能监控这些更重的方案。
我自己的体会是:小程序和 Java 后端的协作,本质上是“信任链”的协作。前端信任后端返回的数据是正确的,后端信任前端传递的身份是经过校验的。而这条信任链的每一环,都是由签名、加密、token 校验这一个个细节搭建起来的。前端同学如果能主动理解后端这些设计,做起小程序项目来会从容很多。
