一些常用业务逻辑
1.防抓取&&防占座
发送短信(图片)验证码
-
生成验证码,及对应的code (图片验证码类似,可以使用谷歌的kaptcha类库)
public class ConfirmCodeUtil { private final static String SESSIONKEY_PREFIX = "aa_bb_xx"; public static String generate() { String chars = "0123456789"; char[] rands = new char[6]; for (int i = 0; i < 6; i++) { int rand = (int) (Math.random() * 9); rands[i] = chars.charAt(rand); } return new String(rands); } //生成手机验证码session //生成图片验证码session public static String createSessionKey() { return System.currentTimeMillis() + DigestUtils.md5Hex(SESSIONKEY_PREFIX + new Random().nextInt()); } }
-
相关信息放入缓存(验证码,验证次数以及过期时间等),并把缓存的key作为cookie的值,存入客户端,如下
co_qsid(cookie的key) : memkey(cookie的值,也是验证码缓存的key) memkey: verifyCode(验证码)
-
通知用户
-
验证:从cookie中获取对应的缓存的key,从缓存中获取对应key的值,比较request中的验证码和缓存中的.
黑名单策略
url加密
2.订单同步
- 业务方订单状态进行更改,发送消息给订单中心,附加有版本号version v1,标识订单当前的状态
- 订单中心接收到消息,主动拉取业务方订单详情,此时订单详情也带一个version v2.
- 应该是v2 >= v1,订单中心才会进行同步.否则校验出错.
3.分布式锁
setnx + expire 这个方案有个问题,一定几率出现数据被永久锁定,一个故障就是这样引起的.
private boolean tryLockTask(TaskInfoType type) {
String key = makeTaskKey(type);
long ret = sedis.setnx(key, key);
// 这里如果机器down掉,网络断了,数据就被永久锁定了.
if (ret == 1L) {
sedis.expire(key, 60);
locked.set(true);
return true;
} else {
locked.set(false);
return false;
}
}
改进方案: 使用redis的
SET key value [EX seconds] [PX milliseconds] [NX|XX]
127.0.0.1:6379> set lockKey lockValue PX 5000 NX
OK
127.0.0.1:6379> get lockKey
"lockValue"
对应于jedis的public String set(final String key, final String value, final String nxxx,final String expx, final long time);