15年前,GitHub作为一个RubyonRails应用程序开始,只有一个MySQL数据库。从那时起,GitHub已经发展了其MySQL架构,以满足平台的扩展和弹性需求,包括构建高可用性,实现测试自动化和分区数据。今天,MySQL仍然是GitHub基础设施的核心部分,也是我们选择的关系数据库。 这是我们如何将1200多台MySQL主机升级到8.0的故事。在不影响我们的服务水平目标(SLO)的情况下升级车队并不是一个小的功能规划,测试和升级本身花了一年多的时间,并在GitHub内的多个团队之间进行协作。 升级动机 为什么要升级到MySQL8.0?随着MySQL5.7的生命周期即将结束,我们将集群...

  YgmmQQ65rPv4   2023年12月11日   15   0   0 mysql应用程序回滚

今天在写脚本的时候发现一个奇怪的错误。经过猜想验证,发现原来Groovy过于灵活了,算是重复踩了之前的坑。Groovy特性描述如下: 当Groovy脚本调用getFun()和setFun()方法时,会默认给这个类有一个FunTester的属性。反过来,如果这个类有Fun这个属性,那么get和set方法是不用显式写出来的。 本来这是个好事情,一方面其实可以免去多余代码,一方面更容易收拢入口方法(因为直接访问属性、修改属性也是有限调用get和set方法)。 但是就是这个特性让我下面的代码报错了。 StringBuildersb=newStringBuilder() for(inti=0;i<...

  YgmmQQ65rPv4   2023年12月07日   15   0   0 JavaGroovy字符串

Java虚拟机创建了C1和C2编译器线程,用以优化应用程序的性能。但是有时这些线程会消耗大量CPU资源。在这篇文章中,我们将深入探讨C1和C2编译器线程,以及如何解决它们可能导致的高CPU消耗问题。 HotspotJIT HotSpotJIT(Just-In-Time)编译器是Java虚拟机(JVM)中的即时编译器,它负责将Java字节码转换为本地机器代码。HotSpot是OracleJDK和OpenJDK中默认的JVM实现,它包含两个主要的即时编译器:C1(ClientCompiler)和C2(ServerCompiler)。 HotSpotJIT编译器的工作方式是在运行时动态地将经常执行的...

  YgmmQQ65rPv4   2023年12月06日   27   0   0 JVM编译器应用程序

采用DevOps文化需要在企业层面改变思维方式、流程和文化。许多人认为采用DevOps只是在不同的团队之间划分任务,并为团队成员分配特定的角色。然而,恰恰相反,它需要在实施最佳实践的同时,致力于更长远的事业。因此,转向DevOps不是一个瞬间的转变,而是一个组织必须共同迈向的持续旅程。 在采用DevOps过程中,最大的挑战之一是确定团队成员之间有效沟通的最佳途径,并在不影响软件质量的情况下将产品交付给客户。面对这些挑战,采用DevOps似乎是一项艰巨的任务。 以下是分享一下DevOps文化的几个关键点。 强调定制的作用 没有一种放之四海而皆准的方法。每个组织都有其独特的需求,因此需要制定适合其...

  YgmmQQ65rPv4   2023年11月30日   13   0   0 持续交付开发人员软件开发

UUID(UniversallyUniqueIdentifier,通用唯一标识符)是一种用于标识信息的128位标识符。Java开发人员倾向于使用java.util.UUIDrandomUUIDAPI来生成UUID编号(类似4c88314f-14ca-4652-8567-4471a0ef917c)。 UUID通常用于标识数据记录、会话、文件、对象等,以确保它们在不同上下文中的唯一性。注意,UUID是一种全局唯一性标识符,不保证在不同时间生成的UUID之间是有序的或可比较的,因此不应该依赖于UUID的大小或顺序。 在某些情况下,使用这个API可能对应用程序的可用性产生负面影响。下面,我们将通过一个...

  YgmmQQ65rPv4   2023年11月19日   12   0   0 Java应用程序

测试是软件开发生命周期(SDLC)的重要组成部分。SDLC的每个阶段都应包含测试,以获得更快的反馈并提高产品质量。 我们来聊聊持续测相关话题,如何从持续测试中获得更大的收益。 何谓持续测试 持续测试有助于在软件开发生命周期(SDLC)的所有阶段提供更快的质量反馈。在软件开发声明周期中大多数情况下,如果在核心功能逻辑越少做单元测试和自动化测试,那么测试金字塔顶层执行手动探索性测试的压力会非常大,尝尝容易出现质量问题导致项目延期。 这实际上会影响质量,因为在开发完成后发现错误是非常昂贵的。下面是Google修复一个错误的成本,你可以看到当在系统测试阶段发现一个错误时,它的成本高达5000美元。 ...

  YgmmQQ65rPv4   2023年11月12日   21   0   0 开发人员软件开发自动化测试

最近真真实实用到了通用池化框架commons-pool2,又学到了一些新的功能。也让自己对这个框架有了新的认识。但是框架提供的API是相对的简单的,针对一些特殊的场景还是需要自己将这些API功能进行一些组合。 下面分享一下我在使用过程中用到的功能拓展。这里使用经验是基于org.apache.commons.pool2.impl.GenericKeyedObjectPool,部分拓展功能已经在org.apache.commons.pool2.impl.GenericObjectPool,估计是前者在使用中情况比较复杂,统一方法调用并不能很好适应多种多样的使用场景。 先来复习一下: 通用池化框架...

  YgmmQQ65rPv4   2023年11月12日   17   0   0 APIapache池化

最近在深度体验了copilot工具之后,真心体会到了AI工具的强大之处。虽说之前也都使用过ChatGPT及其不同代号的分身,当时觉得比搜索引擎强太多,但在工作中直接使用倒是没有体会到效率极大提升。 在与copilot相互磨合当中,逐步感受AI工具给工作带来的改变。在实际编码中,很多代码都是有规律甚至重复的,特别是在写调试代码时,遍历、创建多个实例对象的方法都是这样。现在copilot基本都能够猜到我想写什么了,根据我个人感受,60%70%的时候,copilot都是非常懂我的。 今天听了一段腾讯云的直播,大佬分享了自己对AI工具的认知。我收获了两点思考,分享给各位。 AI工具的定位 AI工具始终...

  YgmmQQ65rPv4   2023年11月05日   16   0   0 API搜索引擎知识体系

在进行Java多线程编程的过程中,始终绕不开一个问题:线程安全。一般来说,我们可以通过对一些资源加锁来实现,大多都是通过synchronized关键字实现。 在做性能测试时,如果TPS或者QPS要求没有特别高,synchronized一招鲜基本也能满足大部分的需求了。 对于一招鲜无法很好解决的问题,就需要我们继续探索java.util.concurrent包的其他内容。今天就分享一下java.util.concurrent.locks.Lock接口的实现类java.util.concurrent.locks.ReentrantLock的基本使用方法。 类功能概览 java.util.concu...

  YgmmQQ65rPv4   2023年11月02日   27   0   0 Java等待时间公平锁

在性能测试中,有一个无法避免的问题,就是如何处理性能测试用例使用到的数据,其中包括前置数据、运行时数据和后置脏数据清理。 相信大家在做性能测试中也会遇到跟我相同的问题,我分享一下自己的思路和解决方案,仅供参考。仅仅根据个人经验,我将性能测试中数据处理分成以下几种类型。 静态数据 这类数据相信是大家最容易配到的。最常见的就是用户账号、密码,用于进行前置的登录功能。这里就以登录为例,分享一下我遇到的几种情况和解决办法。 一次登录 有些团队会将测试用户的登录凭证有效期设置很长,设置无限长。如果是这种情况的话,通常用一个配置文件将用户登录凭证存下来即可。这也是最简单的,甚至可以将用户的基本配置信息也都...

  YgmmQQ65rPv4   2023年11月02日   40   0   0 性能测试数据压测

在软件测试中,经常会遇到随机数。我简单分成了两类: 简单取随机数; 从一个集合中随机取值。 其实第二个场景包含在第一个场景内。对于接口测试来说,通常我们直接使用第二种场景比较多,就是从某一个集合中随机取一个值。如果更复杂一些,每个值拥有不同的权重,其中这个也可以转化成第二个场景来说。 缘起 为什么要把第二个场景和第一个场景分开呢,这个问题源于之前写过的文章ConcurrentHashMap性能测试,当时发现自己封装的com.funtester.frame.SourceCoderandom(java.util.List<F>)方法性能存在瓶颈,特别消耗CPU资源。 虽然单机QPS...

  YgmmQQ65rPv4   2023年11月02日   45   0   0 Java性能测试随机数

在上期文章自定义MySQL连接池中,我提到了没找到一个特别合适的MySQL连接池实现,所以自己写了一个基于通用池化框架commons-pool2的MySQL连接池,并且模仿了Go语言的gorm框架设计思路,把借和还的操作不暴露给用户,只处理用户发来的SQL语句的思路,封装了一个com.funtester.db.mysql.MysqlPool。 可惜打脸的事情来的太快了,在录制视频的时候偶然发现了Intellij代码提示有个com.mysql.cj.jdbc.MysqlConnectionPoolDataSource的类。这还了得,看名字就知道是我想要的那款。 经过查阅资料,好像也没搜到太多详细...

  YgmmQQ65rPv4   2023年11月02日   46   0   0 连接池mysql池化

在互联网行业中,永无止境的讨论主题之一是:敏捷与DevOps。对于这两个概念来说,过程彼此不同;但是它们仍然有一些相似之处。 敏捷 敏捷方法论是一种实践,它促进整个项目的SDLC(软件开发生命周期)的开发和测试的持续迭代。在敏捷方法中,开发和测试活动是同时进行的,这涉及到SDLC过程中开发和测试的持续迭代。 敏捷宣言强调的敏捷软件开发的四个核心价值是: 个体和互动高于流程和工具 工作的软件高于详尽的文档 客户合作高于合同谈判 响应变化高于遵循计划 敏捷是一个软件开发过程,它符合敏捷宣言的品质和标准。它建立在迭代开发的基础上,以跨职能团队的合作为中心,以获得所需的解决方案。 敏捷开发过程将产...

  YgmmQQ65rPv4   2023年11月02日   22   0   0 开发人员软件开发迭代

在之前的性能测试中,用到了延迟队列java.util.concurrent.DelayQueue的功能下单延迟10s撤单性能测试,其实也是简单使用到了基本的API,演示如下DelayQueue基础功能演示。在对Java&Go各种队列做性能对比测试的规划里面也没法这个延迟队列算进来。当时感觉这个队列设计到很多排序,而且用的数组实现的队列,加上了java.util.concurrent.ArrayBlockingQueue队列的性能资料,所以以为延迟队列性能比较差,放弃了做对比测试。 最近在看了goreplay的项目资料后,发现这个真流量回放还是很有搞头的,就是根据请求的时间戳进行判断是否...

  YgmmQQ65rPv4   2023年11月02日   41   0   0 Javaide性能测试

在之前的动态模型之动态增减【FunTester测试框架】中分享了动态的性能测试模型的实现,后面在实际工作中也是受益匪浅,有文为证动态压测模型让工作更轻松。 这里再重复一下思路,就是通过异步线程接收控制台输入信息,然后对线程池的增减管理或者对QPS管理器的QPS进行干预。 相对一段时间来说只有一些简单的功能: 设置步长 增减步长 终止测试 很长一段时间内都够用了,但是随着测试的深入,可能需要执行更多动态用例,如果靠人力一个个输入会比较麻烦。这个时候我又想起来了静态模型的好处来。就是过程不需要中途干预,可以按照预定的测试计划执行。 那么问题来了,如何才能将动态模型和静态模型结合在一起呢? 经过...

  YgmmQQ65rPv4   2023年11月02日   39   0   0 异步线程异步控制性能测试

之前在性能测试中,我重新认识了随机数的功能性能测试中的随机数性能问题探索。但目前工作中接触到的都是静态的比例,即用例真正开始前,各个接口、场景的比例都是固定的。按照我的思路,旧会存在一个提前初始化完成的list,但是最近工作中遇到了需要在压测过程中(动态QPS模型),动态调整两个场景的比例值,计划是在某个范围内周期波动。 其实核心问题:如何在一个变动的list随机实践中,保证线程安全。 这里先分享一下从一个数组中随机取一个对象的思路,如下: / 随机选择某一个对象 @paramlist @param<F> @return / publicstatic<F>Frando...

  YgmmQQ65rPv4   2023年11月02日   30   0   0 Java用例缓存

相信大多数测试er在学习相关技术的时候,都看过对应的视频教程。无论是在线和离线视频都是一个非常好的学习提升自己的路径。 在前段时间的学习过程里,我不禁问了自己一个问题:视频学习是主动学习还是被动学习? 先让我们看一下两者的区别。 主动学习 主动学习是一种学习者重度参与的学习方式,是一种以学习者为中心的学习方式。学习者需要以探索者的角色进入学习状态,需要自己的思考、判断,方能融会贯通。 被动学习 被动学习是传统的学习方法,学生很少参与。环境通常以教授者为中心。学者需要通过被动地接受知识。 从学习效率讲,自然是主动学习效率最高。所以我才会有自己的疑问。同样的,还有一个伴生的问题:看视频教程是接受...

  YgmmQQ65rPv4   2023年11月02日   32   0   0 离线视频教程

Groovy中的Map,不仅兼容了JavaAPI提供的各种功能,还拓展了许多特殊语法和功能方便测试人员在使用的过程中提高效率,更快地构建测试脚本。 下面我就从几个方面分享一下GroovyMap的神奇之处。 创建 Java中通常创建一个Map的常用语法Map<Integer,Integer>map=newHashMap();。而在Groovy中,我们可以使用语法[k:v]来创建Map。相当于给Map对象初始化赋值了,而且语法简洁了许多。 Groovy创建Map语法defmap=[:],同样我们可以在初始化赋值defmap=[a:32,b:32043],Groovy中默认使用的是jav...

  YgmmQQ65rPv4   2023年11月02日   31   0   0 赋值Java运算符

最近在读《卓有成效的工程师》,其中在《精益求精,优化学习方式》这一章节小标题培养成长型思维模式的内容,让我突然多了一层感悟。 提起成长型思维,就不得不提另外一本书《终身成长》,作者卡罗尔·德维克。其中让我印象最深的就是:人的能力是可以改变的。 之所以想起来这个信念,是因为一个现象,总有人愿意把自己遇到问题,原封不到的丢到网上、社群里,请教各路大佬。 在学习的过程中,我有一个非常有用的经验,遇到问题,先看报错,再找日志,有条件就debug。 但是每每看到群里的问题我就很奇怪,为什么把原装的问题截图发出来,或者用一两句甚至错误的描述。在《卓有成效的工程师》书里我得到了可信的的答案:因为他们是固定型...

  YgmmQQ65rPv4   2023年11月02日   20   0   0 搜索

之前写过一个日志回放引擎的第一代千万级日志回放引擎设计稿,当时理解的日志回放就是把日志记录的请求重新发出去,这就是回放线上用户的流量了。可是在我最近看goreplay的过程中,重新刷新了我的认知。 查阅了一些资料,终于算是了解了一些基于时间戳的方案和思路。大体如下:通过工具把线上某段时间的流量记录下来,其中包含时间戳等信息,然后通过回放引擎把流量回放出去。 解决思路 目前流量回放集中于HTTP流量,所以之前写过的引擎的发压部分还是可以继续使用。所以我也有了自己的解决思路: 日志清洗,其实就是把规范化的日志解析成引擎框架可以使用的对象,通常包含HTTP请求的组成部分。 按照时间戳排序,通常使用...

  YgmmQQ65rPv4   2023年11月02日   26   0   0 Java性能测试单线程
关注 更多

空空如也 ~ ~

粉丝 更多

空空如也 ~ ~