分类: 默认

  • Gatling使用的几个小技巧

    Gatling是一个基于Scala,Akka和Netty的开源负载和性能测试框架,从功能上和JMeter很类似,只不过因为是基于DSL书写,从配置上来说灵活性比较好,当然相对的上手难度其实要大一些。

    最近项目上使用了一下Gatling,用的时候还是遇到一些小问题。

    Gradle插件运行

    Gatling官网的运行方式是下载整个Gatling,然后编写脚本以后,直接运行。这个操作不是很方便的,找到一个Gradle插件可以快速运行,其中Gatling的版本,参数等都可以通过build.gradle的参数配置,使用上是比较灵活的。

    插件的配置如下:

    plugins {
        id 'scala'
        id "com.github.lkishalmi.gatling" version "3.0.2"
    }
    
    gatling {
        toolVersion = '3.0.0'
        jvmArgs = [ '-server', '-Xms512M', '-Xmx512M' ]
        simulations = {
            include "**/*.scala"
        }
    }

    目录结构的要求是src/gatling/simulations,这个需要自己改一下

    读取配置

    配置可以是很多东西,比如比较常见的是不同环境不同的数据,比如URL,用户认证信息,或者是压测的压力情况都应该在配置,而不是硬编码在代码中。

    配置文件地址src/galting/resource/application.properties

    使用的时候直接调用

    val conf 
  • MySQL索引

    MySQL索引

    MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在各大互联网公司中,MySQL即其变种是最好的使用最多的关系型数据库。

    MySQL所使用的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL 软件采用了双授权政策,分为社区版和商业版。因为License的问题,还有兼容MySQL的MariaDB分支可选。

    磁盘IO与预读

    因为业务上对于数据库的要求其实是比较高,主要是速度上的,经常是几毫秒的。在这种情况下硬盘IO就需要关注了。机械硬盘是需要机械运动的,比如常说的7200转。IO的消费是很大的,所以操作系统做了一些额外的优化,当执行一次IO时,不光读取当前磁盘地址的数据,也会把相邻数据都读取到内存缓冲区内,每一次IO读取的数据称之为一页,一般为4k或8k。

    所以数据库在设计上有一个重要的方向就是减少IO。

    索引

    最容易的想到的方案就是记录一些数据的IO块的位置,比如自增ID为主键,前1000条在块N,后一千条在块N+1,当然这个方案有很多弊端,所以数据库专门抽象了索引这个概念。

    索引按照官方文档的说法是帮助MySQL高效获取数据的数据结构,具体到不同的存储引擎层面,具体的数据结构是有区别的。

    数据库查询是数据库的最主要功能之一,而应用都希望查询数据的速度能尽可能的快,因此数据库系统从设计层面会对查询进行优化。而不同的算法都只能应用于特定的数据结构之上,比如二叉树查找只能应用于二叉查找树上,但是数据本身的组织结构不可能完全满足各种数据结构。

    所以,在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用或者指向的数据,同时在这些数据结构上实现高级查找算法。这种数据结构就是索引。

    具体的索引结构支持又和引擎绑定,比如最常说B树或者B+树在MyISAM,InnoDB上都是支持的。

    索引 MyISAM引擎 InnoDB引擎 Memory引擎
    B-Tree 索引 支持 支持 支持
    HASH 索引 不支持 不支持 支持
    R-Tree 索引 支持 不支持 不支持
    Full-text 索引
  • Java中的toString

    Java中的toString

    Java中的Object包含一个toString方法,该方法默认实现是输出类名+hashcode,所以一般业务上都需要覆盖此方法实现。

    toString大部分时候都不影响功能,很大程度上是用于日志输出的时候,比如

    logger.info("user {} query keyword:{}", userId, searchParams)

    覆写该方法是必要的,我们以一个简单的类为例

    public class Hello   {
        private long id;
        private String message;
    }

    常见方法主要有以下几种:

    使用StringBuilder

    @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder("Hello{");
            sb.append("id=").append(id);
            sb.append(", message='").append(message).append('\'');
            sb.append('}');
            return sb.toString();
        }
  • 利用H2的自定义函数更好的支持测试

    在写DAO层的单元测试时,用mock的写法意义不大,因为DAO层的测试更多的关注是Java对象的传递和生成SQL的正确性,所以需要链接真实的数据库。

    但是对于单元测试,真实的数据库是很重的,还要依赖于数据库本身的初始化和数据情况。H2作为一个基于Java开发的嵌入式数据库,支持在内存运行,也支持文件模式,非常适合用在单元测试。因为Spring Boot等框架对于这一块的支持很全面了,特别是Spring Boot默认的JDBC测试如果没有配置,会自动启动一个H2的内存数据库。

    H2虽然支持很多模式,可以尽可能的模拟不同的数据库,但是还是有一些支持是不完整的,一些数据库特有的方法H2是不支持的,比如MySQL的UNIX_TIMESTAMP。特别是业务上基本都有创建时间和更新时间这两列,unix_timestamp函数大量使用。

    这里可以使用H2的一个特性–用户自定义函数,支持两种使用方式

    1. Java方法预编译
    2. Java源代码直接使用

    这里来看看如何让H2支持unix_timestamp方法:
    首先新建一个新Java类

    public class H2Extended {
        public static int unix_timestamp() {
            return (int)(System.currentTimeMillis() / 1000);
        }
    }

    然后使用SQL创建一个别名,并将别名链接到我们的Java类的对应方法中

    CREATE ALIAS UNIX_TIMESTAMP FOR "com.huangyunkun.tool.H2Extended.unix_timestamp";

    然后在初始化Datasource的时候执行该SQL语句就行了

    参考

    http://www.h2database.com/html/features.html#user_defined_functions
    https://hyrepo.com/tech/h2-unit-test/…

  • 自动化发布sited插件

    自动化发布sited插件

    最近又在弄多多猫的sited插件了,写插件本身没啥了,写好本地build一下,然后发布到插件中心。

    这里我注意到一个版本问题,大多数情况需要自己手动改一下版本,最近在用阿里的云效CodePipeline,想到这里可以自动化一下。

    阿里云的CodePipeline其实就是jenkins,从环境变量中可以获取当前Pipeline号,可以把这个作为版本号。然后上传的化,其实官方的上传主要就是一个普通的上传,一个curl命令就可以搞定。

    echo "Publish to sited plugins site"
    head dist/index.sited.xml
    curl -v 'http://sited.noear.org/dev/dev.ashx' -F "file=@dist/index.sited.xml"

     …

  • 快速使用SQLAdvisor

    快速使用SQLAdvisor

    美团点评开源的SQLAdvisor可以帮助分析SQL语句,同时提供优化建议。

    遗憾的是官方没有提供快速的使用方法,需要自己安装依赖并编译,使用起来确实不是很方便。今天做了一个Dockerfile,直接把工具打到Docker中,这样就可以快速使用了。

    使用如下:

    docker pull htynkn/sqladvisor

    验证,输出帮助信息

    docker run -rm htynkn/sqladvisor --help

  • Java诊断工具Arthas

    JVM自身提供了大量的诊断和调优工具,从jps、jstack、jmap、jhat、jstat、hprof等到visualvm等,提供了JVM进程信息,堆栈,堆内存等内容。

    Arthas是阿里开源的Java诊断工具,整合很多功能,而且是交互式。部分功能使用字节码增强技术,能够获取更多信息,而且还支持长时间后台监控,确实是一个不错的工具。

    Arthas安装比较简单,直接运行官方的sh脚本就行了,然后运行启动。这里要求本机必须有telnet,但是Mac默认已经移除了telnet,所以需要自己安装一下brew install telnet

    来几个使用示例

    查看类加载

    查看反编译代码

    这有一片文章比较详细的展示了Arthas的使用:

    http://hengyunabc.github.io/spring-boot-arthas-NoSuchMethodError/…

  • 说图

    说图

    什么图

    图是绘画表现出来的形象,图对比别的表现方式更生动,更直观。

    当然作为程序员常接触到的无非就是流程图,ER图,对象图,架构图等等。

    为什么

    工作中需要这些无非就两个用途,自己看;给别人看。

    我个人观点是图可以不绚丽,但是要清晰,可读,并且符合通用的图标标准。

    比如一个时序图,每个参与者是actor还是普通参与者,还是数据库等等,不同的图标代表不同的意义,可以用的比较简单,但是不能误用。

    工具

    画图工具比较多了,主要分两个大类,一是可视化绘制,即所见即所得那种,结果直接可控,而且细节调整度很大,但是操作比较繁琐,容易陷入细节,且工具比较多,付费的或者在线的比较多。

    Visio绝对是这种类型的一个佼佼者,唯一的缺点是平台限制。Mac世界可以用OmniGraffle,当然也是挺贵的。

    Linux世界可以用开源的Dia,我个人绝对还是不错的。

    在线版本的推荐Processon,使用免费,唯一的担心就是需要联网,其次就是有些是公司内部的东西,总不是那么放心。

    当然还有大神使用Excel或者Powerpoint也可以画出很牛的图,不过我觉得那个对于功底要求有点高了。

    另外一种是代码生成图像的,比较符合程序员的风格,可以直接通过代码生成最后的图,操作比较直接,缺陷是反馈比较慢,可调整型也不好。

    我曾经尝试过D3.js,这个控制层次很低,效果可好可坏,看个人了。

    我比较推荐PlantUML,这个画图比较直接,效果还过得去,亮点是对于程序员需要的相关图支持很好,比如UML,时序图,类图,组件图,部署图等等。

    具体的话有本地版本,可以转化为图片,也有在线免费版本,直接把代码转为图。

    比如下图:…

  • Git多套配置的条件应用

    Git是有配置的,比如用户名和邮箱,在一些情况下对于不同的项目可能需要不同的Git配置,比如在家需要做一些公司相关的事情,那么gitconfig的邮箱就是公司邮箱,但是平时有一些自己的代码,放Github那种可能又需要配置其他信息。有时候ssh key也不一样,总的来说需要一种多环境配置的支持,之间相互隔离。

    一种办法是将全局配置和单一配置分开,即单个项目的git目录中加一个config,这样的配置主要问题是每一个需要单一配置的项目都需要这么做。

    另外一个办法是使用条件应用,这种配置可以根据目录来区分,比如有一个目录叫work,那么work中就使用专门一套config。

    [user]
    name = hyunkun
    email = [email protected]
    
    [includeIf "gitdir:~/OpenSource/"]
    path = ~/OpenSource/.gitconfig

     …

  • Hello Flutter

    之前用过React Native,同时开始Android端和iOS端还是比较舒适。

    最近Flutter很火,仔细看了一下,感觉比RN要快一些,所以就上手看看。

    首先上遇到的问题就是Flutter的安装,因为我是Mac,直接写了一个HomeBrew的脚本 https://github.com/htynkn/homebrew-formulas/blob/master/flutter.rb

    另外一个问题就是依赖构建,我平时都使用的maven aliyun的镜像,但是Flutter创建出来的项目很奇怪,访问jcenter会报错,即便我的网络问题解决了。只有手动指向aliyun的地址,但是修改了build.gradle文件以后还是出现了jcenter报错。

    最后是在

    $flutterRoot/packages/flutter_tools/gradle/flutter.gradle

    中找到了jcenter的配置,手动修改以后就好了。

    自动化也是一个很重要的,Travis的配置相对比较繁琐,需要Java,Android,Dart和Flutter环境。

    Travis提供了Android支持,同时可以指定对应的构建工具版本。所以手动安装Flutter就行了。

    language: android
    os:
      - linux
    
    android:
      components:
      - tools
      - platform-tools
      - build-tools-27.0.3
      - android-27
      - extra-android-support
      - extra-google-google_play_services
      - extra-android-m2repository
      - extra-google-m2repository
    
    before_install:
      - git clone -b