记录这两周解决的一个写数据并发的问题(一)

记录这两周解决的一个写数据并发的问题(一)

先说下问题背景: 上周初上线了一个服务,该服务的主要功能是提供用户观看收藏数据的上传以及获取,说直接点就是一个用户级别的数据服务,业务逻辑比较简单。

服务的架构很简单,用spring boot进行开发,使用undertow内置web服务器,用户数据过来了直接了写库,由于是用户级别的数据,服务并未使用缓存。

服务上线后,发现在高峰期,会偶尔短暂出现接口的响应全部放慢到3s以上,而平常正常的接口响应时间是10ms左右。

出现问题后开始排查:

额外配置了一层nginx

目前使用该服务的为某省移动的网络电视的用户,活跃用户规模在200w以上,我们部署了4台服务器,按照该服务压测的结果,按照线上机器的性能,每秒能达到5000到6000的吞吐量,每台机器在高峰期服务50w用户应该是不成问题的,运维在服务前面又部署了一层nginx,运维通过nginx层的访问日志看到有接口响应慢,强烈要求我们开发和测试找问题,我首先怀疑是不是前面部署的这层nginx的问题,然后好死不死我们的服务undertow开启了访问日志,但是访问日志没打印响应时长,因此拿不出证据来证明nginx有问题。

发现日志中有报mysql死锁

在这里插入图片描述
可以看到执行的sql语句业务很简单,但是目前不能确定是这个原因造成的,因为一天这个死锁的错误日志输出也就不到五条,但是还是要想办法解决这个问题,出现死锁肯定是不好的。

开始解决问题

因为我们自己在测试环境压测的过程中试过多加一层nginx做代理的情况,发现如果使用nginx代理会使服务并发性能明显下降,于是一开始我将目标集中在这里,为了向运维证明是nginx的问题,我要将undertow的访问日志里的响应时长打出来。

spring boot1.5.6的参考手册里,关于undertow的访问日志,建议配置如下:

server.undertow.accesslog.enabled=true
server.undertow.accesslog.pattern=%t %a "%r" %s (%D ms)

但是这里有坑,这里的pattern如果直接这样配置,启动会报错。
因为这个原因,我当时没有深究,就没有配置pattern。而如果这个pattern不用显式配置,会默认使用undertow自己的common格式,而这个common格式竟然是没有响应时长的打印的,就是那个%D

然而这时不得不解决这个问题了,其实解决方法很简单patter的配置改成如下即可:

server.undertow.accesslog.pattern='%t %a "%r" %s (%D ms)'

是的,就是这么简单,都怪自己当时没有多尝试啊。。。

但是问题来了,改了以后自己测试发现pattern生效了,但是那个%D竟然打不出来,输出全是null,这就很尴尬了,spring boot的手册也不会告诉你,于是只好找undertow的资料去看,unertow文档里关于%D的解释如下:
在这里插入图片描述
十分没营养,啥都没说。。。

没办法,继续在文档里找线索,搜一下request time看看,然后就搜到了这一条配置:
在这里插入图片描述
尼妹的,真的太坑了,这个竟然没有在%D这一条单独注明。
也就是说必须要开启这个配置,才能在访问日志里打印响应时间,至于undertow为什么不默认开启这个配置,我估计是因为开启后会对性能造成影响。虽然undertow是nio模型的,各种评测也是优于tomcat的,但是就从文档来看,还是任重道远啊。。。

在spring boot要开启这个配置需要通过代码进行配置,遇到同样问题的朋友可以参考以下代码:

@Configuration
public class UndertowConfig {
    @Bean
    public UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory() {
        UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory();
        factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
            @Override
            public void customize(Undertow.Builder builder) {
                builder.setServerOption(UndertowOptions.RECORD_REQUEST_START_TIME, true);
            }
        });

        return factory;
    }
}

打开undertow的这个配置后,发现访问日志输出响应时长正常了,正当开心之时,发现之前服务的主从分离竟然未生效! 惊觉之余,这个问题必须解决,突然想到是不是主从没有分离造成的mysql死锁呢?主从分离未生效问题最后发现是mybatis-starter的坑,这个问题展开来说,又可以开个长篇好好讲一讲了,详情见下回分解。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值