2019-07-17 16:55
@邓小杰 这事肯定与 jfinal 无关了,检查一下 tomcat 部署时的坑:
https://my.oschina.net/jfinal/blog/353062
2019-07-17 16:30
@邓小杰 这个是 java 基础, 代码如果被阻塞,程序执行到那就不会动了, 你 new 出一个线程是让这个线程继续往下走,你的主线程才得以继续
这个问题与 jfinal 是完全无关的, 纯粹 java 基础
2019-07-17 15:48
@think-takn 如果你实在懒得去找源因,做一个 Handler, 花几行代码解决一下:
public class MyHandler extends Handler {
public void handle(String target, req, resp, isHandled) {
if (target.endsWith("/")) {
target = target.substring(0, target.length() -1);
}
next.handle(target, req, resp, isHandler);
}
}
最后在 configHandler 中配置一下:
configHandler(Handlers me) {
me.add(new MyHandler());
}
2019-07-17 15:40
@阿龙 通过改写 Utf8Encoder 即可, 相当于是做一个新的 Utf8mb4Encoder,这部分接口是开放的,你也可以自己写一个, 然后自己通过我前面回复中的方法让其生效
jfinal 中绝大部分功能都是开放可扩展的
2019-07-17 15:32
@邓小杰 为啥不在 afterJFianlStart() 或 onStart() 中也同样用 new 一个新线程启动???
2019-07-17 12:18
@think-takn 升级一定要按文档来,跨多个版本升级,主要就是改点类名、方法名:
https://www.jfinal.com/doc/14-1
2019-07-17 11:45
@10000 status 的取值是 0 和 1,高并发的时候,不知道是谁将这个状态置为 1 的
虽然在事务中也可以保障这个值只能被某个线程抢到,但多一个 UUID 作为 locker 更加安全,因为事务依赖不少的条件,例如必须是 InnoDB 引擎,必须要开启事务
上面的方案用到 UUID 的 locker 相当于是双保险
2019-07-17 11:36
我给的方案,再补充完善一点点:
1:所有任务存放在一个中心的数据库中
2:任务的表名为 task,主要字段有: task(id, locker)
3:创建一个 TaskService 业务类
4:TaskService 中创建一个抢占 Task 的方法:
public class TaskService {
private static final Task dao = new Task().dao();
public Task getTask() {
String UUID = StrKit.getRandomUUID();
// 该 sql 只更新 locker 字段,也就是先只去抢占锁,而不能做其它任何事情
String sql = "update task set locker = ? where locker is NULL";
int n = Db.update(sql, UUID);
if ( n <= 0) {
return null;
};
// n 大于 0 表示 update 成功,但不能保证是当前线程抢到的该 task
// 通过前面生成的 UUID 去查询,查到了才能证明真的是当前线程抢占到了该 task
Task task = dao.findFirst("select * from task where locker = ?", UUID);
if (task != null) {
return task;
} else {
// 如果没有抢占到 task ,可以放弃则 return null, 也可以重试几次
return null;
}
}
}