why搞这么一个玩意
用过vue-cli的小伙伴会很轻松的搭建出一个包含vue骨架的前端开发组件,然后install所需要的模块,后台常见springcloud框架也是如此,但是少了所需要的好多模块,需要引入pom,还要兼容各种版本问题。
### 为了更快进行开发,搭建了一套适合后台的脚手架lei,前后端分离,restful风格接口开发,适合二次开发,主要包含以下模块。
> * 常见cloud模块 全家桶 注册中心 熔断 降级 网关等等
> * 集成常见java集成
> * springboot 集成`kafka`
> * springboot 集成`es` 实现全文检索
> * springboot 初步实现`zookeeper`注册发现
> * springboot 集成`mongodb`
> * springboot 集成`redis`
> * springboot 集成常见`mq`
> * 基于netty的`websocket`拓展 常见基于`json`、`protobuf`通讯拓展、粘包拆包等功能 推送和`im`即时通讯功能实现
> * sso单点登录
> * 常见功能 限流、 利用`aop`分布式锁的实现、`redission`分布式锁的应用等
> * 基于`client `模式的分库+分表核心jar包实现 以及分库产生的跨库事物等
> * 单机分布式事物框架整合 `atomikos`处理多数据源分布式事物
> * 还有其他业务功能待整合 分表之后数据聚合 报表模块 权限管理 等等
------
### 1. 功能清单 [Todo 列表]
- [x] springboot 集成kafka,zookeeper.redis,mongdb完成,初步实现缓存+全文检索
- [x] 基于client 水平分表方案完成 雪花算法生成id
- [x] 完成分布式锁demo,解决重复插入问题
- [x] 基于netty websocket 长连接推送和im完成 消息记录存储mongodb
- [x] 定时任务拆解完成
- [x] 垂直分表 分库以及产生的分布式事物
- [x] mysql读写分离 主库设置事物 同一Transcational 可以切数据源完成
- [ ] 权限接口+安全认证
- [ ] 限流+高并发接口设计
- [ ] 无状态应用水平拓展
- [ ] vue整合 前后端分离
- [ ] nginx负载
### 2. 项目模块介绍
- lei-api 对外暴露接口
- lei-app web rest接口 zookeeper kafka es等功能demo
- lei-demo zookeeper kafka es等功能demo 线程池封装等
- lei-common 一些公共工具包 aop实现分布式锁解决重复插入 单位时间重复请求
- lei-dao 普通mybatis配置 单库查询 mysql查询
- lei-eurake 注册中心
- lei-framework-istranstation 解决单机分布式事物 支持同一Transcation 切库操作 并支持多库事物
- lei-framework-notranstation 解决读写分离 支持主库事物 从库查询不支持事物
- lei-gateway 网关系统
- lei-im 基于netty websocket 长连接 推送 im即时通讯
- lei-job 定时任务+kafka消费
- lei-portal 门户首页
- lei-service 服务逻辑层
- lei-sso 单点登录系统
# 以下一些思路分享
# ** elasticsearch 常见查询
```
1. match match_phrase term
match 全文模糊匹配 分词 适用于text 例如 i am ding 分词设置 i am ding三个词 当match时候 i happy 也能搜到 happy world也能搜到
match_phrase 短语匹配 i am happy 分词成i am happy 当搜索 am happy 搜到 因为短语匹配
term 精确匹配 i am happy 分词成i am happy 当搜索 am happy 搜不到 因为没有分词设置
2.bool 查询 高级查询
must / mustnot/filter等太简单 自己查询即可
```
# ** 基于redission分布式锁demo 模拟100线程同时插入
```
package com.lei.smart;
import com.lei.smart.mapper.UserMapper;
import com.lei.smart.mapper.WebchatSchoolMapper;
import com.lei.smart.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.awt.peer.LabelPeer;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.*;
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class WebchatServiceTests {
@Autowired
UserMapper userMapper;
@Test
public void contextLoads() {
Config config = new Config();
config.useSentinelServers().addSentinelAddress("****,*****,****")
.setMasterName("mymaster");
// CountDownLatch countDownLatch =new CountDownLatch(1);
RedissonClient redissonClient = Redisson.create(config);
ExecutorService executorService = Executors.newFixedThreadPool(100);
CyclicBarrier cyclicBarrier = new CyclicBarrier(100);
for (int i = 0; i < 100; i++) {
executorService.submit(new Runnable() {
@Override
public void run() {
try {
// cyclicBarrier.
log.info(Thread.currentThread().getName() + ">>>>> block");
cyclicBarrier.await();
log.info(Thread.currentThread().getName() + ">>>>> open");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
// log.info("加锁前");
RLock lock = redissonClient.getLock("test10");
// log.info("加锁后");
try {
// log.info("尝试获取到分布式锁<<<<
boolean b = lock.tryLock(500, 2000, TimeUnit.MILLISECONDS);
log.info("获取到分布式锁<<<<