写了个拦截器,每调用一个接口,开启一个新的线程计数+1。因为计数与系统逻辑是分开的,所以放在另外一个线程里。
但是这样是否会带来负载过高?有没有什么好的解决办法?按照key-value周期性的存储吗?
现在代码如下:
public class ModuleStatisticsInterceptor implements Interceptor { /** * 统计接口调用次数 */ @Override public void intercept(Invocation inv) { String controllerPath = inv.getControllerKey(); APICallCount(controllerPath.substring(1, controllerPath.length()), inv.getMethodName()); inv.invoke(); } /** * 统计接口调用次数(另外的线程中执行) * @param className controller类名 * @param methodName controller中的方法名 */ public static void APICallCount(String className, String methodName) { new Thread(new Runnable() { public void run() { try { Record record = Db.findFirst("SELECT controllerName FROM module_statistics WHERE controllerName = ? AND methodName = ?", className, methodName); if(record == null) { Db.update("INSERT INTO module_statistics(controllerName, methodName, count, state) values(?,?, 0, 1)", className, methodName); } Db.update("UPDATE module_statistics SET count = count + 1 WHERE controllerName = ? AND methodName = ? LIMIT 1", className, methodName); } catch (Exception ex) { LogKit.error("统计出错:" + className + "/" + methodName); } } }).start(); } }
然后用 jfinal 提供的 Cron4jPlugin 插件定时将这个 AtomicLong 值写入数据库,并且清零
AtomicLong 放在一个全局拦截器中即可