# 接口报警和排查指引

## 概要说明

微信公众平台已对外开放接口报警，当微信服务器向开发者推送消息失败次数达到预定阈值时，会将报警消息发送到指定微信报警群中设置方式：[微信开发者平台](https://developers.weixin.qq.com/platform) - 服务号 - 接口管理 - 接口告警），请开发者积极主动关注报警，即时解决故障，提高微信服务号的服务质量。

为了更好地根据报警信息尾部的实例（提供了openid及时间戳stamp）进行问题排查，开发者需要在接入层、逻辑层等每一个层级都加上包含关键信息的详细日志，以利于快速定位问题。

## 接口报警

报警目前有2类：

### 通用报警

所有开发者都需要关注。

| 类型 | 描述 |
| --- | --- |
| DNS失败 | 微信服务器向服务号推送消息或事件时，解析DNS失败 |
| DNS超时 | 微信服务器向服务号推送消息或事件时，解析DNS超时，超时时间为5秒 |
| 连接超时 | 微信服务器连接服务号开发者服务器时发生超时，超时时间为5秒 |
| 请求超时 | 微信服务器向服务号推送消息或事件后，开发者5秒内没有返回 |
| 回应失败 | 微信服务器向服务号推送消息或事件后，得到的回应不合法 |
| MarkFail（自动屏蔽） | 微信服务器向服务号推送消息或事件发生多次失败后，暂时不推送消息，一分钟后解除屏蔽 |

### 服务号第三方平台报警

只有在微信开放平台（open.weixin.qq.com）上申请成为服务号第三方平台的开发者，才需要关注此报警。

| 类型 | 描述 |
| --- | --- |
| 推送component_verify_ticket超时 | 推送component_verify_ticket时，开发者5S内没有返回 |
| 推送component_verify_ticket失败 | 推送component_verify_ticket时，开发者没有返回success |
| 推送第三方平台消息超时 | 推送第三方平台消息（如取消授权消息）等，第三方平台5秒内没有返回 |
| 推送第三方平台消息失败 | 推送第三方平台消息（如取消授权消息）等，第三方平台没有返回success |

### 报警内容说明

报警内容描述：

1. appid：服务号appid
2. 昵称: 服务号昵称
3. 时间：所有报警，都会提供首次发生异常的时间。（如首次发生超时的时间，首次发生回应失败的时间）
4. 内容：错误的具体描述
5. 次数：发生失败的次数
6. 错误样例：错误样例里注明了一些帮助查找问题的信息。如：首次超时开发者的IP和推送消息类型。如果是回应失败，错误样例还会注明首次回应失败时开发者的回包。

一般情况下，通过报警提供的IP，时间，消息类型，能够比较快速的定位到第三方发生问题的原因。

## 报警类型

下面对具体的报警做示例以及排查指引说明。

### 超时报警

``` bash
Appid: wxxxxxx
昵称: WxNickName
时间: 2014-12-01 20:12:00
内容: 微信服务器向服务号推送消息或事件后，开发者5秒内没有返回
次数: 5分钟 1272次
错误样例: [IP=203.205.140.29][Event=UnSubscribe]
```

该报警表示：微信服务器向开发者推送取消关注事件时，开发者没有在5秒内返回结果。在2014-12-01 20:12:00-2014-12-01 20:17:00这5分钟内发生了1272次。其中这5分钟内第一次发生超时的时间是：2014-12-01 20:12:00， 开发者的IP是：203.205.140.29，事件类型是取消关注事件。

### 回应失败

``` bash
Appid: wxxxx
昵称: WxNickName
时间: 2014-12-01 20:12:00
内容: 微信服务器向服务号推送消息或事件后，得到的回应不合法
次数: 5分钟 1320次
错误样例: [Event=Click] [ip=58.248.9.218][response_length=10][response_content=Error 500:]
```

该报警表示：微信服务器向开发者推送自定义菜单点击事件时，开发者的返回结果不合法。在2014-12-01 20:12:00-2014-12-01 20:17:00这5分钟内发生了1320次。其中这5分钟内第一次发生回应失败的时间是：2014-12-01 20:12:00， 开发者的IP是：58.248.9.218，事件类型是点击菜单事件，第三方返回的内容长度为10个字节，内容为“Error 500:”。

### 连接超时

``` bash
Appid: wxxxx
昵称: WxNickName
时间: 2015-02-04 20:13:09
内容: 微信服务器连接服务号开发者服务器时发生超时，超时时间为5秒
次数: 5分钟 7289次
错误样例: [IP=180.150.190.135][Msg=Text]
```

该报警表示：微信服务器向开发者推送粉丝发来的文本消息时，无法连接到开发者填写的服务器地址。在2015-02-04 20:13:09-2015-02-04 20:18:00这5分钟内发生了7289次，这5分钟内第一次发生连接超时的时间是：2015-02-04 20:13:09， 开发者的IP是：180.150.190.135，事件类型是用户推送的消息。

## 排查指引

### DNS失败

该错误为微信服务器在推送消息给开发者时，解析dns失败。如遇到此报警，请开发者确认：

1. 填写的url,域名是否有误；
2. 域名是否发生变化，如过期，更新等。

如果不是以上2个问题，请联系微信公众平台。问题解决方案：

1. Ping测试你们MP上配置的url里的域名，确认是否能够得到正确的IP。如不能得到或者错误，请到你们的域名托管商管理系统上检查配置。
2. 如1能够得到正确的IP，又有DNS失败的报警；请使用DNS服务器182.254.116.116             来再测试验证。Linux :   dig @182.254.116.116 域名；windows 修改网络配置里的DNS服务器地址，然后再ping 域名。如果得到的IP不正确或者得不到，请联系微信团队。

### DNS超时

目前不会有此错误。

### 连接超时

该错误是微信服务器和开发者服务器3S内未连接成功。报警消息会提供出首次发生连接失败的时间和连接的IP。如遇此报警，请开发者确认：

1. 该IP是否有误。
2. 该IP机器是否过载，连接过多。
3. 如果是第三方提供服务器托管，托管商是否有故障。
4. 网络运营商是否有故障。
5. 是否设置了防火墙等网络策略，可为微信服务器的IP增设白名单。详细参看[获取微信服务器IP地址](/doc/service/api/base/api_getapidomainip.md)
6. 是否网络不通，可通过[网络检测](/doc/service/api/base/api_callbackcheck.md)排查。

问题解决方案如下：

1. 查看是否网络环境问题。使用[获取微信推送服务器IP接口](/doc/service/api/base/api_getcallbackip.md)，获取微信回调服务器的IP，在你的服务上 ping 测试，检查你们服务器到微信回调用服务器的网络质量情况。如有网络问题，请联系你们的服务器提供商解决。
2. 查看接入层服务器连接数，负载，nginx的配置，允许的连接个数。查看nginx错误日志是否有“Connection reset by peer”或“Connection timed out”错误日志，如有说明nginx连接数过超负载。
3. 建议搭建测试工具，对系统进行心跳检查，对系统负载，连接数，处理数，处理耗时进行实时监控报警。

对于nginx配置，这里提供官方文档和一篇简单配置介绍链接，希望有帮助： http://nginx.org/en/docs/ ，重点关注连接数配置，日志配置等。nginx的一些重要配置参考例子如下：

```bash
worker_processes  16;          //CPU核数
error_log  logs/error.log  info;   //错误日志log
worker_rlimit_nofile 102400;     //打开最大句柄数
events {
   worker_connections  102400;   //允许最大连接数
}
//请求日志记录，关键字段：request_time-请求总时间，upstream_response_time后端处理时 间
log_format  main  '$remote_addr  - $remote_user [$time_local] "$request" '
                 '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for" "$host"  "$cookie_ssl_edition" '
                 '"$upstream_addr"   "$upstream_status"  "$request_time"  '
                 '"$upstream_response_time" ';
access_log  logs/access.log  main;
```

### 请求超时

微信服务器向开发者服务器推送消息或事件，开发者5秒内没有返回。请求超时时，报警消息会提供第一次出现请求超时的时间，开发者IP和消息类型。请开发者确认：

1. 该IP是否有误
2. 该IP是否接收到报警消息给出的该消息类型的请求
3. 该请求是否处理时间过长

解决方案：

每个模块都需要有完整的日志，能够查出每个请求在每个模块的耗时信息，配合微信报警提供信息，能够很容易的定位到是哪个服务器出问题。常见的原因是：

1. 机器负载太高，耗时增加
2. 机器处理异常，消息丢失
3. 机器异常，对于机器处理异常，建议尽快修复bug，对于机器异常，请尽快屏蔽有问题的机器。这里对机器负载太高，简单提供可行的解决方案。

方案一：优化性能，扩容。检查负载情况（cpu，内存，io，网络，详见附录），根据具体性能瓶颈的不同，采取不同的优化方式。

方案二：异步处理。如果微信服务器推送的消息来不及实时处理，可将消息先存储，先返回success给微信服务器，后台可后续再处理消息，如果需要回复用户消息，可通过调用客服消息接口API再回复用户消息。

### 回应失败

开发者没有按照文档的回复消息格式进行回复消息，或者发生网络错误，会报警回应失败，报警消息会提供第一次出现请求回应失败的时间，开发者的IP，消息类型以及回应的消息内容，请开发者确认：

1. 该IP是否有误
2. 该IP是否发生网络错误
3. 该业务处理逻辑是否没有按照wiki规范回复消息，或是进入了异常逻辑。

### MarkFail（自动屏蔽）

微信后台会实时统计开发者的失败次数。在推送消息给开发者发生大量失败时，微信服务器会自动屏蔽开发者，1分钟内不再推送任何消息，并会发送报警到微信群。此报警是级别最高的报警，开发者在收到此报警时请尽快处理后台故障，恢复服务。事实上，开发者在收到此报警前，必然会收到连接超时，请求超时或回应失败等报警，需要开发者即时去解决这些故障，避免被微信服务器屏蔽，严重影响服务号服务！

### 推送component_verify_ticket超时

只有服务号第三方平台开发者会收到，其他服务号开发者无需关注。由于服务号第三方平台承载了更多的服务号，所以服务号第三方平台的服务质量需要更严格要求和报警，所以把这4个特殊的事件单独报警。关于服务号第三方平台的具体申请与开发实现，请前往微信开放平台（open.weixin.qq.com）

### 推送component_verify_ticket失败

只有服务号第三方平台开发者会收到，其他服务号开发者无需关注。由于服务号第三方平台承载了更多的服务号，所以服务号第三方平台的服务质量需要更严格要求和报警，所以把这4个特殊的事件单独报警。关于服务号第三方平台的具体申请与开发实现，请前往微信开放平台（open.weixin.qq.com）

### 推送组件消息超时

只有服务号第三方平台开发者会收到，其他服务号开发者无需关注。由于服务号第三方平台承载了更多的服务号，所以服务号第三方平台的服务质量需要更严格要求和报警，所以把这4个特殊的事件单独报警。关于服务号第三方平台的具体申请与开发实现，请前往微信开放平台（open.weixin.qq.com）

### 推送组件消息失败

只有服务号第三方平台开发者会收到，其他服务号开发者无需关注。由于服务号第三方平台承载了更多的服务号，所以服务号第三方平台的服务质量需要更严格要求和报警，所以把这4个特殊的事件单独报警。关于服务号第三方平台的具体申请与开发实现，请前往微信开放平台（open.weixin.qq.com）

## 常用工具

下面对查看服务器性能负载的常用工具做简单介绍，详细的工具使用请另行查阅。

### 查看CPU的性能负载

- uptime：用于观察服务器整体负载，系统负载指运行队列（1分钟、5分钟、15分钟前）的平均长度， 正常情况需要小于cpu个数。
- vmstat：vmstat是Virtual Meomory Statistics（虚拟内存统计）的缩写，可对操作系统的虚拟内存、进程、CPU活动进行监控。他是对系统的整体情况进行统计，通常使用vmstat 5 5（表示每隔５秒生成一次数据，生成五次）命令测试。将得到一个数据汇总他能够反映真正的系统情况。
- top：top命令是最流行Unix/Linux的性能工具之一。系统管理员可用运行top命令监视进程和Linux整体性能。

### 查看内存的性能负载

- free：Linux下的free命令，可以用于查看当前系统内存的使用情况，它显示系统中剩余及已用的物理内存和交换内存，以及共享内存和被核心使用的缓冲区。

### 查看网络的性能负载

- netstat：Netstat是控制台命令,是一个监控TCP/IP网络的非常有用的工具，它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息。Netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据，一般用于检验本机各端口的网络连接情况。
- sar：sar（System Activity Reporter系统活动情况报告）是目前 Linux 上最为全面的系统性能分析工具之一，可以从多方面对系统的活动进行报告，包括：文件的读写情况、系统调用的使用情况、磁盘I/O、CPU效率、内存使用状况、进程活动及IPC有关的活动等。本文主要以CentOS 6.3 x64系统为例，介绍sar命令。

### 查看磁盘的性能负载

- iostat：Linux下的iostat命令，可用于报告中央处理器（CPU）统计信息和整个系统、适配器、tty 设备、磁盘和 CD-ROM 的输入／输出统计信息。

## nginx配置和排查指引

当出现直接超时、处理返回慢时的报警时，nginx侧的故障排查参考方法有如下： 1、检查请求日志情况， tail -f logs/access.log ，看upstream_status字段。

- 200：表示正常；
- 502/503/504：表示处理慢，或者后端down机；再看upstream_response_time返回的时间是否真的较慢，有没有上百毫秒，或更高的，有则说明是后端服务有问题。
- 404：表示请求的路径不存在或不对，文件不在了。需要检查你配置在公众平台上的url路径是否正确； 服务器上的文件、程序是否存在。
- 403：表示无权限访问。 检查一下nginx.conf 是否有特殊的访问配置。
- 499: 则是客户端的问题，请联系微信团队。  此错误少见。

检查错误日志情况，tail -f logs/error_log ，查看是否有connect() failed、Connection refused、 Connection reset by peer等error错误日志，有则说明有可能nginx出现的连接数超负载等情况。

查看系统的网络连接数情况确认是否有较大的链接数

```bash
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 
```
```bash
CLOSED //无连接是活动的或正在进行    
LISTEN //服务器在等待进入呼叫    
SYN_RECV //一个连接请求已经到达，等待确认 
SYN_SENT //应用已经开始，打开一个连接    
ESTABLISHED //正常数据传输状态/当前并发连接数
FIN_WAIT1 //应用说它已经完成 
FIN_WAIT2 //另一边已同意释放
ITMED_WAIT //等待所有分组死掉
CLOSING //两边同时尝试关闭
TIME_WAIT //另一边已初始化一个释放
LAST_ACK //等待所有分组死掉 
```  

查看系统的句柄配置情况，ulimit -n ，确认是否过小（小于请求数）

worker_rlimit_nofile、worker_connections配置项，是否过小（小于请求数）
