后台开发java 常见工具包 netty、mq 、分布式锁等 干货~

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拓展 常见基于jsonprotobuf通信拓展、粘包拆包等功能 推送和im即时通信功能实现
  • sso单点登陆
  • 常见功能 限流、 利用aop分布式锁的实现、redission分布式锁的应用等
  • 基于client模式的分库+分表核心jar包实现 以及分库产生的跨库事物等
  • 单机分布式事物框架整合 atomikos处理多数据源分布式事物
  • 还有其余业务功能待整合 分表以后数据聚合 报表模块 权限管理 等等

1. 功能清单 [Todo 列表]

  • springboot 集成kafka,zookeeper.redis,mongdb完成,初步实现缓存+全文检索
  • 基于client 水平分表方案完成 雪花算法生成id
  • 完成分布式锁demo,解决重复插入问题
  • 基于netty websocket 长链接推送和im完成 消息记录存储mongodb
  • 定时任务拆解完成
  • 垂直分表 分库以及产生的分布式事物
  • 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("获取到分布式锁<<<<<{}", b);
                        if (b) {
                            User userSelect = userMapper.selectByPrimaryKey(1l);
                            if (userSelect == null) {
                                log.info(Thread.currentThread().getName() + ">>>>> is null");
                                User user = new User();
                                user.setId(1l);
                                user.setName("dingjainlei");
                                userMapper.insert(user);
                            } else {
                                log.info(Thread.currentThread().getName() + ">>>>> is not null");
                            }
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        lock.unlock();
                        log.info("解锁");
//                                redissonClient.shutdown();
                    }
                }
            });
        }


    }

}

复制代码

常规操做

通常是先去数据库查询,若是不存在,则进行插入。若是存在,则不进行操做vue

模拟思路

使用CyclicBarrier 100个线程同时等待await=0的时候同时并发请求查询数据库id=1存不存在
redission 使用tryLock 尝试获取锁 设置超时 自动释放锁时间  防止死锁 ,保证分布式环境下 高并发插入重复问题
复制代码

End

如何启动

下载到本地以后,在msyql中建立数据库lei,一次启动便可java

问题反馈

在使用中有任何问题,欢迎反馈给我,能够用如下联系方式跟我交流mysql

邮件(m13687672481@163.com)nginx

QQ: 1251272104web

微信: kenan13687672481redis

关于做者

下载到本地以后,在msyql中建立数据库lei,一次启动便可算法

var author = {spring

nickName  : "工藤新一",
复制代码

}sql

相关文章
相关标签/搜索