业务梳理
日志
日志模块 + ELK,注解+AOP+反射,filebeat匹配logback规范输出。es索引数据迁移,别名迁移
封装log-starter引用spi机制进行设计,使用AOP对自定义注解修饰的方法进行代理,并封装spel表达式支持参数转义
ES技术选型对比solr?
任务下发任务下发:对接外部,补偿机制,规定任务超时时间,定期补偿,根据macro、micro指令的状态来判断
指令补偿,未下发会重新进行分发,搬运中的任务会询问下位系统进行事件上报,macro多阶段任务会查看是否下发下一个micro,补偿超过次数则进行报警
场景发散单独服务对接mes分发散列保证顺序性,轻量级校验并入库,然后针对指令编号进行散列,保证同一笔指令散列到同一个队列,保证顺序性,指令的进一步封装动作放在mcs,多个mcs节点开多个消费者监听散列对应的队列。实际场景无须保证则直接多消费者对接mes即可
线程管理背景原本是mcs对接多个外部系统,半导体secs协议需要维护长连接,导致线程紊乱,机器内存占用过高,且客户需求对标 C# 需要子服务可以单节点部署,故引入线程调配中心(报文对接)。一个secs协议 ...
Spring
Spring主要加载链路分析包扫描123456<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.6.RELEASE</version> <relativePath /></parent>
application.run => prepareEnvironment 准备环境
发布事件 BootstrapApplicationListener => bootstrap 会触发一个application.run
bootstrap的run执行完后,继续执行原application.run,也就是prepareEnvironment 处理完后,refreshContext刷新上下文
AbstractApplicationContext #invokeBeanFact ...
散装知识点
OncePerRequestFilter(过滤器Filter)Spring针对Servlet原生过滤器Filter的进一步封装。通过继承OncePerRequestFilter,可以自定义一个过滤器,且每个请求都会执行一次。关于重写方法,init、doFilter作为默认实现,有final修饰,我们想进行扩展,需要重写initFilterBean、doFilterInternal
12// 重写doFilterInternal进行业务扩展,别忘了最后进行过滤链调用filterChain.doFilter(request, response);
HandlerInterceptorAdapter(拦截器Interceptor)HandlerInterceptorAdapter是Spring提供的一种拦截器适配器,通过继承该抽象类自定义拦截器。
主要实现三个接口:preHandle、postHandle、afterCompletion
123preHandle:前置处理,Controller执行前postHandle:后置处理,Controller执行完成,可以根据方法参数modelAn ...
Controller接口调用链路浅析
Controller接口调用链路浅析项目初始化,创建代理类12345AbstractClassGenerator#generate() 358:{strategy.generate(this)} ->DefaultGeneratorStrategy#generate() 25:{transform(cg).generateClass(cw)} ->Enhancer#generateClass() 670:{getMethods(...)} ->Enhancer#generateClass() 651:{CollectionUtils.filter(methods, new VisibilityPredicate(superclass, true));} ->AbstractClassGenerator#generate() 363:{gen = ReflectUtils.defineClass(...)}
主要是在AbstractClassGenerator这个 ...
Spel字段解析功能源码浅析
起因最近在写日志功能,aop + 注解 + spel,使用 @RestControllerAdvice 全局捕获到的Exception的异常信息肯定是需要打印的,于是我想当然获取自定义信息的spel表达式是 e.getDetailMessage,detailMessage异常信息字段是异常继承于Throwable的,然后运行代码spel解析出现异常,网上搜一圈无果,只好自己debug看源码,找找原因了。
Debuging题外话,学会debug技巧应该是我们初级后端进阶的第一步,学会debug才好看源码,Evaluate Expression 执行表达式,断点设置条件以及是否线程,这两个小技巧掌握好就可以看源码了。
readPropertydebug步进直到spel判断核心
org.springframework.expression.spel.ast.Indexer#readProperty 关键代码节选
12345678910for (PropertyAccessor accessor : accessorsToTry) { if (accessor.canRead( ...
并发编程实战阅读学习
内存可见性通常我们无法确保执行读操作的线程能适时的看到其他写线程写入的值,为了确保多线程间对内存写入操作的可见性,必须使用同步机制。
加锁与可见性AB线程获取同一个锁,可以保证A中改变的变量,等到B获取锁后仍可以看见。
B线程执行由锁保护的同步代码块时,可以看见A线程之前在同一个同步代码块中的所有操作结果。
可见性即公共变量的可视性、一致性,同步保证并发下不同线程数据变量一致。对于变量来说,锁机制同步是为了确保某个线程写入改变量的值,对于其他线程来说是可见的。
加锁的意义不仅仅局限于互斥行为,还包括内存可见性,为了确保所有线程可以看到共享变量的最新值,所有执行读操作或写操作的线程都必须在同一个锁上同步。
VolatileJava提供一种稍弱的同步机制,volatile关键字,用于确保将变量的更新操作通知到其他线程。
当变量声明为volatile后,编译器和运行时都会注意到该变量是共享的,因此不会将变量上的操作与其他内存操作一起重排序,volatile变量不会被缓存在寄存器或其他处理器不可见的地方,因此在读取volatile变量时总能得到最新写入的值。
volatile不会执行加锁操作, ...
ES operation mark
数据迁移数据迁移流程123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116#先将上次的备份数据清空delete /logger_mes_bakdelete /logger_mcs_bakdelete /logger_mcs_command_bakdelete /logger_mcs_exception_bak# 备份索引PUT /logger_mcs_exception_bak{ "settings": { "number_of_shards": 6, "numbe ...
Spring框架八股
IoC原理https://www.jianshu.com/p/ad05cfe7868e
IoC控制反转,是一种设计思想,将以往通过手动创建对象的控制权交由Spring管理,降低对象之间的耦合性。其控制反转,指的是控制对象创建的权力,然后将控制权反转交给外部环境管理。
所有的Bean在项目启动时生成,加载到Spring容器中统一管理,我们需要使用的时候再去容器中取Bean。而不是单独的去new一个相关类来进行调用。
IoC只是一种思想,而依赖注入DI是具体实现。
实现底层xml配置文件,编写对应属性kv,如k - 类名,v - 类的全路径。
创建一个工厂类解析xml,获取对应类的全路径,并通过反射创建该类对象。
最后从工厂中调用创建好的对象即可。
现在我们开发都是使用注解注入Bean替代xml配置。
AOP简述AOP面向切面编程,能将与业务无关,却被业务模块共同调用的服务进行封装(如工具类等),然后进行统一调用,降低模块之间的耦合性,利于拓展和维护。
AOP基于代理模式实现,其分为静态代理和动态代理。
AspectJ AOP 静态代理
Spring AOP 动态代理(JDK、CGLIB ...
微服务商城项目学习总结
虚拟机环境配置这次使用Virtual Box + Vagrant完成虚拟机安装,比传统VMware配置镜像更方便,Vagrant可下载打包好的镜像文件进行安装,无需详细配置。
https://blog.csdn.net/qq_15990969/article/details/113096469
https://www.cnblogs.com/lxwphp/p/11121283.html
快速反向工程辅助crud使用renren脚手架辅助开发,对应前后端分离,renren-fast,renren-fast-vue,renren-generator使用前需删除.git文件,这是官方的git信息
renren的service层无需注入dao,它继承了一个父类,父类注入了baseMapper,而这个baseMapper的类型是对应继承时类的泛型M的,人人继承这个父类就会用自己的dao实现泛型,所以此时父类注入的baseMapper即我们需要的dao,封装nb。
商品服务https://blog.csdn.net/unique_perfect/article/details/113824202
...
设计模式八股
设计模式七大原则
单一职责原则:一个类只负责一个功能,降低耦合性,方便迭代维护。
开放封闭原则:类、方法可以进行功能扩展,但不能修改。对扩展开放,对修改封闭。
依赖倒置原则:高级模块不能依赖低级模块,都应该依赖于接口。先将类进行抽象,先设计功能接口,再对接口进行功能细节的实现。
接口隔离原则:不同接口定义不同的功能。
里氏代换原则:子类可替换其父类。
迪米特原则:每个模块间要尽可能少的相互调用,减少依赖,降低耦合性。
设计模式讲解链接:
http://www.cyc2018.xyz/%E5%85%B6%E5%AE%83/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%20-%20%E7%9B%AE%E5%BD%95.html#%E4%B8%80%E3%80%81%E5%89%8D%E8%A8%80
单例模式实现懒汉式(线程不安全)123456789101112public class Lazy { private static Lazy lazyInstance; ...