前言

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

之前文章也提过,限于我司的技术架构,除了架构师外大多只能玩玩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,现阶段没做优化,我正愁着呢,但现在首要问题是快速迭代交付,敏捷开发嘛,你们都懂的。

如何挖掘项目中的亮点(多方向带案例)相关推荐

  1. (74)项目中的亮点是什么?

    1.1 项目中的亮点是什么? 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)项目中的亮点是什么?: 5)结束语. 1.1.2 本节引言 "不积跬步,无以至千里 ...

  2. 面试中所谈的项目中的亮点

    前言 我是从18年11月份入职的,一直做的是Java开发,起初和大部分人一样都是CRUD,直到去年年底一个小项目让我做了技术经理,虽然我在项目上受到了比较大的打击(做己方的话如果真的遇到一个很难对付的 ...

  3. 如何利用 webpack 在项目中做出亮点

    大家好,我是若川.最近这几年,在前端代码打包器领域内,webpack 算得上是时下最流行的前端打包工具. 它可以分析各个模块的依赖关系,最终打包成我们常见的静态文件:.js . .css . .jpg ...

  4. 前端如何在项目中做出亮点?

    作者: 磐冲 https://segmentfault.com/a/1190000022795484 你负责的业务是什么?(学会发现问题) 之前在群里参加活动的同学,有不少说在小公司,被业务需求压着. ...

  5. 前端如何在项目中做出亮点

    (给前端大全加星标,提升前端技能) 作者:磐冲 https://segmentfault.com/a/1190000022795484 1.你负责的业务是什么?(学会发现问题) 之前在群里参加活动的同 ...

  6. 项目中的一个JQuery ajax实现案例

    /**  * brief 这些代码用于在线制图中 attention author <list of authors> <date> begin modify by  * nu ...

  7. 项目中的一个AOP的编写案例(配置+案例)

    AOP和Spring事务处理2008年05月01日 星期四 00:40二. AOP 1. AOP是什么? AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面 ...

  8. MCU 微控制器,在实际项目中如何选型(以 STM32为例)

    目录 1.MCU 选型需要考虑的一些因素 2.选型角度:从 MCU 的性能 3.实际项目中常用的 MCU 4.案例:传感器设备的 MCU 选型 5.为什么选择 STM32L031 1.MCU 选型需要 ...

  9. vue项目中画出优雅的线条(虚线、直线、折线、带箭头、流动效果等)

    需求:运行监控图模块,模块之间用虚线或者实线连接,且带有箭头 实现方法: 1.canvas绘制 2.echarts专业的表格软件(画带箭头的虚线有难度) 3.svg方法 4.leader-line插件 ...

最新文章

  1. Django之BBS博客项目
  2. 删除链表的倒数第n个节点 python_19.leetcode题目讲解(Python):删除链表的倒数第N个节点...
  3. 计算机原理基础知识pdf,计算机原理第一章.pdf
  4. python 用两个栈实现一个队列
  5. 全球及中国汽车后市场规模格局及经营趋势研究报告2021-2027年
  6. tif文件转pdf_PPT怎么转换成PDF文件?可以帮到你的PPT转PDF方法
  7. LeetCode 1222. 可以攻击国王的皇后(set)
  8. java平台调试架构JPDA
  9. #CSP 201512-1 数位之和(100分)
  10. 【QT】QT从零入门教程(六):QDockWidget停靠窗口
  11. asp.net Framework 与 asp.net core 知识
  12. ashx 使用Session
  13. 本科自考计算机专业有哪些学校,自考本科计算机专业要学什么?广东有哪些学校可以考?...
  14. sqlserver大批量数据插入 BULK INSERT
  15. 浅谈“知识库管理系统”
  16. qqkey获取原理_HIT我守护的一切手游电脑版苹果版有吗 HIT我守护的一切iOS电脑版模拟器...
  17. Hybird App开发,懂得小程序+kbone+finclip就够了!
  18. 全自动降噪插件-Acon Digital Extract:Dialogue 1.1.2 WiN-MAC
  19. java 随机生成姓名_java生成随机姓氏中文人名
  20. oracle cube语法,oracle Rollup 和 Cube用法

热门文章

  1. Windchill10下 用户反馈收不到系统任务邮件的问题处理
  2. 第4章 入门心法——Windows游戏图形基础(上)
  3. 排序算法的总结 排序算法及其稳定性
  4. 遗传算法 二进制编码 matlab实现
  5. 使用WebView时错误:WebPage not available
  6. 微博开放平台接口整理系列--短链转长链
  7. 商用密码产品认证-动态口令系统标准与产品
  8. 厉害了word哥!这款国产主板品牌强势登陆韩国
  9. 数据库 (学习笔记)
  10. 向量空间中的:线性相关与线性无关