本文正在参加「金石计划 . 分割6万现金大奖」

前言

大数据量、高并发、杂乱事务三不沾?不要紧,没有什么项目是开掘不出来亮点的,除非你摆烂。其实我现在做项目,大多便是事务的增修改查,或许最近做看板相对应的事务核算或许数据量会存在一些难点,可是和传统的巨大上技能基本不沾边。增修改查这东西,很难说亮点,或许我思路比较明晰,手相对快一些,但这些肯定说不上优势,拉开差距的必定是考虑,深入的考虑,要做别人容易做不到的事才行。

之前文章也提过,限于我司的技能架构,除了架构师外大多只能玩玩spring boot和中间件,像是k8s和devops这种不让玩,究竟你做了让架构师做啥,是吧!当然硬要做,暗里花时刻自己做就行,只需证明比公司现有的计划好,谁还能拦得住你前进,比方我自己搞的EFK日志搜集体系,就成功翻身上位,概况看我第二篇文章。

说了一大堆,核心思维便是让三不沾的读者朋友们不要慌,没法从底层下手,咱就往规划计划、功用调优和自定义组件上面靠。

项目亮点

亮点这个东西,说大可大说小可小,大可到体系规划、底层优化,小也可所以事务流程优化、东西类。我个人的话,比较喜欢玩技能,当然事务方向也会涉及举例,读者们定心,比方都会有的。项目亮点,项目在前,在挖掘时肯定要结合项目现状进行描绘,否则也没啥压服力。干说一大堆技能点,不知道的还以为你在卖课,作为开发,玩的便是定制化开发,才能的表现就在于对定制化了解的有多深入。实在找不出来,咱还能够发明亮点,不是吗?稍微过度规划下,只需不犯错就没啥问题。

SQL优化

SQL优化这就立刻开端打脸了,这要让我忽然举个事务相关的比方还真不好说。可是正由于这是通用技能,所所以你说你把所有SQL都优化过也没人说啥。关键是说说你怎么优化的,这里链接一下我之前的文章从零开端的SQL修炼手册-实战篇,里面有具体的事例和优化步骤,这里就挑要点的说了。


SQL优化咱们能够从最根底的SQL句子自身下手,并进一步从场景、表规划、数据库装备、架构四方面着手优化。

在优化之前,需求判断SQL句子是否是真的很慢。或许由于锁、刷新脏页、高并发、buffer pool设置过小导致SQL偶然变慢,要判断也很简略,看看是不是频频呈现在慢SQL日志里就行了。

如果确定是SQL句子的问题,那么就能够按照我首创的九步优化套路操作了。

  • 一是规范字段名称,这一步是便利咱们理解字段并明晰看到归属表。
  • 二是扫除所有的select *句子,包含子查询以及JOIN句子,这一步是削减传输数据。
  • 三是小表驱动大表,这一步需求根据事务来判断是否调整。
  • 四是创建索引,尽量多的运用联合索引,不要创建过多的索引,留意索引失效的状况,比方隐式类型转化、索引列运用函数或参加运算、like左含糊匹配。
  • 五是运用掩盖索引优化。
  • 六是运用where和group by的having来削减查询的数据。
  • 七是经过explain去优化SQL,根据ref key extra等字段的信息来动态调整优化手法。
  • 八是子查询能够换成连接查询,削减临时表创建。
  • 九是调整where句子顺序,过滤数据多的条件放在前面。

场景优化例如深度分页、批量新增。表规划优化例如冷热数据别离、增加冗余字段或中间表。装备优化例如数据库的连接数,buffer pool优化。架构优化便是读写别离、分库分表。


一般来说这么一套组合拳下去又快又准,由点及面,知识面肯定是够了,而且也有必定的深度。SQL的优化这块要点关注索引,了解下索引优化成本,简略来说便是优化器是否挑选运用非主键索引,是要考虑当时索引射中数据在悉数数据的大致占比巨细,占比小才走索引,否则全表查询。联合索引和掩盖索引需求清楚,索引下推等优化能够了解。

东西组件

再来说点群众的,组件自然是spring boot starter,东西则涉及方方面面。和事务强关联的没点技能性的就不用说了,适用性太低,多说点技能相关的。能够从redis、加密解密等方向下手。Spring Boot Starter开发指北(事例+代码地址)


我在工作的时分自己整合了一些东西类和装备项经过spring boot starter的办法集成到项目中。比方加密解密东西,我是整合了jasypt(Java Simplified Encryption,缩写词不要纠结读音,念字母即可)作为加密结构,默认运用PBE加密算法,PBE加密算法实践上是对已知算法的组合,比方常用的MD5和DES,在实践加密时会随机运用一种组合中的加密算法进行加密,密文由前八位盐值和后八位实在密文组成,该结构相比传统的加密办法愈加简略易用,而且支撑装备文件加密。我在项目运用Mybatis作为ORM结构,完成了Mybatis的扩展接口typehandle,对入参和出参拦截后进行加密解密,一起针对。

redis我是引进了redisson结构,封装了大量易用API,而且供给了分布式锁等东西。在此根底上我是封装了一些常用东西,根底思维是运用LUA脚本将多个指令封装在一起,优点有两个,分别是原子性操作以及汇总在一起的指令一次性发送削减了多次发送的网络开销。

  • 发号器便是一个获取递增值的操作,比较简略。
  • 幂等性校验器实践上便是固定时刻窗口算法的运用,一段时刻内允许固定请求数量进入,多余的请求回绝或许排队。我这里是做成了注解,开发者能够经过手动输入KEY值或许不填,不填的话我是在切面搜集办法入参,为了防止入参过长,最终的KEY值是运用了办法名+入参的MD5值。
  • 限流器则是运用了经典的漏斗算法,限制一个最大速率,它和时刻窗口的差异就在于,当时调用结束后要返还占用的次数,会有一个动态的加减,而不是单纯累加直到最大值。

平心而论,东西这一块可聊的点真的很少,JAVA太卷了,轮子太多了,比方大名鼎鼎的HuTool。以上都是一些比较常见的小东西,实在没得说了你再说这些。由于这些东西说白了,也是运用别人的轮子,仅仅做了一个事务封装罢了,最关键的要结合事务和你的考虑有自己的沉淀。redis这块我引进了LUA脚本作为亮点,究竟redisson这样的牛逼结构内部都用的LUA脚本来完成合并操作的原子性。

事务模块规划

后端思维-如何规划一个操作和管理Excel的事务模块

和技能东西造轮子更多专注于技能不同,事务模块规划的要点在于规划,这一块咱们会一起站在架构师和项目经理的角度去考虑,去做一些根据事务模块深度定制的技能选型和流程规划,技能上或许不会太深,这不要紧,要点在于你对整个模块的统筹考虑。

在与人交流的时分,上来就挖技能深度其实不是上策,许多时分技能一旦过深就会有种曲高和寡的感觉,要用简略易懂的言语表现出你的技能深度,关于大多八股高手并非易事,说的让人听不懂并不是一个杰出的交流办法,因而一个咱们都能听懂而且能拿得出手的事务模块规划才是上上之选。


我的excel模块依托于门户网站,整合了主子站的excel文件,对用户和开发者的体验都做了优化。

关于用户侧的优化表现于,用户能够在恣意子体系上传文件,然后在主站的文件列表看到文件的具体信息比方文件校验信息,文件状况,下载次数,还能够直接下载已上传的文件。

开发者部分则是最大极限的封装API,将本来几百行的代码优化为十几行,一致了代码风格和依靠版本。

整个excel模块从事务方向看能够分为导入和导出,根据场景可分为动态和一般,异步和同步。大致事务流是

  1. 用户子站页面导入或许导出
  2. 解析文件(导入)或许生成文件(导出)
  3. 上传到文件服务器获取文件id
  4. 子体系组装文件概况数据并传到主站
  5. 主站展现文件概况

在我规划完成整个excel模块事务流之后,我是用一个spring boot starter来封装了主站、子站和文件服务器的API交互,一起引进easy excel作为解析excel文件的核心结构。这一块封装的优点有两个,一是规范代码削减BUG,便利新老搭档快速上手,二是便利我做整体规划,一致代码风格。接下来针对两个规划上的亮点做一下扼要描绘。

一是展现过错信息,我将过错分红四种。第一种是最基本的过错,也便是excel文件是否为空、格式是否有错、上传到服务器是否反常等准备进程中呈现的根底过错。这些根底的过错必须要直接回来给页面展现给用户。第二种是easy excel解析excel文件时的解析过错,比方表头反常、格式转化过错,我是在监听器中内置了一个过错信息处理办法,而且供给给开发搭档两种挑选,一是抛出一段汇总过错信息,二是在每一行的数据前面生成一个过错信息。第三种过错是excel数据在事务处理时报的事务过错,比方事务校验不经过,这个处理办法和第二种类似。第四种过错便是整个流程中呈现的恣意反常,catch之后将过错信息抛给主站展现在文件列表。

二是做了easy excel的监听器优化,我将一般的监听器改造成了一个通用读取的监听器。而且内置了过错信息处理办法以及表头信息读取办法。除此之外对文件处理部分做了封装,与easy excel的导入导出API做了结合,比方前端传过来一个MultipartFile文件,只用调用我供给的API,即可完成格式转化、文件解析、流水号生成等复合功用。


以上便是一个标准的事务模块规划,选用的也是常见的excel导入导出场景,整个规划包含三个服务以及一个技能结构支撑,分别是主站、子站、文件服务器以及easy excel。根据个人实践状况,能够砍掉主站或许文件服务器,做一个简版的。能够参照上面文章的看看具体的规划进程,有伪代码以及细节讲解。

功用优化

功用优化-如何爽玩多线程来开发

功用优化这一块肯定是走向大佬的敲门砖,能结合理论和实践讲一个好的事例出来无疑是大大的加分项,我直接叫你大佬。由于我个人对调优这块了解不透,比方服务器调优、中间件或许程序调优都是有必定的理论,可是实践比较少,动态调优对我来说仍是比较困难。现在我对JVM、Kafka、ES有必定的调优经验,对功用优化的理论也有必定了解,但为了防止误人子弟,我仍是从常见且相对简略的多线程说起。


我在项目中是大量的用到了多线程编码来进步运转功率。主要运用场景便是并行聚合处理数据,这里是用到了CompletableFuture.allOf()办法,将本来串行运转的事务逻辑改为并行处理,比方处理A逻辑开启线程1,处理B逻辑时开启线程2,等1234所有线程都执行结束后再汇总数据进行下一步处理,这一块思路类似于CountDownLatch。运用相同的思路,我也能够修改for循环为并行操作,这一步学习parallelStream的分治法思维,将list切分红多个小list,然后开启对应数量的线程,最终仍是运用CompletableFuture.allOf()办法聚合数据。同理,将Map切成List,也能修改为并行操作,进步循环功率。

除此之外,还有一些小技巧,比方List转Map用空间换时刻破解双层循环。常见的场景有,外来数据ListA比照数据库数据ListB,根据仅有值比照,惯例做法是A循环嵌套B循环,根据仅有值找匹配数据,这样便是双层循环。咱们能够将ListB转化为Map,然后用仅有值做Key,那么只需求一层循环即可。


多线程这个相对说的比较简略,可是非常有用,而且大多数状况下,开发并不会或许说懒得运用这样的技巧。由此也能够引申一些知识点,比方线程池如何装备的,你就能够说大致分为两种状况。IO密集型的便是多开线程,小队列,由于IO不占用CPU。CPU密集型则是要少线程,防止频频上下文切换,队列要大,防止高并发的时分使命丢失。

技能模块规划

Filebeat+Kafka+数据处理服务+Elasticsearch+Kibana+Skywalking日志搜集体系

技能模块这么说呢,主要是和事务模块区分隔,和惯例的事务开发肯定是有差异的。一说这种,肯定能联想到惯例的Seata分布式事务、Kafka音讯队列、Prometheus监控、Redis等等中间件,当然做成这种肯定是大牛中的大牛了,咱不考虑这种状况。在技能深度暂时达不到那种高度的时分,学习国内手机厂商的做法,做一个计划整合商呗,本地化改造或许整合封装都能够,得有你自己的考虑。


我是自己搭建了一套完整的日志搜集体系用于搜集团队内部的事务日志,服务于XX个项目,月均XX条日志XXGB数据,上线XX年稳定运转。整个日志搜集体系的架构规划采用了经典的EFK架构,运用的技能栈有Filebeat+Kafka+Elasticsearch+Kibana+Skywalking,除此之外单独写了一个微服务用于数据处理。日志搜集的流程是Filebeat担任搜集Log4j2产生的log文件然后抛到Kafka,数据处理服务消费Kafka音讯后批量插入到ES,日志展现用的kibana,链路追寻用的skywalking中间件支撑

整个架构规划大致是迭代了三个版本。第一个版本是根据注解切面+Kafka+数据处理服务+ES,这个版本本来是合作公司原有的日志搜集做一个行为日志的弥补,结果后来我发现搭档在运用的时分都是默认装备,不喜欢写注解参数,而且注解的办法耦合度太高,一旦变化改的当地太多。因而我在第一版的根底上砍掉了注解切面,直接用log4j2推送到Kafka,而且布置了kibana来展现日志,一起针对Kafka和ES进行了高并发的优化,第二版类似于传统的ELK架构。在第二版上线稳定运转半年后,我就开端想着晋级一下,首先是引进了Filebeat做了一个搜集的扩展,由此能够做一下Seata、MySQL之类中间件的日志搜集,其次是加入了链路追寻,这一块调研了Zipkin和Skywalking等,最终是挑选了Skywalking,这个之前接触过,就直接用了,和Log4j2的集成也很便利,而且是根据JavaAgent的无侵入探针技能,做组件比较便利。

优化从各个组件聊起吧。Filebeat自身做了一个环境阻隔以及堆栈信息合并优化,一起装备文件调整了Kafka生产者的装备。要点是尽量往高并发的方向去调整,比方批量巨细增加、发送时延拉长这样就能削减批量的次数,对应的Kafka缓冲区也要合作着调大,音讯巨细肯定要调大,部分堆栈信息会超越默认的1MB.ACK的话用1,不怕丢失用0。数据处理服务在Kafka的消费者装备上主要做了一个批量接收以及并发消费的优化。特别是留意手动提交偏移量,防止由于程序处理失误导致数据丢失。ES的优化主要是索引部分,动态索引肯定是必要的,我是按月建索引,然后会定时去删去一年以上的索引,新增肯定也是批量操作,索引还能够调整落盘战略为异步,时刻从1s一次改成5s一次,进步新增功率。


整个日志搜集体系,我是先描绘了下现在的运用状况,然后聊了下技能栈以及整个日志搜集的流程。接下来说了下,整个架构规划以及迭代进程,复盘了下迭代的优点。最终聊了聊整个模块优化的部分,从技能选型运用到功用优化都有涉及,仍是比较完整的一次规划进程。

写在最终

亮点这块一开端我就想好了大致分为上面这几个模块开端写,可是写着写着我发现扫除去巨大上的高并发、大流量,剩余的这些惯例事务的确是比较难抓亮点。写出来的东西有时分我感觉都压服不了我自己,亮点这东西我感觉仍是要结合实践状况来说,否则总有种海市蜃楼的感觉,没啥底气。我发现网上的确也是很少有人像我这样细致的来讲亮点,百度必应看了好多页,仍是讲思维的比较多,还有便是经典秒杀,哈哈。以上几个仅做参阅吧,希望能对咱们有所帮助,能开掘一些自己的亮点。更欢迎咱们评论指路,聊聊自己的亮点,人多力量大。

来点碎碎念吧,最近在网上看相关文章,发现写这块的是真的少啊,莫非是我查找办法不对,求指导。这种结合实践的东西写起来真是头大,下一篇写项目难点更是头大。我自己的话,最近项目开发太紧张了,整个十月没有更新。自身的懒散和高强度的加班让我身心俱疲,选题也憋了一段时刻,现在剩余的选题有项目难点和如何写一篇优异的开发文档。项目的话,仍是做看板项目,数据量的话没有特别大,核算逻辑杂乱可是事务逻辑不杂乱,高并发不至于内部看板罢了,经典三不沾,但仍是在我的技巧下成功出产了两篇文章,哈哈。一篇规划,一篇优化,总的来说,这个项目自身很容易触发OOM,现阶段没做优化,我正愁着呢,但现在首要问题是快速迭代交给,敏捷开发嘛,你们都懂的。