避坑记录汇总

1、JSF启动报错,排查jsf使用到的jar包,如netty-all、javassist等
2、金融网关序列化对Long、String会转换,所以字段端名称不可使用此类关键词
3、金融网关序列化对Long会有精度丢失,使用String替代,front层做转换
4、金融网关方法名称全局唯一性,使用带有项目业务属性的名称规避命名重复
5、启动tomcat异常,注意关注启动日志,一般会有jar冲突,特别是log4j12
6、核心服务尽量提供release包,确保引用方jar包稳定性,更新快照jar要充分考虑给调用方带来的问题
7、目前jsf序列化方式默认是msgpack,对于对象序列化顺序有严格要求,新增字段一定要在类局部变量后添加,不能插队打乱之前的顺序【给类加父类、给类的父类增加字段都会引起问题、泛型类一定要指定类型,明确定义】
8、JSF调用超时一定要按照合理阈值进行配置,否则会拖垮服务
9、对象增加了字段,但是已经被序列化到的缓存中,反序列化会有问题。两种处理方案,一个是增加删除逻辑,解析异常便删除重存,还有就是给缓存key迭代版本号,需要注意线上查询量,因为更换key版本相当于所有请求都打到数据库重新缓存数据
10、私服先传jar,再传pom
11、org.springframework.jdbc.UncategorizedSQLException: SqlMapClient operation; uncategorized SQLException for SQL []; SQL state [null]; error code [0]; 看看dao里的条件入参req写没写
12、jsf的序列化对象声明有参构造,也要声明无参构造,否则序列化会有潜在问题
13、注意Float、Double、BigDecimal的精度问题,对除法要进行保留位数处理防止除不尽,还有就是各种精度之间出现的转换问题,比如Double转BigDecimal,不能直接new BigDecimal(double)精度会有丢失,一般先转字符串再转数值类型,或者使用BigDecimal.valueOf(xxx)处理
14、分库分表创建多张表,可以用create table TABLE_0001 like TABLE_0000,这么做是为了防止提交工单sql过长过不去,还有就是sql比较简洁,避免sql杂乱产生错误
15、无论是线上、预发、测试任何环境,如果catalina.out没有明显异常日志,可以查看tomcat/logs/localhost_XXX.log辅助排查问题,特别是tomcat启动过程中,一般都能找到问题所在
16、前端发版前,预发验证外,还可以增加H5预发切服务端生产再次验证,增加试错机会,确保万无一失
17、JUnit 4.12报错initializationError

  • ①有返回值的方法不能直接测试
    ②带参数的方法不能直接测试
    ③访问权限在public以下的方法不能直接测试
    ④static静态方法不能直接测试(不能带任何修饰符)
    ⑤不能给出现前四个条件中任意一个的方法添加@Test注解,否则执行满足@Test条件的方法也会出现initializationerror初始化异常

一般测试框架使用junit + mockito,检查下一下依赖有没有完整

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>1.10.19</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-core</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-library</artifactId>
    <version>1.3.RC2</version>
    <scope>test</scope>
</dependency>

18、关于POM版本,一般开发用SNAPSHOT比较多,好处是迭代快,可以重复上传,依赖方无需更新jar版本,快照相当于没有进行封版,可变性高,所以风险也很高,线上稳定业务尽量使用RELEASE版本,特别是提供给外部业务的服务jar
19、JSF别名切换步骤 【思路:下游提供新老服务,上游全切换,下游再全切换】

  • ①底层服务A 切换别名,A1→A2
  • ②底层服务A 更新一半,另一半待更新,线上保持A1、A2 provider共存
  • ③上层服务B 切换别名,B1→B2
  • ④上层服务B 更新一半,另一半待更新,线上保持B1、B2 provider共存
  • ⑤此时服务链路是 B1请求A1(老),B2请求A2(新)
  • ⑥B1老服务停止,此时完整服务链路是 B2→A2(新),但是只有一半机器服役
  • ⑦重启剩余A服务,所有A1→A2
  • ⑧重启剩余B服务,所有B1→B2
  • ⑨最终,全链路 B2→A2

20、try必须和catch一起使用,特别是在内层方法中,不然异常直接被忽略,不容易发现问题,可以不finally,但是必须catch
21、校验器配置

<!--校验器-->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.4.1.Final</version>
</dependency>
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>
<dependency>
    <groupId>javax.el</groupId>
    <artifactId>javax.el-api</artifactId>
    <version>2.2.4</version>
</dependency>
<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>javax.el</artifactId>
    <version>2.2.4</version>
</dependency>

22、数据中心(DataCenter)分页的limit不能超过10000,比如 limit 10000,N 会异常
23、maven无法下载仓库jar的可能问题,maven版本,确认是否开启了离线模式,如果是OFFLINE,无法下载
24、使用ThreadLocal必须清理,不清理带来的问题除了内存溢出问题,还会有线程变量污染的问题,比如不同请求被同一个线程处理,当之前线程的本地变量没有清理,如果后一个请求再次发起则本地线程变量会被污染,特别是在写切面时候一定要注意
要额外关注异常问题,如果有异常抛出一定要先清理本地线程变量再抛出,否则一定会出现线程变量污染的问题
25、所有分库分表的表,都需要有它的全局唯一ID,可以是业务属性拼接的uuid,也可以是专属业务的bizId等,数据同步到数据中心需要使用uuid做rowKey
26、做DataCenter数据同步时,如果后续需要进行条件查询,需要配置ES索引,索引的创建原则也是尽量合理,避免浪费资源和性能
27、jsf的超时时间配置大家都知道要配置合理,而且所有的服务调用一定要考虑上下游,全链路的开始到结束才是一次完整调用,要有全局视角,既为上游提供服务,也要考虑为下游分摊,同时也做好桥梁不要把自身搞垮
28、jdk1.6升级到1.8,spring从3.x升级到4.x,有个文件上传的异常,补充在这里 https://blog.csdn.net/SmileorSilence/article/details/82996105
29、不要使用java自带的assert做断言,这玩意需要JVM配置开启才起作用,否则不报错,参考https://blog.csdn.net/qq_38522268/article/details/90437146
30、在进行dao分库分表路由时,不要在spring事务中处理,线程变量副本和失误应该剥离开,不应耦合,否则会有问题
31、多线程环境下,比如主线程下启动线程池即子线程处理任务,一般不要使用ThreadLocal,容易出现问题
32、切面没获取到目标类的MethodSignature,检查注解@Annotation是否是运行时状态或是否忘记配置
33、mybatis没获取到入参参数,检查dao层查询方法,重载方法是否忘记传入请求对象
34、mapper注意区分 ${} 与 #{} 区别,前置进行参数解析,后者不做参数解析直接代入SQL
35、使用curator要注意与zookeeper的版本兼容问题
36、 org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler cannot be cast to org.springframework.web.method.HandlerMethod
由于资源路径变更,写错等原因,请求的资源路径确实不存在的时候,Handler是空的,导致报错,这里可以多加一层判断优化下,参考https://blog.csdn.net/u012848709/article/details/82725311
37、Arrays.asList 提供了方便也有很多坑,比如对象引用不一致,没有实现Collection一些方法等
38、切面拦截的是target代理对象,所以如果A、B方法都被切面X拦截,A中调用B,B不会被拦截,因为此时的target是A,只会拦截A。

  • 如果要在target代理中再调用内置方法,需要通过声明代理调用 AopContext.getCurrentProxy() 从spring的aop线程变量中获取真实代理对象进行调用内置方法,这样是基于被环绕的target进行的,方法会被拦截到。
  • 代理只能对public、protected方法产生左右,private方法是无法拦截的

39、走RPC接口的定义DTO都要实现Serializable,默认序列化方式是msgpack,但是如果要切换hessian需要DTO实现序列化接口才可以。另外,父类实现Serializable后,子类自动继承不需要再实现,子类实现父类没实现的话,子类可以序列化父类不可以
40、数据中心的切分键使用的是createTime,索引createTime字段一定要加es索引,否则无法进行切分,数据灌入不了
41、序列化与反序列化一定要使用同一套api,否则会出现不对称导致序列化异常问题
42、线上问题排查 java.lang.OutOfMemoryError: unable to create new native thread。产生原因是由于滥用线程池导致的,线程池的使用一定要统一管理,合理分配核心线程数和队列长度,避免OOM

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大摩羯先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值