在企业公众号中全局缓存access_token和jsapi_ticket的方案

说明

在每次主动调用企业号接口时需要带上AccessToken参数。AccessToken参数由CorpIDSecret换取。
AccessToken是企业号的全局唯一票据,调用接口时需携带AccessToken。正常情况下AccessToken有效期为7200秒,有效期内重复获取返回相同结果;有效期内有接口交互(包括获取AccessToken的接口),会自动续期

主动调用的频率限制

当你获取到AccessToken时,你的应用就可以成功调用企业号后台所提供的各种接口以管理或访问企业号后台的资源或给企业号成员发消息。
为了防止企业应用的程序错误而引发企业号服务器负载异常,默认情况下,每个企业号调用接口都有一定的频率限制,当超过此限制时,调用对应接口会收到相应错误码。
以下是当前默认的频率限制,企业号后台可能会根据运营情况调整此阈值:

  1. 基础频率
    每企业调用单个cgi/api不可超过1000次/分,30000次/小时
    每ip调用单个cgi/api不可超过2000次/分,60000次/小时
    第三方应用提供商由于需要同时服务于多个企业,ip频率限制如下:每ip调用单个cgi/api不可超过20000次/分,600000次/小时
  2. 发消息频率
    每企业不可超过帐号上限数*30人次/天
  3. 创建帐号频率
    每企业创建帐号数不可超过帐号上限数*3/月
  4. 创建应用频率
    每企业最大应用数限制为30个,创建应用次数不可超过30*3/月
    在企业公众号的API接口调用中,每次请求都必须带access_token,如果是使用jsapi的话也要获取jsapi_ticket,并放入请求参数中,

jsapi_ticket

jsapi_ticket是企业号号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket

缓存方案

说起来也比较简单,就是将从服务器端获取到的token和ticket保存到本地properties文件中,每次调用之前用已保存的超期时间expires_in与当前时间比较,如果发现已超期,就主动从微信服务器上获取。

附关键代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public String getAccessToken() {
String access_token = "";
try {
Resource tokenFile = properties.getTokenFile();
Properties wxprop = PropertiesLoaderUtils.loadProperties(tokenFile);
String expires = wxprop.getProperty(WxConstant.EXPIRES_IN);
long now = Calendar.getInstance().getTimeInMillis() / 1000;
if (expires != null) {
long expires_in = Long.parseLong(wxprop.getProperty(WxConstant.EXPIRES_IN));
if (expires_in < now) {
access_token = getFromServer(tokenFile, wxprop, now, WxConstant.ACCESS_TOKEN);
} else {
access_token = wxprop.getProperty(WxConstant.ACCESS_TOKEN);
}
} else {
access_token = getFromServer(tokenFile, wxprop, now, WxConstant.ACCESS_TOKEN);
}
} catch (IOException e) {
e.printStackTrace();
}
return access_token;
}

public String getJsApiTicket() throws WeixinException {
String jsApiTicket = "";
try {
Resource tokenFile = properties.getTokenFile();
Properties wxprop = PropertiesLoaderUtils.loadProperties(tokenFile);
String expires = wxprop.getProperty(WxConstant.EXPIRE_TIME);
long now = Calendar.getInstance().getTimeInMillis() / 1000;
if (expires != null) {
long expire_time = Long.parseLong(wxprop.getProperty(WxConstant.EXPIRE_TIME));
if (expire_time < now) {
jsApiTicket = getFromServer(tokenFile, wxprop, now, WxConstant.JSAPI_TICKET);
} else {
jsApiTicket = wxprop.getProperty(WxConstant.JSAPI_TICKET);
}
} else {
jsApiTicket = getFromServer(tokenFile, wxprop, now, WxConstant.JSAPI_TICKET);
}

} catch (IOException e) {
e.printStackTrace();
}
return jsApiTicket;
}

参考文档

文章目录
  1. 1. 说明
    1. 1.1. 主动调用的频率限制
    2. 1.2. jsapi_ticket
  2. 2. 缓存方案
  3. 3. 参考文档