无题
面试官您好,我叫熊强,现在是南昌大学软件工程应届生。大一的时候,主要学习了Java框架栈,mysql,redis,mq,ssm,SpringCloud常用组件,看一些常用框架的源码spring,nacos,sential。大二开始学一些云原生相关的知识,docker,k8s,开始做一些项目,小到个人博客,微软云+docker,电商项目都做过,已经成功用k8s部署到甲骨文的三个云主机节点,安装KubeSphere来持续集成持续交付。大三上半年去美团公司实习,主要从事的是美团到家研发平台的后端开发工作,主要负责美团电商、交易、广告相关功能模块的研发及优化工作,我主要是用一些美团自研的组件来完成一些需求。下半年在快手实习,主要在电商技术部-交易中心负责售后相关模块的研发及优化工作,做了一个买家首页红点查询开发的需求,将db中的数据通过kbus同步到es,实现自定义锁和限流组件,对标pdd,在下单返现金,到门槛后可以提现活动中,提供逆向规则,敲定等比例退方案 ,降低业务资损风险,提升用户体验, 用户端逆向交易资金表达的重构,售后链路各环节实现了与正向交易钱款、营销资产信息拉齐,新增展示了退营销 ...
oom线上问题排查
定时任务背景团队负责的一个后端服务某天环境出现无法启动的现象,本文通过此次问题排查,引出一些开发规范问题。
现象
测试环境部署后端服务一直无法启动;但是main.log没有任何异常信息
怀疑可能是启动时内存溢出。查看日志目录发现,多了很多hprof文件,起初怀疑可能是Metaspace溢出问题
但是这个项目的类很少,按理说不至于Metaspace溢出,于是查看stdout.log日志文件发现:java.lang.OutOfMemoryError: Java heap space… 竟然是堆内存溢出
但是以我对此服务的了解,更不应该出现启动时堆内存溢出的现象
开始分析hprof内存文件
先看下概况
com.mysql.jdbc.JDBC42ResultSet竟然占了2.08G,main线程也占了2.63G
JDBC42ResultSet一定是某个sql查了一堆数据返回的结果
再去支配树里找一下线索:先层层打开内存占用最大的主线程,找找线索,看看内存里都是哪些业务类的实例:里面竟然有7138519个LinkedCaseInsensitiveMap,但是这个不是我们项目里定义的业务 ...
redis集群key
发现问题7月29号, 晚上23:30我们收到kcc报警,我们有个redis集群liveStreamStats内存使用率达到了90%。
发现有两个redis实例redis使用率到了90%,但是其他的实例内存并没有这么高。
问题止损 因为当时7月29号成龙大哥在开播,并且开播时间是19:50,和监控上内存上涨的时间点吻合,我们怀疑和成龙大哥开播在线人数比较多导致的。当时紧急联系kcc同学垂直扩容了这两台实例。
问题初步定位 当时kcc同学通过解析rdb数据发现以wd_11285866346:(11285866346是成龙大哥的liveStreamId)为前缀的key在这两台实例占的内存最多,对应hash key大概有3w个filed。结合liveStreamStats集群上游服务和成龙大哥在线观众行为,我们怀疑是通过处理观众心跳消息记录观看时长的consumer有数据倾斜或者大key问题,导致liveStreamStats集群中两台实例内存使用率到达90%,通过前缀查看定位到具体代码:通过代码和redis key确认,确实是这个逻辑有问题。
是否是存在大key问题 可以通过 ...
spring容器的创建过程
@SpringBootApplication等同于@SpringBootConfiguration@EnableAutoConfiguration @Import(AutoConfigurationImportSelector.class)@ComponentScan(“com.atguigu.boot”)
1234567public ApplicationContext(annotatedClasses){this();//注册配置类, 因为配置需要解析,一般不需自己扫描register(annotatedClasses) ;refresh();}
Spring容器的refresh()【创建刷新】;
1、prepareRefresh()刷新前的预处理;
1)、initPropertySources()初始化一些属性设置;子类自定义个性化的属性设置方法;
2)、getEnvironment().validateRequiredProperties();检验属性的合法等
3)、earlyApplicationEvents= new LinkedHa ...
快手
redis锁mysql 数据800gb,日志300gb
es10个索引,每个索引120gb
redis 6主6从,3gb
自定义注解
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface RefundRedisLock {
String key(); // 示例: orderId, param.orderId ()
String keyPrefix() default StringUtils.EMPTY; // 示例:order.state (biz prefix string)
long limitWaitTimeSeconds() default 3; // 示例 3秒有限等待
long expireSeconds() default 30; // 示例:30秒自动释放}
@Pointcut(“@annotation(com.kuaishou.kwaishop.refund.annotati ...
Spring三级缓存
如果 Spring 选择二级缓存来解决循环依赖的话,那么就意味着所有 Bean 都需要在实例化完成之后就立马为其创建代理,而 Spring 的设计原则是在 Bean 初始化完成之后才为其创建代理。所以,Spring 选择了三级缓存。但是因为循环依赖的出现,导致了 Spring 不得不提前去创建代理,因为如果不提前创建代理对象,那么注入的就是原始对象,这样就会产生错误。
对于构造器注入产生的循环依赖,可以使用 @Lazy 注解,延迟加载。
对于多例 Bean 和 prototype 作用域产生的循环依赖,可以尝试改为单例 Bean
hr面
面试官您好,我叫熊强,现在是南昌大学软件工程应届生。大一的时候,主要学习了Java框架栈,mysql,redis,mq,ssm,SpringCloud常用组件,看一些常用框架的源码。大二开始学一些云原生相关的知识,docker,k8s,开始做一些项目,小到个人博客,微软云+docker,电商项目都做过,已经成功用k8s部署到甲骨文的三个云主机节点,安装KubeSphere来持续集成持续交付。大三上半年去美团公司实习,主要从事的是美团到家研发平台的后端开发工作,主要负责美团电商、交易、广告相关功能模块的研发及优化工作,我主要是用一些美团自研的组件来完成一些需求。下半年在快手实习,主要在电商技术部-交易中心负责售后相关模块的研发及优化工作,做了一个买家首页红点查询开发的需求,将db中的数据通过kbus同步到es,实现自定义锁和限流组件,对标pdd,在下单返现金,到门槛后可以提现活动中,提供逆向规则,敲定等比例退方案 ,降低业务资损风险,提升用户体验, 用户端逆向交易资金表达的重构,售后链路各环节实现了与正向交易钱款、营销资产信息拉齐,新增展示了退营销资产信息,清晰透传各明细项分摊结果,并对 ...
kbus
传统同步或者异步写到其他存储
多写入端,无法保证全部写入事务性,准确性,顺序性受限网络、不同终端性能、复杂拓扑等问题,对生产系统产生耦合性太强。性能也受到严重制约跨机房,下游变更,业务修改等都会对生产系统产生影响
使用kbus数据总线异步处理数据流能更灵活的应对各种架构演变,解耦生产系统和消费系统。以及跨机房,甚至跨语言带来的各种复杂性。
使用服务化方式发布,业务端和中间件完全解耦合。
只暴露给用户最简单、最易用的消费功能API,减少用户的学习成本,使用成本
业务不需要频繁升级就可以享受各种KBus的新优化和新功能
在公司内部出现大促活动或者其他大的基础设施变更时,涉及的流量/机器调度、服务保障等都不需要用户过多介入。涉及到多机房异地机房变更等各种底层设施变化也都平滑给用户提供解决方案,让用户无感知
一处生产,处处消费设计理念。
用户不需要关心数据输入源,只需要KBus这边启动server端,用户可以在任何机房启动消费
可进行跨AZ/Region消费。用户不需要在需要消费的AZ或region部署生产源就可以直接消费,只要有一处源头生产端即可
提供用户可定制的托管化 ...
高并发
那我以美团外卖演进路的高并发和高可用来举例子吧,外卖业务其实已经非常是一个非常普遍存在的一个这种业务了,然后呢它的其实主要就是围绕我们线上的一个商品交易以及一个及时的一个配送服务搭建一个o2o的综合电商的交易平台,外卖业务的一个整个的一个增长的一个里程碑,也就是发展的历程,然后业务呢于一三年的十一月上线,然后在通过一年的发展我们在一四年的十一月达到了一个一订单突破百万的这么一个量级,针对于我们业务的每一个阶段的一些业务的特点,然后系统呢也进行了相应的一些迭代啊,主要是包括四个阶段啊,分别是起步阶段,微服务化阶段,以及精细化阶段,以及我们当前的一个set阶段
起步阶段我们简单来看一下起步阶段的一个特点啊为起步阶段呢,主要是我们是主要是对对这个业务进行一个探索看看这个业务到底发展方向对不对好,我们系统比较单一 ,通用而且比较复杂的外卖servise的一个jar包来供各个前端的应用加载进来来提供服务,核心优化点就是lbs算法,缓存还有程序执行中的一些异步,批量的一些操作
微服务化阶段为什么要提出这个阶段,就是因为我们这个业务在14年15年我们明确了业务的方向,并且我们业务的方向是可以稳定向前 ...
swan
Swan 是美团的分布式事务事务,推行 SOA 的过程,会带来大量的服务拆分和数据库拆分,造成跨服务调用和跨库操作的需求日益增多。这些场景下单次业务操作通常需要更新多个数据库、调用上下游多个服务才得以完成,单库事务已不再能解决问题,需要引入分布式事务解决方案
TCC一个 TCC 事务由三个方法组成,分别是 Try、Confirm 和 Cancel,三者分别定义了针对某种资源的预留(也叫冻结或者锁定)、提交和回滚逻辑,其中只有一阶段 Try 操作是可能需要加锁的,Confirm 与 Cancel 方法体应该尽可能简单,仅仅涉及资源的提交和回滚逻辑,不再做任何资源锁定、重复检查等逻辑。
TCC 三个方法描述:
Try:资源预留/锁定操作,是事务发起方调用服务提供方的try方法来锁定业务需要的所有资源。这里通常会通过加锁,完成资源的隔离(一阶段成功之后每个 TCC 事务都已经拥有了自己独占的一份资源)
Confirm:确认执行业务逻辑操作,这里使用的资源一定是 Try 阶段预留的业务资源。在 TCC 事务机制中认为,如果在try阶段能正常的预留资源,那么 Confirm 和 Cancel ...