diff --git a/lib/arangodb-java-driver-5.0.1.jar b/lib/arangodb-java-driver-5.0.1.jar new file mode 100644 index 0000000..769b3c6 Binary files /dev/null and b/lib/arangodb-java-driver-5.0.1.jar differ diff --git a/lib/enjoy-3.4.jar b/lib/enjoy-3.4.jar deleted file mode 100644 index 7f46fda..0000000 Binary files a/lib/enjoy-3.4.jar and /dev/null differ diff --git a/lib/enjoy-3.5.jar b/lib/enjoy-3.5.jar new file mode 100644 index 0000000..7024a06 Binary files /dev/null and b/lib/enjoy-3.5.jar differ diff --git a/lib/jackson-core-2.9.5.jar b/lib/jackson-core-2.9.5.jar new file mode 100644 index 0000000..b70d1ef Binary files /dev/null and b/lib/jackson-core-2.9.5.jar differ diff --git a/lib/mongo-java-driver-3.8.0.jar b/lib/mongo-java-driver-3.9.0.jar similarity index 64% rename from lib/mongo-java-driver-3.8.0.jar rename to lib/mongo-java-driver-3.9.0.jar index 2893527..502541f 100644 Binary files a/lib/mongo-java-driver-3.8.0.jar and b/lib/mongo-java-driver-3.9.0.jar differ diff --git a/lib/netty-all-4.1.29.Final.jar b/lib/netty-all-4.1.29.Final.jar new file mode 100644 index 0000000..b84979f Binary files /dev/null and b/lib/netty-all-4.1.29.Final.jar differ diff --git a/lib/redkale-1.9.8.jar b/lib/redkale-1.9.8.jar new file mode 100644 index 0000000..c19e9e7 Binary files /dev/null and b/lib/redkale-1.9.8.jar differ diff --git a/lib/redkale-plugins-1.9.8.jar b/lib/redkale-plugins-1.9.8.jar new file mode 100644 index 0000000..a009737 Binary files /dev/null and b/lib/redkale-plugins-1.9.8.jar differ diff --git a/lib/redkale-plugins.jar b/lib/redkale-plugins.jar deleted file mode 100644 index 214224d..0000000 Binary files a/lib/redkale-plugins.jar and /dev/null differ diff --git a/lib/redkale.jar b/lib/redkale.jar deleted file mode 100644 index a720365..0000000 Binary files a/lib/redkale.jar and /dev/null differ diff --git a/lib/slf4j-api-1.7.13.jar b/lib/slf4j-api-1.7.13.jar new file mode 100644 index 0000000..f07884e Binary files /dev/null and b/lib/slf4j-api-1.7.13.jar differ diff --git a/lib/velocypack-1.4.1.jar b/lib/velocypack-1.4.1.jar new file mode 100644 index 0000000..6f0e5a6 Binary files /dev/null and b/lib/velocypack-1.4.1.jar differ diff --git a/libs/redbbs.jar b/libs/redbbs.jar index 209413a..929b682 100644 Binary files a/libs/redbbs.jar and b/libs/redbbs.jar differ diff --git a/src/com/lxyer/bbs/base/ArangoKit.java b/src/com/lxyer/bbs/base/ArangoKit.java index 9d5c308..cc6dad5 100644 --- a/src/com/lxyer/bbs/base/ArangoKit.java +++ b/src/com/lxyer/bbs/base/ArangoKit.java @@ -5,6 +5,9 @@ import com.arangodb.ArangoDB; import com.arangodb.ArangoDatabase; import com.lxyer.bbs.base.entity.VisLog; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.function.Function; /** @@ -21,7 +24,6 @@ public class ArangoKit { protected static ArangoDatabase dbDev = arangoDb.db(chDev.apply("redbbs")); protected static ArangoCollection colVisLog = dbDev.collection(chDev.apply("vis_log")); - //check exists static { if (!dbDev.exists()) { dbDev.create(); @@ -30,12 +32,35 @@ public class ArangoKit { if (!colVisLog.exists()) { colVisLog.create(); } + + //java.net.SocketTimeoutException: Read timed out 加入下面两行,观察是否正常 + System.setProperty("sun.net.client.defaultConnectTimeout", String.valueOf(1000)); + System.setProperty("sun.net.client.defaultReadTimeout", String.valueOf(1000)); } - public static void save(T t) { - if (t instanceof VisLog) { - colVisLog.insertDocument(t); - } + public static CompletableFuture save(T t) { + return CompletableFuture.supplyAsync(() -> { + if (t instanceof VisLog) { + colVisLog.insertDocument(t); + } + return t; + }); + } + + public static long findInt(String aql) { + return dbDev.query(aql, long.class).first(); + } + public static long findInt(String aql, Map para) { + return dbDev.query(aql, long.class).first(); + } + + public static List find(String aql, Class clazz) { + return dbDev.query(aql, clazz).asListRemaining(); + } + + public static List find(String aql, Map para, Class clazz) { + + return dbDev.query(aql, para, clazz).asListRemaining(); } } diff --git a/src/com/lxyer/bbs/base/BaseServlet.java b/src/com/lxyer/bbs/base/BaseServlet.java index 0f58633..b800116 100644 --- a/src/com/lxyer/bbs/base/BaseServlet.java +++ b/src/com/lxyer/bbs/base/BaseServlet.java @@ -86,6 +86,7 @@ public class BaseServlet extends HttpServlet { VisLog visLog = new VisLog(); visLog.setIp(request.getRemoteAddr()); + visLog.setUri(request.getRequestURI()); visLog.setHeaders(headers); visLog.setPara(para); visLog.setTime(System.currentTimeMillis()); diff --git a/src/com/lxyer/bbs/base/TaskQueue.java b/src/com/lxyer/bbs/base/TaskQueue.java index 18be055..cb891db 100644 --- a/src/com/lxyer/bbs/base/TaskQueue.java +++ b/src/com/lxyer/bbs/base/TaskQueue.java @@ -1,5 +1,6 @@ package com.lxyer.bbs.base; +import com.lxyer.bbs.base.entity.Count; import com.lxyer.bbs.base.entity.VisLog; import com.lxyer.bbs.base.kit.LxyKit; import com.lxyer.bbs.base.user.UserInfo; @@ -8,14 +9,10 @@ import com.lxyer.bbs.base.user.UserService; import com.lxyer.bbs.content.Content; import com.lxyer.bbs.content.ContentInfo; import com.lxyer.bbs.content.ContentService; -import com.mongodb.Block; import com.mongodb.MongoClient; -import com.mongodb.client.AggregateIterable; import com.mongodb.client.FindIterable; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; -import com.mongodb.client.model.Accumulators; -import com.mongodb.client.model.Aggregates; import org.bson.Document; import org.bson.conversions.Bson; import org.redkale.net.http.RestMapping; @@ -30,11 +27,11 @@ import org.redkale.util.Sheet; import javax.annotation.Resource; import java.util.*; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.LinkedBlockingQueue; +import java.util.function.Consumer; +import java.util.function.Function; -import static com.mongodb.client.model.Filters.*; -import static java.util.Arrays.asList; +import static com.mongodb.client.model.Filters.eq; /** * Created by liangxianyou at 2018/6/20 22:54. @@ -82,81 +79,78 @@ public class TaskQueue extends BaseService implements Runnable @Override @RestMapping(ignore = true, comment = "独立线程,用户访问行为记录到数据库") public void run() { - try { - while (true){ + do { + try { T task = take(); + + //记录访问日志,如果是访问的文章详情:对文章访问数量更新 if (task instanceof VisLog) { - ArangoKit.save(task); + ArangoKit.save(task).thenAcceptAsync((_task) -> { + VisLog visLog = (VisLog) _task; + //[访问量] + String uri = visLog.getUri(); + if (uri != null && uri.startsWith("/jie/detail/")){ + updateViewNum(visLog); + } + }); } - /*Map logData = (Map) take(); - - logData.put("ftime", String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS", logData.get("time"))); - visLog.insertOne(new Document(logData)); - - //在这里处理日志数据 - String uri = logData.get("uri")+""; - - //[访问量] - if (uri.startsWith("/jie/detail/")){ - updateViewNumAsync(logData); - }*/ + } catch (InterruptedException e) { + e.printStackTrace(); } - } catch (InterruptedException e) { - e.printStackTrace(); - } + } while (true); } @Comment("帖子阅读数处理") - private void updateViewNumAsync(Map logData) { - CompletableFuture.runAsync(()->{ - Bson filter = and( - eq("uri", logData.get("uri"))//帖子 - ,eq("ip", logData.get("ip"))//IP - ,or( - eq("userid", logData.get("userid"))//登录人 - ,eq("userid", 0)//未登录userid=0 - ) - ); - long count = visLog.count(filter); - if (count <= 1){ - String uri = logData.get("uri") + ""; - int contentid = Integer.parseInt(uri.replace("/jie/detail/", "")); - source.updateColumn(Content.class, contentid, ColumnValue.inc("viewnum", 1)); - } - }); + private void updateViewNum(VisLog visLog) { + + String aql = String.format("for d in vis_log_dev\n" + + " filter d.uri == '%s' and d.ip == '%s' and (d.userid == %s or d.userid==0)\n" + + " collect WITH COUNT INTO total\n" + + " return total", visLog.getUri(), visLog.getIp(), visLog.getUserid()); + + long total = ArangoKit.findInt(aql); + + + if (total <= 1) { + String uri = visLog.getUri(); + int contentid = Integer.parseInt(uri.replace("/jie/detail/", "")); + source.updateColumn(Content.class, contentid, ColumnValue.inc("viewnum", 1)); + } } @RestMapping(ignore = true, comment = "访问热帖数据") public Sheet hotView(String sessionid){ int limit = 8; String cacheKey = "hotView"; - Object ids = cacheSource.get(cacheKey); + Object ids = null;//cacheSource.get(cacheKey); if (ids == null){ Calendar cal = Calendar.getInstance(); cal.set(Calendar.DAY_OF_MONTH, -7); + Map para = new HashMap(); + para.put("time", cal.getTimeInMillis()); //查询一周某热帖记录 - Bson filter = and(ne("userid", 100001) - ,regex("uri", "/jie/detail/*") - ,ne("ip", "") - ,gt("time", cal.getTimeInMillis()) - ); - List list = asList( - Aggregates.match(filter) - ,Aggregates.group("$uri", Accumulators.sum("count", 1)) - ,Aggregates.sort(new Document("count", -1)) - ,Aggregates.limit(8) - ); - AggregateIterable documents = visLog.aggregate(list, Document.class); + List hotArticle = ArangoKit.find( + "for d in vis_log_dev\n" + + " filter d.uri =~ '^/jie/detail/[0-9]+$' and d.userid != 100001 and d.time > @time\n" + + " COLLECT uri=d.uri WITH COUNT INTO total\n" + + " sort total desc\n" + + " limit 10\n" + + " return {name: uri,total:total}", + Map.of("time", cal.getTimeInMillis()), + Count.class); - List _ids = new ArrayList<>(limit); - documents.forEach((Block) x->{ - String uri = x.getString("_id"); - _ids.add(Integer.parseInt(uri.replace("/jie/detail/", ""))); - }); + Function, List> deal = (counts) -> { + List _ids = new ArrayList<>(); + counts.forEach(x -> { + _ids.add(Integer.parseInt(x.getName().replace("/jie/detail/", ""))); + }); + return _ids; + }; - cacheSource.set(30 * 60, cacheKey, ids = _ids); + ids = deal.apply(hotArticle); + cacheSource.set(30 * 60, cacheKey, ids); } int[] contentids = new int[limit]; @@ -189,7 +183,7 @@ public class TaskQueue extends BaseService implements Runnable List rows = new ArrayList<>(); List uids = new ArrayList<>(); - documents.forEach((Block) x->{ + documents.forEach((Consumer) x->{ Integer userid = x.getInteger("userid"); if (userid > 0) uids.add(userid); diff --git a/src/com/lxyer/bbs/base/entity/Count.java b/src/com/lxyer/bbs/base/entity/Count.java new file mode 100644 index 0000000..d48da79 --- /dev/null +++ b/src/com/lxyer/bbs/base/entity/Count.java @@ -0,0 +1,37 @@ +package com.lxyer.bbs.base.entity; + +/** + * 用来计数用 + * + * @author: liangxianyou at 2018/11/18 20:42. + */ +public class Count { + private String name; + private long total; + + //------------------- + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getTotal() { + return total; + } + + public void setTotal(long total) { + this.total = total; + } + + @Override + public String toString() { + return "Count{" + + "name='" + name + '\'' + + ", total=" + total + + '}'; + } +} diff --git a/src/com/lxyer/bbs/base/entity/VisLog.java b/src/com/lxyer/bbs/base/entity/VisLog.java index 1515cef..f1b7809 100644 --- a/src/com/lxyer/bbs/base/entity/VisLog.java +++ b/src/com/lxyer/bbs/base/entity/VisLog.java @@ -71,4 +71,17 @@ public class VisLog { public void setHeaders(Map headers) { this.headers = headers; } + + @Override + public String toString() { + return "VisLog{" + + "ip='" + ip + '\'' + + ", userid='" + userid + '\'' + + ", ftime='" + ftime + '\'' + + ", uri='" + uri + '\'' + + ", time=" + time + + ", para=" + para + + ", headers=" + headers + + '}'; + } } diff --git a/src/com/lxyer/bbs/base/user/UserService.java b/src/com/lxyer/bbs/base/user/UserService.java index aa9f0f1..0cb27d7 100644 --- a/src/com/lxyer/bbs/base/user/UserService.java +++ b/src/com/lxyer/bbs/base/user/UserService.java @@ -131,7 +131,7 @@ public class UserService extends BaseService { user.setNickname(nickname);//去除昵称中的空格 source.updateColumn(user ,FilterNode.create("userid", currentUserid(sessionid)) - ,SelectColumn.createIncludes(columns) + ,SelectColumn.includes(columns) ); return RetResult.success(); } @@ -139,7 +139,7 @@ public class UserService extends BaseService { //最新加入 public Sheet lastReg(){ Sheet users = source.querySheet(UserRecord.class - , SelectColumn.createIncludes("userid", "nickname", "avatar", "createtime") + , SelectColumn.includes("userid", "nickname", "avatar", "createtime") , new Flipper().sort("createtime DESC").limit(8) , FilterNode.create("status", 10)); diff --git a/src/com/lxyer/bbs/comment/CommentService.java b/src/com/lxyer/bbs/comment/CommentService.java index e445152..34f06f6 100644 --- a/src/com/lxyer/bbs/comment/CommentService.java +++ b/src/com/lxyer/bbs/comment/CommentService.java @@ -51,7 +51,7 @@ public class CommentService extends BaseService implements UIService comments = source.querySheet(Comment.class, new Flipper().sort("createtime DESC"), FilterNode.create("userid", userid)); int[] contentIds = comments.stream().mapToInt(x -> x.getCommentid()).toArray(); - List contents = source.queryList(Content.class, SelectColumn.createIncludes("contentid","title"), FilterNode.create("contentid", FilterExpress.IN, contentIds)); + List contents = source.queryList(Content.class, SelectColumn.includes("contentid","title"), FilterNode.create("contentid", FilterExpress.IN, contentIds)); Sheet infos = createInfo(comments); infos.forEach(x->{